<commit_before>// This file is part of Caribon.
//
// Caribon is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
//
// Caribon is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Caribon.  If not, see <http://www.gnu.org/licenses/>.

use error::Error;
use error::Result;

/// `Word` type: some inner representation used by `Parser`.
///
/// You probably should not use this type directly.
#[derive(Debug,Clone)]
pub enum Word {
    /// A String which is not part of the text (typically whitespace, HTML formatting, ...)
    Untracked(String),
    /// A word that is ignored, either because it is in `parser.ignored` or because it is
    /// a proper noun and `ignore_proper` has been set to `true`.
    Ignored(String),
    /// Tracked string, containing the string, the stemmed variant of the
    /// string, some value corresponding to the degree of repetitions and
    /// an option to a highlighting colour
    Tracked(String, String, f32, Option<&'static str>),
}

impl Word {
    /// Sets the stemmed value of a word.
    pub fn set_stemmed(&mut self, s:String) {
        match self {
            &mut Word::Tracked(_, ref mut stemmed, _, _) => {
                *stemmed = s;
            },
            _ => {}
        }
    }

    /// Sets the repetition value of a word.
    pub fn set_count(&mut self, x: f32)  {
        match self {
            &mut Word::Tracked(_, _, ref mut v, _) => {
                *v = x;
            },
            _ => {}
        }
    }
}

#[derive(Debug,Clone)]
/// Represents an AST. Contains a vector of words plus some additonal informations for HTML parsing
pub struct Ast {
    /// Vector of words, used by detect_[local|global]
    pub words: Vec<Word>,
    /// Position of <head> tag, if any
    pub begin_head: Option<usize>,
    /// position of <body> tag, if any
    pub begin_body: Option<usize>,
    /// position of </body> tag, if any
    pub end_body: Option<usize>,
}

impl Ast {
    /// Creates a new, empty AST
    pub fn new() -> Ast {
        Ast {
            words: vec!(),
            begin_head: None,
            begin_body: None,
            end_body: None
        }
    }

    /// Sets begin_head to current last position of words
    pub fn mark_begin_head(&mut self) {
        if self.begin_head.is_some() {
            return;
        }

        let i = self.words.len();
        self.begin_head = Some(i);
    }

    /// Sets begin_head to current last position of words
    pub fn mark_begin_body(&mut self)  {
        if self.begin_body.is_some() {
            return;
        }

        let i = self.words.len();
        self.begin_body = Some(i);
    }

    /// Sets begin_head to current last position of words
    pub fn mark_end_body(&mut self) {
        let i = self.words.len();
        self.end_body = Some(i);
    }

    /// Get only the words contained between <body> and </body>
    ///
    /// If body_begin and body_end are both set (and the fist one is before the second),
    /// returns a slice that contains only words in this part; else, returns all words.
    pub fn get_body(&self) -> &[Word] {
        if let Some(begin) = self.begin_body {
            if let Some(end) = self.end_body {
                if begin < end {
                    return &self.words[begin + 1..end];
                }
            }
        }
        return &self.words;
    }
}
<commit_msg>removed unused import<commit_after>// This file is part of Caribon.
//
// Caribon is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
//
// Caribon is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Caribon.  If not, see <http://www.gnu.org/licenses/>.

/// `Word` type: some inner representation used by `Parser`.
///
/// You probably should not use this type directly.
#[derive(Debug,Clone)]
pub enum Word {
    /// A String which is not part of the text (typically whitespace, HTML formatting, ...)
    Untracked(String),
    /// A word that is ignored, either because it is in `parser.ignored` or because it is
    /// a proper noun and `ignore_proper` has been set to `true`.
    Ignored(String),
    /// Tracked string, containing the string, the stemmed variant of the
    /// string, some value corresponding to the degree of repetitions and
    /// an option to a highlighting colour
    Tracked(String, String, f32, Option<&'static str>),
}

impl Word {
    /// Sets the stemmed value of a word.
    pub fn set_stemmed(&mut self, s:String) {
        match self {
            &mut Word::Tracked(_, ref mut stemmed, _, _) => {
                *stemmed = s;
            },
            _ => {}
        }
    }

    /// Sets the repetition value of a word.
    pub fn set_count(&mut self, x: f32)  {
        match self {
            &mut Word::Tracked(_, _, ref mut v, _) => {
                *v = x;
            },
            _ => {}
        }
    }
}

#[derive(Debug,Clone)]
/// Represents an AST. Contains a vector of words plus some additonal informations for HTML parsing
pub struct Ast {
    /// Vector of words, used by detect_[local|global]
    pub words: Vec<Word>,
    /// Position of <head> tag, if any
    pub begin_head: Option<usize>,
    /// position of <body> tag, if any
    pub begin_body: Option<usize>,
    /// position of </body> tag, if any
    pub end_body: Option<usize>,
}

impl Ast {
    /// Creates a new, empty AST
    pub fn new() -> Ast {
        Ast {
            words: vec!(),
            begin_head: None,
            begin_body: None,
            end_body: None
        }
    }

    /// Sets begin_head to current last position of words
    pub fn mark_begin_head(&mut self) {
        if self.begin_head.is_some() {
            return;
        }

        let i = self.words.len();
        self.begin_head = Some(i);
    }

    /// Sets begin_head to current last position of words
    pub fn mark_begin_body(&mut self)  {
        if self.begin_body.is_some() {
            return;
        }

        let i = self.words.len();
        self.begin_body = Some(i);
    }

    /// Sets begin_head to current last position of words
    pub fn mark_end_body(&mut self) {
        let i = self.words.len();
        self.end_body = Some(i);
    }

    /// Get only the words contained between <body> and </body>
    ///
    /// If body_begin and body_end are both set (and the fist one is before the second),
    /// returns a slice that contains only words in this part; else, returns all words.
    pub fn get_body(&self) -> &[Word] {
        if let Some(begin) = self.begin_body {
            if let Some(end) = self.end_body {
                if begin < end {
                    return &self.words[begin + 1..end];
                }
            }
        }
        return &self.words;
    }
}
<|endoftext|>


<commit_before>use regex::Regex;

pub fn pattern(pattern: &String) -> bool {
    return !is_banned_speech_act(pattern) && !is_banned_pattern(pattern);
}

fn is_banned_speech_act(pattern: &String) -> bool {
    if !pattern.contains("PERSON.noun") || pattern.split_whitespace().count() != 2 {
        return false;
    }
    let re = Regex::new(r"\s(object|continue|come|go|sit|open|close|begin|end|believe|happen|leave|understand|realize|debate|speak|show|stand|call|refer|believe|lose|change|care|hear|write|disagree|read|tell|start|talk|explain|come|live|take|support|guess|feel|follow|make|go|get|move|agree|find|fail|think|wonder|feel|ask|argue|try)\.").unwrap();
    return re.is_match(pattern);
}

fn is_banned_pattern(pattern: &String) -> bool {
    if vec![
        "PERSON.noun be.verb correct.adj",
        "PERSON.noun be.verb able.adj",
        "PERSON.noun be.verb good.adj",
        "PERSON.noun be.verb likely.adj",
        "PERSON.noun be.verb sorry.adj",
        "PERSON.noun be.verb say.verb",
        "PERSON.noun be.verb aware.adj",
        "PERSON.noun be.verb one.noun",
        "PERSON.noun be.verb sure.adj",
        "PERSON.noun be.verb wrong.adj",
        "PERSON.noun be.verb right.adj",
        "PERSON.noun be.verb glad.adj",
        "PERSON.noun be.verb here.noun",
        "PERSON.noun be.verb willing.verb",
        "PERSON.noun be.verb true.adj",
        "PERSON.noun be.verb false.adj",
        "PERSON.noun be.verb favor.noun",
        "PERSON.noun be.verb interested.adj",
        "PERSON.noun want.verb have.verb",
        "PERSON.noun want.verb what.wp",
        "PERSON.noun want.verb what.wp do.verb",
        "PERSON.noun say.verb what.wp",
        "PERSON.noun mean.verb what.wp",
        "PERSON.noun know.verb what.wp",
        "PERSON.noun believe.verb what.wp",
        "PERSON.noun see.verb what.wp",
        "PERSON.noun see.verb argument.noun",
        "PERSON.noun have.verb problem.noun",
        "PERSON.noun tell.verb PERSON.noun",
        "PERSON.noun think.verb what.wp",
        "PERSON.noun argue.verb in.prep fact.noun",
        "PERSON.noun argue.verb with.prep PERSON.noun",
        "debate.noun be.verb about.adj",
        "question.noun be.verb",
        "make.verb claim.noun",
        "ask.verb PERSON.noun",
        "thing.noun happen.verb",
        "something.noun happen.verb"].contains(&pattern.as_str()) {
            return true;
        } else {
            return false;
        }
}
<commit_msg>Remove patterns with ambiguous subjects<commit_after>use regex::Regex;

pub fn pattern(pattern: &String) -> bool {
    return !is_banned_speech_act(pattern) &&
        !is_banned_pattern(pattern) &&
        !has_banned_subject(&pattern);
}

fn has_banned_subject(pattern: &String) -> bool {
    let re = Regex::new(r"(^|\s)(it.pn|which.wdt|what.wp|that.dt|this.dt)($|\s)").unwrap();
    return re.is_match(pattern);
}

fn is_banned_speech_act(pattern: &String) -> bool {
    if !pattern.contains("PERSON.noun") || pattern.split_whitespace().count() != 2 {
        return false;
    }
    let re = Regex::new(r"\s(object|continue|come|go|sit|open|close|begin|end|believe|happen|leave|understand|realize|debate|speak|show|stand|call|refer|believe|lose|change|care|hear|write|disagree|read|tell|start|talk|explain|come|live|take|support|guess|feel|follow|make|go|get|move|agree|find|fail|think|wonder|feel|ask|argue|try)\.").unwrap();
    return re.is_match(pattern);
}

fn is_banned_pattern(pattern: &String) -> bool {
    if vec![
        "PERSON.noun be.verb correct.adj",
        "PERSON.noun be.verb able.adj",
        "PERSON.noun be.verb good.adj",
        "PERSON.noun be.verb likely.adj",
        "PERSON.noun be.verb sorry.adj",
        "PERSON.noun be.verb say.verb",
        "PERSON.noun be.verb aware.adj",
        "PERSON.noun be.verb one.noun",
        "PERSON.noun be.verb sure.adj",
        "PERSON.noun be.verb wrong.adj",
        "PERSON.noun be.verb right.adj",
        "PERSON.noun be.verb glad.adj",
        "PERSON.noun be.verb here.noun",
        "PERSON.noun be.verb willing.verb",
        "PERSON.noun be.verb true.adj",
        "PERSON.noun be.verb false.adj",
        "PERSON.noun be.verb favor.noun",
        "PERSON.noun be.verb interested.adj",
        "PERSON.noun want.verb have.verb",
        "PERSON.noun want.verb what.wp",
        "PERSON.noun want.verb what.wp do.verb",
        "PERSON.noun say.verb what.wp",
        "PERSON.noun mean.verb what.wp",
        "PERSON.noun know.verb what.wp",
        "PERSON.noun believe.verb what.wp",
        "PERSON.noun see.verb what.wp",
        "PERSON.noun see.verb argument.noun",
        "PERSON.noun have.verb problem.noun",
        "PERSON.noun tell.verb PERSON.noun",
        "PERSON.noun think.verb what.wp",
        "PERSON.noun argue.verb in.prep fact.noun",
        "PERSON.noun argue.verb with.prep PERSON.noun",
        "debate.noun be.verb about.adj",
        "question.noun be.verb",
        "make.verb claim.noun",
        "ask.verb PERSON.noun",
        "thing.noun happen.verb",
        "something.noun happen.verb"].contains(&pattern.as_str()) {
            return true;
        } else {
            return false;
        }
}
<|endoftext|>


<commit_before>use bytes::BytesMut;
use chrono_04::{DateTime, Duration, FixedOffset, Local, NaiveDate, NaiveDateTime, NaiveTime, Utc};
use postgres_protocol::types;
use std::error::Error;

use crate::{FromSql, IsNull, ToSql, Type};

fn base() -> NaiveDateTime {
    NaiveDate::from_ymd_opt(2000, 1, 1).unwrap().and_hms_opt(0, 0, 0).unwrap()
}

impl<'a> FromSql<'a> for NaiveDateTime {
    fn from_sql(_: &Type, raw: &[u8]) -> Result<NaiveDateTime, Box<dyn Error + Sync + Send>> {
        let t = types::timestamp_from_sql(raw)?;
        base()
            .checked_add_signed(Duration::microseconds(t))
            .ok_or_else(|| "value too large to decode".into())
    }

