<commit_before>use types::*;
use types::flags::*;
use types::generation::*;
use types::parsing::*;

use cookie_factory::GenError;

pub mod metadata {
    use super::*;

    pub const NAME:          &'static str   = "{{protocol.name}}";
    pub const MAJOR_VERSION: ShortShortUInt = {{protocol.major_version}};
    pub const MINOR_VERSION: ShortShortUInt = {{protocol.minor_version}};
    pub const REVISION:      ShortShortUInt = {{protocol.revision}};
    pub const PORT:          LongUInt       = {{protocol.port}};
    pub const COPYRIGHT:     &'static str   = r#"{{copyright}}"#;
}

pub mod constants {
    use super::*;

    {{#each protocol.constants as |constant| ~}}
    pub const {{sanitize_name constant.name}}: {{constant.type}} = {{constant.value}};
    {{/each ~}}
}

pub enum AMQPError {
    Soft(AMQPSoftError),
    Hard(AMQPHardError),
}

impl AMQPError {
    pub fn get_id(&self) -> ShortUInt {
        match *self {
            AMQPError::Soft(ref s) => s.get_id(),
            AMQPError::Hard(ref h) => h.get_id(),
        }
    }

    pub fn from_id(id: ShortUInt) -> Option<AMQPError> {
        AMQPSoftError::from_id(id).map(AMQPError::Soft).or_else(|| AMQPHardError::from_id(id).map(AMQPError::Hard))
    }
}

pub enum AMQPSoftError {
    {{#each protocol.soft_errors as |constant| ~}}
    {{camel constant.name}},
    {{/each ~}}
}

impl AMQPSoftError {
    pub fn get_id(&self) -> ShortUInt {
        match *self {
            {{#each protocol.soft_errors as |constant| ~}}
            AMQPSoftError::{{camel constant.name}} => {{constant.value}},
            {{/each ~}}
        }
    }

    pub fn from_id(id: ShortUInt) -> Option<AMQPSoftError> {
        match id {
            {{#each protocol.soft_errors as |constant| ~}}
            {{constant.value}} => Some(AMQPSoftError::{{camel constant.name}}),
            {{/each ~}}
            _                  => None,
        }
    }
}

pub enum AMQPHardError {
    {{#each protocol.hard_errors as |constant| ~}}
    {{camel constant.name}},
    {{/each ~}}
}

impl AMQPHardError {
    pub fn get_id(&self) -> ShortUInt {
        match *self {
            {{#each protocol.hard_errors as |constant| ~}}
            AMQPHardError::{{camel constant.name}} => {{constant.value}},
            {{/each ~}}
        }
    }

    pub fn from_id(id: ShortUInt) -> Option<AMQPHardError> {
        match id {
            {{#each protocol.hard_errors as |constant| ~}}
            {{constant.value}} => Some(AMQPHardError::{{camel constant.name}}),
            {{/each ~}}
            _                  => None,
        }
    }
}

{{#each protocol.classes as |class| ~}}
use self::{{snake class.name}}::parse_{{snake class.name}};
{{/each ~}}

named!(pub parse_class<AMQPClass>, switch!(parse_id,
    {{#each protocol.classes as |class| ~}}
    {{class.id}} => map!(call!(parse_{{snake class.name}}), AMQPClass::{{camel class.name}}) {{#unless @last ~}}|{{/unless ~}}
    {{/each ~}}
));

pub fn gen_class<'a>(input: (&'a mut [u8], usize), class: &AMQPClass) -> Result<(&'a mut [u8], usize), GenError> {
    match *class {
        {{#each protocol.classes as |class| ~}}
        AMQPClass::{{camel class.name}}(ref {{snake class.name}}) => {{snake class.name}}::gen_{{snake class.name}}(input, {{snake class.name}}),
        {{/each ~}}
    }
}

#[derive(Clone, Debug, PartialEq)]
pub enum AMQPClass {
    {{#each protocol.classes as |class| ~}}
    {{camel class.name}}({{snake class.name}}::AMQPMethod),
    {{/each ~}}
}

{{#each protocol.classes as |class|}}
pub mod {{snake class.name}} {
    use super::*;

    named!(pub parse_{{snake class.name}}<{{snake class.name}}::AMQPMethod>, switch!(parse_id,
        {{#each class.methods as |method| ~}}
        {{method.id}} => map!(call!(parse_{{snake method.name}}), AMQPMethod::{{camel method.name}}) {{#unless @last ~}}|{{/unless ~}}
        {{/each ~}}
    ));

    pub fn gen_{{snake class.name}}<'a>(input: (&'a mut [u8], usize), method: &AMQPMethod) -> Result<(&'a mut [u8], usize), GenError> {
        match *method {
            {{#each class.methods as |method| ~}}
            AMQPMethod::{{camel method.name}}(ref {{snake method.name}}) => {
                do_gen!(input,
                    gen_id(&{{class.id}}) >>
                    gen_{{snake method.name}}({{snake method.name}})
                )
            },
            {{/each ~}}
        }
    }

    #[derive(Clone, Debug, PartialEq)]
    pub enum AMQPMethod {
        {{#each class.methods as |method| ~}}
        {{camel method.name}}({{camel method.name}}),
        {{/each ~}}
    }

    {{#each class.methods as |method|}}
    #[derive(Clone, Debug, PartialEq)]
    pub struct {{camel method.name}} {
        {{#each_argument method.arguments as |argument| ~}}
        {{#if argument_is_value ~}}
        pub {{snake argument.name}}: {{argument.type}},
        {{else}}
        {{#each_flag argument as |flag| ~}}
        pub {{snake flag.name}}: Boolean,
        {{/each_flag ~}}
        {{/if ~}}
        {{/each_argument ~}}
    }

    named!(pub parse_{{snake method.name}}<{{camel method.name}}>, do_parse!(
        {{#each_argument method.arguments as |argument| ~}}
        {{#if argument_is_value ~}}
        {{snake argument.name}}: parse_{{snake_type argument.type}} >>
        {{else}}
        /* FIXME: support multiple flags structs? */
        flags: apply!(parse_flags, &[
            {{#each_flag argument as |flag| ~}}
            "{{flag.name}}",
            {{/each_flag ~}}
        ]) >>
        {{/if ~}}
        {{/each_argument ~}}
        ({{camel method.name}} {
            {{#each_argument method.arguments as |argument| ~}}
            {{#if argument_is_value ~}}
            {{snake argument.name}}: {{snake argument.name}},
            {{else}}
            {{#each_flag argument as |flag| ~}}
            {{snake flag.name}}: flags.get_flag("{{snake flag.name}}").unwrap_or({{flag.default_value}}),
            {{/each_flag ~}}
            {{/if ~}}
            {{/each_argument ~}}
        })
    ));

    pub fn gen_{{snake method.name}}<'a>(input: (&'a mut [u8], usize), {{#if method.has_arguments ~}}method{{else}}_{{/if ~}}: &{{camel method.name}}) -> Result<(&'a mut [u8],usize), GenError> {
        {{#if method.has_flags ~}}
        /* FIXME: support multiple flags structs? */
        let mut flags = AMQPFlags::new();
        {{#each_argument method.arguments as |argument| ~}}
        {{#unless argument_is_value ~}}
        {{#each_flag argument as |flag| ~}}
        flags.add_flag("{{snake flag.name}}".to_string(), method.{{snake flag.name}});
        {{/each_flag ~}}
        {{/unless ~}}
        {{/each_argument ~}}
        {{/if ~}}
        do_gen!(input,
            gen_id(&{{method.id}})
            {{#each_argument method.arguments as |argument| ~}}
            {{#if argument_is_value ~}}
            >> gen_{{snake_type argument.type}}(&method.{{snake argument.name}})
            {{else}}
            >> gen_flags(&flags)
            {{/if ~}}
            {{/each_argument ~}}
        )
    }
    {{/each ~}}
    {{#if class.has_properties ~}}
    #[derive(Clone, Debug, PartialEq)]
    pub struct AMQPProperties {
        {{#each class.properties as |property| ~}}
        {{snake property.name}}: Option<{{property.type}}>,
        {{/each ~}}
    }

    impl Default for AMQPProperties {
        fn default() -> AMQPProperties {
            AMQPProperties {
                {{#each class.properties as |property| ~}}
                {{snake property.name}}: None,
                {{/each ~}}
            }
        }
    }

    impl AMQPProperties {
        {{#each class.properties as |property| ~}}
        pub fn with_{{snake property.name}}(mut self, value: {{property.type}}) -> AMQPProperties {
            self.{{snake property.name}} = Some(value);
            self
        }
        {{/each ~}}

        pub fn bitmask(&self) -> ShortUInt {
            {{#each class.properties as |property| ~}}
            (if self.{{snake property.name}}.is_some() { 1 << (15 - {{@index}}) } else { 0 }) {{#unless @last ~}} + {{/unless ~}}
            {{/each ~}}
        }
    }

    named!(pub parse_properties<AMQPProperties>, do_parse!(
        flags: parse_short_uint >>
        {{#each class.properties as |property| ~}}
        {{snake property.name}}: cond!(flags & (1 << (15 - {{@index}})) != 0, parse_{{snake_type property.type}}) >>
        {{/each ~}}
        (AMQPProperties {
            {{#each class.properties as |property| ~}}
            {{snake property.name}}: {{snake property.name}},
            {{/each ~}}
        })
    ));

    pub fn gen_properties<'a>(input:(&'a mut [u8],usize), props: &AMQPProperties) -> Result<(&'a mut [u8],usize),GenError> {
        do_gen!(input,
            gen_short_uint(&props.bitmask())
            {{#each class.properties as |property| ~}}
            >> gen_cond!(props.{{snake property.name}}.is_some(), gen_call!(gen_{{snake_type property.type}}, &props.{{snake property.name}}.as_ref().unwrap()))
            {{/each ~}}
        )
    }
    {{/if ~}}
}
{{/each ~}}
<commit_msg>protocol: don't use AMQPFlags::new<commit_after>use types::*;
use types::flags::*;
use types::generation::*;
use types::parsing::*;

use cookie_factory::GenError;

pub mod metadata {
    use super::*;

    pub const NAME:          &'static str   = "{{protocol.name}}";
    pub const MAJOR_VERSION: ShortShortUInt = {{protocol.major_version}};
    pub const MINOR_VERSION: ShortShortUInt = {{protocol.minor_version}};
    pub const REVISION:      ShortShortUInt = {{protocol.revision}};
    pub const PORT:          LongUInt       = {{protocol.port}};
    pub const COPYRIGHT:     &'static str   = r#"{{copyright}}"#;
}

pub mod constants {
    use super::*;

    {{#each protocol.constants as |constant| ~}}
    pub const {{sanitize_name constant.name}}: {{constant.type}} = {{constant.value}};
    {{/each ~}}
}

pub enum AMQPError {
    Soft(AMQPSoftError),
    Hard(AMQPHardError),
}

impl AMQPError {
    pub fn get_id(&self) -> ShortUInt {
        match *self {
            AMQPError::Soft(ref s) => s.get_id(),
            AMQPError::Hard(ref h) => h.get_id(),
        }
    }

    pub fn from_id(id: ShortUInt) -> Option<AMQPError> {
        AMQPSoftError::from_id(id).map(AMQPError::Soft).or_else(|| AMQPHardError::from_id(id).map(AMQPError::Hard))
    }
}

pub enum AMQPSoftError {
    {{#each protocol.soft_errors as |constant| ~}}
    {{camel constant.name}},
    {{/each ~}}
}

impl AMQPSoftError {
    pub fn get_id(&self) -> ShortUInt {
        match *self {
            {{#each protocol.soft_errors as |constant| ~}}
            AMQPSoftError::{{camel constant.name}} => {{constant.value}},
            {{/each ~}}
        }
    }

    pub fn from_id(id: ShortUInt) -> Option<AMQPSoftError> {
        match id {
            {{#each protocol.soft_errors as |constant| ~}}
            {{constant.value}} => Some(AMQPSoftError::{{camel constant.name}}),
            {{/each ~}}
            _                  => None,
        }
    }
}

pub enum AMQPHardError {
    {{#each protocol.hard_errors as |constant| ~}}
    {{camel constant.name}},
    {{/each ~}}
}

impl AMQPHardError {
    pub fn get_id(&self) -> ShortUInt {
        match *self {
            {{#each protocol.hard_errors as |constant| ~}}
            AMQPHardError::{{camel constant.name}} => {{constant.value}},
            {{/each ~}}
        }
    }

    pub fn from_id(id: ShortUInt) -> Option<AMQPHardError> {
        match id {
            {{#each protocol.hard_errors as |constant| ~}}
            {{constant.value}} => Some(AMQPHardError::{{camel constant.name}}),
            {{/each ~}}
            _                  => None,
        }
    }
}

{{#each protocol.classes as |class| ~}}
use self::{{snake class.name}}::parse_{{snake class.name}};
{{/each ~}}

named!(pub parse_class<AMQPClass>, switch!(parse_id,
    {{#each protocol.classes as |class| ~}}
    {{class.id}} => map!(call!(parse_{{snake class.name}}), AMQPClass::{{camel class.name}}) {{#unless @last ~}}|{{/unless ~}}
    {{/each ~}}
));

pub fn gen_class<'a>(input: (&'a mut [u8], usize), class: &AMQPClass) -> Result<(&'a mut [u8], usize), GenError> {
    match *class {
        {{#each protocol.classes as |class| ~}}
        AMQPClass::{{camel class.name}}(ref {{snake class.name}}) => {{snake class.name}}::gen_{{snake class.name}}(input, {{snake class.name}}),
        {{/each ~}}
    }
}

#[derive(Clone, Debug, PartialEq)]
pub enum AMQPClass {
    {{#each protocol.classes as |class| ~}}
    {{camel class.name}}({{snake class.name}}::AMQPMethod),
    {{/each ~}}
}

{{#each protocol.classes as |class|}}
pub mod {{snake class.name}} {
    use super::*;

    named!(pub parse_{{snake class.name}}<{{snake class.name}}::AMQPMethod>, switch!(parse_id,
        {{#each class.methods as |method| ~}}
        {{method.id}} => map!(call!(parse_{{snake method.name}}), AMQPMethod::{{camel method.name}}) {{#unless @last ~}}|{{/unless ~}}
        {{/each ~}}
    ));

    pub fn gen_{{snake class.name}}<'a>(input: (&'a mut [u8], usize), method: &AMQPMethod) -> Result<(&'a mut [u8], usize), GenError> {
        match *method {
            {{#each class.methods as |method| ~}}
            AMQPMethod::{{camel method.name}}(ref {{snake method.name}}) => {
                do_gen!(input,
                    gen_id(&{{class.id}}) >>
                    gen_{{snake method.name}}({{snake method.name}})
                )
            },
            {{/each ~}}
        }
    }

    #[derive(Clone, Debug, PartialEq)]
    pub enum AMQPMethod {
        {{#each class.methods as |method| ~}}
        {{camel method.name}}({{camel method.name}}),
        {{/each ~}}
    }

    {{#each class.methods as |method|}}
    #[derive(Clone, Debug, PartialEq)]
    pub struct {{camel method.name}} {
        {{#each_argument method.arguments as |argument| ~}}
        {{#if argument_is_value ~}}
        pub {{snake argument.name}}: {{argument.type}},
        {{else}}
        {{#each_flag argument as |flag| ~}}
        pub {{snake flag.name}}: Boolean,
        {{/each_flag ~}}
        {{/if ~}}
        {{/each_argument ~}}
    }

    named!(pub parse_{{snake method.name}}<{{camel method.name}}>, do_parse!(
        {{#each_argument method.arguments as |argument| ~}}
        {{#if argument_is_value ~}}
        {{snake argument.name}}: parse_{{snake_type argument.type}} >>
        {{else}}
        /* FIXME: support multiple flags structs? */
        flags: apply!(parse_flags, &[
            {{#each_flag argument as |flag| ~}}
            "{{flag.name}}",
            {{/each_flag ~}}
        ]) >>
        {{/if ~}}
        {{/each_argument ~}}
        ({{camel method.name}} {
            {{#each_argument method.arguments as |argument| ~}}
            {{#if argument_is_value ~}}
            {{snake argument.name}}: {{snake argument.name}},
            {{else}}
            {{#each_flag argument as |flag| ~}}
            {{snake flag.name}}: flags.get_flag("{{snake flag.name}}").unwrap_or({{flag.default_value}}),
            {{/each_flag ~}}
            {{/if ~}}
            {{/each_argument ~}}
        })
    ));

    pub fn gen_{{snake method.name}}<'a>(input: (&'a mut [u8], usize), {{#if method.has_arguments ~}}method{{else}}_{{/if ~}}: &{{camel method.name}}) -> Result<(&'a mut [u8],usize), GenError> {
        {{#if method.has_flags ~}}
        /* FIXME: support multiple flags structs? */
        let mut flags = AMQPFlags::default();
        {{#each_argument method.arguments as |argument| ~}}
        {{#unless argument_is_value ~}}
        {{#each_flag argument as |flag| ~}}
        flags.add_flag("{{snake flag.name}}".to_string(), method.{{snake flag.name}});
        {{/each_flag ~}}
        {{/unless ~}}
        {{/each_argument ~}}
        {{/if ~}}
        do_gen!(input,
            gen_id(&{{method.id}})
            {{#each_argument method.arguments as |argument| ~}}
            {{#if argument_is_value ~}}
            >> gen_{{snake_type argument.type}}(&method.{{snake argument.name}})
            {{else}}
            >> gen_flags(&flags)
            {{/if ~}}
            {{/each_argument ~}}
        )
    }
    {{/each ~}}
    {{#if class.has_properties ~}}
    #[derive(Clone, Debug, PartialEq)]
    pub struct AMQPProperties {
        {{#each class.properties as |property| ~}}
        {{snake property.name}}: Option<{{property.type}}>,
        {{/each ~}}
    }

    impl Default for AMQPProperties {
        fn default() -> AMQPProperties {
            AMQPProperties {
                {{#each class.properties as |property| ~}}
                {{snake property.name}}: None,
                {{/each ~}}
            }
        }
    }

    impl AMQPProperties {
        {{#each class.properties as |property| ~}}
        pub fn with_{{snake property.name}}(mut self, value: {{property.type}}) -> AMQPProperties {
            self.{{snake property.name}} = Some(value);
            self
        }
        {{/each ~}}

        pub fn bitmask(&self) -> ShortUInt {
            {{#each class.properties as |property| ~}}
            (if self.{{snake property.name}}.is_some() { 1 << (15 - {{@index}}) } else { 0 }) {{#unless @last ~}} + {{/unless ~}}
            {{/each ~}}
        }
    }

    named!(pub parse_properties<AMQPProperties>, do_parse!(
        flags: parse_short_uint >>
        {{#each class.properties as |property| ~}}
        {{snake property.name}}: cond!(flags & (1 << (15 - {{@index}})) != 0, parse_{{snake_type property.type}}) >>
        {{/each ~}}
        (AMQPProperties {
            {{#each class.properties as |property| ~}}
            {{snake property.name}}: {{snake property.name}},
            {{/each ~}}
        })
    ));

    pub fn gen_properties<'a>(input:(&'a mut [u8],usize), props: &AMQPProperties) -> Result<(&'a mut [u8],usize),GenError> {
        do_gen!(input,
            gen_short_uint(&props.bitmask())
            {{#each class.properties as |property| ~}}
            >> gen_cond!(props.{{snake property.name}}.is_some(), gen_call!(gen_{{snake_type property.type}}, &props.{{snake property.name}}.as_ref().unwrap()))
            {{/each ~}}
        )
    }
    {{/if ~}}
}
{{/each ~}}
<|endoftext|>


<commit_before>pub fn add(num_l: &str, num_r: &str) -> String {
    let mut sum: Vec<u8> = denormalize(num_l).into();
    sum.extend(denormalize(num_r).bytes());

    sum.sort();
    sum.reverse();

    normalize(&String::from_utf8(sum).unwrap())
}

pub fn denormalize(num: &str) -> String {
    match num {
        "IV" => "IIII",
        "IX" => "VIIII",
        _ => num,
    }.to_string()
}

pub fn normalize(num: &str) -> String {
    match num {
        "IIII" => "IV".to_string(),
        "IIIII" => "V".to_string(),
        "VV" => "X".to_string(),
        "VIIIII" => "X".to_string(),
        _ => num.to_string(),
    }
}

#[cfg(test)]
mod tests {
    use super::add;
    use super::normalize;
    use super::denormalize;

    #[test]
    fn add_i_i() {
        assert_eq!("II", add("I", "I"));
    }

    #[test]
    fn add_i_ii() {
        assert_eq!("III", add("I", "II"));
    }

    #[test]
    fn add_ii_iii_requires_normalization_to_v() {
        assert_eq!("V", add("II", "III"));

    }

    #[test]
    fn add_v_i() {
        assert_eq!("VI", add("V", "I"));
    }

    #[test]
    fn add_i_v_understands_the_relative_order_of_v_and_i() {
        assert_eq!("VI", add("I", "V"));
    }

    #[test]
    fn add_i_iv_denormalizes_before_adding() {
        assert_eq!("V", add("I", "IV"));
    }

    #[test]
    fn denormalize_iv() {
        assert_eq!("IIII", denormalize("IV"));
    }

    #[test]
    fn denormalize_ix() {
        assert_eq!("VIIII", denormalize("IX"));
    }

    #[test]
    fn normalize_iiiii() {
        assert_eq!("V", normalize("IIIII"));
    }

    #[test]
    fn normalize_iiii() {
        assert_eq!("IV", normalize("IIII"));
    }

    #[test]
    fn normalize_vv() {
        assert_eq!("X", normalize("VV"));
    }

    #[test]
    fn normalize_viiiii() {
        assert_eq!("X", normalize("VIIIII"));
    }

}
<commit_msg>Normalization of VIIII -> IX in Rust<commit_after>pub fn add(num_l: &str, num_r: &str) -> String {
    let mut sum: Vec<u8> = denormalize(num_l).into();
    sum.extend(denormalize(num_r).bytes());

    sum.sort();
    sum.reverse();

    normalize(&String::from_utf8(sum).unwrap())
}

pub fn denormalize(num: &str) -> String {
    match num {
        "IV" => "IIII",
        "IX" => "VIIII",
        _ => num,
    }.to_string()
}

pub fn normalize(num: &str) -> String {
    match num {
        "IIII" => "IV".to_string(),
        "IIIII" => "V".to_string(),
        "VIIII" => "IX".to_string(),
        "VIIIII" => "X".to_string(),
        "VV" => "X".to_string(),
        _ => num.to_string(),
    }
}

#[cfg(test)]
mod tests {
    use super::add;
    use super::normalize;
    use super::denormalize;

    #[test]
    fn add_i_i() {
        assert_eq!("II", add("I", "I"));
    }

    #[test]
    fn add_i_ii() {
        assert_eq!("III", add("I", "II"));
    }

    #[test]
    fn add_ii_iii_requires_normalization_to_v() {
        assert_eq!("V", add("II", "III"));

    }

    #[test]
    fn add_v_i() {
        assert_eq!("VI", add("V", "I"));
    }

    #[test]
    fn add_i_v_understands_the_relative_order_of_v_and_i() {
        assert_eq!("VI", add("I", "V"));
    }

    #[test]
    fn add_i_iv_denormalizes_before_adding() {
        assert_eq!("V", add("I", "IV"));
    }

    #[test]
    fn denormalize_iv() {
        assert_eq!("IIII", denormalize("IV"));
    }

    #[test]
    fn denormalize_ix() {
        assert_eq!("VIIII", denormalize("IX"));
    }

    #[test]
    fn normalize_iiiii() {
        assert_eq!("V", normalize("IIIII"));
    }

    #[test]
    fn normalize_iiii() {
        assert_eq!("IV", normalize("IIII"));
    }

    #[test]
    fn normalize_vv() {
        assert_eq!("X", normalize("VV"));
    }

    #[test]
    fn normalize_viiii() {
        assert_eq!("IX", normalize("VIIII"));
    }

    #[test]
    fn normalize_viiiii() {
        assert_eq!("X", normalize("VIIIII"));
    }

}
<|endoftext|>


<commit_before>// no-reformat

#[doc = "

    A demonstration module

    Contains documentation in various forms that rustdoc understands,
    for testing purposes. It doesn't surve any functional
    purpose. This here, for instance, is just some filler text.

    FIXME (1654): It would be nice if we could run some automated
    tests on this file

"];

#[doc = "The base price of a muffin on a non-holiday"]
const price_of_a_muffin: float = 70f;

type waitress = {
    hair_color: str
};

#[doc = "The type of things that produce omnomnom"]
enum omnomnomy {
    #[doc = "Delicious sugar cookies"]
    cookie,
    #[doc = "It's pizza"]
    pizza_pie([uint])
}

fn take_my_order_please(
    _waitress: waitress,
    _order: [omnomnomy]
) -> uint {

    #[doc(
        desc = "OMG would you take my order already?",
        args(_waitress = "The waitress that you want to bother",
             _order = "The order vector. It should be filled with food."),
        return = "The price of the order, including tax",
        failure = "This function is full of fail"
    )];

    fail;
}

mod fortress_of_solitude {
    #[doc(
        brief = "Superman's vacation home",
        desc = "

        The fortress of solitude is located in the Arctic and it is
        cold. What you may not know about the fortress of solitude
        though is that it contains two separate bowling alleys. One of
        them features bumper-bowling and is kind of lame.

        Really, it's pretty cool.

    ")];

}

mod blade_runner {
    #[doc(
        brief = "Blade Runner is probably the best movie ever",
        desc = "I like that in the world of Blade Runner it is always
                raining, and that it's always night time. And Aliens
                was also a really good movie.

                Alien 3 was crap though."
    )];
}

#[doc(
    brief = "Bored",
    desc = "

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nec
    molestie nisl. Duis massa risus, pharetra a scelerisque a,
    molestie eu velit. Donec mattis ligula at ante imperdiet ut
    dapibus mauris malesuada. Sed gravida nisi a metus elementum sit
    amet hendrerit dolor bibendum. Aenean sit amet neque massa, sed
    tempus tortor. Sed ut lobortis enim. Proin a mauris quis nunc
    fermentum ultrices eget a erat. Mauris in lectus vitae metus
    sodales auctor. Morbi nunc quam, ultricies at venenatis non,
    pellentesque ac dui.

    Quisque vitae est id eros placerat laoreet sit amet eu
    nisi. Curabitur suscipit neque porttitor est euismod
    lacinia. Curabitur non quam vitae ipsum adipiscing
    condimentum. Mauris ut ante eget metus sollicitudin
    blandit. Aliquam erat volutpat. Morbi sed nisl mauris. Nulla
    facilisi. Phasellus at mollis ipsum. Maecenas sed convallis
    sapien. Nullam in ligula turpis. Pellentesque a neque augue. Sed
    eget ante feugiat tortor congue auctor ac quis ante. Proin
    condimentum lacinia tincidunt.

")]
resource bored(bored: bool) {
    log(error, bored);
}<commit_msg>rustdoc: Add ifaces to demo module<commit_after>// no-reformat

#[doc = "

    A demonstration module

    Contains documentation in various forms that rustdoc understands,
    for testing purposes. It doesn't surve any functional
    purpose. This here, for instance, is just some filler text.

    FIXME (1654): It would be nice if we could run some automated
    tests on this file

"];

#[doc = "The base price of a muffin on a non-holiday"]
const price_of_a_muffin: float = 70f;

type waitress = {
    hair_color: str
};

#[doc = "The type of things that produce omnomnom"]
enum omnomnomy {
    #[doc = "Delicious sugar cookies"]
    cookie,
    #[doc = "It's pizza"]
    pizza_pie([uint])
}

fn take_my_order_please(
    _waitress: waitress,
    _order: [omnomnomy]
) -> uint {

    #[doc(
        desc = "OMG would you take my order already?",
        args(_waitress = "The waitress that you want to bother",
             _order = "The order vector. It should be filled with food."),
        return = "The price of the order, including tax",
        failure = "This function is full of fail"
    )];

    fail;
}

mod fortress_of_solitude {
    #[doc(
        brief = "Superman's vacation home",
        desc = "

        The fortress of solitude is located in the Arctic and it is
        cold. What you may not know about the fortress of solitude
        though is that it contains two separate bowling alleys. One of
        them features bumper-bowling and is kind of lame.

        Really, it's pretty cool.

    ")];

}

mod blade_runner {
    #[doc(
        brief = "Blade Runner is probably the best movie ever",
        desc = "I like that in the world of Blade Runner it is always
                raining, and that it's always night time. And Aliens
                was also a really good movie.

                Alien 3 was crap though."
    )];
}

#[doc(
    brief = "Bored",
    desc = "

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nec
    molestie nisl. Duis massa risus, pharetra a scelerisque a,
    molestie eu velit. Donec mattis ligula at ante imperdiet ut
    dapibus mauris malesuada. Sed gravida nisi a metus elementum sit
    amet hendrerit dolor bibendum. Aenean sit amet neque massa, sed
    tempus tortor. Sed ut lobortis enim. Proin a mauris quis nunc
    fermentum ultrices eget a erat. Mauris in lectus vitae metus
    sodales auctor. Morbi nunc quam, ultricies at venenatis non,
    pellentesque ac dui.

    Quisque vitae est id eros placerat laoreet sit amet eu
    nisi. Curabitur suscipit neque porttitor est euismod
    lacinia. Curabitur non quam vitae ipsum adipiscing
    condimentum. Mauris ut ante eget metus sollicitudin
    blandit. Aliquam erat volutpat. Morbi sed nisl mauris. Nulla
    facilisi. Phasellus at mollis ipsum. Maecenas sed convallis
    sapien. Nullam in ligula turpis. Pellentesque a neque augue. Sed
    eget ante feugiat tortor congue auctor ac quis ante. Proin
    condimentum lacinia tincidunt.

")]
resource bored(bored: bool) {
    log(error, bored);
}

#[doc(
    brief = "The Shunned House",
    desc = "

From even the greatest of horrors irony is seldom absent. Sometimes it
enters directly into the composition of the events, while sometimes it
relates only to their fortuitous position among persons and
places. The latter sort is splendidly exemplified by a case in the
ancient city of Providence, where in the late forties Edgar Allan Poe
used to sojourn often during his unsuccessful wooing of the gifted
poetess, Mrs.  Whitman. Poe generally stopped at the Mansion House in
Benefit Street--the renamed Golden Ball Inn whose roof has sheltered
Washington, Jefferson, and Lafayette--and his favorite walk led
northward along the same street to Mrs. Whitman's home and the
neighboring hillside churchyard of St. John's, whose hidden expanse of
Eighteenth Century gravestones had for him a peculiar fascination.

")]
iface the_shunned_house {
    #[doc(
        desc = "

    Now the irony is this. In this walk, so many times repeated, the
    world's greatest master of the terrible and the bizarre was
    obliged to pass a particular house on the eastern side of the
    street; a dingy, antiquated structure perched on the abruptly
    rising side hill, with a great unkempt yard dating from a time
    when the region was partly open country. It does not appear that
    he ever wrote or spoke of it, nor is there any evidence that he
    even noticed it. And yet that house, to the two persons in
    possession of certain information, equals or outranks in horror
    the wildest fantasy of the genius who so often passed it
    unknowingly, and stands starkly leering as a symbol of all that is
    unutterably hideous.

    ",
        args(
            a =
            "A yard dating from a time when the region was partly
             open country"
    ))]
    fn dingy_house(unkempt_yard: int);

    #[doc(
        desc = "

    The house was--and for that matter still is--of a kind to attract
    the attention of the curious. Originally a farm or semi-farm
    building, it followed the average New England colonial lines of
    the middle Eighteenth Century--the prosperous peaked-roof sort,
    with two stories and dormerless attic, and with the Georgian
    doorway and interior panelling dictated by the progress of taste
    at that time. It faced south, with one gable end buried to the
    lower windows in the eastward rising hill, and the other exposed
    to the foundations toward the street. Its construction, over a
    century and a half ago, had followed the grading and straightening
    of the road in that especial vicinity; for Benefit Street--at
    first called Back Street--was laid out as a lane winding amongst
    the graveyards of the first settlers, and straightened only when
    the removal of the bodies to the North Burial Ground made it
    decently possible to cut through the old family plots.

    ",
        return = "A dingy house with an unkempt yard",
        failure = "Will fail if bodies are removed from premises"
    )]
    fn construct() -> bool;
}<|endoftext|>


<commit_before>export fold;
export fold_crate, fold_mod, fold_fn, fold_modlist, fold_fnlist;
export default_seq_fold;

tag fold = t;

type fold_crate = fn~(fold: fold, doc: doc::cratedoc) -> doc::cratedoc;
type fold_mod = fn~(fold: fold, doc: doc::moddoc) -> doc::moddoc;
type fold_fn = fn~(fold: fold, doc: doc::fndoc) -> doc::fndoc;
type fold_modlist = fn~(fold: fold, list: doc::modlist) -> doc::modlist;
type fold_fnlist = fn~(fold: fold, list: doc::fnlist) -> doc::fnlist;

type t = {
    fold_crate: fold_crate,
    fold_mod: fold_mod,
    fold_fn: fold_fn,
    fold_modlist: fold_modlist,
    fold_fnlist: fold_fnlist
};

// This exists because fn types don't infer correctly as record
// initializers, but they do as function arguments
fn mk_fold(
    fold_crate: fold_crate,
    fold_mod: fold_mod,
    fold_fn: fold_fn,
    fold_modlist: fold_modlist,
    fold_fnlist: fold_fnlist
) -> fold {
    fold({
        fold_crate: fold_crate,
        fold_mod: fold_mod,
        fold_fn: fold_fn,
        fold_modlist: fold_modlist,
        fold_fnlist: fold_fnlist
    })
}

fn default_seq_fold() -> fold {
    mk_fold(
        default_seq_fold_crate,
        default_seq_fold_mod,
        default_seq_fold_fn,
        default_seq_fold_modlist,
        default_seq_fold_fnlist
    )
}

fn default_seq_fold_crate(
    fold: fold,
    doc: doc::cratedoc
) -> doc::cratedoc {
    ~{
        topmod: fold.fold_mod(fold, doc.topmod)
    }
}

fn default_seq_fold_mod(
    fold: fold,
    doc: doc::moddoc
) -> doc::moddoc {
    ~{
        name: doc.name,
        mods: fold.fold_modlist(fold, doc.mods),
        fns: fold.fold_fnlist(fold, doc.fns)
    }
}

fn default_seq_fold_fn(
    _fold: fold,
    doc: doc::fndoc
) -> doc::fndoc {
    doc
}

fn default_seq_fold_modlist(
    fold: fold,
    list: doc::modlist
) -> doc::modlist {
    doc::modlist(vec::map(*list) {|doc|
        fold.fold_mod(fold, doc)
    })
}

fn default_seq_fold_fnlist(
    fold: fold,
    list: doc::fnlist
) -> doc::fnlist {
    doc::fnlist(vec::map(*list) {|doc|
        fold.fold_fn(fold, doc)
    })
}

#[cfg(test)]
mod tests {
    #[test]
    fn default_fold_should_produce_same_doc() {
        let source = "mod a { fn b() { } mod c { fn d() { } } }";
        let ast = parse::from_str(source);
        let doc = extract::extract(ast, "");
        let fld = default_seq_fold();
        let folded = fld.fold_crate(fld, doc);
        assert doc == folded;
    }
}<commit_msg>rustdoc: Make fold polymorphic on a context type<commit_after>export fold;
export fold_crate, fold_mod, fold_fn, fold_modlist, fold_fnlist;
export default_seq_fold;
export default_seq_fold_fn;

tag fold<T> = t<T>;

type fold_crate<T> = fn~(
    fold: fold<T>,
    doc: doc::cratedoc
) -> doc::cratedoc;

type fold_mod<T> = fn~(
    fold: fold<T>,
    doc: doc::moddoc
) -> doc::moddoc;

type fold_fn<T> = fn~(
    fold: fold<T>,
    doc: doc::fndoc
) -> doc::fndoc;

type fold_modlist<T> = fn~(
    fold: fold<T>,
    list: doc::modlist
) -> doc::modlist;

type fold_fnlist<T> = fn~(
    fold: fold<T>,
    list: doc::fnlist
) -> doc::fnlist;

type t<T> = {
    ctxt: T,
    fold_crate: fold_crate<T>,
    fold_mod: fold_mod<T>,
    fold_fn: fold_fn<T>,
    fold_modlist: fold_modlist<T>,
    fold_fnlist: fold_fnlist<T>
};

// This exists because fn types don't infer correctly as record
// initializers, but they do as function arguments
fn mk_fold<T:copy>(
    ctxt: T,
    fold_crate: fold_crate<T>,
    fold_mod: fold_mod<T>,
    fold_fn: fold_fn<T>,
    fold_modlist: fold_modlist<T>,
    fold_fnlist: fold_fnlist<T>
) -> fold<T> {
    fold({
        ctxt: ctxt,
        fold_crate: fold_crate,
        fold_mod: fold_mod,
        fold_fn: fold_fn,
        fold_modlist: fold_modlist,
        fold_fnlist: fold_fnlist
    })
}

fn default_seq_fold<T:copy>(ctxt: T) -> fold<T> {
    mk_fold(
        ctxt,
        {|f, d| default_seq_fold_crate(f, d)},
        {|f, d| default_seq_fold_mod(f, d)},
        {|f, d| default_seq_fold_fn(f, d)},
        {|f, d| default_seq_fold_modlist(f, d)},
        {|f, d| default_seq_fold_fnlist(f, d)}
    )
}

fn default_seq_fold_crate<T>(
    fold: fold<T>,
    doc: doc::cratedoc
) -> doc::cratedoc {
    ~{
        topmod: fold.fold_mod(fold, doc.topmod)
    }
}

fn default_seq_fold_mod<T>(
    fold: fold<T>,
    doc: doc::moddoc
) -> doc::moddoc {
    ~{
        name: doc.name,
        mods: fold.fold_modlist(fold, doc.mods),
        fns: fold.fold_fnlist(fold, doc.fns)
    }
}

fn default_seq_fold_fn<T>(
    _fold: fold<T>,
    doc: doc::fndoc
) -> doc::fndoc {
    doc
}

fn default_seq_fold_modlist<T>(
    fold: fold<T>,
    list: doc::modlist
) -> doc::modlist {
    doc::modlist(vec::map(*list) {|doc|
        fold.fold_mod(fold, doc)
    })
}

fn default_seq_fold_fnlist<T>(
    fold: fold<T>,
    list: doc::fnlist
) -> doc::fnlist {
    doc::fnlist(vec::map(*list) {|doc|
        fold.fold_fn(fold, doc)
    })
}

#[cfg(test)]
mod tests {
    #[test]
    fn default_fold_should_produce_same_doc() {
        let source = "mod a { fn b() { } mod c { fn d() { } } }";
        let ast = parse::from_str(source);
        let doc = extract::extract(ast, "");
        let fld = default_seq_fold(());
        let folded = fld.fold_crate(fld, doc);
        assert doc == folded;
    }
}<|endoftext|>


<commit_before>use range::Range;

use {
    update,
    MetaReader,
    ParseError,
    Rule,
};

/// Stores inforamtion about separated by.
pub struct SeparatedBy {
    /// The rule to separate.
    pub rule: Rule,
    /// The rule to separate by.
    pub by: Rule,
    /// Whether the rule must occur at least once.
    pub optional: bool,
    /// Whether the rule can end with separator.
    pub allow_trail: bool,
}

impl SeparatedBy {
    /// Parses rule repeatedly separated by another rule.
    pub fn parse<M>(
        &self,
        meta_reader: &mut M,
        state: &M::State,
        mut chars: &[char],
        start_offset: usize
    ) -> Result<(Range, M::State), (Range, ParseError)>
        where M: MetaReader
    {
        let mut offset = start_offset;
        let mut state = state.clone();
        let mut first = true;
        loop {
            state = match self.rule.parse(meta_reader, &state, chars, offset) {
                Err(err) => {
                    match (first, self.optional, self.allow_trail) {
                          (true, false, _)
                        | (false, _, false) => { return Err(err); }
                          (true, true, _)
                        | (false, _, true) => { break; }
                    }
                }
                Ok((range, state)) => {
                    update(range, &mut chars, &mut offset);
                    state
                }
            };
            state = match self.by.parse(meta_reader, &state, chars, offset) {
                Err(_) => { break; }
                Ok((range, state)) => {
                    update(range, &mut chars, &mut offset);
                    state
                }
            };
            first = false;
        }
        Ok((Range::new(start_offset, offset - start_offset), state))
    }
}
<commit_msg>Added parse unit tests for `SeparatedBy`<commit_after>use range::Range;

use {
    update,
    MetaReader,
    ParseError,
    Rule,
};

/// Stores inforamtion about separated by.
pub struct SeparatedBy {
    /// The rule to separate.
    pub rule: Rule,
    /// The rule to separate by.
    pub by: Rule,
    /// Whether the rule must occur at least once.
    pub optional: bool,
    /// Whether the rule can end with separator.
    pub allow_trail: bool,
}

impl SeparatedBy {
    /// Parses rule repeatedly separated by another rule.
    pub fn parse<M>(
        &self,
        meta_reader: &mut M,
        state: &M::State,
        mut chars: &[char],
        start_offset: usize
    ) -> Result<(Range, M::State), (Range, ParseError)>
        where M: MetaReader
    {
        let mut offset = start_offset;
        let mut state = state.clone();
        let mut first = true;
        loop {
            state = match self.rule.parse(meta_reader, &state, chars, offset) {
                Err(err) => {
                    match (first, self.optional, self.allow_trail) {
                          (true, false, _)
                        | (false, _, false) => { return Err(err); }
                          (true, true, _)
                        | (false, _, true) => { break; }
                    }
                }
                Ok((range, state)) => {
                    update(range, &mut chars, &mut offset);
                    state
                }
            };
            state = match self.by.parse(meta_reader, &state, chars, offset) {
                Err(_) => { break; }
                Ok((range, state)) => {
                    update(range, &mut chars, &mut offset);
                    state
                }
            };
            first = false;
        }
        Ok((Range::new(start_offset, offset - start_offset), state))
    }
}

#[cfg(test)]
mod tests {
    use super::super::*;
    use std::rc::Rc;
    use range::Range;

    #[test]
    fn required() {
        let text = "foo()";
        let chars: Vec<char> = text.chars().collect();
        let mut tokenizer = Tokenizer::new();
        let s = TokenizerState::new();
        let sep = SeparatedBy {
            rule: Rule::UntilAnyOrWhitespace(UntilAnyOrWhitespace {
                any_characters: Rc::new(",)".into()),
                optional: false,
                property: None,
            }),
            by: Rule::Token(Token {
                text: Rc::new(",".into()),
                inverted: false,
                property: None,
            }),
            optional: false,
            allow_trail: false,
        };
        let res = sep.parse(&mut tokenizer, &s, &chars[4..], 4);
        assert_eq!(res, Err((Range::new(4, 0), ParseError::ExpectedSomething)));
    }

    #[test]
    fn optional() {
        let text = "foo()";
        let chars: Vec<char> = text.chars().collect();
        let mut tokenizer = Tokenizer::new();
        let s = TokenizerState::new();
        let sep = SeparatedBy {
            rule: Rule::UntilAnyOrWhitespace(UntilAnyOrWhitespace {
                any_characters: Rc::new(",)".into()),
                optional: false,
                property: None,
            }),
            by: Rule::Token(Token {
                text: Rc::new(",".into()),
                inverted: false,
                property: None,
            }),
            optional: true,
            allow_trail: false,
        };
        let res = sep.parse(&mut tokenizer, &s, &chars[4..], 4);
        assert_eq!(res, Ok((Range::new(4, 0), s)));
    }

    #[test]
    fn disallow_trail() {
        let text = "foo(a,b,c,)";
        let chars: Vec<char> = text.chars().collect();
        let mut tokenizer = Tokenizer::new();
        let s = TokenizerState::new();
        let arg: Rc<String> = Rc::new("arg".into());
        let sep = SeparatedBy {
            rule: Rule::UntilAnyOrWhitespace(UntilAnyOrWhitespace {
                any_characters: Rc::new(",)".into()),
                optional: false,
                property: Some(arg.clone()),
            }),
            by: Rule::Token(Token {
                text: Rc::new(",".into()),
                inverted: false,
                property: None,
            }),
            optional: true,
            allow_trail: false,
        };
        let res = sep.parse(&mut tokenizer, &s, &chars[4..], 4);
        assert_eq!(res, Err((Range::new(10, 0), ParseError::ExpectedSomething)));
    }

    #[test]
    fn allow_trail() {
        let text = "foo(a,b,c,)";
        let chars: Vec<char> = text.chars().collect();
        let mut tokenizer = Tokenizer::new();
        let s = TokenizerState::new();
        let arg: Rc<String> = Rc::new("arg".into());
        let sep = SeparatedBy {
            rule: Rule::UntilAnyOrWhitespace(UntilAnyOrWhitespace {
                any_characters: Rc::new(",)".into()),
                optional: false,
                property: Some(arg.clone()),
            }),
            by: Rule::Token(Token {
                text: Rc::new(",".into()),
                inverted: false,
                property: None,
            }),
            optional: true,
            allow_trail: true,
        };
        let res = sep.parse(&mut tokenizer, &s, &chars[4..], 4);
        assert_eq!(res, Ok((Range::new(4, 6), TokenizerState(3))));
        assert_eq!(tokenizer.tokens.len(), 3);
        assert_eq!(&tokenizer.tokens[0].0,
            &MetaData::String(arg.clone(), "a".into()));
        assert_eq!(&tokenizer.tokens[1].0,
            &MetaData::String(arg.clone(), "b".into()));
        assert_eq!(&tokenizer.tokens[2].0,
            &MetaData::String(arg.clone(), "c".into()));
    }

    #[test]
    fn successful() {
        let text = "foo(a,b,c)";
        let chars: Vec<char> = text.chars().collect();
        let mut tokenizer = Tokenizer::new();
        let s = TokenizerState::new();
        let arg: Rc<String> = Rc::new("arg".into());
        let sep = SeparatedBy {
            rule: Rule::UntilAnyOrWhitespace(UntilAnyOrWhitespace {
                any_characters: Rc::new(",)".into()),
                optional: false,
                property: Some(arg.clone()),
            }),
            by: Rule::Token(Token {
                text: Rc::new(",".into()),
                inverted: false,
                property: None,
            }),
            optional: true,
            allow_trail: false,
        };
        let res = sep.parse(&mut tokenizer, &s, &chars[4..], 4);
        assert_eq!(res, Ok((Range::new(4, 5), TokenizerState(3))));
        assert_eq!(tokenizer.tokens.len(), 3);
        assert_eq!(&tokenizer.tokens[0].0,
            &MetaData::String(arg.clone(), "a".into()));
        assert_eq!(&tokenizer.tokens[1].0,
            &MetaData::String(arg.clone(), "b".into()));
        assert_eq!(&tokenizer.tokens[2].0,
            &MetaData::String(arg.clone(), "c".into()));
    }
}
<|endoftext|>


<commit_before>// This file is part of libfringe, a low-level green threading library.
// Copyright (c) whitequark <whitequark@whitequark.org>,
//               edef <edef@edef.eu>
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
extern crate fringe;

use fringe::{SliceStack, OwnedStack, OsStack};
use fringe::generator::{Generator, Yielder};

fn add_one_fn(yielder: &Yielder<i32, i32>, mut input: i32) {
  loop {
    if input == 0 { break }
    input = yielder.suspend(input + 1)
  }
}

fn new_add_one() -> Generator<'static, i32, i32, OsStack> {
  let stack = OsStack::new(0).unwrap();
  Generator::new(stack, add_one_fn)
}

#[test]
fn generator() {
  let mut add_one = new_add_one();
  assert_eq!(add_one.resume(1), Some(2));
  assert_eq!(add_one.resume(2), Some(3));
  assert_eq!(add_one.resume(0), None);
}

#[test]
fn move_after_new() {
  let mut add_one = new_add_one();
  assert_eq!(add_one.resume(1), Some(2));

  #[inline(never)]
  fn run_moved(mut add_one: Generator<i32, i32, OsStack>) {
    assert_eq!(add_one.resume(2), Some(3));
    assert_eq!(add_one.resume(3), Some(4));
    assert_eq!(add_one.resume(0), None);
  }
  run_moved(add_one);
}

#[test]
#[should_panic]
fn panic_safety() {
  struct Wrapper {
    gen: Generator<'static, (), (), OsStack>
  }

  impl Drop for Wrapper {
    fn drop(&mut self) {
      self.gen.resume(());
    }
  }

  let stack = OsStack::new(4 << 20).unwrap();
  let gen = Generator::new(stack, move |_yielder, ()| {
    panic!("foo")
  });

  let mut wrapper = Wrapper { gen: gen };
  wrapper.gen.resume(());
}

#[test]
fn with_slice_stack() {
  let mut memory = [0; 1024];
  let stack = SliceStack::new(&mut memory);
  let mut add_one = unsafe { Generator::unsafe_new(stack, add_one_fn) };
  assert_eq!(add_one.resume(1), Some(2));
  assert_eq!(add_one.resume(2), Some(3));
}

#[test]
fn with_owned_stack() {
  let stack = OwnedStack::new(1024);
  let mut add_one = unsafe { Generator::unsafe_new(stack, add_one_fn) };
  assert_eq!(add_one.resume(1), Some(2));
  assert_eq!(add_one.resume(2), Some(3));
}

#[test]
fn forget_yielded() {
  struct Dropper(*mut bool);

  impl Drop for Dropper {
    fn drop(&mut self) {
      unsafe {
        if *self.0 {
          panic!("double drop!")
        }
        *self.0 = true;
      }
    }
  }

  let stack = fringe::OsStack::new(1<<16).unwrap();
  let mut generator = Generator::new(stack, |yielder, ()| {
    let mut flag = false;
    yielder.suspend(Dropper(&mut flag as *mut bool));
  });
  generator.resume(());
  generator.resume(());
}
<commit_msg>Don't use unsafe for the forget_yielded test<commit_after>// This file is part of libfringe, a low-level green threading library.
// Copyright (c) whitequark <whitequark@whitequark.org>,
//               edef <edef@edef.eu>
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
extern crate fringe;

use fringe::{SliceStack, OwnedStack, OsStack};
use fringe::generator::{Generator, Yielder};

fn add_one_fn(yielder: &Yielder<i32, i32>, mut input: i32) {
  loop {
    if input == 0 { break }
    input = yielder.suspend(input + 1)
  }
}

fn new_add_one() -> Generator<'static, i32, i32, OsStack> {
  let stack = OsStack::new(0).unwrap();
  Generator::new(stack, add_one_fn)
}

#[test]
fn generator() {
  let mut add_one = new_add_one();
  assert_eq!(add_one.resume(1), Some(2));
  assert_eq!(add_one.resume(2), Some(3));
  assert_eq!(add_one.resume(0), None);
}

#[test]
fn move_after_new() {
  let mut add_one = new_add_one();
  assert_eq!(add_one.resume(1), Some(2));

  #[inline(never)]
  fn run_moved(mut add_one: Generator<i32, i32, OsStack>) {
    assert_eq!(add_one.resume(2), Some(3));
    assert_eq!(add_one.resume(3), Some(4));
    assert_eq!(add_one.resume(0), None);
  }
  run_moved(add_one);
}

#[test]
#[should_panic]
fn panic_safety() {
  struct Wrapper {
    gen: Generator<'static, (), (), OsStack>
  }

  impl Drop for Wrapper {
    fn drop(&mut self) {
      self.gen.resume(());
    }
  }

  let stack = OsStack::new(4 << 20).unwrap();
  let gen = Generator::new(stack, move |_yielder, ()| {
    panic!("foo")
  });

  let mut wrapper = Wrapper { gen: gen };
  wrapper.gen.resume(());
}

#[test]
fn with_slice_stack() {
  let mut memory = [0; 1024];
  let stack = SliceStack::new(&mut memory);
  let mut add_one = unsafe { Generator::unsafe_new(stack, add_one_fn) };
  assert_eq!(add_one.resume(1), Some(2));
  assert_eq!(add_one.resume(2), Some(3));
}

#[test]
fn with_owned_stack() {
  let stack = OwnedStack::new(1024);
  let mut add_one = unsafe { Generator::unsafe_new(stack, add_one_fn) };
  assert_eq!(add_one.resume(1), Some(2));
  assert_eq!(add_one.resume(2), Some(3));
}

#[test]
fn forget_yielded() {
  use std::cell::Cell;
  struct Dropper<'a>(&'a Cell<bool>);

  impl<'a> Drop for Dropper<'a> {
    fn drop(&mut self) {
      if self.0.get() {
        panic!("double drop!")
      }
      self.0.set(true);
    }
  }

  let stack = fringe::OsStack::new(1<<16).unwrap();
  let flag = Cell::new(false);
  let mut generator = Generator::new(stack, |yielder, ()| {
    yielder.suspend(Dropper(&flag));
  });
  generator.resume(());
  generator.resume(());
}
<|endoftext|>


<commit_before>//
// Copyright 2015 Joshua R. Rodgers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#[macro_use]
extern crate query_rs;

#[allow(unused_variables)]
#[test]
fn where_let_clauses_should_filter_the_source_iterator() {
    let source = [Some(1), None, Some(3), None, Some(5)];

    let result = query! { from x => source.iter(),
                          where let Some(y) = x,
                          select y };

    let expected = vec! [ 1, 3, 5 ];

    for (i, x) in result.enumerate() {
        assert_eq!(x, expected[i]);
    }
}

#[test]
fn where_let_clauses_should_allow_patterns_with_no_parameters() {
    let source = [Some(1), None, Some(3), None, Some(5)];

    let result = query! { from x => source.iter(),
                          where let None = x,
                          select x };

    let expected = vec! [ None, None ];

    for (i, x) in result.enumerate() {
        assert_eq!(x, expected[i]);
    }
}

#[allow(unused_variables)]
#[test]
fn where_clauses_can_follow_where_let() {
    let source = [Some(1), None, Some(3), None, Some(5)];

    let result = query! { from x => source.iter(),
                          where let Some(y) = x,
                          where y >= 3,
                          select y };

    let expected = vec! [ 3, 5 ];

    for (i, x) in result.enumerate() {
        assert_eq!(x, expected[i]);
    }
}

//TODO: I need to fix select-many clauses for this to properly work.
//#[test]
//fn from_clause_can_follow_where_let() {
//    let source = vec! [None, Some(vec! [1, 2]), None, Some(vec! [3, 4])];
//
//    let result = query! { from xs => source.into_iter(),
//                          where let Some(ys) = xs,
//                          from &y => ys.clone().into_iter(),
//                          select y };
//
//    let expected = vec! [ 1, 2, 3, 4 ];
//
//    for (i, x) in result.enumerate() {
//        assert_eq!(x, expected[i]);
//    }
//}<commit_msg>Added a rudimentary test for select clauses following where let clauses.<commit_after>//
// Copyright 2015 Joshua R. Rodgers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#[macro_use]
extern crate query_rs;

#[allow(unused_variables)]
#[test]
fn where_let_clauses_should_filter_the_source_iterator() {
    let source = [Some(1), None, Some(3), None, Some(5)];

    let result = query! { from x => source.iter(),
                          where let Some(y) = x,
                          select y };

    let expected = vec! [ 1, 3, 5 ];

    for (i, x) in result.enumerate() {
        assert_eq!(x, expected[i]);
    }
}

#[test]
fn where_let_clauses_should_allow_patterns_with_no_parameters() {
    let source = [Some(1), None, Some(3), None, Some(5)];

    let result = query! { from x => source.iter(),
                          where let None = x,
                          select x };

    let expected = vec! [ None, None ];

    for (i, x) in result.enumerate() {
        assert_eq!(x, expected[i]);
    }
}

#[allow(unused_variables)]
#[test]
fn where_clauses_can_follow_where_let() {
    let source = [Some(1), None, Some(3), None, Some(5)];

    let result = query! { from x => source.iter(),
                          where let Some(y) = x,
                          where y >= 3,
                          select y };

    let expected = vec! [ 3, 5 ];

    for (i, x) in result.enumerate() {
        assert_eq!(x, expected[i]);
    }
}

#[allow(unused_variables)]
#[test]
fn from_clause_can_follow_where_let() {
    let source = vec! [None, Some(()), None, Some(())];
    let inner_source = [1, 2, 3, 4];

    let result = query! { from xs => source.iter(),
                          where let Some(()) = xs,
                          from &y => inner_source.iter(),
                          select y };

    let expected = vec! [ 1, 2, 3, 4, 1, 2, 3, 4 ];

    for (i, x) in result.enumerate() {
        assert_eq!(x, expected[i]);
    }
}<|endoftext|>


<commit_before>use runtime::Runtime;
use storage::backend::StorageBackend;

use module::Module;
use module::CommandResult;
use module::CommandEnv;

use module::bm::header::build_header;
use storage::json::parser::JsonHeaderParser;
use storage::parser::FileHeaderParser;

use clap::ArgMatches;
use regex::Regex;

pub fn add_command(module: &Module, env: CommandEnv) -> CommandResult {
    let url = env.matches.value_of("url").unwrap();
    let tags = get_tags(env.rt, env.matches);
    info!("Adding url '{}' with tags '{:?}'", url, tags);

    let header = build_header(&String::from(url), &tags);
    let jheader = JsonHeaderParser::new(None).write(&header);
    println!("JSON: {:?}", jheader);

    Ok(())
}

pub fn list_command(module: &Module, env: CommandEnv) -> CommandResult {
    let tags    = get_tags(env.rt, env.matches);
    let matcher = get_matcher(env.rt, env.matches);

    match matcher {
        Some(reg) => {
            info!("Listing urls with matcher '{}' and with tags {:?}",
                     reg.as_str(),
                     tags);
        }
        None => {
            info!("Listing urls with tags {:?}", tags);
        }
    }

    Ok(())
}

pub fn remove_command(module: &Module, env: CommandEnv) -> CommandResult {
    let tags    = get_tags(env.rt, env.matches);
    let matcher = get_matcher(env.rt, env.matches);
    let id      = get_id(env.rt, env.matches);

    match id {
        Some(idstr) => {
            info!("Removing urls with id '{}'", idstr);
        }
        None => {
            match matcher {
                Some(reg) => {
                    info!("Removing urls with matcher '{}' and with tags {:?}",
                             reg.as_str(), tags);
                }
                None => {
                    info!("Listing urls with tags {:?}", tags);
                }
            }
        }
    }

    Ok(())
}

/*
 *
 * Private helpers
 *
 */

fn get_tags<'a>(rt: &Runtime, sub: &ArgMatches<'a, 'a>) -> Vec<String> {
    debug!("Fetching tags from commandline");
    sub.value_of("tags").and_then(|tags|
                                  Some(tags.split(",")
                                       .into_iter()
                                       .map(|s| s.to_string())
                                       .filter(|e|
                                            if e.contains(" ") {
                                                warn!("Tag contains spaces: '{}'", e);
                                                false
                                            } else {
                                                true
                                            }).collect()
                                      )
                                 ).or(Some(vec![])).unwrap()

}

fn get_matcher<'a>(rt: &Runtime, sub: &ArgMatches<'a, 'a>) -> Option<Regex> {
    debug!("Fetching matcher from commandline");
    if let Some(s) = sub.value_of("match") {
        if let Ok(r) = Regex::new(s) {
            return Some(r)
        } else {
            error!("Regex error, continuing without regex");
        }
    }
    None

}

fn get_id<'a>(rt: &Runtime, sub: &ArgMatches<'a, 'a>) -> Option<String> {
    debug!("Fetching id from commandline");
    sub.value_of("id").and_then(|s| Some(String::from(s)))
}

<commit_msg>Implement add_command() with backend<commit_after>use runtime::Runtime;
use storage::backend::StorageBackend;

use module::Module;
use module::CommandResult;
use module::CommandEnv;

use module::bm::header::build_header;
use storage::json::parser::JsonHeaderParser;
use storage::parser::{Parser, FileHeaderParser};
use storage::file::File;

use clap::ArgMatches;
use regex::Regex;

pub fn add_command(module: &Module, env: CommandEnv) -> CommandResult {
    let url = env.matches.value_of("url").unwrap();
    let tags = get_tags(env.rt, env.matches);
    info!("Adding url '{}' with tags '{:?}'", url, tags);

    let header  = build_header(&String::from(url), &tags);
    let file    = File::new_with_header(module, header);
    let parser  = Parser::new(JsonHeaderParser::new(None));
    let putres  = env.bk.put_file(file, &parser);

    Ok(())
}

pub fn list_command(module: &Module, env: CommandEnv) -> CommandResult {
    let tags    = get_tags(env.rt, env.matches);
    let matcher = get_matcher(env.rt, env.matches);

    match matcher {
        Some(reg) => {
            info!("Listing urls with matcher '{}' and with tags {:?}",
                     reg.as_str(),
                     tags);
        }
        None => {
            info!("Listing urls with tags {:?}", tags);
        }
    }

    Ok(())
}

pub fn remove_command(module: &Module, env: CommandEnv) -> CommandResult {
    let tags    = get_tags(env.rt, env.matches);
    let matcher = get_matcher(env.rt, env.matches);
    let id      = get_id(env.rt, env.matches);

    match id {
        Some(idstr) => {
            info!("Removing urls with id '{}'", idstr);
        }
        None => {
            match matcher {
                Some(reg) => {
                    info!("Removing urls with matcher '{}' and with tags {:?}",
                             reg.as_str(), tags);
                }
                None => {
                    info!("Listing urls with tags {:?}", tags);
                }
            }
        }
    }

    Ok(())
}

/*
 *
 * Private helpers
 *
 */

fn get_tags<'a>(rt: &Runtime, sub: &ArgMatches<'a, 'a>) -> Vec<String> {
    debug!("Fetching tags from commandline");
    sub.value_of("tags").and_then(|tags|
                                  Some(tags.split(",")
                                       .into_iter()
                                       .map(|s| s.to_string())
                                       .filter(|e|
                                            if e.contains(" ") {
                                                warn!("Tag contains spaces: '{}'", e);
                                                false
                                            } else {
                                                true
                                            }).collect()
                                      )
                                 ).or(Some(vec![])).unwrap()

}

fn get_matcher<'a>(rt: &Runtime, sub: &ArgMatches<'a, 'a>) -> Option<Regex> {
    debug!("Fetching matcher from commandline");
    if let Some(s) = sub.value_of("match") {
        if let Ok(r) = Regex::new(s) {
            return Some(r)
        } else {
            error!("Regex error, continuing without regex");
        }
    }
    None

}

fn get_id<'a>(rt: &Runtime, sub: &ArgMatches<'a, 'a>) -> Option<String> {
    debug!("Fetching id from commandline");
    sub.value_of("id").and_then(|s| Some(String::from(s)))
}

<|endoftext|>


<commit_before>use common::util::ConfigurableProgram;
use common::util::ProgramFragment;

use common::module::Module;

use std::option::Option;

use std::path::PathBuf;

pub struct ParseBuilder{
    is_verbose : bool,
    is_archive : bool,
    module_path : Option<String>,
    input_path : Option<String>,
    output_path : Option<String>
}

impl ParseBuilder {
    pub fn new() -> ParseBuilder {
        ParseBuilder {
            is_verbose : false,
            is_archive : false,
            module_path : Option::None,
            input_path : Option::None,
            output_path : Option::None
        }
    }
}

impl ConfigurableProgram<ParseRunner> for ParseBuilder {
    fn set_flag(&mut self, name:&str, value:bool) -> &mut Self {
        match name {
            "verbose" => self.is_verbose = value,
            "archive" => self.is_archive = value,
            _ => ()
        };
        self
    }
    fn set_arg(&mut self, name:&str, value:String) -> &mut Self {
        match name {
            "module" => self.module_path = Option::Some(value),
            "input" => self.input_path = Option::Some(value),
            "output" => self.output_path = Option::Some(value),
            _ => ()
        };
        self
    }
    fn config(&self) -> ParseRunner {
        let module = match self.module_path {
            Some(ref value) => value,
            None => panic!("Incorrectly configured ParseRunner, missing 'module' def")
        };

        let input = match self.input_path {
            Some(ref value) => value,
            None => panic!("Incorrectly configured ParseRunner, missing 'input' def")
        };

        let output = match self.output_path {
            Some(ref value) => value,
            None => panic!("Incorrectly configured ParseRunner, missing 'output' def")
        };

        ParseRunner {
            is_verbose: self.is_verbose,
            is_archive: self.is_archive,
            module_path: module.clone(),
            input_path: input.clone(),
            output_path: output.clone()
        }
    }
}

pub struct ParseRunner {
    is_verbose : bool,
    is_archive : bool,
    module_path : String,
    input_path : String,
    output_path : String
}

impl ProgramFragment for ParseRunner {
    fn run<'a>(&self) -> Result<(), String> {
        let mut module_conf_path = PathBuf::from(&self.module_path);

        // if self.is_verbose {
        //     println!("Loading the module file [{}]", module_conf_path.to_str().unwrap());
        // }

        let mut module_conf = Module::new(module_conf_path.as_path());
        let module_opts = match module_conf.get_opts() {
            Ok(opts) => opts,
            Err(e) => return Err(e)
        };

        if self.is_verbose {
            println!(r#"Found configuration for module named [{0}]
    :: Written by {1} and licensed under {2}
    :: Module Version {3}"#, module_opts.meta.name,
            module_opts.meta.author, module_opts.meta.license, module_opts.meta.version);
        }

        Result::Ok(())
    }
}
<commit_msg>Removed redundant path setup from ParseRunner<commit_after>use common::util::ConfigurableProgram;
use common::util::ProgramFragment;

use common::module::Module;

use std::option::Option;

use std::path::Path;

pub struct ParseBuilder{
    is_verbose : bool,
    is_archive : bool,
    module_path : Option<String>,
    input_path : Option<String>,
    output_path : Option<String>
}

impl ParseBuilder {
    pub fn new() -> ParseBuilder {
        ParseBuilder {
            is_verbose : false,
            is_archive : false,
            module_path : Option::None,
            input_path : Option::None,
            output_path : Option::None
        }
    }
}

impl ConfigurableProgram<ParseRunner> for ParseBuilder {
    fn set_flag(&mut self, name:&str, value:bool) -> &mut Self {
        match name {
            "verbose" => self.is_verbose = value,
            "archive" => self.is_archive = value,
            _ => ()
        };
        self
    }
    fn set_arg(&mut self, name:&str, value:String) -> &mut Self {
        match name {
            "module" => self.module_path = Option::Some(value),
            "input" => self.input_path = Option::Some(value),
            "output" => self.output_path = Option::Some(value),
            _ => ()
        };
        self
    }
    fn config(&self) -> ParseRunner {
        let module = match self.module_path {
            Some(ref value) => value,
            None => panic!("Incorrectly configured ParseRunner, missing 'module' def")
        };

        let input = match self.input_path {
            Some(ref value) => value,
            None => panic!("Incorrectly configured ParseRunner, missing 'input' def")
        };

        let output = match self.output_path {
            Some(ref value) => value,
            None => panic!("Incorrectly configured ParseRunner, missing 'output' def")
        };

        ParseRunner {
            is_verbose: self.is_verbose,
            is_archive: self.is_archive,
            module_path: module.clone(),
            input_path: input.clone(),
            output_path: output.clone()
        }
    }
}

pub struct ParseRunner {
    is_verbose : bool,
    is_archive : bool,
    module_path : String,
    input_path : String,
    output_path : String
}

impl ProgramFragment for ParseRunner {
    fn run<'a>(&self) -> Result<(), String> {
        let mut module_conf = Module::new(Path::new(&self.module_path));
        let module_opts = match module_conf.get_opts() {
            Ok(opts) => opts,
            Err(e) => return Err(e)
        };

        if self.is_verbose {
            println!(r#"Found configuration for module named [{0}]
    :: Written by {1} and licensed under {2}
    :: Module Version {3}"#, module_opts.meta.name,
            module_opts.meta.author, module_opts.meta.license, module_opts.meta.version);
        }

        Result::Ok(())
    }
}
<|endoftext|>


<commit_before>#![cfg(target_os = "macos")]

use CreationError;
use CreationError::OsError;
use ContextError;
use GlAttributes;
use GlContext;
use PixelFormat;
use PixelFormatRequirements;
use Robustness;
use WindowAttributes;
use os::macos::ActivationPolicy;

use objc::runtime::{BOOL, NO};

use cgl::{CGLEnable, kCGLCECrashOnRemovedFunctions, CGLSetParameter, kCGLCPSurfaceOpacity};

use cocoa::base::{id, nil};
use cocoa::foundation::NSAutoreleasePool;
use cocoa::appkit::{self, NSOpenGLContext, NSOpenGLPixelFormat};

use core_foundation::base::TCFType;
use core_foundation::string::CFString;
use core_foundation::bundle::{CFBundleGetBundleWithIdentifier, CFBundleGetFunctionPointerForName};

use std::collections::HashMap;
use std::str::FromStr;
use std::ops::Deref;
use std::sync::{Arc, Mutex, Weak};

use libc;

use winit;
use winit::os::macos::WindowExt;
pub use winit::{MonitorId, NativeMonitorId, get_available_monitors, get_primary_monitor};
pub use self::headless::HeadlessContext;
pub use self::headless::PlatformSpecificHeadlessBuilderAttributes;

mod headless;
mod helpers;

#[derive(Clone, Default)]
pub struct PlatformSpecificWindowBuilderAttributes {
    pub activation_policy: ActivationPolicy,
}

pub struct Window {
    // A handle to the GL context associated with this window.
    context: Arc<Context>,
    // The Window must store a handle to the map in order to remove its own context when dropped.
    contexts: Arc<ContextMap>,
    winit_window: winit::Window,
}

pub struct EventsLoop {
    winit_events_loop: winit::EventsLoop,
    window_contexts: Mutex<Weak<ContextMap>>,
}

struct Context {
    // NSOpenGLContext
    gl: IdRef,
    pixel_format: PixelFormat,
}

struct ContextMap {
    map: Mutex<HashMap<winit::WindowId, Weak<Context>>>,
}

impl EventsLoop {
    /// Builds a new events loop.
    pub fn new() -> EventsLoop {
        EventsLoop {
            winit_events_loop: winit::EventsLoop::new(),
            window_contexts: Mutex::new(Weak::new()),
        }
    }

    fn handle_event(&self, event: &winit::Event) {
        match *event {
            winit::Event::WindowEvent { window_id, ref event } => match *event {

                // If a `Resized` event was received for a window, update the GL context for that
                // window but only if that window is still alive.
                winit::WindowEvent::Resized(..) => {
                    if let Some(window_contexts) = self.window_contexts.lock().unwrap().upgrade() {
                        if let Some(context) = window_contexts.map.lock().unwrap()[&window_id].upgrade() {
                            unsafe { context.gl.update(); }
                        }
                    }
                },

                // If a `Closed` event was received for a window, remove the associated context
                // from the map.
                winit::WindowEvent::Closed => {
                    if let Some(window_contexts) = self.window_contexts.lock().unwrap().upgrade() {
                        window_contexts.map.lock().unwrap().remove(&window_id);
                    }
                },

                _ => (),
            },
        }
    }

    /// Fetches all the events that are pending, calls the callback function for each of them,
    /// and returns.
    #[inline]
    pub fn poll_events<F>(&self, mut callback: F)
        where F: FnMut(winit::Event)
    {
        self.winit_events_loop.poll_events(|event| {
            self.handle_event(&event);
            callback(event);
        });
    }

    /// Runs forever until `interrupt()` is called. Whenever an event happens, calls the callback.
    #[inline]
    pub fn run_forever<F>(&self, mut callback: F)
        where F: FnMut(winit::Event)
    {
        self.winit_events_loop.run_forever(|event| {
            self.handle_event(&event);
            callback(event);
        })
    }

    /// If we called `run_forever()`, stops the process of waiting for events.
    #[inline]
    pub fn interrupt(&self) {
        self.winit_events_loop.interrupt()
    }
}

unsafe impl Send for Window {}
unsafe impl Sync for Window {}

impl Window {

    pub fn new(events_loop: &EventsLoop,
               _win_attribs: &WindowAttributes,
               pf_reqs: &PixelFormatRequirements,
               opengl: &GlAttributes<&Window>,
               _pl_attribs: &PlatformSpecificWindowBuilderAttributes,
               winit_builder: winit::WindowBuilder)
               -> Result<Self, CreationError> {
        if opengl.sharing.is_some() {
            unimplemented!()
        }

        match opengl.robustness {
            Robustness::RobustNoResetNotification |
            Robustness::RobustLoseContextOnReset => {
                return Err(CreationError::RobustnessNotSupported);
            }
            _ => (),
        }

        let transparent = winit_builder.window.transparent;
        let winit_window = winit_builder.build(&events_loop.winit_events_loop).unwrap();
        let window_id = winit_window.id();
        let view = winit_window.get_nsview() as id;
        let context = match Context::new(view, pf_reqs, opengl, transparent) {
            Ok(context) => Arc::new(context),
            Err(e) => {
                return Err(OsError(format!("Couldn't create OpenGL context: {}", e)));
            }
        };
        let weak_context = Arc::downgrade(&context);

        let new_window = |window_contexts| Window {
            context: context,
            winit_window: winit_window,
            contexts: window_contexts,
        };

        // If a `ContextMap` exists, insert the context for this new window and return it.
        if let Some(window_contexts) = events_loop.window_contexts.lock().unwrap().upgrade() {
            window_contexts.map.lock().unwrap().insert(window_id, weak_context);
            return Ok(new_window(window_contexts));
        }

        // If there is not yet a `ContextMap`, this must be the first window so we must create it.
        let mut map = HashMap::new();
        map.insert(window_id, weak_context);
        let window_contexts = Arc::new(ContextMap { map: Mutex::new(map) });
        *events_loop.window_contexts.lock().unwrap() = Arc::downgrade(&window_contexts);
        Ok(new_window(window_contexts))
    }

    pub fn set_title(&self, title: &str) {
        self.winit_window.set_title(title)
    }

    #[inline]
    pub fn as_winit_window(&self) -> &winit::Window {
        &self.winit_window
    }

    #[inline]
    pub fn as_winit_window_mut(&mut self) -> &mut winit::Window {
        &mut self.winit_window
    }

    pub fn show(&self) {
        self.winit_window.show()
    }

    pub fn hide(&self) {
        self.winit_window.hide()
    }

    pub fn get_position(&self) -> Option<(i32, i32)> {
        self.winit_window.get_position()
    }

    pub fn set_position(&self, x: i32, y: i32) {
        self.winit_window.set_position(x, y)
    }

    pub fn get_inner_size(&self) -> Option<(u32, u32)> {
        self.winit_window.get_inner_size()
    }

    pub fn get_inner_size_points(&self) -> Option<(u32, u32)> {
        self.winit_window.get_inner_size()
    }

    pub fn get_inner_size_pixels(&self) -> Option<(u32, u32)> {
        self.winit_window.get_inner_size().map(|(x, y)| {
            let hidpi = self.hidpi_factor();
            ((x as f32 * hidpi) as u32, (y as f32 * hidpi) as u32)
        })
    }

    pub fn get_outer_size(&self) -> Option<(u32, u32)> {
        self.winit_window.get_outer_size()
    }

    pub fn set_inner_size(&self, x: u32, y: u32) {
        self.winit_window.set_inner_size(x, y)
    }

    #[allow(deprecated)]
    pub unsafe fn platform_display(&self) -> *mut libc::c_void {
        self.winit_window.platform_display()
    }

    #[allow(deprecated)]
    pub unsafe fn platform_window(&self) -> *mut libc::c_void {
        self.winit_window.platform_window()
    }

    pub fn set_cursor(&self, cursor: winit::MouseCursor) {
        self.winit_window.set_cursor(cursor);
    }

    pub fn hidpi_factor(&self) -> f32 {
        self.winit_window.hidpi_factor()
    }

    pub fn set_cursor_position(&self, x: i32, y: i32) -> Result<(), ()> {
        self.winit_window.set_cursor_position(x, y)
    }

    pub fn set_cursor_state(&self, state: winit::CursorState) -> Result<(), String> {
        self.winit_window.set_cursor_state(state)
    }

    pub fn id(&self) -> winit::WindowId {
        self.winit_window.id()
    }
}

impl Drop for Window {
    fn drop(&mut self) {
        self.contexts.map.lock().unwrap().remove(&self.id());
    }
}

impl Context {
    fn new(view: id,
           pf_reqs: &PixelFormatRequirements,
           opengl: &GlAttributes<&Window>,
           transparent: bool) -> Result<Self, CreationError>
    {
        let attributes = try!(helpers::build_nsattributes(pf_reqs, opengl));
        unsafe {
            let pixelformat = IdRef::new(NSOpenGLPixelFormat::alloc(nil)
                .initWithAttributes_(&attributes));

            if let Some(pixelformat) = pixelformat.non_nil() {

                // TODO: Add context sharing
                let context = IdRef::new(NSOpenGLContext::alloc(nil)
                    .initWithFormat_shareContext_(*pixelformat, nil));

                if let Some(cxt) = context.non_nil() {
                    let pf = {
                        let get_attr = |attrib: appkit::NSOpenGLPixelFormatAttribute| -> i32 {
                            let mut value = 0;

                            NSOpenGLPixelFormat::getValues_forAttribute_forVirtualScreen_(
                                *pixelformat,
                                &mut value,
                                attrib,
                                NSOpenGLContext::currentVirtualScreen(*cxt));

                            value
                        };

                        PixelFormat {
                            hardware_accelerated: get_attr(appkit::NSOpenGLPFAAccelerated) != 0,
                            color_bits: (get_attr(appkit::NSOpenGLPFAColorSize) - get_attr(appkit::NSOpenGLPFAAlphaSize)) as u8,
                            alpha_bits: get_attr(appkit::NSOpenGLPFAAlphaSize) as u8,
                            depth_bits: get_attr(appkit::NSOpenGLPFADepthSize) as u8,
                            stencil_bits: get_attr(appkit::NSOpenGLPFAStencilSize) as u8,
                            stereoscopy: get_attr(appkit::NSOpenGLPFAStereo) != 0,
                            double_buffer: get_attr(appkit::NSOpenGLPFADoubleBuffer) != 0,
                            multisampling: if get_attr(appkit::NSOpenGLPFAMultisample) > 0 {
                                Some(get_attr(appkit::NSOpenGLPFASamples) as u16)
                            } else {
                                None
                            },
                            srgb: true,
                        }
                    };

                    cxt.setView_(view);
                    let value = if opengl.vsync { 1 } else { 0 };
                    cxt.setValues_forParameter_(&value, appkit::NSOpenGLContextParameter::NSOpenGLCPSwapInterval);

                    if transparent {
                        let mut opacity = 0;
                        CGLSetParameter(cxt.CGLContextObj() as *mut _, kCGLCPSurfaceOpacity, &mut opacity);
                    }

                    CGLEnable(cxt.CGLContextObj() as *mut _, kCGLCECrashOnRemovedFunctions);

                    Ok(Context { gl: cxt, pixel_format: pf })
                } else {
                    Err(CreationError::NotSupported)
                }
            } else {
                Err(CreationError::NoAvailablePixelFormat)
            }
        }
    }
}

impl GlContext for Window {
    #[inline]
    unsafe fn make_current(&self) -> Result<(), ContextError> {
        let _: () = msg_send![*self.context.gl, update];
        self.context.gl.makeCurrentContext();
        Ok(())
    }

    #[inline]
    fn is_current(&self) -> bool {
        unsafe {
            let current = NSOpenGLContext::currentContext(nil);
            if current != nil {
                let is_equal: BOOL = msg_send![current, isEqual:*self.context.gl];
                is_equal != NO
            } else {
                false
            }
        }
    }

    fn get_proc_address(&self, addr: &str) -> *const () {
        let symbol_name: CFString = FromStr::from_str(addr).unwrap();
        let framework_name: CFString = FromStr::from_str("com.apple.opengl").unwrap();
        let framework =
            unsafe { CFBundleGetBundleWithIdentifier(framework_name.as_concrete_TypeRef()) };
        let symbol = unsafe {
            CFBundleGetFunctionPointerForName(framework, symbol_name.as_concrete_TypeRef())
        };
        symbol as *const _
    }

    #[inline]
    fn swap_buffers(&self) -> Result<(), ContextError> {
        unsafe {
            let pool = NSAutoreleasePool::new(nil);
            self.context.gl.flushBuffer();
            let _: () = msg_send![pool, release];
        }
        Ok(())
    }

    #[inline]
    fn get_api(&self) -> ::Api {
        ::Api::OpenGl
    }

    #[inline]
    fn get_pixel_format(&self) -> PixelFormat {
        self.context.pixel_format.clone()
    }
}

struct IdRef(id);

impl IdRef {
    fn new(i: id) -> IdRef {
        IdRef(i)
    }

    #[allow(dead_code)]
    fn retain(i: id) -> IdRef {
        if i != nil {
            let _: id = unsafe { msg_send![i, retain] };
        }
        IdRef(i)
    }

    fn non_nil(self) -> Option<IdRef> {
        if self.0 == nil { None } else { Some(self) }
    }
}

impl Drop for IdRef {
    fn drop(&mut self) {
        if self.0 != nil {
            let _: () = unsafe { msg_send![self.0, release] };
        }
    }
}

impl Deref for IdRef {
    type Target = id;
    fn deref<'a>(&'a self) -> &'a id {
        &self.0
    }
}

impl Clone for IdRef {
    fn clone(&self) -> IdRef {
        if self.0 != nil {
            let _: id = unsafe { msg_send![self.0, retain] };
        }
        IdRef(self.0)
    }
}
<commit_msg>Add missing Send and Sync impl for macOS EventsLoop<commit_after>#![cfg(target_os = "macos")]

use CreationError;
use CreationError::OsError;
use ContextError;
use GlAttributes;
use GlContext;
use PixelFormat;
use PixelFormatRequirements;
use Robustness;
use WindowAttributes;
use os::macos::ActivationPolicy;

use objc::runtime::{BOOL, NO};

use cgl::{CGLEnable, kCGLCECrashOnRemovedFunctions, CGLSetParameter, kCGLCPSurfaceOpacity};

use cocoa::base::{id, nil};
use cocoa::foundation::NSAutoreleasePool;
use cocoa::appkit::{self, NSOpenGLContext, NSOpenGLPixelFormat};

use core_foundation::base::TCFType;
use core_foundation::string::CFString;
use core_foundation::bundle::{CFBundleGetBundleWithIdentifier, CFBundleGetFunctionPointerForName};

use std::collections::HashMap;
use std::str::FromStr;
use std::ops::Deref;
use std::sync::{Arc, Mutex, Weak};

use libc;

use winit;
use winit::os::macos::WindowExt;
pub use winit::{MonitorId, NativeMonitorId, get_available_monitors, get_primary_monitor};
pub use self::headless::HeadlessContext;
pub use self::headless::PlatformSpecificHeadlessBuilderAttributes;

mod headless;
mod helpers;

#[derive(Clone, Default)]
pub struct PlatformSpecificWindowBuilderAttributes {
    pub activation_policy: ActivationPolicy,
}

pub struct Window {
    // A handle to the GL context associated with this window.
    context: Arc<Context>,
    // The Window must store a handle to the map in order to remove its own context when dropped.
    contexts: Arc<ContextMap>,
    winit_window: winit::Window,
}

pub struct EventsLoop {
    winit_events_loop: winit::EventsLoop,
    window_contexts: Mutex<Weak<ContextMap>>,
}

struct Context {
    // NSOpenGLContext
    gl: IdRef,
    pixel_format: PixelFormat,
}

struct ContextMap {
    map: Mutex<HashMap<winit::WindowId, Weak<Context>>>,
}

unsafe impl Send for ContextMap {}
unsafe impl Sync for ContextMap {}

impl EventsLoop {
    /// Builds a new events loop.
    pub fn new() -> EventsLoop {
        EventsLoop {
            winit_events_loop: winit::EventsLoop::new(),
            window_contexts: Mutex::new(Weak::new()),
        }
    }

    fn handle_event(&self, event: &winit::Event) {
        match *event {
            winit::Event::WindowEvent { window_id, ref event } => match *event {

                // If a `Resized` event was received for a window, update the GL context for that
                // window but only if that window is still alive.
                winit::WindowEvent::Resized(..) => {
                    if let Some(window_contexts) = self.window_contexts.lock().unwrap().upgrade() {
                        if let Some(context) = window_contexts.map.lock().unwrap()[&window_id].upgrade() {
                            unsafe { context.gl.update(); }
                        }
                    }
                },

                // If a `Closed` event was received for a window, remove the associated context
                // from the map.
                winit::WindowEvent::Closed => {
                    if let Some(window_contexts) = self.window_contexts.lock().unwrap().upgrade() {
                        window_contexts.map.lock().unwrap().remove(&window_id);
                    }
                },

                _ => (),
            },
        }
    }

    /// Fetches all the events that are pending, calls the callback function for each of them,
    /// and returns.
    #[inline]
    pub fn poll_events<F>(&self, mut callback: F)
        where F: FnMut(winit::Event)
    {
        self.winit_events_loop.poll_events(|event| {
            self.handle_event(&event);
            callback(event);
        });
    }

    /// Runs forever until `interrupt()` is called. Whenever an event happens, calls the callback.
    #[inline]
    pub fn run_forever<F>(&self, mut callback: F)
        where F: FnMut(winit::Event)
    {
        self.winit_events_loop.run_forever(|event| {
            self.handle_event(&event);
            callback(event);
        })
    }

    /// If we called `run_forever()`, stops the process of waiting for events.
    #[inline]
    pub fn interrupt(&self) {
        self.winit_events_loop.interrupt()
    }
}

unsafe impl Send for Window {}
unsafe impl Sync for Window {}

impl Window {

    pub fn new(events_loop: &EventsLoop,
               _win_attribs: &WindowAttributes,
               pf_reqs: &PixelFormatRequirements,
               opengl: &GlAttributes<&Window>,
               _pl_attribs: &PlatformSpecificWindowBuilderAttributes,
               winit_builder: winit::WindowBuilder)
               -> Result<Self, CreationError> {
        if opengl.sharing.is_some() {
            unimplemented!()
        }

        match opengl.robustness {
            Robustness::RobustNoResetNotification |
            Robustness::RobustLoseContextOnReset => {
                return Err(CreationError::RobustnessNotSupported);
            }
            _ => (),
        }

        let transparent = winit_builder.window.transparent;
        let winit_window = winit_builder.build(&events_loop.winit_events_loop).unwrap();
        let window_id = winit_window.id();
        let view = winit_window.get_nsview() as id;
        let context = match Context::new(view, pf_reqs, opengl, transparent) {
            Ok(context) => Arc::new(context),
            Err(e) => {
                return Err(OsError(format!("Couldn't create OpenGL context: {}", e)));
            }
        };
        let weak_context = Arc::downgrade(&context);

        let new_window = |window_contexts| Window {
            context: context,
            winit_window: winit_window,
            contexts: window_contexts,
        };

        // If a `ContextMap` exists, insert the context for this new window and return it.
        if let Some(window_contexts) = events_loop.window_contexts.lock().unwrap().upgrade() {
            window_contexts.map.lock().unwrap().insert(window_id, weak_context);
            return Ok(new_window(window_contexts));
        }

        // If there is not yet a `ContextMap`, this must be the first window so we must create it.
        let mut map = HashMap::new();
        map.insert(window_id, weak_context);
        let window_contexts = Arc::new(ContextMap { map: Mutex::new(map) });
        *events_loop.window_contexts.lock().unwrap() = Arc::downgrade(&window_contexts);
        Ok(new_window(window_contexts))
    }

    pub fn set_title(&self, title: &str) {
        self.winit_window.set_title(title)
    }

    #[inline]
    pub fn as_winit_window(&self) -> &winit::Window {
        &self.winit_window
    }

    #[inline]
    pub fn as_winit_window_mut(&mut self) -> &mut winit::Window {
        &mut self.winit_window
    }

    pub fn show(&self) {
        self.winit_window.show()
    }

    pub fn hide(&self) {
        self.winit_window.hide()
    }

    pub fn get_position(&self) -> Option<(i32, i32)> {
        self.winit_window.get_position()
    }

    pub fn set_position(&self, x: i32, y: i32) {
        self.winit_window.set_position(x, y)
    }

    pub fn get_inner_size(&self) -> Option<(u32, u32)> {
        self.winit_window.get_inner_size()
    }

    pub fn get_inner_size_points(&self) -> Option<(u32, u32)> {
        self.winit_window.get_inner_size()
    }

    pub fn get_inner_size_pixels(&self) -> Option<(u32, u32)> {
        self.winit_window.get_inner_size().map(|(x, y)| {
            let hidpi = self.hidpi_factor();
            ((x as f32 * hidpi) as u32, (y as f32 * hidpi) as u32)
        })
    }

    pub fn get_outer_size(&self) -> Option<(u32, u32)> {
        self.winit_window.get_outer_size()
    }

    pub fn set_inner_size(&self, x: u32, y: u32) {
        self.winit_window.set_inner_size(x, y)
    }

    #[allow(deprecated)]
    pub unsafe fn platform_display(&self) -> *mut libc::c_void {
        self.winit_window.platform_display()
    }

    #[allow(deprecated)]
    pub unsafe fn platform_window(&self) -> *mut libc::c_void {
        self.winit_window.platform_window()
    }

    pub fn set_cursor(&self, cursor: winit::MouseCursor) {
        self.winit_window.set_cursor(cursor);
    }

    pub fn hidpi_factor(&self) -> f32 {
        self.winit_window.hidpi_factor()
    }

    pub fn set_cursor_position(&self, x: i32, y: i32) -> Result<(), ()> {
        self.winit_window.set_cursor_position(x, y)
    }

    pub fn set_cursor_state(&self, state: winit::CursorState) -> Result<(), String> {
        self.winit_window.set_cursor_state(state)
    }

    pub fn id(&self) -> winit::WindowId {
        self.winit_window.id()
    }
}

impl Drop for Window {
    fn drop(&mut self) {
        self.contexts.map.lock().unwrap().remove(&self.id());
    }
}

impl Context {
    fn new(view: id,
           pf_reqs: &PixelFormatRequirements,
           opengl: &GlAttributes<&Window>,
           transparent: bool) -> Result<Self, CreationError>
    {
        let attributes = try!(helpers::build_nsattributes(pf_reqs, opengl));
        unsafe {
            let pixelformat = IdRef::new(NSOpenGLPixelFormat::alloc(nil)
                .initWithAttributes_(&attributes));

            if let Some(pixelformat) = pixelformat.non_nil() {

                // TODO: Add context sharing
                let context = IdRef::new(NSOpenGLContext::alloc(nil)
                    .initWithFormat_shareContext_(*pixelformat, nil));

                if let Some(cxt) = context.non_nil() {
                    let pf = {
                        let get_attr = |attrib: appkit::NSOpenGLPixelFormatAttribute| -> i32 {
                            let mut value = 0;

                            NSOpenGLPixelFormat::getValues_forAttribute_forVirtualScreen_(
                                *pixelformat,
                                &mut value,
                                attrib,
                                NSOpenGLContext::currentVirtualScreen(*cxt));

                            value
                        };

                        PixelFormat {
                            hardware_accelerated: get_attr(appkit::NSOpenGLPFAAccelerated) != 0,
                            color_bits: (get_attr(appkit::NSOpenGLPFAColorSize) - get_attr(appkit::NSOpenGLPFAAlphaSize)) as u8,
                            alpha_bits: get_attr(appkit::NSOpenGLPFAAlphaSize) as u8,
                            depth_bits: get_attr(appkit::NSOpenGLPFADepthSize) as u8,
                            stencil_bits: get_attr(appkit::NSOpenGLPFAStencilSize) as u8,
                            stereoscopy: get_attr(appkit::NSOpenGLPFAStereo) != 0,
                            double_buffer: get_attr(appkit::NSOpenGLPFADoubleBuffer) != 0,
                            multisampling: if get_attr(appkit::NSOpenGLPFAMultisample) > 0 {
                                Some(get_attr(appkit::NSOpenGLPFASamples) as u16)
                            } else {
                                None
                            },
                            srgb: true,
                        }
                    };

                    cxt.setView_(view);
                    let value = if opengl.vsync { 1 } else { 0 };
                    cxt.setValues_forParameter_(&value, appkit::NSOpenGLContextParameter::NSOpenGLCPSwapInterval);

                    if transparent {
                        let mut opacity = 0;
                        CGLSetParameter(cxt.CGLContextObj() as *mut _, kCGLCPSurfaceOpacity, &mut opacity);
                    }

                    CGLEnable(cxt.CGLContextObj() as *mut _, kCGLCECrashOnRemovedFunctions);

                    Ok(Context { gl: cxt, pixel_format: pf })
                } else {
                    Err(CreationError::NotSupported)
                }
            } else {
                Err(CreationError::NoAvailablePixelFormat)
            }
        }
    }
}

impl GlContext for Window {
    #[inline]
    unsafe fn make_current(&self) -> Result<(), ContextError> {
        let _: () = msg_send![*self.context.gl, update];
        self.context.gl.makeCurrentContext();
        Ok(())
    }

    #[inline]
    fn is_current(&self) -> bool {
        unsafe {
            let current = NSOpenGLContext::currentContext(nil);
            if current != nil {
                let is_equal: BOOL = msg_send![current, isEqual:*self.context.gl];
                is_equal != NO
            } else {
                false
            }
        }
    }

    fn get_proc_address(&self, addr: &str) -> *const () {
        let symbol_name: CFString = FromStr::from_str(addr).unwrap();
        let framework_name: CFString = FromStr::from_str("com.apple.opengl").unwrap();
        let framework =
            unsafe { CFBundleGetBundleWithIdentifier(framework_name.as_concrete_TypeRef()) };
        let symbol = unsafe {
            CFBundleGetFunctionPointerForName(framework, symbol_name.as_concrete_TypeRef())
        };
        symbol as *const _
    }

    #[inline]
    fn swap_buffers(&self) -> Result<(), ContextError> {
        unsafe {
            let pool = NSAutoreleasePool::new(nil);
            self.context.gl.flushBuffer();
            let _: () = msg_send![pool, release];
        }
        Ok(())
    }

    #[inline]
    fn get_api(&self) -> ::Api {
        ::Api::OpenGl
    }

    #[inline]
    fn get_pixel_format(&self) -> PixelFormat {
        self.context.pixel_format.clone()
    }
}

struct IdRef(id);

impl IdRef {
    fn new(i: id) -> IdRef {
        IdRef(i)
    }

    #[allow(dead_code)]
    fn retain(i: id) -> IdRef {
        if i != nil {
            let _: id = unsafe { msg_send![i, retain] };
        }
        IdRef(i)
    }

    fn non_nil(self) -> Option<IdRef> {
        if self.0 == nil { None } else { Some(self) }
    }
}

impl Drop for IdRef {
    fn drop(&mut self) {
        if self.0 != nil {
            let _: () = unsafe { msg_send![self.0, release] };
        }
    }
}

impl Deref for IdRef {
    type Target = id;
    fn deref<'a>(&'a self) -> &'a id {
        &self.0
    }
}

impl Clone for IdRef {
    fn clone(&self) -> IdRef {
        if self.0 != nil {
            let _: id = unsafe { msg_send![self.0, retain] };
        }
        IdRef(self.0)
    }
}
<|endoftext|>