    accepts!(TIMESTAMP);
}

impl ToSql for NaiveDateTime {
    fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
        let time = match self.signed_duration_since(base()).num_microseconds() {
            Some(time) => time,
            None => return Err("value too large to transmit".into()),
        };
        types::timestamp_to_sql(time, w);
        Ok(IsNull::No)
    }

    accepts!(TIMESTAMP);
    to_sql_checked!();
}

impl<'a> FromSql<'a> for DateTime<Utc> {
    fn from_sql(type_: &Type, raw: &[u8]) -> Result<DateTime<Utc>, Box<dyn Error + Sync + Send>> {
        let naive = NaiveDateTime::from_sql(type_, raw)?;
        Ok(DateTime::from_utc(naive, Utc))
    }

    accepts!(TIMESTAMPTZ);
}

impl ToSql for DateTime<Utc> {
    fn to_sql(
        &self,
        type_: &Type,
        w: &mut BytesMut,
    ) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
        self.naive_utc().to_sql(type_, w)
    }

    accepts!(TIMESTAMPTZ);
    to_sql_checked!();
}

impl<'a> FromSql<'a> for DateTime<Local> {
    fn from_sql(type_: &Type, raw: &[u8]) -> Result<DateTime<Local>, Box<dyn Error + Sync + Send>> {
        let utc = DateTime::<Utc>::from_sql(type_, raw)?;
        Ok(utc.with_timezone(&Local))
    }

    accepts!(TIMESTAMPTZ);
}

impl ToSql for DateTime<Local> {
    fn to_sql(
        &self,
        type_: &Type,
        w: &mut BytesMut,
    ) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
        self.with_timezone(&Utc).to_sql(type_, w)
    }

    accepts!(TIMESTAMPTZ);
    to_sql_checked!();
}

impl<'a> FromSql<'a> for DateTime<FixedOffset> {
    fn from_sql(
        type_: &Type,
        raw: &[u8],
    ) -> Result<DateTime<FixedOffset>, Box<dyn Error + Sync + Send>> {
        let utc = DateTime::<Utc>::from_sql(type_, raw)?;
        Ok(utc.with_timezone(&FixedOffset::east_opt(0).unwrap()))
    }

    accepts!(TIMESTAMPTZ);
}

impl ToSql for DateTime<FixedOffset> {
    fn to_sql(
        &self,
        type_: &Type,
        w: &mut BytesMut,
    ) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
        self.with_timezone(&Utc).to_sql(type_, w)
    }

    accepts!(TIMESTAMPTZ);
    to_sql_checked!();
}

impl<'a> FromSql<'a> for NaiveDate {
    fn from_sql(_: &Type, raw: &[u8]) -> Result<NaiveDate, Box<dyn Error + Sync + Send>> {
        let jd = types::date_from_sql(raw)?;
        base()
            .date()
            .checked_add_signed(Duration::days(i64::from(jd)))
            .ok_or_else(|| "value too large to decode".into())
    }

    accepts!(DATE);
}

impl ToSql for NaiveDate {
    fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
        let jd = self.signed_duration_since(base().date()).num_days();
        if jd > i64::from(i32::max_value()) || jd < i64::from(i32::min_value()) {
            return Err("value too large to transmit".into());
        }

        types::date_to_sql(jd as i32, w);
        Ok(IsNull::No)
    }

    accepts!(DATE);
    to_sql_checked!();
}

impl<'a> FromSql<'a> for NaiveTime {
    fn from_sql(_: &Type, raw: &[u8]) -> Result<NaiveTime, Box<dyn Error + Sync + Send>> {
        let usec = types::time_from_sql(raw)?;
        Ok(NaiveTime::from_hms_opt(0, 0, 0).unwrap() + Duration::microseconds(usec))
    }

    accepts!(TIME);
}

impl ToSql for NaiveTime {
    fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
        let delta = self.signed_duration_since(NaiveTime::from_hms_opt(0, 0, 0).unwrap());
        let time = match delta.num_microseconds() {
            Some(time) => time,
            None => return Err("value too large to transmit".into()),
        };
        types::time_to_sql(time, w);
        Ok(IsNull::No)
    }

    accepts!(TIME);
    to_sql_checked!();
}
<commit_msg>rustfmt<commit_after>use bytes::BytesMut;
use chrono_04::{DateTime, Duration, FixedOffset, Local, NaiveDate, NaiveDateTime, NaiveTime, Utc};
use postgres_protocol::types;
use std::error::Error;

use crate::{FromSql, IsNull, ToSql, Type};

fn base() -> NaiveDateTime {
    NaiveDate::from_ymd_opt(2000, 1, 1)
        .unwrap()
        .and_hms_opt(0, 0, 0)
        .unwrap()
}

impl<'a> FromSql<'a> for NaiveDateTime {
    fn from_sql(_: &Type, raw: &[u8]) -> Result<NaiveDateTime, Box<dyn Error + Sync + Send>> {
        let t = types::timestamp_from_sql(raw)?;
        base()
            .checked_add_signed(Duration::microseconds(t))
            .ok_or_else(|| "value too large to decode".into())
    }

    accepts!(TIMESTAMP);
}

impl ToSql for NaiveDateTime {
    fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
        let time = match self.signed_duration_since(base()).num_microseconds() {
            Some(time) => time,
            None => return Err("value too large to transmit".into()),
        };
        types::timestamp_to_sql(time, w);
        Ok(IsNull::No)
    }

    accepts!(TIMESTAMP);
    to_sql_checked!();
}

impl<'a> FromSql<'a> for DateTime<Utc> {
    fn from_sql(type_: &Type, raw: &[u8]) -> Result<DateTime<Utc>, Box<dyn Error + Sync + Send>> {
        let naive = NaiveDateTime::from_sql(type_, raw)?;
        Ok(DateTime::from_utc(naive, Utc))
    }

    accepts!(TIMESTAMPTZ);
}

impl ToSql for DateTime<Utc> {
    fn to_sql(
        &self,
        type_: &Type,
        w: &mut BytesMut,
    ) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
        self.naive_utc().to_sql(type_, w)
    }

    accepts!(TIMESTAMPTZ);
    to_sql_checked!();
}

impl<'a> FromSql<'a> for DateTime<Local> {
    fn from_sql(type_: &Type, raw: &[u8]) -> Result<DateTime<Local>, Box<dyn Error + Sync + Send>> {
        let utc = DateTime::<Utc>::from_sql(type_, raw)?;
        Ok(utc.with_timezone(&Local))
    }

    accepts!(TIMESTAMPTZ);
}

impl ToSql for DateTime<Local> {
    fn to_sql(
        &self,
        type_: &Type,
        w: &mut BytesMut,
    ) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
        self.with_timezone(&Utc).to_sql(type_, w)
    }

    accepts!(TIMESTAMPTZ);
    to_sql_checked!();
}

impl<'a> FromSql<'a> for DateTime<FixedOffset> {
    fn from_sql(
        type_: &Type,
        raw: &[u8],
    ) -> Result<DateTime<FixedOffset>, Box<dyn Error + Sync + Send>> {
        let utc = DateTime::<Utc>::from_sql(type_, raw)?;
        Ok(utc.with_timezone(&FixedOffset::east_opt(0).unwrap()))
    }

    accepts!(TIMESTAMPTZ);
}

impl ToSql for DateTime<FixedOffset> {
    fn to_sql(
        &self,
        type_: &Type,
        w: &mut BytesMut,
    ) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
        self.with_timezone(&Utc).to_sql(type_, w)
    }

    accepts!(TIMESTAMPTZ);
    to_sql_checked!();
}

impl<'a> FromSql<'a> for NaiveDate {
    fn from_sql(_: &Type, raw: &[u8]) -> Result<NaiveDate, Box<dyn Error + Sync + Send>> {
        let jd = types::date_from_sql(raw)?;
        base()
            .date()
            .checked_add_signed(Duration::days(i64::from(jd)))
            .ok_or_else(|| "value too large to decode".into())
    }

    accepts!(DATE);
}

impl ToSql for NaiveDate {
    fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
        let jd = self.signed_duration_since(base().date()).num_days();
        if jd > i64::from(i32::max_value()) || jd < i64::from(i32::min_value()) {
            return Err("value too large to transmit".into());
        }

        types::date_to_sql(jd as i32, w);
        Ok(IsNull::No)
    }

    accepts!(DATE);
    to_sql_checked!();
}

impl<'a> FromSql<'a> for NaiveTime {
    fn from_sql(_: &Type, raw: &[u8]) -> Result<NaiveTime, Box<dyn Error + Sync + Send>> {
        let usec = types::time_from_sql(raw)?;
        Ok(NaiveTime::from_hms_opt(0, 0, 0).unwrap() + Duration::microseconds(usec))
    }

    accepts!(TIME);
}

impl ToSql for NaiveTime {
    fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
        let delta = self.signed_duration_since(NaiveTime::from_hms_opt(0, 0, 0).unwrap());
        let time = match delta.num_microseconds() {
            Some(time) => time,
            None => return Err("value too large to transmit".into()),
        };
        types::time_to_sql(time, w);
        Ok(IsNull::No)
    }

    accepts!(TIME);
    to_sql_checked!();
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use geom::point::Point2D;
use geom::rect::Rect;
use geom::size::Size2D;

use core::num::NumCast;

pub struct Au(i32);

impl Add<Au,Au> for Au {
    fn add(&self, other: &Au) -> Au { Au(**self + **other) }
}

impl Sub<Au,Au> for Au {
    fn sub(&self, other: &Au) -> Au { Au(**self - **other) }
}

impl Mul<Au,Au> for Au {
    fn mul(&self, other: &Au) -> Au { Au(**self * **other) }
}

impl Quot<Au,Au> for Au {
    fn quot(&self, other: &Au) -> Au { Au(**self / **other) }
}

impl Rem<Au,Au> for Au {
    fn rem(&self, other: &Au) -> Au { Au(**self % **other) }
}

impl Neg<Au> for Au {
    fn neg(&self) -> Au { Au(-**self) }
}

impl cmp::Ord for Au {
    fn lt(&self, other: &Au) -> bool { **self <  **other }
    fn le(&self, other: &Au) -> bool { **self <= **other }
    fn ge(&self, other: &Au) -> bool { **self >= **other }
    fn gt(&self, other: &Au) -> bool { **self >  **other }
}

impl cmp::Eq for Au {
    fn eq(&self, other: &Au) -> bool { **self == **other }
    fn ne(&self, other: &Au) -> bool { **self != **other }
}

pub fn min(x: Au, y: Au) -> Au { if x < y { x } else { y } }
pub fn max(x: Au, y: Au) -> Au { if x > y { x } else { y } }

impl NumCast for Au {
    fn from<T:NumCast>(n: T) -> Au { Au(n.to_i32()) }

    fn to_u8(&self) -> u8       { (**self).to_u8() }
    fn to_u16(&self) -> u16     { (**self).to_u16() }
    fn to_u32(&self) -> u32     { (**self).to_u32() }
    fn to_u64(&self) -> u64     { (**self).to_u64() }
    fn to_uint(&self) -> uint   { (**self).to_uint() }

    fn to_i8(&self) -> i8       { (**self).to_i8() }
    fn to_i16(&self) -> i16     { (**self).to_i16() }
    fn to_i32(&self) -> i32     { (**self).to_i32() }
    fn to_i64(&self) -> i64     { (**self).to_i64() }
    fn to_int(&self) -> int     { (**self).to_int() }

    fn to_f32(&self) -> f32     { (**self).to_f32() }
    fn to_f64(&self) -> f64     { (**self).to_f64() }
    fn to_float(&self) -> float { (**self).to_float() }
}

pub fn box<T:Copy + Ord + Add<T,T> + Sub<T,T>>(x: T, y: T, w: T, h: T) -> Rect<T> {
    Rect(Point2D(x, y), Size2D(w, h))
}

pub impl Au {
    pub fn scale_by(self, factor: float) -> Au {
        Au(((*self as float) * factor) as i32)
    }

    pub fn from_px(i: int) -> Au {
        NumCast::from(i * 60)
    }

    pub fn to_px(&self) -> int {
        (**self / 60) as int
    }

    pub fn to_snapped(&self) -> Au {
        let res = **self % 60i32;
        return if res >= 30i32 { return Au(**self - res + 60i32) }
                       else { return Au(**self - res) };
    }

    pub fn zero_point() -> Point2D<Au> {
        Point2D(Au(0), Au(0))
    }

    pub fn zero_rect() -> Rect<Au> {
        let z = Au(0);
        Rect(Point2D(z, z), Size2D(z, z))
    }

    // assumes 72 points per inch, and 96 px per inch
    pub fn from_pt(f: float) -> Au {
        from_px((f / 72f * 96f) as int)
    }

    pub fn from_frac_px(f: float) -> Au {
        Au((f * 60f) as i32)
    }

    pub fn min(x: Au, y: Au) -> Au { if *x < *y { x } else { y } }
    pub fn max(x: Au, y: Au) -> Au { if *x > *y { x } else { y } }
}

pub fn zero_rect() -> Rect<Au> {
    let z = Au(0);
    Rect(Point2D(z, z), Size2D(z, z))
}

pub fn zero_point() -> Point2D<Au> {
    Point2D(Au(0), Au(0))
}

pub fn zero_size() -> Size2D<Au> {
    Size2D(Au(0), Au(0))
}

pub fn from_frac_px(f: float) -> Au {
    Au((f * 60f) as i32)
}

pub fn from_px(i: int) -> Au {
    NumCast::from(i * 60)
}

pub fn to_px(au: Au) -> int {
    (*au / 60) as int
}

pub fn to_frac_px(au: Au) -> float {
    (*au as float) / 60f
}

// assumes 72 points per inch, and 96 px per inch
pub fn from_pt(f: float) -> Au {
    from_px((f / 72f * 96f) as int)
}
<commit_msg>Change Quot back to Div.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use geom::point::Point2D;
use geom::rect::Rect;
use geom::size::Size2D;

use core::num::NumCast;

pub struct Au(i32);

impl Add<Au,Au> for Au {
    fn add(&self, other: &Au) -> Au { Au(**self + **other) }
}

impl Sub<Au,Au> for Au {
    fn sub(&self, other: &Au) -> Au { Au(**self - **other) }
}

impl Mul<Au,Au> for Au {
    fn mul(&self, other: &Au) -> Au { Au(**self * **other) }
}

impl Div<Au,Au> for Au {
    fn div(&self, other: &Au) -> Au { Au(**self / **other) }
}

impl Rem<Au,Au> for Au {
    fn rem(&self, other: &Au) -> Au { Au(**self % **other) }
}

impl Neg<Au> for Au {
    fn neg(&self) -> Au { Au(-**self) }
}

impl cmp::Ord for Au {
    fn lt(&self, other: &Au) -> bool { **self <  **other }
    fn le(&self, other: &Au) -> bool { **self <= **other }
    fn ge(&self, other: &Au) -> bool { **self >= **other }
    fn gt(&self, other: &Au) -> bool { **self >  **other }
}

impl cmp::Eq for Au {
    fn eq(&self, other: &Au) -> bool { **self == **other }
    fn ne(&self, other: &Au) -> bool { **self != **other }
}

pub fn min(x: Au, y: Au) -> Au { if x < y { x } else { y } }
pub fn max(x: Au, y: Au) -> Au { if x > y { x } else { y } }

impl NumCast for Au {
    fn from<T:NumCast>(n: T) -> Au { Au(n.to_i32()) }

    fn to_u8(&self) -> u8       { (**self).to_u8() }
    fn to_u16(&self) -> u16     { (**self).to_u16() }
    fn to_u32(&self) -> u32     { (**self).to_u32() }
    fn to_u64(&self) -> u64     { (**self).to_u64() }
    fn to_uint(&self) -> uint   { (**self).to_uint() }

    fn to_i8(&self) -> i8       { (**self).to_i8() }
    fn to_i16(&self) -> i16     { (**self).to_i16() }
    fn to_i32(&self) -> i32     { (**self).to_i32() }
    fn to_i64(&self) -> i64     { (**self).to_i64() }
    fn to_int(&self) -> int     { (**self).to_int() }

    fn to_f32(&self) -> f32     { (**self).to_f32() }
    fn to_f64(&self) -> f64     { (**self).to_f64() }
    fn to_float(&self) -> float { (**self).to_float() }
}

pub fn box<T:Copy + Ord + Add<T,T> + Sub<T,T>>(x: T, y: T, w: T, h: T) -> Rect<T> {
    Rect(Point2D(x, y), Size2D(w, h))
}

pub impl Au {
    pub fn scale_by(self, factor: float) -> Au {
        Au(((*self as float) * factor) as i32)
    }

    pub fn from_px(i: int) -> Au {
        NumCast::from(i * 60)
    }

    pub fn to_px(&self) -> int {
        (**self / 60) as int
    }

    pub fn to_snapped(&self) -> Au {
        let res = **self % 60i32;
        return if res >= 30i32 { return Au(**self - res + 60i32) }
                       else { return Au(**self - res) };
    }

    pub fn zero_point() -> Point2D<Au> {
        Point2D(Au(0), Au(0))
    }

    pub fn zero_rect() -> Rect<Au> {
        let z = Au(0);
        Rect(Point2D(z, z), Size2D(z, z))
    }

    // assumes 72 points per inch, and 96 px per inch
    pub fn from_pt(f: float) -> Au {
        from_px((f / 72f * 96f) as int)
    }

    pub fn from_frac_px(f: float) -> Au {
        Au((f * 60f) as i32)
    }

    pub fn min(x: Au, y: Au) -> Au { if *x < *y { x } else { y } }
    pub fn max(x: Au, y: Au) -> Au { if *x > *y { x } else { y } }
}

pub fn zero_rect() -> Rect<Au> {
    let z = Au(0);
    Rect(Point2D(z, z), Size2D(z, z))
}

pub fn zero_point() -> Point2D<Au> {
    Point2D(Au(0), Au(0))
}

pub fn zero_size() -> Size2D<Au> {
    Size2D(Au(0), Au(0))
}

pub fn from_frac_px(f: float) -> Au {
    Au((f * 60f) as i32)
}

pub fn from_px(i: int) -> Au {
    NumCast::from(i * 60)
}

pub fn to_px(au: Au) -> int {
    (*au / 60) as int
}

pub fn to_frac_px(au: Au) -> float {
    (*au as float) / 60f
}

// assumes 72 points per inch, and 96 px per inch
pub fn from_pt(f: float) -> Au {
    from_px((f / 72f * 96f) as int)
}
<|endoftext|>


<commit_before>//! Module: czmq-zmsg

use {czmq_sys, Error, ErrorKind, RawInterface, Result, Sockish, ZFrame};
use std::{error, fmt, mem, ptr, result};
use std::ffi::{CStr, CString};

pub struct ZMsg {
    zmsg: *mut czmq_sys::zmsg_t,
    owned: bool,
}

unsafe impl Send for ZMsg {}
unsafe impl Sync for ZMsg {}

impl Drop for ZMsg {
    fn drop(&mut self) {
        if self.owned {
            unsafe { czmq_sys::zmsg_destroy(&mut self.zmsg) };
        }
    }
}

impl ZMsg {
    pub fn new() -> ZMsg {
        ZMsg {
            zmsg: unsafe { czmq_sys::zmsg_new() },
            owned: true,
        }
    }

    pub fn recv<S: Sockish>(source: &S) -> Result<ZMsg> {
        let zmsg = unsafe { czmq_sys::zmsg_recv(source.borrow_raw()) };

        if zmsg == ptr::null_mut() {
            Err(Error::new(ErrorKind::NullPtr, ZMsgError::CmdFailed))
        } else {
            Ok(ZMsg {
                zmsg: zmsg,
                owned: true,
            })
        }
    }

    // XXX We'll have to roll our own here as we can't imitate a C
    // file handle without C boilerplate...which we're not doing!
    // pub fn zmsg_load(file: *mut FILE) -> *mut zmsg_t;

    pub fn encode(&self) -> Result<ZFrame> {
        let zframe = unsafe { czmq_sys::zmsg_encode(self.zmsg) };

        if zframe == ptr::null_mut() {
            Err(Error::new(ErrorKind::NullPtr, ZMsgError::CmdFailed))
        } else {
            Ok(ZFrame::from_raw(zframe, true))
        }
    }

    pub fn decode(frame: &ZFrame) -> Result<ZMsg> {
        let zmsg = unsafe { czmq_sys::zmsg_decode(frame.borrow_raw()) };

        if zmsg == ptr::null_mut() {
            Err(Error::new(ErrorKind::NullPtr, ZMsgError::CmdFailed))
        } else {
            Ok(ZMsg {
                zmsg: zmsg,
                owned: true,
            })
        }
    }

    pub fn new_signal(status: u8) -> Result<ZMsg> {
        let zmsg = unsafe { czmq_sys::zmsg_new_signal(status) };

        if zmsg == ptr::null_mut() {
            Err(Error::new(ErrorKind::NullPtr, ZMsgError::CmdFailed))
        } else {
            Ok(ZMsg {
                zmsg: zmsg,
                owned: true,
            })
        }
    }

    pub fn send<D: Sockish>(self, dest: &D) -> Result<()> {
        let mut zmsg = self;

        let rc = unsafe { czmq_sys::zmsg_send(&mut zmsg.zmsg, dest.borrow_raw()) };
        if rc == -1 {
            Err(Error::new(ErrorKind::NonZero, ZMsgError::CmdFailed))
        } else {
            Ok(())
        }
    }

    // pub fn zmsg_sendm(self_p: *mut *mut zmsg_t,
    //                   dest: *mut ::std::os::raw::c_void)
    //  -> ::std::os::raw::c_int;

    pub fn size(&self) -> usize {
        unsafe { czmq_sys::zmsg_size(self.zmsg) as usize }
    }

    // pub fn zmsg_content_size(_self: *mut zmsg_t) -> size_t;

    pub fn prepend(&self, frame: ZFrame) -> Result<()> {
        let rc = unsafe { czmq_sys::zmsg_prepend(self.zmsg, &mut frame.into_raw()) };

        if rc == 0 {
            Ok(())
        } else {
            Err(Error::new(ErrorKind::NonZero, ZMsgError::CmdFailed))
        }
    }

    pub fn append(&self, frame: ZFrame) -> Result<()> {
        let rc = unsafe { czmq_sys::zmsg_append(self.zmsg, &mut frame.into_raw()) };

        if rc == 0 {
            Ok(())
        } else {
            Err(Error::new(ErrorKind::NonZero, ZMsgError::CmdFailed))
        }
    }

    pub fn pop(&self) -> Option<ZFrame> {
        let ptr = unsafe { czmq_sys::zmsg_pop(self.zmsg) };

        if ptr == ptr::null_mut() {
            None
        } else {
            Some(ZFrame::from_raw(ptr, true))
        }
    }

    // pub fn zmsg_pushmem(_self: *mut zmsg_t,
    //                     src: *const ::std::os::raw::c_void, size: size_t)
    //  -> ::std::os::raw::c_int;
    // pub fn zmsg_addmem(_self: *mut zmsg_t, src: *const ::std::os::raw::c_void,
    //                    size: size_t) -> ::std::os::raw::c_int;
    // pub fn zmsg_pushstr(_self: *mut zmsg_t,
    //                     string: *const ::std::os::raw::c_char)
    //  -> ::std::os::raw::c_int;

    pub fn addstr(&self, string: &str) -> Result<()> {
        let string_c = CString::new(string).unwrap_or(CString::new("").unwrap());
        let rc = unsafe { czmq_sys::zmsg_addstr(self.zmsg, string_c.as_ptr()) };

        // Deliberately leak this memory, which will be managed by C
        mem::forget(string_c);

        if rc == -1 {
            Err(Error::new(ErrorKind::NonZero, ZMsgError::CmdFailed))
        } else {
            Ok(())
        }
    }

    // pub fn zmsg_pushstrf(_self: *mut zmsg_t,
    //                      format: *const ::std::os::raw::c_char, ...)
    //  -> ::std::os::raw::c_int;
    // pub fn zmsg_addstrf(_self: *mut zmsg_t,
    //                     format: *const ::std::os::raw::c_char, ...)
    //  -> ::std::os::raw::c_int;

    pub fn popstr(&self) -> Option<result::Result<String, Vec<u8>>> {
        let ptr = unsafe { czmq_sys::zmsg_popstr(self.zmsg) };

        if ptr == ptr::null_mut() {
            None
        } else {
            let c_string = unsafe { CStr::from_ptr(ptr).to_owned() };
            let bytes = c_string.as_bytes().to_vec();
            match c_string.into_string() {
                Ok(s) => Some(Ok(s)),
                Err(_) => Some(Err(bytes)),
            }
        }
    }

    pub fn popbytes(&self) -> Option<Vec<u8>> {
        let ptr = unsafe { czmq_sys::zmsg_popstr(self.zmsg) };

        if ptr == ptr::null_mut() {
            None
        } else {
            let c_string = unsafe { CStr::from_ptr(ptr).to_owned() };
            Some(c_string.to_bytes().to_vec())
        }
    }

    // pub fn zmsg_addmsg(_self: *mut zmsg_t, msg_p: *mut *mut zmsg_t)
    //  -> ::std::os::raw::c_int;
    // pub fn zmsg_popmsg(_self: *mut zmsg_t) -> *mut zmsg_t;
    // pub fn zmsg_remove(_self: *mut zmsg_t, frame: *mut zframe_t);

    pub fn first(&self) -> Option<ZFrame> {
        let ptr = unsafe { czmq_sys::zmsg_first(self.zmsg) };

        if ptr == ptr::null_mut() {
            None
        } else {
            Some(ZFrame::from_raw(ptr, false))
        }
    }

    pub fn next(&self) -> Option<ZFrame> {
        let ptr = unsafe { czmq_sys::zmsg_next(self.zmsg) };

        if ptr == ptr::null_mut() {
            None
        } else {
            Some(ZFrame::from_raw(ptr, false))
        }
    }

    // We can't call this fn last() as it conflicts with
    // Iterator::last(), which is implemented for ZMsg.
    pub fn ref_last(&self) -> Option<ZFrame> {
        let ptr = unsafe { czmq_sys::zmsg_last(self.zmsg) };

        if ptr == ptr::null_mut() {
            None
        } else {
            Some(ZFrame::from_raw(ptr, false))
        }
    }

    // pub fn zmsg_save(_self: *mut zmsg_t, file: *mut FILE)
    //  -> ::std::os::raw::c_int;
    // pub fn zmsg_dup(_self: *mut zmsg_t) -> *mut zmsg_t;
    // pub fn zmsg_print(_self: *mut zmsg_t);
    // pub fn zmsg_eq(_self: *mut zmsg_t, other: *mut zmsg_t) -> u8;

    pub fn signal(&self) -> Result<u8> {
        let signal = unsafe { czmq_sys::zmsg_signal(self.zmsg) };
        if signal == -1 {
            Err(Error::new(ErrorKind::NonZero, ZMsgError::CmdFailed))
        } else {
            Ok(signal as u8)
        }
    }

    // pub fn zmsg_test(verbose: u8);

    pub fn borrow_raw(&self) -> *mut czmq_sys::zmsg_t {
        self.zmsg
    }
}

impl RawInterface<czmq_sys::zmsg_t> for ZMsg {
    fn from_raw(ptr: *mut czmq_sys::zmsg_t, owned: bool) -> ZMsg {
        ZMsg {
            zmsg: ptr,
            owned: owned,
        }
    }

    fn into_raw(mut self) -> *mut czmq_sys::zmsg_t {
        self.owned = false;
        self.zmsg
    }

    fn borrow_raw(&self) -> *mut czmq_sys::zmsg_t {
        self.zmsg
    }
}

impl Iterator for ZMsg {
    type Item = ZFrame;

    fn next(&mut self) -> Option<Self::Item> {
        ZMsg::next(self)
    }
}

#[derive(Debug)]
pub enum ZMsgError {
    CmdFailed,
}

impl fmt::Display for ZMsgError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ZMsgError::CmdFailed => write!(f, "ZMsg command failed"),
        }
    }
}

impl error::Error for ZMsgError {
    fn description(&self) -> &str {
        match *self {
            ZMsgError::CmdFailed => "ZMsg command failed",
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use {zmq, ZFrame, ZSock, zsys_init};

    #[test]
    fn test_sendrecv_zmq() {
        let mut ctx = zmq::Context::new();

        let mut server = ctx.socket(zmq::REP).unwrap();
        server.bind("inproc://zmsg_sendrecv_zmq").unwrap();

        let mut client = ctx.socket(zmq::REQ).unwrap();
        client.connect("inproc://zmsg_sendrecv_zmq").unwrap();

        let zmsg = ZMsg::new();
        zmsg.addstr("Hello world!").unwrap();
        zmsg.send(&client).unwrap();

        let zmsg_recv = ZMsg::recv(&server).unwrap();
        assert_eq!(zmsg_recv.popstr().unwrap().unwrap(), "Hello world!");
    }

    #[test]
    fn test_sendrecv_zsock() {
        zsys_init();

        let server = ZSock::new_rep("inproc://zmsg_sendrecv_zsock").unwrap();
        let client = ZSock::new_req("inproc://zmsg_sendrecv_zsock").unwrap();

        let zmsg = ZMsg::new();
        zmsg.addstr("Hello world!").unwrap();
        zmsg.send(&client).unwrap();

        let msg = ZMsg::recv(&server).unwrap();
        assert_eq!(msg.popstr().unwrap().unwrap(), "Hello world!");
    }

    #[test]
    fn test_encode_decode() {
        let msg = ZMsg::new();
        msg.addstr("moo").unwrap();
        let msg_decoded = ZMsg::decode(&msg.encode().unwrap()).unwrap();
        assert_eq!(msg_decoded.popstr().unwrap().unwrap(), "moo");
    }

    #[test]
    fn test_signal() {
        let msg = ZMsg::new_signal(97).unwrap();
        assert_eq!(msg.signal().unwrap(), 97);
    }

    #[test]
    fn test_size() {
        let msg = ZMsg::new();
        msg.addstr("123").unwrap();
        assert_eq!(msg.size(), 1);
    }

    #[test]
    fn test_prepend() {
        let msg = ZMsg::new();
        msg.prepend(ZFrame::from("123").unwrap()).unwrap();
        assert_eq!(msg.popstr().unwrap().unwrap(), "123");
    }

    #[test]
    fn test_append() {
        let msg = ZMsg::new();
        msg.append(ZFrame::from("123").unwrap()).unwrap();
        assert_eq!(msg.popstr().unwrap().unwrap(), "123");
    }

    #[test]
    fn test_pop() {
        let msg = ZMsg::new();
        msg.addstr("123").unwrap();
        assert_eq!(msg.pop().unwrap().data().unwrap().unwrap(), "123");
    }

    #[test]
    fn test_popstr() {
        let msg = ZMsg::new();
        msg.addstr("123").unwrap();
        assert_eq!(msg.popstr().unwrap().unwrap(), "123");
    }

    #[test]
    fn test_popbytes() {
        let msg = ZMsg::new();
        msg.addstr("123").unwrap();
        assert_eq!(msg.popbytes().unwrap(), "123".as_bytes());
    }

    #[test]
    fn test_iter_fns() {
        let msg = ZMsg::new();
        msg.addstr("1").unwrap();
        msg.addstr("2").unwrap();
        msg.addstr("3").unwrap();

        let frame = msg.first().unwrap();
        assert_eq!(frame.data().unwrap().unwrap(), "1");

        let frame = msg.next().unwrap();
        assert_eq!(frame.data().unwrap().unwrap(), "2");

        let frame = msg.ref_last().unwrap();
        assert_eq!(frame.data().unwrap().unwrap(), "3");
    }

    #[test]
    fn test_iter() {
        let msg = ZMsg::new();
        msg.addstr("1").unwrap();
        msg.addstr("2").unwrap();
        msg.addstr("3").unwrap();

        let mut i = 1;
        for x in msg {
            assert_eq!(x.data().unwrap().unwrap(), i.to_string());
            i += 1;
        }
    }
}
<commit_msg>ZMsg::pushstr<commit_after>//! Module: czmq-zmsg

use {czmq_sys, Error, ErrorKind, RawInterface, Result, Sockish, ZFrame};
use std::{error, fmt, mem, ptr, result};
use std::ffi::{CStr, CString};

pub struct ZMsg {
    zmsg: *mut czmq_sys::zmsg_t,
    owned: bool,
}

unsafe impl Send for ZMsg {}
unsafe impl Sync for ZMsg {}

impl Drop for ZMsg {
    fn drop(&mut self) {
        if self.owned {
            unsafe { czmq_sys::zmsg_destroy(&mut self.zmsg) };
        }
    }
}

impl ZMsg {
    pub fn new() -> ZMsg {
        ZMsg {
            zmsg: unsafe { czmq_sys::zmsg_new() },
            owned: true,
        }
    }

    pub fn recv<S: Sockish>(source: &S) -> Result<ZMsg> {
        let zmsg = unsafe { czmq_sys::zmsg_recv(source.borrow_raw()) };

        if zmsg == ptr::null_mut() {
            Err(Error::new(ErrorKind::NullPtr, ZMsgError::CmdFailed))
        } else {
            Ok(ZMsg {
                zmsg: zmsg,
                owned: true,
            })
        }
    }

    // XXX We'll have to roll our own here as we can't imitate a C
    // file handle without C boilerplate...which we're not doing!
    // pub fn zmsg_load(file: *mut FILE) -> *mut zmsg_t;

    pub fn encode(&self) -> Result<ZFrame> {
        let zframe = unsafe { czmq_sys::zmsg_encode(self.zmsg) };

        if zframe == ptr::null_mut() {
            Err(Error::new(ErrorKind::NullPtr, ZMsgError::CmdFailed))
        } else {
            Ok(ZFrame::from_raw(zframe, true))
        }
    }

    pub fn decode(frame: &ZFrame) -> Result<ZMsg> {
        let zmsg = unsafe { czmq_sys::zmsg_decode(frame.borrow_raw()) };

        if zmsg == ptr::null_mut() {
            Err(Error::new(ErrorKind::NullPtr, ZMsgError::CmdFailed))
        } else {
            Ok(ZMsg {
                zmsg: zmsg,
                owned: true,
            })
        }
    }

    pub fn new_signal(status: u8) -> Result<ZMsg> {
        let zmsg = unsafe { czmq_sys::zmsg_new_signal(status) };

        if zmsg == ptr::null_mut() {
            Err(Error::new(ErrorKind::NullPtr, ZMsgError::CmdFailed))
        } else {
            Ok(ZMsg {
                zmsg: zmsg,
                owned: true,
            })
        }
    }

    pub fn send<D: Sockish>(self, dest: &D) -> Result<()> {
        let mut zmsg = self;

        let rc = unsafe { czmq_sys::zmsg_send(&mut zmsg.zmsg, dest.borrow_raw()) };
        if rc == -1 {
            Err(Error::new(ErrorKind::NonZero, ZMsgError::CmdFailed))
        } else {
            Ok(())
        }
    }

    // pub fn zmsg_sendm(self_p: *mut *mut zmsg_t,
    //                   dest: *mut ::std::os::raw::c_void)
    //  -> ::std::os::raw::c_int;

    pub fn size(&self) -> usize {
        unsafe { czmq_sys::zmsg_size(self.zmsg) as usize }
    }

    // pub fn zmsg_content_size(_self: *mut zmsg_t) -> size_t;

    pub fn prepend(&self, frame: ZFrame) -> Result<()> {
        let rc = unsafe { czmq_sys::zmsg_prepend(self.zmsg, &mut frame.into_raw()) };

        if rc == 0 {
            Ok(())
        } else {
            Err(Error::new(ErrorKind::NonZero, ZMsgError::CmdFailed))
        }
    }

    pub fn append(&self, frame: ZFrame) -> Result<()> {
        let rc = unsafe { czmq_sys::zmsg_append(self.zmsg, &mut frame.into_raw()) };

        if rc == 0 {
            Ok(())
        } else {
            Err(Error::new(ErrorKind::NonZero, ZMsgError::CmdFailed))
        }
    }

    pub fn pop(&self) -> Option<ZFrame> {
        let ptr = unsafe { czmq_sys::zmsg_pop(self.zmsg) };

        if ptr == ptr::null_mut() {
            None
        } else {
            Some(ZFrame::from_raw(ptr, true))
        }
    }

    // pub fn zmsg_pushmem(_self: *mut zmsg_t,
    //                     src: *const ::std::os::raw::c_void, size: size_t)
    //  -> ::std::os::raw::c_int;
    // pub fn zmsg_addmem(_self: *mut zmsg_t, src: *const ::std::os::raw::c_void,
    //                    size: size_t) -> ::std::os::raw::c_int;

    pub fn pushstr(&self, string: &str) -> Result<()> {
        let string_c = CString::new(string).unwrap_or(CString::new("").unwrap());
        let rc = unsafe { czmq_sys::zmsg_pushstr(self.zmsg, string_c.as_ptr()) };

        // Deliberately leak this memory, which will be managed by C
        mem::forget(string_c);

        if rc == -1 {
            Err(Error::new(ErrorKind::NonZero, ZMsgError::CmdFailed))
        } else {
            Ok(())
        }
    }

    pub fn addstr(&self, string: &str) -> Result<()> {
        let string_c = CString::new(string).unwrap_or(CString::new("").unwrap());
        let rc = unsafe { czmq_sys::zmsg_addstr(self.zmsg, string_c.as_ptr()) };

        // Deliberately leak this memory, which will be managed by C
        mem::forget(string_c);

        if rc == -1 {
            Err(Error::new(ErrorKind::NonZero, ZMsgError::CmdFailed))
        } else {
            Ok(())
        }
    }

    // pub fn zmsg_pushstrf(_self: *mut zmsg_t,
    //                      format: *const ::std::os::raw::c_char, ...)
    //  -> ::std::os::raw::c_int;
    // pub fn zmsg_addstrf(_self: *mut zmsg_t,
    //                     format: *const ::std::os::raw::c_char, ...)
    //  -> ::std::os::raw::c_int;

    pub fn popstr(&self) -> Option<result::Result<String, Vec<u8>>> {
        let ptr = unsafe { czmq_sys::zmsg_popstr(self.zmsg) };

        if ptr == ptr::null_mut() {
            None
        } else {
            let c_string = unsafe { CStr::from_ptr(ptr).to_owned() };
            let bytes = c_string.as_bytes().to_vec();
            match c_string.into_string() {
                Ok(s) => Some(Ok(s)),
                Err(_) => Some(Err(bytes)),
            }
        }
    }

    pub fn popbytes(&self) -> Option<Vec<u8>> {
        let ptr = unsafe { czmq_sys::zmsg_popstr(self.zmsg) };

        if ptr == ptr::null_mut() {
            None
        } else {
            let c_string = unsafe { CStr::from_ptr(ptr).to_owned() };
            Some(c_string.to_bytes().to_vec())
        }
    }

    // pub fn zmsg_addmsg(_self: *mut zmsg_t, msg_p: *mut *mut zmsg_t)
    //  -> ::std::os::raw::c_int;
    // pub fn zmsg_popmsg(_self: *mut zmsg_t) -> *mut zmsg_t;
    // pub fn zmsg_remove(_self: *mut zmsg_t, frame: *mut zframe_t);

    pub fn first(&self) -> Option<ZFrame> {
        let ptr = unsafe { czmq_sys::zmsg_first(self.zmsg) };

        if ptr == ptr::null_mut() {
            None
        } else {
            Some(ZFrame::from_raw(ptr, false))
        }
    }

    pub fn next(&self) -> Option<ZFrame> {
        let ptr = unsafe { czmq_sys::zmsg_next(self.zmsg) };

        if ptr == ptr::null_mut() {
            None
        } else {
            Some(ZFrame::from_raw(ptr, false))
        }
    }

    // We can't call this fn last() as it conflicts with
    // Iterator::last(), which is implemented for ZMsg.
    pub fn ref_last(&self) -> Option<ZFrame> {
        let ptr = unsafe { czmq_sys::zmsg_last(self.zmsg) };

        if ptr == ptr::null_mut() {
            None
        } else {
            Some(ZFrame::from_raw(ptr, false))
        }
    }

    // pub fn zmsg_save(_self: *mut zmsg_t, file: *mut FILE)
    //  -> ::std::os::raw::c_int;
    // pub fn zmsg_dup(_self: *mut zmsg_t) -> *mut zmsg_t;
    // pub fn zmsg_print(_self: *mut zmsg_t);
    // pub fn zmsg_eq(_self: *mut zmsg_t, other: *mut zmsg_t) -> u8;

    pub fn signal(&self) -> Result<u8> {
        let signal = unsafe { czmq_sys::zmsg_signal(self.zmsg) };
        if signal == -1 {
            Err(Error::new(ErrorKind::NonZero, ZMsgError::CmdFailed))
        } else {
            Ok(signal as u8)
        }
    }

    // pub fn zmsg_test(verbose: u8);

    pub fn borrow_raw(&self) -> *mut czmq_sys::zmsg_t {
        self.zmsg
    }
}

impl RawInterface<czmq_sys::zmsg_t> for ZMsg {
    fn from_raw(ptr: *mut czmq_sys::zmsg_t, owned: bool) -> ZMsg {
        ZMsg {
            zmsg: ptr,
            owned: owned,
        }
    }

    fn into_raw(mut self) -> *mut czmq_sys::zmsg_t {
        self.owned = false;
        self.zmsg
    }

    fn borrow_raw(&self) -> *mut czmq_sys::zmsg_t {
        self.zmsg
    }
}

impl Iterator for ZMsg {
    type Item = ZFrame;

    fn next(&mut self) -> Option<Self::Item> {
        ZMsg::next(self)
    }
}

#[derive(Debug)]
pub enum ZMsgError {
    CmdFailed,
}

impl fmt::Display for ZMsgError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ZMsgError::CmdFailed => write!(f, "ZMsg command failed"),
        }
    }
}

impl error::Error for ZMsgError {
    fn description(&self) -> &str {
        match *self {
            ZMsgError::CmdFailed => "ZMsg command failed",
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use {zmq, ZFrame, ZSock, zsys_init};

    #[test]
    fn test_sendrecv_zmq() {
        let mut ctx = zmq::Context::new();

        let mut server = ctx.socket(zmq::REP).unwrap();
        server.bind("inproc://zmsg_sendrecv_zmq").unwrap();

        let mut client = ctx.socket(zmq::REQ).unwrap();
        client.connect("inproc://zmsg_sendrecv_zmq").unwrap();

        let zmsg = ZMsg::new();
        zmsg.addstr("Hello world!").unwrap();
        zmsg.send(&client).unwrap();

        let zmsg_recv = ZMsg::recv(&server).unwrap();
        assert_eq!(zmsg_recv.popstr().unwrap().unwrap(), "Hello world!");
    }

    #[test]
    fn test_sendrecv_zsock() {
        zsys_init();

        let server = ZSock::new_rep("inproc://zmsg_sendrecv_zsock").unwrap();
        let client = ZSock::new_req("inproc://zmsg_sendrecv_zsock").unwrap();

        let zmsg = ZMsg::new();
        zmsg.addstr("Hello world!").unwrap();
        zmsg.send(&client).unwrap();

        let msg = ZMsg::recv(&server).unwrap();
        assert_eq!(msg.popstr().unwrap().unwrap(), "Hello world!");
    }

    #[test]
    fn test_encode_decode() {
        let msg = ZMsg::new();
        msg.addstr("moo").unwrap();
        let msg_decoded = ZMsg::decode(&msg.encode().unwrap()).unwrap();
        assert_eq!(msg_decoded.popstr().unwrap().unwrap(), "moo");
    }

    #[test]
    fn test_signal() {
        let msg = ZMsg::new_signal(97).unwrap();
        assert_eq!(msg.signal().unwrap(), 97);
    }

    #[test]
    fn test_size() {
        let msg = ZMsg::new();
        msg.addstr("123").unwrap();
        assert_eq!(msg.size(), 1);
    }

    #[test]
    fn test_prepend() {
        let msg = ZMsg::new();
        msg.prepend(ZFrame::from("123").unwrap()).unwrap();
        assert_eq!(msg.popstr().unwrap().unwrap(), "123");
    }

    #[test]
    fn test_append() {
        let msg = ZMsg::new();
        msg.append(ZFrame::from("123").unwrap()).unwrap();
        assert_eq!(msg.popstr().unwrap().unwrap(), "123");
    }

    #[test]
    fn test_pop() {
        let msg = ZMsg::new();
        msg.addstr("123").unwrap();
        assert_eq!(msg.pop().unwrap().data().unwrap().unwrap(), "123");
    }

    #[test]
    fn test_pushstr() {
        let msg = ZMsg::new();
        msg.addstr("456").unwrap();
        msg.pushstr("123").unwrap();
        assert_eq!(msg.popstr().unwrap().unwrap(), "123");
    }

    #[test]
    fn test_popstr() {
        let msg = ZMsg::new();
        msg.addstr("123").unwrap();
        assert_eq!(msg.popstr().unwrap().unwrap(), "123");
    }

    #[test]
    fn test_popbytes() {
        let msg = ZMsg::new();
        msg.addstr("123").unwrap();
        assert_eq!(msg.popbytes().unwrap(), "123".as_bytes());
    }

    #[test]
    fn test_iter_fns() {
        let msg = ZMsg::new();
        msg.addstr("1").unwrap();
        msg.addstr("2").unwrap();
        msg.addstr("3").unwrap();

        let frame = msg.first().unwrap();
        assert_eq!(frame.data().unwrap().unwrap(), "1");

        let frame = msg.next().unwrap();
        assert_eq!(frame.data().unwrap().unwrap(), "2");

        let frame = msg.ref_last().unwrap();
        assert_eq!(frame.data().unwrap().unwrap(), "3");
    }

    #[test]
    fn test_iter() {
        let msg = ZMsg::new();
        msg.addstr("1").unwrap();
        msg.addstr("2").unwrap();
        msg.addstr("3").unwrap();

        let mut i = 1;
        for x in msg {
            assert_eq!(x.data().unwrap().unwrap(), i.to_string());
            i += 1;
        }
    }
}
<|endoftext|>


<commit_before>use typenum;
use typenum::operator_aliases::Compare;
use typenum::{Greater, Equal, Less};

pub type Min<A, B> = <(A, B, Compare<A, B>) as MinImpl>::Output;

pub trait MinImpl {
    type Output: typenum::Unsigned;
}

impl<A, B> MinImpl for (A, B, Equal)
    where A: typenum::Unsigned, B: typenum::Unsigned,
{
    type Output = A;
}

impl<A, B> MinImpl for (A, B, Greater)
    where A: typenum::Unsigned, B: typenum::Unsigned,
{
    type Output = B;
}

impl<A, B> MinImpl for (A, B, Less)
    where A: typenum::Unsigned, B: typenum::Unsigned,
{
    type Output = A;
}

<commit_msg>Add test for util::Min<commit_after>use typenum;
use typenum::operator_aliases::Compare;
use typenum::{Greater, Equal, Less};

pub type Min<A, B> = <(A, B, Compare<A, B>) as MinImpl>::Output;

pub trait MinImpl {
    type Output: typenum::Unsigned;
}

impl<A, B> MinImpl for (A, B, Equal)
    where A: typenum::Unsigned, B: typenum::Unsigned,
{
    type Output = A;
}

impl<A, B> MinImpl for (A, B, Greater)
    where A: typenum::Unsigned, B: typenum::Unsigned,
{
    type Output = B;
}

impl<A, B> MinImpl for (A, B, Less)
    where A: typenum::Unsigned, B: typenum::Unsigned,
{
    type Output = A;
}

#[test]
fn test_typenum_min() {
    use typenum::consts::*;
    use typenum::Unsigned;

    assert_eq!(<Min<U3, U5>>::to_usize(), 3);
    assert_eq!(<Min<U6, U5>>::to_usize(), 5);
    assert_eq!(<Min<U4, U4>>::to_usize(), 4);
}
<|endoftext|>


<commit_before>//! Various convenience functions for `built` at runtime.

/// Parses version-strings with `semver::Version::parse()`.
///
/// This function is only available if `built` was compiled with the
/// `semver` feature.
///
/// The function takes a reference to an array of names and version numbers as
/// serialized by `built` and returns an iterator over the unchanged names
/// and parsed version numbers.
///
/// ```
/// extern crate built;
/// extern crate semver;
/// pub mod build_info {
///     pub const DEPENDENCIES: [(&'static str, &'static str); 1] = [("built", "0.1.0")];
/// }
///
/// let deps = build_info::DEPENDENCIES;
/// assert!(built::util::parse_versions(&deps)
///                      .any(|(name, ver)| name == "built" &&
///                                         ver >= semver::Version::parse("0.1.0").unwrap()));
/// ```
///
/// # Panics
/// If a version can't be parsed by `semver::Version::parse()`. This should never
/// happen with version strings provided by Cargo and `built`.
#[cfg(feature = "semver")]
pub fn parse_versions<'a, T>(
    name_and_versions: T,
) -> impl Iterator<Item = (&'a str, semver::Version)>
where
    T: IntoIterator<Item = &'a (&'a str, &'a str)>,
{
    fn parse_version<'a>(t: &'a (&'a str, &'a str)) -> (&'a str, semver::Version) {
        (t.0, t.1.parse().unwrap())
    }
    name_and_versions.into_iter().map(parse_version)
}

/// Parse a time-string as formatted by `built`.
///
/// ```
/// use chrono::Datelike;
///
/// pub mod build_info {
///     pub const BUILT_TIME_UTC: &'static str = "Tue, 14 Feb 2017 05:21:41 GMT";
/// }
///
/// assert_eq!(built::util::strptime(&build_info::BUILT_TIME_UTC).year(), 2017);
/// ```
///
/// # Panics
/// If the string can't be parsed. This should never happen with input provided
/// by `built`.
#[cfg(feature = "chrono")]
pub fn strptime(s: &str) -> chrono::DateTime<chrono::offset::Utc> {
    chrono::DateTime::parse_from_rfc2822(s)
        .unwrap()
        .with_timezone(&chrono::offset::Utc)
}

/// Retrieves the git-tag or hash describing the exact version.
///
/// If a valid git-repo can't be discovered at or above the given path,
/// `Ok(None)` is returned instead of an `Err`-value.
///
/// # Errors
/// Errors from `git2` are returned if the repository does exists at all.
#[cfg(feature = "git2")]
pub fn get_repo_description<P: AsRef<std::path::Path>>(root: P) -> Result<Option<String>, git2::Error> {
    match git2::Repository::discover(root) {
        Ok(repo) => {
            let mut desc_opt = git2::DescribeOptions::new();
            desc_opt.describe_tags().show_commit_oid_as_fallback(true);
            Ok(Some(
                repo.describe(&desc_opt)
                    .and_then(|desc| desc.format(None))?,
            ))
        }
        Err(ref e)
            if e.class() == git2::ErrorClass::Repository
                && e.code() == git2::ErrorCode::NotFound =>
        {
            Ok(None)
        }
        Err(e) => Err(e),
    }
}

/// Detect execution on various Continiuous Integration platforms.
///
/// CI-platforms are detected by the presence of known environment variables.
/// This allows to detect specific CI-platform (like `GitLab`); various
/// generic environment variables are also checked, which may result in
/// `CIPlatform::Generic`.
///
/// Since some platforms have fairly generic environment variables to begin with
/// (e.g. `TASK_ID`), this function may have false positives.
pub fn detect_ci() -> Option<super::CIPlatform> {
    super::CIPlatform::detect_from_envmap(&super::get_environment())
}
<commit_msg>Rustfmt<commit_after>//! Various convenience functions for `built` at runtime.

/// Parses version-strings with `semver::Version::parse()`.
///
/// This function is only available if `built` was compiled with the
/// `semver` feature.
///
/// The function takes a reference to an array of names and version numbers as
/// serialized by `built` and returns an iterator over the unchanged names
/// and parsed version numbers.
///
/// ```
/// extern crate built;
/// extern crate semver;
/// pub mod build_info {
///     pub const DEPENDENCIES: [(&'static str, &'static str); 1] = [("built", "0.1.0")];
/// }
///
/// let deps = build_info::DEPENDENCIES;
/// assert!(built::util::parse_versions(&deps)
///                      .any(|(name, ver)| name == "built" &&
///                                         ver >= semver::Version::parse("0.1.0").unwrap()));
/// ```
///
/// # Panics
/// If a version can't be parsed by `semver::Version::parse()`. This should never
/// happen with version strings provided by Cargo and `built`.
#[cfg(feature = "semver")]
pub fn parse_versions<'a, T>(
    name_and_versions: T,
) -> impl Iterator<Item = (&'a str, semver::Version)>
where
    T: IntoIterator<Item = &'a (&'a str, &'a str)>,
{
    fn parse_version<'a>(t: &'a (&'a str, &'a str)) -> (&'a str, semver::Version) {
        (t.0, t.1.parse().unwrap())
    }
    name_and_versions.into_iter().map(parse_version)
}

/// Parse a time-string as formatted by `built`.
///
/// ```
/// use chrono::Datelike;
///
/// pub mod build_info {
///     pub const BUILT_TIME_UTC: &'static str = "Tue, 14 Feb 2017 05:21:41 GMT";
/// }
///
/// assert_eq!(built::util::strptime(&build_info::BUILT_TIME_UTC).year(), 2017);
/// ```
///
/// # Panics
/// If the string can't be parsed. This should never happen with input provided
/// by `built`.
#[cfg(feature = "chrono")]
pub fn strptime(s: &str) -> chrono::DateTime<chrono::offset::Utc> {
    chrono::DateTime::parse_from_rfc2822(s)
        .unwrap()
        .with_timezone(&chrono::offset::Utc)
}

/// Retrieves the git-tag or hash describing the exact version.
///
/// If a valid git-repo can't be discovered at or above the given path,
/// `Ok(None)` is returned instead of an `Err`-value.
///
/// # Errors
/// Errors from `git2` are returned if the repository does exists at all.
#[cfg(feature = "git2")]
pub fn get_repo_description<P: AsRef<std::path::Path>>(
    root: P,
) -> Result<Option<String>, git2::Error> {
    match git2::Repository::discover(root) {
        Ok(repo) => {
            let mut desc_opt = git2::DescribeOptions::new();
            desc_opt.describe_tags().show_commit_oid_as_fallback(true);
            Ok(Some(
                repo.describe(&desc_opt)
                    .and_then(|desc| desc.format(None))?,
            ))
        }
        Err(ref e)
            if e.class() == git2::ErrorClass::Repository
                && e.code() == git2::ErrorCode::NotFound =>
        {
            Ok(None)
        }
        Err(e) => Err(e),
    }
}

/// Detect execution on various Continiuous Integration platforms.
///
/// CI-platforms are detected by the presence of known environment variables.
/// This allows to detect specific CI-platform (like `GitLab`); various
/// generic environment variables are also checked, which may result in
/// `CIPlatform::Generic`.
///
/// Since some platforms have fairly generic environment variables to begin with
/// (e.g. `TASK_ID`), this function may have false positives.
pub fn detect_ci() -> Option<super::CIPlatform> {
    super::CIPlatform::detect_from_envmap(&super::get_environment())
}
<|endoftext|>


<commit_before>use base::{
    AbstractCFTypeRef,
    CFAllocatorRef,
    CFIndex,
    CFRange,
    CFTypeID,
    CFTypeRef,
    CFWrapper,
    kCFAllocatorDefault,
};
use core::libc::c_void;

pub type CFArrayRetainCallBack = *u8;
pub type CFArrayReleaseCallBack = *u8;
pub type CFArrayCopyDescriptionCallBack = *u8;
pub type CFArrayEqualCallBack = *u8;

pub struct CFArrayCallBacks {
    version: CFIndex,
    retain: CFArrayRetainCallBack,
    release: CFArrayReleaseCallBack,
    copyDescription: CFArrayCopyDescriptionCallBack,
    equal: CFArrayEqualCallBack,
}

struct __CFArray { private: () }
pub type CFArrayRef = *__CFArray;

impl AbstractCFTypeRef for CFArrayRef {
    fn as_type_ref(&self) -> CFTypeRef { *self as CFTypeRef }
    fn type_id() -> CFTypeID { unsafe { CFArrayGetTypeID() } }
}

pub type CFArray<ElemRefType> = CFWrapper<CFArrayRef, ElemRefType, ()>;

pub impl<ElemRefType:AbstractCFTypeRef> CFArray<ElemRefType> {
    fn new(elems: &[ElemRefType]) -> CFArray<ElemRefType> {
        let array_ref: CFArrayRef;
        let elems_refs = do vec::map(elems) |e: &ElemRefType| { e.as_type_ref() };

        unsafe {
            array_ref = CFArrayCreate(kCFAllocatorDefault,
                                      cast::transmute::<*CFTypeRef, **c_void>(vec::raw::to_ptr(elems_refs)),
                                      elems.len() as CFIndex,
                                      ptr::to_unsafe_ptr(&kCFTypeArrayCallBacks));
        }

        CFWrapper::wrap_owned(array_ref)
    }

    pub fn each_ref<A>(&self, cb: &fn(ElemRefType) -> A) {
        for uint::range(0, self.len()) |i| { cb(self[i]); }
    }

    pub fn eachi_ref<A>(&self, cb: &fn(uint, ElemRefType) -> A) {
        for uint::range(0, self.len()) |i| { cb(i, self[i]); }
    }

    // Careful; the callback must wrap the reference properly.
    // Generally, when array elements are Core Foundation objects (not
    // always true), they need to be wrapped with CFWrapper::wrap_shared.
    pub fn each<A>(&self, cb: &fn(&ElemRefType) -> A) {
        for uint::range(0, self.len()) |i| { cb(&self[i]); }
    }

    // Careful; the callback must wrap the reference properly.
    // Generally, when array elements are Core Foundation objects (not
    // always true), they need to be wrapped with CFWrapper::wrap_shared.
    pub fn eachi<A>(&self, cb: &fn(uint, &ElemRefType) -> A) {
        for uint::range(0, self.len()) |i| { cb(i, &self[i]); }
    }

    pub fn len(&self) -> uint {
        unsafe { return CFArrayGetCount(*self.borrow_ref()) as uint; }
    }
}

impl<ElemRefType:AbstractCFTypeRef> Index<uint,ElemRefType> for CFArray<ElemRefType> {
    // Careful; the caller must wrap any returned reference properly.
    // Generally, when array elements are Core Foundation objects (not
    // always true), they need to be wrapped with CFWrapper::wrap_shared.
    fn index(&self, idx: uint) -> ElemRefType {
        assert!(idx < self.len());
        unsafe {
            let elem = CFArrayGetValueAtIndex(*self.borrow_ref(), idx as CFIndex);
            // Don't return a wrapped thing, since we don't know whether
            // it needs base::wrap_shared() or base::wrap_owned()
            cast::transmute::<*c_void,ElemRefType>(elem)
        }
    }
}

#[link_args="-framework CoreFoundation"]
#[nolink]
extern {
    /*
     * CFArray.h
     */
    static kCFTypeArrayCallBacks: CFArrayCallBacks;

    fn CFArrayCreate(allocator: CFAllocatorRef, values: **c_void,
                     numValues: CFIndex, callBacks: *CFArrayCallBacks) -> CFArrayRef;
    // CFArrayCreateCopy
    // CFArrayBSearchValues
    // CFArrayContainsValue
    fn CFArrayGetCount(theArray: CFArrayRef) -> CFIndex;
    // CFArrayGetCountOfValue
    // CFArrayGetFirstIndexOfValue
    // CFArrayGetLastIndexOfValue
    // CFArrayGetValues
    fn CFArrayGetValueAtIndex(theArray: CFArrayRef, idx: CFIndex) -> *c_void;
    // CFArrayApplyFunction
    fn CFArrayGetTypeID() -> CFTypeID;
}

#[test]
fn should_box_and_unbox() {
    use number::{CFNumber, CFNumberRef};

    let one = CFNumber::new(1 as i32);
    let two = CFNumber::new(2 as i32);
    let thr = CFNumber::new(3 as i32);
    let fou = CFNumber::new(4 as i32);
    let fiv = CFNumber::new(5 as i32);

    let arr = CFArray::new([
        *one.borrow_ref(),
        *two.borrow_ref(),
        *thr.borrow_ref(),
        *fou.borrow_ref(),
        *fiv.borrow_ref()]);

    let mut sum = 0i32;

    for arr.each |elem: &CFNumberRef| {
        sum += CFWrapper::wrap_shared(*elem).to_i32();
    }

    assert!(sum == 15);

    for arr.each |elem: &CFNumberRef| {
        sum += CFWrapper::wrap_shared(*elem).to_i32();
    }

    assert!(sum == 30);
}
<commit_msg>More 0.6 changes.<commit_after>use base::{
    AbstractCFTypeRef,
    CFAllocatorRef,
    CFIndex,
    CFRange,
    CFTypeID,
    CFTypeRef,
    CFWrapper,
    kCFAllocatorDefault,
};
use core::libc::c_void;

pub type CFArrayRetainCallBack = *u8;
pub type CFArrayReleaseCallBack = *u8;
pub type CFArrayCopyDescriptionCallBack = *u8;
pub type CFArrayEqualCallBack = *u8;

pub struct CFArrayCallBacks {
    version: CFIndex,
    retain: CFArrayRetainCallBack,
    release: CFArrayReleaseCallBack,
    copyDescription: CFArrayCopyDescriptionCallBack,
    equal: CFArrayEqualCallBack,
}

struct __CFArray { private: () }
pub type CFArrayRef = *__CFArray;

impl AbstractCFTypeRef for CFArrayRef {
    fn as_type_ref(&self) -> CFTypeRef { *self as CFTypeRef }
    fn type_id() -> CFTypeID { unsafe { CFArrayGetTypeID() } }
}

pub type CFArray<ElemRefType> = CFWrapper<CFArrayRef, ElemRefType, ()>;

pub impl<ElemRefType:AbstractCFTypeRef> CFArray<ElemRefType> {
    fn new(elems: &[ElemRefType]) -> CFArray<ElemRefType> {
        let array_ref: CFArrayRef;
        let elems_refs = do vec::map(elems) |e: &ElemRefType| { e.as_type_ref() };

        unsafe {
            array_ref = CFArrayCreate(kCFAllocatorDefault,
                                      cast::transmute::<*CFTypeRef, **c_void>(vec::raw::to_ptr(elems_refs)),
                                      elems.len() as CFIndex,
                                      ptr::to_unsafe_ptr(&kCFTypeArrayCallBacks));
        }

        CFWrapper::wrap_owned(array_ref)
    }

    pub fn each_ref<A>(&self, cb: &fn(ElemRefType) -> A) {
        for uint::range(0, self.len()) |i| { cb(self[i]); }
    }

    pub fn eachi_ref<A>(&self, cb: &fn(uint, ElemRefType) -> A) {
        for uint::range(0, self.len()) |i| { cb(i, self[i]); }
    }

    // Careful; the callback must wrap the reference properly.
    // Generally, when array elements are Core Foundation objects (not
    // always true), they need to be wrapped with CFWrapper::wrap_shared.
    pub fn each<A>(&self, cb: &fn(&ElemRefType) -> A) {
        for uint::range(0, self.len()) |i| { cb(&self[i]); }
    }

    // Careful; the callback must wrap the reference properly.
    // Generally, when array elements are Core Foundation objects (not
    // always true), they need to be wrapped with CFWrapper::wrap_shared.
    pub fn eachi<A>(&self, cb: &fn(uint, &ElemRefType) -> A) {
        for uint::range(0, self.len()) |i| { cb(i, &self[i]); }
    }

    pub fn len(&self) -> uint {
        unsafe { return CFArrayGetCount(*self.borrow_ref()) as uint; }
    }
}

impl<ElemRefType:AbstractCFTypeRef> Index<uint,ElemRefType> for CFArray<ElemRefType> {
    // Careful; the caller must wrap any returned reference properly.
    // Generally, when array elements are Core Foundation objects (not
    // always true), they need to be wrapped with CFWrapper::wrap_shared.
    fn index(&self, idx: &uint) -> ElemRefType {
        assert!(*idx < self.len());
        unsafe {
            let elem = CFArrayGetValueAtIndex(*self.borrow_ref(), *idx as CFIndex);
            // Don't return a wrapped thing, since we don't know whether
            // it needs base::wrap_shared() or base::wrap_owned()
            cast::transmute::<*c_void,ElemRefType>(elem)
        }
    }
}

#[link_args="-framework CoreFoundation"]
#[nolink]
extern {
    /*
     * CFArray.h
     */
    static kCFTypeArrayCallBacks: CFArrayCallBacks;

    fn CFArrayCreate(allocator: CFAllocatorRef, values: **c_void,
                     numValues: CFIndex, callBacks: *CFArrayCallBacks) -> CFArrayRef;
    // CFArrayCreateCopy
    // CFArrayBSearchValues
    // CFArrayContainsValue
    fn CFArrayGetCount(theArray: CFArrayRef) -> CFIndex;
    // CFArrayGetCountOfValue
    // CFArrayGetFirstIndexOfValue
    // CFArrayGetLastIndexOfValue
    // CFArrayGetValues
    fn CFArrayGetValueAtIndex(theArray: CFArrayRef, idx: CFIndex) -> *c_void;
    // CFArrayApplyFunction
    fn CFArrayGetTypeID() -> CFTypeID;
}

#[test]
fn should_box_and_unbox() {
    use number::{CFNumber, CFNumberRef};

    let one = CFNumber::new(1 as i32);
    let two = CFNumber::new(2 as i32);
    let thr = CFNumber::new(3 as i32);
    let fou = CFNumber::new(4 as i32);
    let fiv = CFNumber::new(5 as i32);

    let arr = CFArray::new([
        *one.borrow_ref(),
        *two.borrow_ref(),
        *thr.borrow_ref(),
        *fou.borrow_ref(),
        *fiv.borrow_ref()]);

    let mut sum = 0i32;

    for arr.each |elem: &CFNumberRef| {
        sum += CFWrapper::wrap_shared(*elem).to_i32();
    }

    assert!(sum == 15);

    for arr.each |elem: &CFNumberRef| {
        sum += CFWrapper::wrap_shared(*elem).to_i32();
    }

    assert!(sum == 30);
}
<|endoftext|>


<commit_before>// This file is part of the uutils coreutils package.
//
// (c) Joao Oliveira <joaoxsouls@gmail.com>
// (c) Jian Zeng <anonymousknight96 AT gmail.com>
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

// last synced with: uname (GNU coreutils) 8.21

// spell-checker:ignore (ToDO) nodename kernelname kernelrelease kernelversion sysname hwplatform mnrsv

#[macro_use]
extern crate uucore;

use clap::{crate_version, App, Arg};
use platform_info::*;

const ABOUT: &str = "Print certain system information.  With no OPTION, same as -s.";

pub mod options {
    pub static ALL: &str = "all";
    pub static KERNELNAME: &str = "kernel-name";
    pub static NODENAME: &str = "nodename";
    pub static KERNELVERSION: &str = "kernel-version";
    pub static KERNELRELEASE: &str = "kernel-release";
    pub static MACHINE: &str = "machine";
    pub static PROCESSOR: &str = "processor";
    pub static HWPLATFORM: &str = "hardware-platform";
    pub static OS: &str = "operating-system";
}

#[cfg(target_os = "linux")]
const HOST_OS: &str = "GNU/Linux";
#[cfg(target_os = "windows")]
const HOST_OS: &str = "Windows NT";
#[cfg(target_os = "freebsd")]
const HOST_OS: &str = "FreeBSD";
#[cfg(target_os = "openbsd")]
const HOST_OS: &str = "OpenBSD";
#[cfg(target_vendor = "apple")]
const HOST_OS: &str = "Darwin";
#[cfg(target_os = "fuchsia")]
const HOST_OS: &str = "Fuchsia";
#[cfg(target_os = "redox")]
const HOST_OS: &str = "Redox";

pub fn uumain(args: impl uucore::Args) -> i32 {
    let usage = format!("{} [OPTION]...", executable!());
    let matches = uu_app().usage(&usage[..]).get_matches_from(args);

    let uname = return_if_err!(1, PlatformInfo::new());
    let mut output = String::new();

    let all = matches.is_present(options::ALL);
    let kernelname = matches.is_present(options::KERNELNAME);
    let nodename = matches.is_present(options::NODENAME);
    let kernelrelease = matches.is_present(options::KERNELRELEASE);
    let kernelversion = matches.is_present(options::KERNELVERSION);
    let machine = matches.is_present(options::MACHINE);
    let processor = matches.is_present(options::PROCESSOR);
    let hwplatform = matches.is_present(options::HWPLATFORM);
    let os = matches.is_present(options::OS);

    let none = !(all
        || kernelname
        || nodename
        || kernelrelease
        || kernelversion
        || machine
        || os
        || processor
        || hwplatform);

    if kernelname || all || none {
        output.push_str(&uname.sysname());
        output.push(' ');
    }

    if nodename || all {
        output.push_str(&uname.nodename());
        output.push(' ');
    }
    if kernelrelease || all {
        output.push_str(&uname.release());
        output.push(' ');
    }
    if kernelversion || all {
        output.push_str(&uname.version());
        output.push(' ');
    }
    if machine || all {
        output.push_str(&uname.machine());
        output.push(' ');
    }
    if processor || all {
        // According to https://stackoverflow.com/posts/394271/revisions
        // Most of the time, it returns unknown
        output.push_str("unknown");
        output.push(' ');
    }
    if hwplatform || all {
        // According to https://lists.gnu.org/archive/html/bug-coreutils/2005-09/msg00063.html
        // Most of the time, it returns unknown
        output.push_str("unknown");
        output.push(' ');
    }
    if os || all {
        output.push_str(HOST_OS);
        output.push(' ');
    }
    println!("{}", output.trim_end());

    0
}

pub fn uu_app() -> App<'static, 'static> {
    App::new(executable!())
        .version(crate_version!())
        .about(ABOUT)
        .arg(Arg::with_name(options::ALL)
            .short("a")
            .long(options::ALL)
            .help("Behave as though all of the options -mnrsv were specified."))
        .arg(Arg::with_name(options::KERNELNAME)
            .short("s")
            .long(options::KERNELNAME)
            .alias("sysname") // Obsolescent option in GNU uname
            .help("print the kernel name."))
        .arg(Arg::with_name(options::NODENAME)
            .short("n")
            .long(options::NODENAME)
            .help("print the nodename (the nodename may be a name that the system is known by to a communications network)."))
        .arg(Arg::with_name(options::KERNELRELEASE)
            .short("r")
            .long(options::KERNELRELEASE)
            .alias("release") // Obsolescent option in GNU uname
            .help("print the operating system release."))
        .arg(Arg::with_name(options::KERNELVERSION)
            .short("v")
            .long(options::KERNELVERSION)
            .help("print the operating system version."))
        .arg(Arg::with_name(options::HWPLATFORM)
            .short("i")
            .long(options::HWPLATFORM)
            .help("print the hardware platform (non-portable)"))
        .arg(Arg::with_name(options::MACHINE)
            .short("m")
            .long(options::MACHINE)
            .help("print the machine hardware name."))
        .arg(Arg::with_name(options::PROCESSOR)
            .short("p")
            .long(options::PROCESSOR)
            .help("print the processor type (non-portable)"))
        .arg(Arg::with_name(options::OS)
            .short("o")
            .long(options::OS)
            .help("print the operating system name."))
}
<commit_msg>uname: don't report OS as "GNU/Linux" without GNU<commit_after>// This file is part of the uutils coreutils package.
//
// (c) Joao Oliveira <joaoxsouls@gmail.com>
// (c) Jian Zeng <anonymousknight96 AT gmail.com>
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

// last synced with: uname (GNU coreutils) 8.21

// spell-checker:ignore (ToDO) nodename kernelname kernelrelease kernelversion sysname hwplatform mnrsv

#[macro_use]
extern crate uucore;

use clap::{crate_version, App, Arg};
use platform_info::*;

const ABOUT: &str = "Print certain system information.  With no OPTION, same as -s.";

pub mod options {
    pub static ALL: &str = "all";
    pub static KERNELNAME: &str = "kernel-name";
    pub static NODENAME: &str = "nodename";
    pub static KERNELVERSION: &str = "kernel-version";
    pub static KERNELRELEASE: &str = "kernel-release";
    pub static MACHINE: &str = "machine";
    pub static PROCESSOR: &str = "processor";
    pub static HWPLATFORM: &str = "hardware-platform";
    pub static OS: &str = "operating-system";
}

#[cfg(all(target_os = "linux", any(target_env = "gnu", target_env = "")))]
const HOST_OS: &str = "GNU/Linux";
#[cfg(all(target_os = "linux", not(any(target_env = "gnu", target_env = ""))))]
const HOST_OS: &str = "Linux";
#[cfg(target_os = "windows")]
const HOST_OS: &str = "Windows NT";
#[cfg(target_os = "freebsd")]
const HOST_OS: &str = "FreeBSD";
#[cfg(target_os = "openbsd")]
const HOST_OS: &str = "OpenBSD";
#[cfg(target_vendor = "apple")]
const HOST_OS: &str = "Darwin";
#[cfg(target_os = "fuchsia")]
const HOST_OS: &str = "Fuchsia";
#[cfg(target_os = "redox")]
const HOST_OS: &str = "Redox";

pub fn uumain(args: impl uucore::Args) -> i32 {
    let usage = format!("{} [OPTION]...", executable!());
    let matches = uu_app().usage(&usage[..]).get_matches_from(args);

    let uname = return_if_err!(1, PlatformInfo::new());
    let mut output = String::new();

    let all = matches.is_present(options::ALL);
    let kernelname = matches.is_present(options::KERNELNAME);
    let nodename = matches.is_present(options::NODENAME);
    let kernelrelease = matches.is_present(options::KERNELRELEASE);
    let kernelversion = matches.is_present(options::KERNELVERSION);
    let machine = matches.is_present(options::MACHINE);
    let processor = matches.is_present(options::PROCESSOR);
    let hwplatform = matches.is_present(options::HWPLATFORM);
    let os = matches.is_present(options::OS);

    let none = !(all
        || kernelname
        || nodename
        || kernelrelease
        || kernelversion
        || machine
        || os
        || processor
        || hwplatform);

    if kernelname || all || none {
        output.push_str(&uname.sysname());
        output.push(' ');
    }

    if nodename || all {
        output.push_str(&uname.nodename());
        output.push(' ');
    }
    if kernelrelease || all {
        output.push_str(&uname.release());
        output.push(' ');
    }
    if kernelversion || all {
        output.push_str(&uname.version());
        output.push(' ');
    }
    if machine || all {
        output.push_str(&uname.machine());
        output.push(' ');
    }
    if processor || all {
        // According to https://stackoverflow.com/posts/394271/revisions
        // Most of the time, it returns unknown
        output.push_str("unknown");
        output.push(' ');
    }
    if hwplatform || all {
        // According to https://lists.gnu.org/archive/html/bug-coreutils/2005-09/msg00063.html
        // Most of the time, it returns unknown
        output.push_str("unknown");
        output.push(' ');
    }
    if os || all {
        output.push_str(HOST_OS);
        output.push(' ');
    }
    println!("{}", output.trim_end());

    0
}

pub fn uu_app() -> App<'static, 'static> {
    App::new(executable!())
        .version(crate_version!())
        .about(ABOUT)
        .arg(Arg::with_name(options::ALL)
            .short("a")
            .long(options::ALL)
            .help("Behave as though all of the options -mnrsv were specified."))
        .arg(Arg::with_name(options::KERNELNAME)
            .short("s")
            .long(options::KERNELNAME)
            .alias("sysname") // Obsolescent option in GNU uname
            .help("print the kernel name."))
        .arg(Arg::with_name(options::NODENAME)
            .short("n")
            .long(options::NODENAME)
            .help("print the nodename (the nodename may be a name that the system is known by to a communications network)."))
        .arg(Arg::with_name(options::KERNELRELEASE)
            .short("r")
            .long(options::KERNELRELEASE)
            .alias("release") // Obsolescent option in GNU uname
            .help("print the operating system release."))
        .arg(Arg::with_name(options::KERNELVERSION)
            .short("v")
            .long(options::KERNELVERSION)
            .help("print the operating system version."))
        .arg(Arg::with_name(options::HWPLATFORM)
            .short("i")
            .long(options::HWPLATFORM)
            .help("print the hardware platform (non-portable)"))
        .arg(Arg::with_name(options::MACHINE)
            .short("m")
            .long(options::MACHINE)
            .help("print the machine hardware name."))
        .arg(Arg::with_name(options::PROCESSOR)
            .short("p")
            .long(options::PROCESSOR)
            .help("print the processor type (non-portable)"))
        .arg(Arg::with_name(options::OS)
            .short("o")
            .long(options::OS)
            .help("print the operating system name."))
}
<|endoftext|>