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

<%namespace name="helpers" file="/helpers.mako.rs" />

<% data.new_style_struct("InheritedBox", inherited=True, gecko_name="Visibility") %>

// TODO: collapse. Well, do tables first.
${helpers.single_keyword("visibility",
                         "visible hidden",
                         extra_gecko_values="collapse",
                         gecko_ffi_name="mVisible",
                         animation_value_type="ComputedValue",
                         spec="https://drafts.csswg.org/css-box/#propdef-visibility")}

// CSS Writing Modes Level 3
// https://drafts.csswg.org/css-writing-modes-3
${helpers.single_keyword("writing-mode",
                         "horizontal-tb vertical-rl vertical-lr",
                         extra_gecko_values="sideways-rl sideways-lr",
                         extra_gecko_aliases="lr=horizontal-tb lr-tb=horizontal-tb \
                                              rl=horizontal-tb rl-tb=horizontal-tb \
                                              tb=vertical-rl   tb-rl=vertical-rl",
                         experimental=True,
                         animation_value_type="discrete",
                         spec="https://drafts.csswg.org/css-writing-modes/#propdef-writing-mode")}

${helpers.single_keyword("direction", "ltr rtl", animation_value_type="discrete",
                         spec="https://drafts.csswg.org/css-writing-modes/#propdef-direction",
                         needs_conversion=True)}

${helpers.single_keyword("text-orientation",
                         "mixed upright sideways",
                         extra_gecko_aliases="sideways-right=sideways",
                         products="gecko",
                         animation_value_type="discrete",
                         spec="https://drafts.csswg.org/css-writing-modes/#propdef-text-orientation")}

// CSS Color Module Level 4
// https://drafts.csswg.org/css-color/
${helpers.single_keyword("color-adjust",
                         "economy exact", products="gecko",
                         animation_value_type="discrete",
                         spec="https://drafts.csswg.org/css-color/#propdef-color-adjust")}

<% image_rendering_custom_consts = { "crisp-edges": "CRISPEDGES",
                                     "-moz-crisp-edges": "CRISPEDGES" } %>
// According to to CSS-IMAGES-3, `optimizespeed` and `optimizequality` are synonyms for `auto`
// And, firefox doesn't support `pixelated` yet (https://bugzilla.mozilla.org/show_bug.cgi?id=856337)
${helpers.single_keyword("image-rendering",
                         "auto",
                         extra_gecko_values="optimizespeed optimizequality -moz-crisp-edges",
                         extra_servo_values="pixelated crisp-edges",
                         custom_consts=image_rendering_custom_consts,
                         animation_value_type="discrete",
                         spec="https://drafts.csswg.org/css-images/#propdef-image-rendering")}

// Image Orientation
<%helpers:longhand name="image-orientation"
                   products="gecko"
                   animation_value_type="none"
    spec="https://drafts.csswg.org/css-images/#propdef-image-orientation, \
      /// additional values in https://developer.mozilla.org/en-US/docs/Web/CSS/image-orientation">
    use std::fmt;
    use style_traits::ToCss;
    use values::specified::Angle;

    no_viewport_percentage!(SpecifiedValue);

    use std::f64::consts::PI;
    const TWO_PI: f64 = 2.0 * PI;

    #[derive(Clone, PartialEq, Copy, Debug)]
    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
    pub struct SpecifiedValue {
        pub angle: Option<Angle>,
        pub flipped: bool
    }

    impl ToCss for SpecifiedValue {
        fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
            if let Some(angle) = self.angle {
                angle.to_css(dest)?;
                if self.flipped {
                    dest.write_str(" flip")
                } else {
                    Ok(())
                }
            } else {
                if self.flipped {
                    dest.write_str("flip")
                } else {
                    dest.write_str("from-image")
                }
            }
        }
    }

    pub mod computed_value {
        use std::fmt;
        use style_traits::ToCss;
        use values::specified::Angle;

        #[derive(Copy, Clone, Debug, Eq, PartialEq)]
        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
        pub enum Orientation {
            Angle0 = 0,
            Angle90,
            Angle180,
            Angle270,
        }

        impl Orientation {
            pub fn angle(&self) -> Angle {
                match *self {
                    Orientation::Angle0 => Angle::from_degrees(0.0, false),
                    Orientation::Angle90 => Angle::from_degrees(90.0, false),
                    Orientation::Angle180 => Angle::from_degrees(180.0, false),
                    Orientation::Angle270 => Angle::from_degrees(270.0, false),
                }
            }
        }

        impl ToCss for Orientation {
            fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
                // Should agree with Angle::to_css.
                match *self {
                    Orientation::Angle0 => dest.write_str("0deg"),
                    Orientation::Angle90 => dest.write_str("90deg"),
                    Orientation::Angle180 => dest.write_str("180deg"),
                    Orientation::Angle270 => dest.write_str("270deg"),
                }
            }
        }

        #[derive(Clone, PartialEq, Copy, Debug)]
        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
        pub enum T {
            FromImage,
            AngleWithFlipped(Orientation, bool),
        }
    }

    use self::computed_value::Orientation;

    #[inline]
    pub fn get_initial_value() -> computed_value::T {
        computed_value::T::AngleWithFlipped(Orientation::Angle0, false)
    }

    // According to CSS Content Module Level 3:
    // The computed value of the property is calculated by rounding the specified angle
    // to the nearest quarter-turn, rounding away from 0, then moduloing the value by 1 turn.
    // This mirrors the Gecko implementation in
    // nsStyleImageOrientation::CreateAsAngleAndFlip.
    #[inline]
    fn orientation_of_angle(angle: &computed::Angle) -> Orientation {
        // Note that `angle` can be negative.
        let mut rounded_angle = angle.radians64() % TWO_PI;
        if rounded_angle < 0.0 {
            // This computation introduces rounding error. Gecko previously
            // didn't handle the negative case correctly; by branching we can
            // match Gecko's behavior when it was correct.
            rounded_angle = rounded_angle + TWO_PI;
        }
        if      rounded_angle < 0.25 * PI { Orientation::Angle0   }
        else if rounded_angle < 0.75 * PI { Orientation::Angle90  }
        else if rounded_angle < 1.25 * PI { Orientation::Angle180 }
        else if rounded_angle < 1.75 * PI { Orientation::Angle270 }
        else                              { Orientation::Angle0   }
    }

    impl ToComputedValue for SpecifiedValue {
        type ComputedValue = computed_value::T;

        #[inline]
        fn to_computed_value(&self, context: &Context) -> computed_value::T {
            if let Some(ref angle) = self.angle {
                let angle = angle.to_computed_value(context);
                let orientation = orientation_of_angle(&angle);
                computed_value::T::AngleWithFlipped(orientation, self.flipped)
            } else {
                if self.flipped {
                    computed_value::T::AngleWithFlipped(Orientation::Angle0, true)
                } else {
                    computed_value::T::FromImage
                }
            }
        }

        #[inline]
        fn from_computed_value(computed: &computed_value::T) -> Self {
            match *computed {
                computed_value::T::FromImage => SpecifiedValue { angle: None, flipped: false },
                computed_value::T::AngleWithFlipped(ref orientation, flipped) => {
                    SpecifiedValue {
                        angle: Some(orientation.angle()),
                        flipped: flipped,
                    }
                }
            }
        }
    }

    impl ToCss for computed_value::T {
        fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
            match *self {
                computed_value::T::FromImage => dest.write_str("from-image"),
                computed_value::T::AngleWithFlipped(angle, flipped) => {
                    angle.to_css(dest)?;
                    if flipped {
                        dest.write_str(" flip")?;
                    }
                    Ok(())
                },
            }
        }
    }

    // from-image | <angle> | [<angle>? flip]
    pub fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
                         -> Result<SpecifiedValue, ParseError<'i>> {
        if input.try(|input| input.expect_ident_matching("from-image")).is_ok() {
            // Handle from-image
            Ok(SpecifiedValue { angle: None, flipped: false })
        } else if input.try(|input| input.expect_ident_matching("flip")).is_ok() {
            // Handle flip
            Ok(SpecifiedValue { angle: Some(Angle::zero()), flipped: true })
        } else {
            // Handle <angle> | <angle> flip
            let angle = input.try(|input| Angle::parse(context, input)).ok();
            if angle.is_none() {
                return Err(StyleParseError::UnspecifiedError.into());
            }

            let flipped = input.try(|input| input.expect_ident_matching("flip")).is_ok();
            Ok(SpecifiedValue { angle: angle, flipped: flipped })
        }
    }
</%helpers:longhand>

// Used in the bottom-up flow construction traversal to avoid constructing flows for
// descendants of nodes with `display: none`.
<%helpers:longhand name="-servo-under-display-none"
                   derived_from="display"
                   products="servo"
                   animation_value_type="none"
                   spec="Nonstandard (internal layout use only)">
    use std::fmt;
    use style_traits::ToCss;
    use values::computed::ComputedValueAsSpecified;

    no_viewport_percentage!(SpecifiedValue);

    #[derive(Copy, Clone, Debug, Eq, PartialEq)]
    #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
    pub struct SpecifiedValue(pub bool);

    pub mod computed_value {
        pub type T = super::SpecifiedValue;
    }
    impl ComputedValueAsSpecified for SpecifiedValue {}

    pub fn get_initial_value() -> computed_value::T {
        SpecifiedValue(false)
    }

    impl ToCss for SpecifiedValue {
        fn to_css<W>(&self, _: &mut W) -> fmt::Result where W: fmt::Write {
            Ok(()) // Internal property
        }
    }

    #[inline]
    pub fn derive_from_display(context: &mut Context) {
        use super::display::computed_value::T as Display;

        if context.style().get_box().clone_display() == Display::none {
            context.mutate_style().mutate_inheritedbox()
                                  .set__servo_under_display_none(SpecifiedValue(true));
        }
    }
</%helpers:longhand>
<commit_msg>rustify if statements style<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

<%namespace name="helpers" file="/helpers.mako.rs" />

<% data.new_style_struct("InheritedBox", inherited=True, gecko_name="Visibility") %>

// TODO: collapse. Well, do tables first.
${helpers.single_keyword("visibility",
                         "visible hidden",
                         extra_gecko_values="collapse",
                         gecko_ffi_name="mVisible",
                         animation_value_type="ComputedValue",
                         spec="https://drafts.csswg.org/css-box/#propdef-visibility")}

// CSS Writing Modes Level 3
// https://drafts.csswg.org/css-writing-modes-3
${helpers.single_keyword("writing-mode",
                         "horizontal-tb vertical-rl vertical-lr",
                         extra_gecko_values="sideways-rl sideways-lr",
                         extra_gecko_aliases="lr=horizontal-tb lr-tb=horizontal-tb \
                                              rl=horizontal-tb rl-tb=horizontal-tb \
                                              tb=vertical-rl   tb-rl=vertical-rl",
                         experimental=True,
                         animation_value_type="discrete",
                         spec="https://drafts.csswg.org/css-writing-modes/#propdef-writing-mode")}

${helpers.single_keyword("direction", "ltr rtl", animation_value_type="discrete",
                         spec="https://drafts.csswg.org/css-writing-modes/#propdef-direction",
                         needs_conversion=True)}

${helpers.single_keyword("text-orientation",
                         "mixed upright sideways",
                         extra_gecko_aliases="sideways-right=sideways",
                         products="gecko",
                         animation_value_type="discrete",
                         spec="https://drafts.csswg.org/css-writing-modes/#propdef-text-orientation")}

// CSS Color Module Level 4
// https://drafts.csswg.org/css-color/
${helpers.single_keyword("color-adjust",
                         "economy exact", products="gecko",
                         animation_value_type="discrete",
                         spec="https://drafts.csswg.org/css-color/#propdef-color-adjust")}

<% image_rendering_custom_consts = { "crisp-edges": "CRISPEDGES",
                                     "-moz-crisp-edges": "CRISPEDGES" } %>
// According to to CSS-IMAGES-3, `optimizespeed` and `optimizequality` are synonyms for `auto`
// And, firefox doesn't support `pixelated` yet (https://bugzilla.mozilla.org/show_bug.cgi?id=856337)
${helpers.single_keyword("image-rendering",
                         "auto",
                         extra_gecko_values="optimizespeed optimizequality -moz-crisp-edges",
                         extra_servo_values="pixelated crisp-edges",
                         custom_consts=image_rendering_custom_consts,
                         animation_value_type="discrete",
                         spec="https://drafts.csswg.org/css-images/#propdef-image-rendering")}

// Image Orientation
<%helpers:longhand name="image-orientation"
                   products="gecko"
                   animation_value_type="none"
    spec="https://drafts.csswg.org/css-images/#propdef-image-orientation, \
      /// additional values in https://developer.mozilla.org/en-US/docs/Web/CSS/image-orientation">
    use std::fmt;
    use style_traits::ToCss;
    use values::specified::Angle;

    no_viewport_percentage!(SpecifiedValue);

    use std::f64::consts::PI;
    const TWO_PI: f64 = 2.0 * PI;

    #[derive(Clone, PartialEq, Copy, Debug)]
    #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
    pub struct SpecifiedValue {
        pub angle: Option<Angle>,
        pub flipped: bool
    }

    impl ToCss for SpecifiedValue {
        fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
            if let Some(angle) = self.angle {
                angle.to_css(dest)?;
                if self.flipped {
                    dest.write_str(" flip")
                } else {
                    Ok(())
                }
            } else {
                if self.flipped {
                    dest.write_str("flip")
                } else {
                    dest.write_str("from-image")
                }
            }
        }
    }

    pub mod computed_value {
        use std::fmt;
        use style_traits::ToCss;
        use values::specified::Angle;

        #[derive(Copy, Clone, Debug, Eq, PartialEq)]
        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
        pub enum Orientation {
            Angle0 = 0,
            Angle90,
            Angle180,
            Angle270,
        }

        impl Orientation {
            pub fn angle(&self) -> Angle {
                match *self {
                    Orientation::Angle0 => Angle::from_degrees(0.0, false),
                    Orientation::Angle90 => Angle::from_degrees(90.0, false),
                    Orientation::Angle180 => Angle::from_degrees(180.0, false),
                    Orientation::Angle270 => Angle::from_degrees(270.0, false),
                }
            }
        }

        impl ToCss for Orientation {
            fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
                // Should agree with Angle::to_css.
                match *self {
                    Orientation::Angle0 => dest.write_str("0deg"),
                    Orientation::Angle90 => dest.write_str("90deg"),
                    Orientation::Angle180 => dest.write_str("180deg"),
                    Orientation::Angle270 => dest.write_str("270deg"),
                }
            }
        }

        #[derive(Clone, PartialEq, Copy, Debug)]
        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
        pub enum T {
            FromImage,
            AngleWithFlipped(Orientation, bool),
        }
    }

    use self::computed_value::Orientation;

    #[inline]
    pub fn get_initial_value() -> computed_value::T {
        computed_value::T::AngleWithFlipped(Orientation::Angle0, false)
    }

    // According to CSS Content Module Level 3:
    // The computed value of the property is calculated by rounding the specified angle
    // to the nearest quarter-turn, rounding away from 0, then moduloing the value by 1 turn.
    // This mirrors the Gecko implementation in
    // nsStyleImageOrientation::CreateAsAngleAndFlip.
    #[inline]
    fn orientation_of_angle(angle: &computed::Angle) -> Orientation {
        // Note that `angle` can be negative.
        let mut rounded_angle = angle.radians64() % TWO_PI;
        if rounded_angle < 0.0 {
            // This computation introduces rounding error. Gecko previously
            // didn't handle the negative case correctly; by branching we can
            // match Gecko's behavior when it was correct.
            rounded_angle = rounded_angle + TWO_PI;
        }
        if rounded_angle < 0.25 * PI {
            return Orientation::Angle0
        }
        if rounded_angle < 0.75 * PI {
            return Orientation::Angle90
        }
        if rounded_angle < 1.25 * PI {
            return Orientation::Angle180
        }
        if rounded_angle < 1.75 * PI {
            return Orientation::Angle270
        }
        Orientation::Angle0
    }

    impl ToComputedValue for SpecifiedValue {
        type ComputedValue = computed_value::T;

        #[inline]
        fn to_computed_value(&self, context: &Context) -> computed_value::T {
            if let Some(ref angle) = self.angle {
                let angle = angle.to_computed_value(context);
                let orientation = orientation_of_angle(&angle);
                computed_value::T::AngleWithFlipped(orientation, self.flipped)
            } else {
                if self.flipped {
                    computed_value::T::AngleWithFlipped(Orientation::Angle0, true)
                } else {
                    computed_value::T::FromImage
                }
            }
        }

        #[inline]
        fn from_computed_value(computed: &computed_value::T) -> Self {
            match *computed {
                computed_value::T::FromImage => SpecifiedValue { angle: None, flipped: false },
                computed_value::T::AngleWithFlipped(ref orientation, flipped) => {
                    SpecifiedValue {
                        angle: Some(orientation.angle()),
                        flipped: flipped,
                    }
                }
            }
        }
    }

    impl ToCss for computed_value::T {
        fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
            match *self {
                computed_value::T::FromImage => dest.write_str("from-image"),
                computed_value::T::AngleWithFlipped(angle, flipped) => {
                    angle.to_css(dest)?;
                    if flipped {
                        dest.write_str(" flip")?;
                    }
                    Ok(())
                },
            }
        }
    }

    // from-image | <angle> | [<angle>? flip]
    pub fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
                         -> Result<SpecifiedValue, ParseError<'i>> {
        if input.try(|input| input.expect_ident_matching("from-image")).is_ok() {
            // Handle from-image
            Ok(SpecifiedValue { angle: None, flipped: false })
        } else if input.try(|input| input.expect_ident_matching("flip")).is_ok() {
            // Handle flip
            Ok(SpecifiedValue { angle: Some(Angle::zero()), flipped: true })
        } else {
            // Handle <angle> | <angle> flip
            let angle = input.try(|input| Angle::parse(context, input)).ok();
            if angle.is_none() {
                return Err(StyleParseError::UnspecifiedError.into());
            }

            let flipped = input.try(|input| input.expect_ident_matching("flip")).is_ok();
            Ok(SpecifiedValue { angle: angle, flipped: flipped })
        }
    }
</%helpers:longhand>

// Used in the bottom-up flow construction traversal to avoid constructing flows for
// descendants of nodes with `display: none`.
<%helpers:longhand name="-servo-under-display-none"
                   derived_from="display"
                   products="servo"
                   animation_value_type="none"
                   spec="Nonstandard (internal layout use only)">
    use std::fmt;
    use style_traits::ToCss;
    use values::computed::ComputedValueAsSpecified;

    no_viewport_percentage!(SpecifiedValue);

    #[derive(Copy, Clone, Debug, Eq, PartialEq)]
    #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
    pub struct SpecifiedValue(pub bool);

    pub mod computed_value {
        pub type T = super::SpecifiedValue;
    }
    impl ComputedValueAsSpecified for SpecifiedValue {}

    pub fn get_initial_value() -> computed_value::T {
        SpecifiedValue(false)
    }

    impl ToCss for SpecifiedValue {
        fn to_css<W>(&self, _: &mut W) -> fmt::Result where W: fmt::Write {
            Ok(()) // Internal property
        }
    }

    #[inline]
    pub fn derive_from_display(context: &mut Context) {
        use super::display::computed_value::T as Display;

        if context.style().get_box().clone_display() == Display::none {
            context.mutate_style().mutate_inheritedbox()
                                  .set__servo_under_display_none(SpecifiedValue(true));
        }
    }
</%helpers:longhand>
<|endoftext|>


<commit_before>use super::*;

impl Editor {
    /// Go to next char
    pub fn next(&mut self) {
        if self.x() == self.text[self.y()].len() {
            if self.y() >= self.text.len() {
                self.text.push_back(VecDeque::new())
            }
            if self.y() < self.text.len() - 1 {
                self.cursor_mut().x = 0;
                self.cursor_mut().y += 1;
            }

        } else {
            self.cursor_mut().x += 1;
        }
    }

    /// Go to previous char
    pub fn previous(&mut self) {
        if self.x() == 0 {
            if self.y() > 0 {
                self.cursor_mut().y -= 1;
                self.cursor_mut().x = self.text[self.y() - 1].len();
            }
        } else {
            self.cursor_mut().y -= 1;
        }

    }

    /// Go right
    pub fn right(&mut self, n: usize) {
        let x = self.x() + n;
        let y = self.y();

        let text = self.text.clone();
        let curs = self.cursor_mut();

        curs.x += n;

        if x > text[y].len() {
            curs.x = text[y].len();
        }
    }
    /// Go left
    pub fn left(&mut self, n: usize) {
        let x = self.x();
        let y = self.y();

        let text = self.text.clone();
        let curs = self.cursor_mut();

        if n <= x {
            curs.x -= n;
        } else {
            curs.x = 0;
        }

    }
    /// Go up
    pub fn up(&mut self, n: usize) {
        let y = self.y();
        let curs = self.cursor_mut();
        if n <= y {
            curs.y -= n;
        } else {
            curs.y = 0;
        }
    }
    /// Go down
    pub fn down(&mut self, n: usize) {
        let x = self.x();
        let y = self.y() + n;

        let text = self.text.clone();
        let curs = self.cursor_mut();

        curs.y += n;

        if y >= text.len() {
            curs.y = text.len() - 1;
        }
    }
}
<commit_msg>Fix movement<commit_after>use super::*;

impl Editor {
    /// Go to next char
    pub fn next(&mut self) {
        if self.x() == self.text[self.y()].len() {
            if self.y() >= self.text.len() {
                self.text.push_back(VecDeque::new())
            }
            if self.y() < self.text.len() - 1 {
                self.cursor_mut().x = 0;
                self.cursor_mut().y += 1;
            }

        } else {
            self.cursor_mut().x += 1;
        }
    }

    /// Go to previous char
    pub fn previous(&mut self) {
        if self.x() == 0 {
            if self.y() > 0 {
                self.cursor_mut().y -= 1;
                self.cursor_mut().x = self.text[self.y() - 1].len();
            }
        } else {
            self.cursor_mut().y -= 1;
        }

    }

    /// Go right
    pub fn right(&mut self, n: usize) {
        let x = self.x() + n;
        let y = self.y();

        let text = self.text.clone();
        let curs = self.cursor_mut();

        curs.x += n;

        if x > text[y].len() {
            curs.x = text[y].len();
        }
    }
    /// Go left
    pub fn left(&mut self, n: usize) {
        let x = self.x();
        let y = self.y();

        let text = self.text.clone();
        let curs = self.cursor_mut();

        if n <= x {
            curs.x = x - n;
        } else {
            curs.x = 0;
        }

    }
    /// Go up
    pub fn up(&mut self, n: usize) {
        let y = self.y();
        let curs = self.cursor_mut();
        if n <= y {
            curs.y -= n;
        } else {
            curs.y = 0;
        }
    }
    /// Go down
    pub fn down(&mut self, n: usize) {
        let x = self.x();
        let y = self.y() + n;

        let text = self.text.clone();
        let curs = self.cursor_mut();

        curs.y += n;

        if y >= text.len() {
            curs.y = text.len() - 1;
        }
    }
}
<|endoftext|>


<commit_before>use Module;
use socket::Socket;

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum TriggerSource {
    EXT_PE,
    EXT_NE,
    INT,
    GATED,
}

impl ::std::convert::Into<String> for TriggerSource {
    fn into(self) -> String {
        let s = match self {
            TriggerSource::EXT_PE => "EXT_PE",
            TriggerSource::EXT_NE => "EXT_NE",
            TriggerSource::INT => "INT",
            TriggerSource::GATED => "GATED",
        };

        String::from(s)
    }
}

impl ::std::str::FromStr for TriggerSource {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "EXT_PE" => Ok(TriggerSource::EXT_PE),
            "EXT_NE" => Ok(TriggerSource::EXT_NE),
            "INT" => Ok(TriggerSource::INT),
            "GATED" => Ok(TriggerSource::GATED),
            source => Err(format!("Unknow source '{}'", source)),
        }
    }
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Form {
    SINE,
    SQUARE,
    TRIANGLE,
    SAWU,
    SAWD,
    PWM,
    ARBITRARY,
}

impl ::std::convert::Into<String> for Form {
    fn into(self) -> String {
        let s = match self {
            Form::SINE => "SINE",
            Form::SQUARE => "SQUARE",
            Form::TRIANGLE => "TRIANGLE",
            Form::SAWU => "SAWU",
            Form::SAWD => "SAWD",
            Form::PWM => "PWM",
            Form::ARBITRARY => "ARBITRARY",
        };

        String::from(s)
    }
}

impl ::std::str::FromStr for Form {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "SINE" => Ok(Form::SINE),
            "SQUARE" => Ok(Form::SQUARE),
            "TRIANGLE" => Ok(Form::TRIANGLE),
            "SAWU" => Ok(Form::SAWU),
            "SAWD" => Ok(Form::SAWD),
            "PWM" => Ok(Form::PWM),
            "ARBITRARY" => Ok(Form::ARBITRARY),
            form => Err(format!("Unknow signal form '{}'", form)),
        }
    }
}

impl ::std::fmt::Display for Form {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        let display = match self {
            &Form::SINE => "Sine",
            &Form::SQUARE => "Square",
            &Form::TRIANGLE => "Triangle",
            &Form::SAWU => "SAWU",
            &Form::SAWD => "SAWD",
            &Form::PWM => "PWM",
            &Form::ARBITRARY => "Arbitrary",
        };

        write!(f, "{}", display)
    }
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Source {
    OUT1,
    OUT2,
}

impl ::std::convert::Into<String> for Source {
    fn into(self) -> String {
        let s = match self {
            Source::OUT1 => "SOUR1",
            Source::OUT2 => "SOUR2",
        };

        String::from(s)
    }
}

// @TODO impl std::slice::SliceIndex<generator::State> instead
impl ::std::convert::Into<usize> for Source {
    fn into(self) -> usize {
        match self {
            Source::OUT1 => 0,
            Source::OUT2 => 1,
        }
    }
}

impl ::std::fmt::Display for Source {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        let display = match self {
            &Source::OUT1 => "OUT 1",
            &Source::OUT2 => "OUT 2",
        };

        write!(f, "{}", display)
    }
}

#[derive(Clone)]
pub struct Generator {
    socket: ::std::cell::RefCell<Socket>,
}

impl ::Module for Generator {
    fn get_socket<'a>(&'a self) -> ::std::cell::RefMut<'a, ::socket::Socket> {
        self.socket.borrow_mut()
    }
}

impl Generator {
    pub fn new(socket: Socket) -> Self {
        Generator {
            socket: ::std::cell::RefCell::new(socket),
        }
    }

    /**
     * Enable fast analog outputs.
     */
    pub fn start(&self, source: Source) {
        self.set_state(&source, "ON");
    }

    /**
     * Disable fast analog outputs.
     */
    pub fn stop(&self, source: Source) {
        self.set_state(&source, "OFF");
    }

    fn set_state(&self, source: &Source, state: &str) {
        let output = match *source {
            Source::OUT1 => "OUTPUT1",
            Source::OUT2 => "OUTPUT2",
        };

        self.send(format!("{}:STATE {}", output, state));
    }

    pub fn is_started(&self, source: Source) -> Result<bool, <i8 as ::std::str::FromStr>::Err> {
        self.send(format!("{}:STATE?", Into::<String>::into(source)));

        match self.receive().parse::<u8>() {
            Ok(state) => Ok(state == 1),
            Err(err) => Err(err),
        }
    }

    /**
     * Set frequency of fast analog outputs.
     */
    pub fn set_frequency(&self, source: Source, frequency: u32) {
        self.send(format!("{}:FREQ:FIX {}", Into::<String>::into(source), frequency));
    }

    /**
     * Get frequency of fast analog outputs.
     */
    pub fn get_frequency(&self, source: Source) -> Result<u32, <f32 as ::std::str::FromStr>::Err> {
        self.send(format!("{}:FREQ:FIX?", Into::<String>::into(source)));

        let value: f32 =self.receive()
            .parse()?;

        Ok(value as u32)
    }

    /**
     * Set waveform of fast analog outputs.
     *
     * PWM doesn’t work https://github.com/RedPitaya/RedPitaya/issues/81
     */
    pub fn set_form(&self, source: Source, form: Form) {
        self.send(format!("{}:FUNC {}", Into::<String>::into(source), Into::<String>::into(form)));
    }

    pub fn get_form(&self, source: Source) -> Result<Form, String> {
        self.send(format!("{}:FUNC?", Into::<String>::into(source)));

        self.receive()
            .parse()
    }

    /**
     * Set amplitude voltage of fast analog outputs.
     *
     * Amplitude + offset value must be less than maximum output range ± 1V
     */
    pub fn set_amplitude(&self, source: Source, amplitude: f32) {
        self.send(format!("{}:VOLT {}", Into::<String>::into(source), amplitude));
    }

    /**
     * Get amplitude voltage of fast analog outputs.
     */
    pub fn get_amplitude(&self, source: Source) -> Result<f32, <f32 as ::std::str::FromStr>::Err> {
        self.send(format!("{}:VOLT?", Into::<String>::into(source)));

        self.receive()
            .parse()
    }

    /**
     * Set offset voltage of fast analog outputs.
     *
     * Amplitude + offset value must be less than maximum output range ± 1V
     */
    pub fn set_offset(&self, source: Source, offset: f32) {
        self.send(format!("{}:VOLT:OFFS {}", Into::<String>::into(source), offset));
    }

    /**
     * Get offset voltage of fast analog outputs.
     */
    pub fn get_offset(&self, source: Source) -> Result<f32, <f32 as ::std::str::FromStr>::Err> {
        self.send(format!("{}:VOLT:OFFS?", Into::<String>::into(source)));

        self.receive()
            .parse()
    }

    /**
     * Set phase of fast analog outputs.
     */
    pub fn set_phase(&self, source: Source, phase: i32) {
        self.send(format!("{}:PHAS {}", Into::<String>::into(source), phase));
    }

    /**
     * Get phase of fast analog outputs.
     */
    pub fn get_phase(&self, source: Source) -> Result<i32, <i32 as ::std::str::FromStr>::Err> {
        self.send(format!("{}:PHAS?", Into::<String>::into(source)));

        self.receive()
            .parse()
    }

    /**
     * Set duty cycle of PWM waveform.
     */
    pub fn set_duty_cycle(&self, source: Source, dcyc: f32) {
        self.send(format!("{}:DCYC {}", Into::<String>::into(source), dcyc));
    }

    /**
     * Get duty cycle of PWM waveform.
     */
    pub fn get_duty_cycle(&self, source: Source) -> Result<f32, <f32 as ::std::str::FromStr>::Err> {
        self.send(format!("{}:DCYC?", Into::<String>::into(source)));

        self.receive()
            .parse()
    }

    /**
     * Import data for arbitrary waveform generation.
     */
    pub fn set_arbitrary_waveform(&self, source: Source, data: Vec<f32>) {
        let mut data = data.iter()
            .fold(String::new(), |acc, e| {
                format!("{}{},", acc, e)
            });
        data.pop();

        self.send(format!("{}:TRAC:DATA:DATA {}", Into::<String>::into(source), data));
    }

    /**
     * Get data for arbitrary waveform generation.
     */
    pub fn get_arbitrary_waveform(&self, source: Source) -> Vec<f32> {
        self.send(format!("{}:TRAC:DATA:DATA?", Into::<String>::into(source)));

        let data = self.receive();
        data.split(",")
            .map(|x| x.parse().unwrap())
            .collect()
    }

    /**
     * Set trigger source for selected signal.
     */
    pub fn set_trigger_source(&self, source: Source, trigger: TriggerSource) {
        self.send(format!("{}:TRIG:SOUR {}", Into::<String>::into(source), Into::<String>::into(trigger)));
    }

    /**
     * Get trigger source for selected signal.
     */
    pub fn get_trigger_source(&self, source: Source) -> Result<TriggerSource, String> {
        self.send(format!("{}:TRIG:SOUR?", Into::<String>::into(source)));

        self.receive()
            .parse()
    }

    /**
     * Triggers selected source immediately.
     */
    pub fn trigger(&self, source: Source) {
        self.send(format!("{}:TRIG:IMM", Into::<String>::into(source)));
    }

    /**
     * Triggers both sources immediately.
     */
    pub fn trigger_all(&self) {
        self.send("TRIG:IMM");
    }

    /**
     * Reset generator to default settings.
     */
    pub fn reset(&self) {
        self.send("GEN:RST");
    }
}

#[cfg(test)]
mod test {
    macro_rules! generator_assert {
        ($f:ident, $e:expr) => {
            let (rx, generator) = create_generator();

            generator.$f();
            assert_eq!($e, rx.recv().unwrap());
        }
    }

    #[test]
    fn test_status() {
        let (rx, generator) = create_generator();

        generator.start(::generator::Source::OUT2);
        assert_eq!("OUTPUT2:STATE ON\r\n", rx.recv().unwrap());

        assert_eq!(generator.is_started(::generator::Source::OUT2), Ok(true));

        generator.stop(::generator::Source::OUT2);
        assert_eq!("OUTPUT2:STATE OFF\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_frequency() {
        let (rx, generator) = create_generator();

        generator.set_frequency(::generator::Source::OUT1, 1_000);
        assert_eq!("SOUR1:FREQ:FIX 1000\r\n", rx.recv().unwrap());

        assert_eq!(generator.get_frequency(::generator::Source::OUT1), Ok(1_000));

        assert_eq!(generator.get_frequency(::generator::Source::OUT1), Ok(1_000));
    }

    #[test]
    fn test_form() {
        let (rx, generator) = create_generator();

        generator.set_form(::generator::Source::OUT1, ::generator::Form::SINE);
        assert_eq!("SOUR1:FUNC SINE\r\n", rx.recv().unwrap());

        assert_eq!(generator.get_form(::generator::Source::OUT1), Ok(::generator::Form::SINE));
    }

    #[test]
    fn test_amplitude() {
        let (rx, generator) = create_generator();

        generator.set_amplitude(::generator::Source::OUT1, -1.1);
        assert_eq!("SOUR1:VOLT -1.1\r\n", rx.recv().unwrap());

        assert_eq!(generator.get_amplitude(::generator::Source::OUT1), Ok(-1.1));
    }

    #[test]
    fn test_offset() {
        let (rx, generator) = create_generator();

        generator.set_offset(::generator::Source::OUT1, -1.2);
        assert_eq!("SOUR1:VOLT:OFFS -1.2\r\n", rx.recv().unwrap());

        assert_eq!(generator.get_offset(::generator::Source::OUT1), Ok(1.2));
    }

    #[test]
    fn test_phase() {
        let (rx, generator) = create_generator();

        generator.set_phase(::generator::Source::OUT1, -180);
        assert_eq!("SOUR1:PHAS -180\r\n", rx.recv().unwrap());

        assert_eq!(generator.get_phase(::generator::Source::OUT1), Ok(-180));
    }

    #[test]
    fn test_duty_cycle() {
        let (rx, generator) = create_generator();

        generator.set_duty_cycle(::generator::Source::OUT1, 1.0);
        assert_eq!("SOUR1:DCYC 1\r\n", rx.recv().unwrap());

        assert_eq!(generator.get_duty_cycle(::generator::Source::OUT1), Ok(1.0));
    }

    #[test]
    fn test_arbitrary_waveform() {
        let (rx, generator) = create_generator();

        generator.set_arbitrary_waveform(::generator::Source::OUT1, vec![1.0, 0.5, 0.2]);
        assert_eq!("SOUR1:TRAC:DATA:DATA 1,0.5,0.2\r\n", rx.recv().unwrap());

        #[cfg(features = "mock")]
        assert_eq!(generator.get_arbitrary_waveform(::generator::Source::OUT1), vec![1.0, 0.5, 0.2]);

        #[cfg(not(features = "mock"))]
        assert!(generator.get_arbitrary_waveform(::generator::Source::OUT1).len() > 0);
    }

    #[test]
    fn test_trigger_source() {
        let (rx, generator) = create_generator();

        generator.set_trigger_source(::generator::Source::OUT1, ::generator::TriggerSource::EXT_NE);
        assert_eq!("SOUR1:TRIG:SOUR EXT_NE\r\n", rx.recv().unwrap());

        assert_eq!(generator.get_trigger_source(::generator::Source::OUT1), Ok(::generator::TriggerSource::EXT_NE));
    }

    #[test]
    fn test_trigger() {
        let (rx, generator) = create_generator();

        generator.trigger(::generator::Source::OUT1);
        assert_eq!("SOUR1:TRIG:IMM\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_trigger_all() {
        generator_assert!(trigger_all, "TRIG:IMM\r\n");
    }

    #[test]
    fn test_reset() {
        generator_assert!(reset, "GEN:RST\r\n");
    }

    fn create_generator() -> (::std::sync::mpsc::Receiver<String>, ::generator::Generator) {
        let (addr, rx) = ::test::launch_server();
        let socket = ::socket::Socket::new(addr);

        (rx, ::generator::Generator::new(socket))
    }
}
<commit_msg>Fix waveform data parsing<commit_after>use Module;
use socket::Socket;

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum TriggerSource {
    EXT_PE,
    EXT_NE,
    INT,
    GATED,
}

impl ::std::convert::Into<String> for TriggerSource {
    fn into(self) -> String {
        let s = match self {
            TriggerSource::EXT_PE => "EXT_PE",
            TriggerSource::EXT_NE => "EXT_NE",
            TriggerSource::INT => "INT",
            TriggerSource::GATED => "GATED",
        };

        String::from(s)
    }
}

impl ::std::str::FromStr for TriggerSource {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "EXT_PE" => Ok(TriggerSource::EXT_PE),
            "EXT_NE" => Ok(TriggerSource::EXT_NE),
            "INT" => Ok(TriggerSource::INT),
            "GATED" => Ok(TriggerSource::GATED),
            source => Err(format!("Unknow source '{}'", source)),
        }
    }
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Form {
    SINE,
    SQUARE,
    TRIANGLE,
    SAWU,
    SAWD,
    PWM,
    ARBITRARY,
}

impl ::std::convert::Into<String> for Form {
    fn into(self) -> String {
        let s = match self {
            Form::SINE => "SINE",
            Form::SQUARE => "SQUARE",
            Form::TRIANGLE => "TRIANGLE",
            Form::SAWU => "SAWU",
            Form::SAWD => "SAWD",
            Form::PWM => "PWM",
            Form::ARBITRARY => "ARBITRARY",
        };

        String::from(s)
    }
}

impl ::std::str::FromStr for Form {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "SINE" => Ok(Form::SINE),
            "SQUARE" => Ok(Form::SQUARE),
            "TRIANGLE" => Ok(Form::TRIANGLE),
            "SAWU" => Ok(Form::SAWU),
            "SAWD" => Ok(Form::SAWD),
            "PWM" => Ok(Form::PWM),
            "ARBITRARY" => Ok(Form::ARBITRARY),
            form => Err(format!("Unknow signal form '{}'", form)),
        }
    }
}

impl ::std::fmt::Display for Form {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        let display = match self {
            &Form::SINE => "Sine",
            &Form::SQUARE => "Square",
            &Form::TRIANGLE => "Triangle",
            &Form::SAWU => "SAWU",
            &Form::SAWD => "SAWD",
            &Form::PWM => "PWM",
            &Form::ARBITRARY => "Arbitrary",
        };

        write!(f, "{}", display)
    }
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Source {
    OUT1,
    OUT2,
}

impl ::std::convert::Into<String> for Source {
    fn into(self) -> String {
        let s = match self {
            Source::OUT1 => "SOUR1",
            Source::OUT2 => "SOUR2",
        };

        String::from(s)
    }
}

// @TODO impl std::slice::SliceIndex<generator::State> instead
impl ::std::convert::Into<usize> for Source {
    fn into(self) -> usize {
        match self {
            Source::OUT1 => 0,
            Source::OUT2 => 1,
        }
    }
}

impl ::std::fmt::Display for Source {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        let display = match self {
            &Source::OUT1 => "OUT 1",
            &Source::OUT2 => "OUT 2",
        };

        write!(f, "{}", display)
    }
}

#[derive(Clone)]
pub struct Generator {
    socket: ::std::cell::RefCell<Socket>,
}

impl ::Module for Generator {
    fn get_socket<'a>(&'a self) -> ::std::cell::RefMut<'a, ::socket::Socket> {
        self.socket.borrow_mut()
    }
}

impl Generator {
    pub fn new(socket: Socket) -> Self {
        Generator {
            socket: ::std::cell::RefCell::new(socket),
        }
    }

    /**
     * Enable fast analog outputs.
     */
    pub fn start(&self, source: Source) {
        self.set_state(&source, "ON");
    }

    /**
     * Disable fast analog outputs.
     */
    pub fn stop(&self, source: Source) {
        self.set_state(&source, "OFF");
    }

    fn set_state(&self, source: &Source, state: &str) {
        let output = match *source {
            Source::OUT1 => "OUTPUT1",
            Source::OUT2 => "OUTPUT2",
        };

        self.send(format!("{}:STATE {}", output, state));
    }

    pub fn is_started(&self, source: Source) -> Result<bool, <i8 as ::std::str::FromStr>::Err> {
        self.send(format!("{}:STATE?", Into::<String>::into(source)));

        match self.receive().parse::<u8>() {
            Ok(state) => Ok(state == 1),
            Err(err) => Err(err),
        }
    }

    /**
     * Set frequency of fast analog outputs.
     */
    pub fn set_frequency(&self, source: Source, frequency: u32) {
        self.send(format!("{}:FREQ:FIX {}", Into::<String>::into(source), frequency));
    }

    /**
     * Get frequency of fast analog outputs.
     */
    pub fn get_frequency(&self, source: Source) -> Result<u32, <f32 as ::std::str::FromStr>::Err> {
        self.send(format!("{}:FREQ:FIX?", Into::<String>::into(source)));

        let value: f32 =self.receive()
            .parse()?;

        Ok(value as u32)
    }

    /**
     * Set waveform of fast analog outputs.
     *
     * PWM doesn’t work https://github.com/RedPitaya/RedPitaya/issues/81
     */
    pub fn set_form(&self, source: Source, form: Form) {
        self.send(format!("{}:FUNC {}", Into::<String>::into(source), Into::<String>::into(form)));
    }

    pub fn get_form(&self, source: Source) -> Result<Form, String> {
        self.send(format!("{}:FUNC?", Into::<String>::into(source)));

        self.receive()
            .parse()
    }

    /**
     * Set amplitude voltage of fast analog outputs.
     *
     * Amplitude + offset value must be less than maximum output range ± 1V
     */
    pub fn set_amplitude(&self, source: Source, amplitude: f32) {
        self.send(format!("{}:VOLT {}", Into::<String>::into(source), amplitude));
    }

    /**
     * Get amplitude voltage of fast analog outputs.
     */
    pub fn get_amplitude(&self, source: Source) -> Result<f32, <f32 as ::std::str::FromStr>::Err> {
        self.send(format!("{}:VOLT?", Into::<String>::into(source)));

        self.receive()
            .parse()
    }

    /**
     * Set offset voltage of fast analog outputs.
     *
     * Amplitude + offset value must be less than maximum output range ± 1V
     */
    pub fn set_offset(&self, source: Source, offset: f32) {
        self.send(format!("{}:VOLT:OFFS {}", Into::<String>::into(source), offset));
    }

    /**
     * Get offset voltage of fast analog outputs.
     */
    pub fn get_offset(&self, source: Source) -> Result<f32, <f32 as ::std::str::FromStr>::Err> {
        self.send(format!("{}:VOLT:OFFS?", Into::<String>::into(source)));

        self.receive()
            .parse()
    }

    /**
     * Set phase of fast analog outputs.
     */
    pub fn set_phase(&self, source: Source, phase: i32) {
        self.send(format!("{}:PHAS {}", Into::<String>::into(source), phase));
    }

    /**
     * Get phase of fast analog outputs.
     */
    pub fn get_phase(&self, source: Source) -> Result<i32, <i32 as ::std::str::FromStr>::Err> {
        self.send(format!("{}:PHAS?", Into::<String>::into(source)));

        self.receive()
            .parse()
    }

    /**
     * Set duty cycle of PWM waveform.
     */
    pub fn set_duty_cycle(&self, source: Source, dcyc: f32) {
        self.send(format!("{}:DCYC {}", Into::<String>::into(source), dcyc));
    }

    /**
     * Get duty cycle of PWM waveform.
     */
    pub fn get_duty_cycle(&self, source: Source) -> Result<f32, <f32 as ::std::str::FromStr>::Err> {
        self.send(format!("{}:DCYC?", Into::<String>::into(source)));

        self.receive()
            .parse()
    }

    /**
     * Import data for arbitrary waveform generation.
     */
    pub fn set_arbitrary_waveform(&self, source: Source, data: Vec<f32>) {
        let mut data = data.iter()
            .fold(String::new(), |acc, e| {
                format!("{}{},", acc, e)
            });
        data.pop();

        self.send(format!("{}:TRAC:DATA:DATA {}", Into::<String>::into(source), data));
    }

    /**
     * Get data for arbitrary waveform generation.
     */
    pub fn get_arbitrary_waveform(&self, source: Source) -> Vec<f32> {
        self.send(format!("{}:TRAC:DATA:DATA?", Into::<String>::into(source)));

        let data = self.receive();
        data.trim_matches(|c| c == '{' || c == '}')
            .split(",")
            .map(|x| x.parse().unwrap())
            .collect()
    }

    /**
     * Set trigger source for selected signal.
     */
    pub fn set_trigger_source(&self, source: Source, trigger: TriggerSource) {
        self.send(format!("{}:TRIG:SOUR {}", Into::<String>::into(source), Into::<String>::into(trigger)));
    }

    /**
     * Get trigger source for selected signal.
     */
    pub fn get_trigger_source(&self, source: Source) -> Result<TriggerSource, String> {
        self.send(format!("{}:TRIG:SOUR?", Into::<String>::into(source)));

        self.receive()
            .parse()
    }

    /**
     * Triggers selected source immediately.
     */
    pub fn trigger(&self, source: Source) {
        self.send(format!("{}:TRIG:IMM", Into::<String>::into(source)));
    }

    /**
     * Triggers both sources immediately.
     */
    pub fn trigger_all(&self) {
        self.send("TRIG:IMM");
    }

    /**
     * Reset generator to default settings.
     */
    pub fn reset(&self) {
        self.send("GEN:RST");
    }
}

#[cfg(test)]
mod test {
    macro_rules! generator_assert {
        ($f:ident, $e:expr) => {
            let (rx, generator) = create_generator();

            generator.$f();
            assert_eq!($e, rx.recv().unwrap());
        }
    }

    #[test]
    fn test_status() {
        let (rx, generator) = create_generator();

        generator.start(::generator::Source::OUT2);
        assert_eq!("OUTPUT2:STATE ON\r\n", rx.recv().unwrap());

        assert_eq!(generator.is_started(::generator::Source::OUT2), Ok(true));

        generator.stop(::generator::Source::OUT2);
        assert_eq!("OUTPUT2:STATE OFF\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_frequency() {
        let (rx, generator) = create_generator();

        generator.set_frequency(::generator::Source::OUT1, 1_000);
        assert_eq!("SOUR1:FREQ:FIX 1000\r\n", rx.recv().unwrap());

        assert_eq!(generator.get_frequency(::generator::Source::OUT1), Ok(1_000));

        assert_eq!(generator.get_frequency(::generator::Source::OUT1), Ok(1_000));
    }

    #[test]
    fn test_form() {
        let (rx, generator) = create_generator();

        generator.set_form(::generator::Source::OUT1, ::generator::Form::SINE);
        assert_eq!("SOUR1:FUNC SINE\r\n", rx.recv().unwrap());

        assert_eq!(generator.get_form(::generator::Source::OUT1), Ok(::generator::Form::SINE));
    }

    #[test]
    fn test_amplitude() {
        let (rx, generator) = create_generator();

        generator.set_amplitude(::generator::Source::OUT1, -1.1);
        assert_eq!("SOUR1:VOLT -1.1\r\n", rx.recv().unwrap());

        assert_eq!(generator.get_amplitude(::generator::Source::OUT1), Ok(-1.1));
    }

    #[test]
    fn test_offset() {
        let (rx, generator) = create_generator();

        generator.set_offset(::generator::Source::OUT1, -1.2);
        assert_eq!("SOUR1:VOLT:OFFS -1.2\r\n", rx.recv().unwrap());

        assert_eq!(generator.get_offset(::generator::Source::OUT1), Ok(1.2));
    }

    #[test]
    fn test_phase() {
        let (rx, generator) = create_generator();

        generator.set_phase(::generator::Source::OUT1, -180);
        assert_eq!("SOUR1:PHAS -180\r\n", rx.recv().unwrap());

        assert_eq!(generator.get_phase(::generator::Source::OUT1), Ok(-180));
    }

    #[test]
    fn test_duty_cycle() {
        let (rx, generator) = create_generator();

        generator.set_duty_cycle(::generator::Source::OUT1, 1.0);
        assert_eq!("SOUR1:DCYC 1\r\n", rx.recv().unwrap());

        assert_eq!(generator.get_duty_cycle(::generator::Source::OUT1), Ok(1.0));
    }

    #[test]
    fn test_arbitrary_waveform() {
        let (rx, generator) = create_generator();

        generator.set_arbitrary_waveform(::generator::Source::OUT1, vec![1.0, 0.5, 0.2]);
        assert_eq!("SOUR1:TRAC:DATA:DATA 1,0.5,0.2\r\n", rx.recv().unwrap());

        #[cfg(features = "mock")]
        assert_eq!(generator.get_arbitrary_waveform(::generator::Source::OUT1), vec![1.0, 0.5, 0.2]);

        #[cfg(not(features = "mock"))]
        assert!(generator.get_arbitrary_waveform(::generator::Source::OUT1).len() > 0);
    }

    #[test]
    fn test_trigger_source() {
        let (rx, generator) = create_generator();

        generator.set_trigger_source(::generator::Source::OUT1, ::generator::TriggerSource::EXT_NE);
        assert_eq!("SOUR1:TRIG:SOUR EXT_NE\r\n", rx.recv().unwrap());

        assert_eq!(generator.get_trigger_source(::generator::Source::OUT1), Ok(::generator::TriggerSource::EXT_NE));
    }

    #[test]
    fn test_trigger() {
        let (rx, generator) = create_generator();

        generator.trigger(::generator::Source::OUT1);
        assert_eq!("SOUR1:TRIG:IMM\r\n", rx.recv().unwrap());
    }

    #[test]
    fn test_trigger_all() {
        generator_assert!(trigger_all, "TRIG:IMM\r\n");
    }

    #[test]
    fn test_reset() {
        generator_assert!(reset, "GEN:RST\r\n");
    }

    fn create_generator() -> (::std::sync::mpsc::Receiver<String>, ::generator::Generator) {
        let (addr, rx) = ::test::launch_server();
        let socket = ::socket::Socket::new(addr);

        (rx, ::generator::Generator::new(socket))
    }
}
<|endoftext|>


<commit_before>use std::error::Error;

use rotor::Time;

use {Expectation, Intent, IntentBuilder};

impl<M> Intent<M> {
    /// Start building the Intent object of the state machine
    pub fn of(machine: M) -> IntentBuilder<M> {
        IntentBuilder(machine)
    }
    /// Notifies that state machine has done it's work
    pub fn done() -> Self {
        Intent(Err(None), Expectation::Sleep, None)
    }
    /// Notifies that we have protocol error and connection should be closed
    pub fn error(e: Box<Error>) -> Self {
        Intent(Err(Some(e)), Expectation::Sleep, None)
    }
    /// Add/change the deadline
    ///
    /// Note: if you skip this method on next return timeout will be reset.
    /// Which means this state machine may hang indefinitely.
    pub fn deadline(self, deadline: Time) -> Intent<M> {
        Intent(self.0, self.1, Some(deadline))
    }
    /// Add/change the deadline as an optional value
    ///
    /// Note this will reset timeout if deadline is None, not keep unchanged
    pub fn deadline_opt(self, deadline: Option<Time>) -> Intent<M> {
        Intent(self.0, self.1, deadline)
    }
}

impl<M> IntentBuilder<M> {
    pub fn expect_bytes(self, min_bytes: usize) -> Intent<M> {
        Intent(Ok(self.0), Expectation::Bytes(min_bytes), None)
    }
    pub fn expect_delimiter(self, delim: &'static [u8], max_bytes: usize)
        -> Intent<M>
    {
        Intent(Ok(self.0),
               Expectation::Delimiter(0, delim, max_bytes), None)
    }
    pub fn expect_delimiter_after(self, offset: usize,
        delim: &'static [u8], max_bytes: usize)
        -> Intent<M>
    {
        Intent(Ok(self.0),
               Expectation::Delimiter(offset, delim, max_bytes), None)
    }
    pub fn expect_flush(self) -> Intent<M> {
        Intent(Ok(self.0), Expectation::Flush(0), None)
    }
    pub fn sleep(self) -> Intent<M> {
        Intent(Ok(self.0), Expectation::Sleep, None)
    }
}
<commit_msg>Add generic Intention::expect method<commit_after>use std::error::Error;

use rotor::Time;

use {Expectation, Intent, IntentBuilder};

impl<M> Intent<M> {
    /// Start building the Intent object of the state machine
    pub fn of(machine: M) -> IntentBuilder<M> {
        IntentBuilder(machine)
    }
    /// Notifies that state machine has done it's work
    pub fn done() -> Self {
        Intent(Err(None), Expectation::Sleep, None)
    }
    /// Notifies that we have protocol error and connection should be closed
    pub fn error(e: Box<Error>) -> Self {
        Intent(Err(Some(e)), Expectation::Sleep, None)
    }
    /// Add/change the deadline
    ///
    /// Note: if you skip this method on next return timeout will be reset.
    /// Which means this state machine may hang indefinitely.
    pub fn deadline(self, deadline: Time) -> Intent<M> {
        Intent(self.0, self.1, Some(deadline))
    }
    /// Add/change the deadline as an optional value
    ///
    /// Note this will reset timeout if deadline is None, not keep unchanged
    pub fn deadline_opt(self, deadline: Option<Time>) -> Intent<M> {
        Intent(self.0, self.1, deadline)
    }
}

impl<M> IntentBuilder<M> {
    pub fn expect_bytes(self, min_bytes: usize) -> Intent<M> {
        Intent(Ok(self.0), Expectation::Bytes(min_bytes), None)
    }
    pub fn expect_delimiter(self, delim: &'static [u8], max_bytes: usize)
        -> Intent<M>
    {
        Intent(Ok(self.0),
               Expectation::Delimiter(0, delim, max_bytes), None)
    }
    pub fn expect_delimiter_after(self, offset: usize,
        delim: &'static [u8], max_bytes: usize)
        -> Intent<M>
    {
        Intent(Ok(self.0),
               Expectation::Delimiter(offset, delim, max_bytes), None)
    }
    pub fn expect_flush(self) -> Intent<M> {
        Intent(Ok(self.0), Expectation::Flush(0), None)
    }
    /// Add a generic expectation
    ///
    /// The method is useful if you're returning an expectation from somewhere
    /// otherwise use specific `expect_*` methods
    pub fn expect(self, e: Expectation) -> Intent<M> {
        Intent(Ok(self.0), e, None)
    }
    pub fn sleep(self) -> Intent<M> {
        Intent(Ok(self.0), Expectation::Sleep, None)
    }
}
<|endoftext|>


<commit_before>use std::any::TypeId;
use std::fmt;
use std::hash::Hash;
use std::hash::Hasher;

use crate::descriptor::EnumDescriptorProto;
use crate::descriptor::EnumValueDescriptorProto;
use crate::enums::ProtobufEnum;
use crate::reflect::enums::dynamic::DynamicEnumDescriptor;
use crate::reflect::enums::generated::GeneratedEnumDescriptor;
#[cfg(not(rustc_nightly))]
use crate::reflect::enums::generated::GetEnumDescriptor;
use crate::reflect::file::FileDescriptorImpl;
use crate::reflect::FileDescriptor;

pub(crate) mod dynamic;
pub(crate) mod generated;
pub(crate) mod index;

/// Description for enum variant.
///
/// Used in reflection.
#[derive(Clone, Eq, PartialEq)]
pub struct EnumValueDescriptor {
    pub(crate) enum_descriptor: EnumDescriptor,
    pub(crate) index: usize,
}

impl Hash for EnumValueDescriptor {
    fn hash<H: Hasher>(&self, state: &mut H) {
        Hash::hash(&self.value(), state)
    }
}

fn _assert_send_sync() {
    fn _assert_send_sync<T: Send + Sync>() {}
    _assert_send_sync::<EnumValueDescriptor>();
}

impl fmt::Debug for EnumValueDescriptor {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("EnumValueDescriptor")
            // TODO: add something
            .field("value", &"...")
            .finish()
    }
}

impl EnumValueDescriptor {
    pub(crate) fn new(enum_descriptor: EnumDescriptor, index: usize) -> EnumValueDescriptor {
        EnumValueDescriptor {
            enum_descriptor,
            index,
        }
    }

    /// `.proto` object which declared this value.
    pub fn get_proto(&self) -> &EnumValueDescriptorProto {
        &self.enum_descriptor.get_proto().value[self.index as usize]
    }

    /// Name of enum variant as specified in proto file
    pub fn get_name(&self) -> &str {
        self.get_proto().get_name()
    }

    /// `i32` value of the enum variant
    pub fn value(&self) -> i32 {
        self.get_proto().get_number()
    }

    /// Get descriptor of enum holding this value.
    pub fn enum_descriptor(&self) -> &EnumDescriptor {
        &self.enum_descriptor
    }

    /// Convert this value descriptor into proper enum object.
    ///
    /// ```
    /// # use protobuf::well_known_types::NullValue;
    /// # use protobuf::ProtobufEnum;
    /// # use protobuf::reflect::EnumValueDescriptor;
    ///
    /// let value: EnumValueDescriptor = NullValue::NULL_VALUE.descriptor();
    /// let null: Option<NullValue> = value.cast();
    /// assert_eq!(Some(NullValue::NULL_VALUE), null);
    /// ```
    pub fn cast<E: ProtobufEnum>(&self) -> Option<E> {
        if self.enum_descriptor != E::enum_descriptor_static() {
            return None;
        }
        E::from_i32(self.value())
    }
}

/// Dynamic representation of enum type.
///
/// Can be used in reflective operations.
#[derive(Clone, Eq, PartialEq, Hash)]
pub struct EnumDescriptor {
    file_descriptor: FileDescriptor,
    index: usize,
}

impl fmt::Debug for EnumDescriptor {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("EnumDescriptor")
            // TODO
            //.field("full_name", &self.full_name)
            .field("..", &"..")
            .finish()
    }
}

impl EnumDescriptor {
    pub(crate) fn new(file_descriptor: FileDescriptor, index: usize) -> EnumDescriptor {
        EnumDescriptor {
            file_descriptor,
            index,
        }
    }

    fn get_impl(&self) -> EnumDescriptorImplRef {
        match &self.file_descriptor.imp {
            FileDescriptorImpl::Generated(g) => {
                EnumDescriptorImplRef::Generated(&g.enums[self.index])
            }
            FileDescriptorImpl::Dynamic(d) => EnumDescriptorImplRef::Dynamic(&d.enums[self.index]),
        }
    }

    /// Descriptor objects which defined this enum.
    pub fn get_proto(&self) -> &EnumDescriptorProto {
        match self.get_impl() {
            EnumDescriptorImplRef::Generated(g) => &g.proto,
            EnumDescriptorImplRef::Dynamic(d) => d.get_proto(),
        }
    }

    /// Enum name as given in `.proto` file
    pub fn get_name(&self) -> &str {
        // TODO: get_proto is inefficient
        self.get_proto().get_name()
    }

    /// Fully qualified protobuf name of enum
    pub fn full_name(&self) -> &str {
        match self.get_impl() {
            EnumDescriptorImplRef::Generated(g) => &g.full_name,
            EnumDescriptorImplRef::Dynamic(d) => &d.full_name,
        }
    }

    /// Get `EnumDescriptor` object for given enum type
    pub fn for_type<E: ProtobufEnum>() -> EnumDescriptor {
        E::enum_descriptor_static()
    }

    #[doc(hidden)]
    pub fn new_generated_2(file_descriptor: FileDescriptor, index: usize) -> EnumDescriptor {
        EnumDescriptor {
            file_descriptor,
            index,
        }
    }

    /// This enum values
    pub fn values<'a>(&'a self) -> impl Iterator<Item = EnumValueDescriptor> + 'a {
        let value_len = self.get_proto().value.len();
        (0..value_len).map(move |index| EnumValueDescriptor {
            enum_descriptor: self.clone(),
            index,
        })
    }

    /// First variant (also default in proto3).
    pub fn first_value(&self) -> EnumValueDescriptor {
        self.values().next().unwrap()
    }

    /// Find enum variant by name
    pub fn get_value_by_name<'a>(&'a self, name: &str) -> Option<EnumValueDescriptor> {
        let index = match self.get_impl() {
            EnumDescriptorImplRef::Generated(g) => *g.indices.index_by_name.get(name)?,
            EnumDescriptorImplRef::Dynamic(d) => *d.indices.index_by_name.get(name)?,
        };
        Some(EnumValueDescriptor {
            enum_descriptor: self.clone(),
            index,
        })
    }

    /// Find enum variant by number
    pub fn get_value_by_number(&self, number: i32) -> Option<EnumValueDescriptor> {
        let index = match self.get_impl() {
            EnumDescriptorImplRef::Generated(g) => *g.indices.index_by_number.get(&number)?,
            EnumDescriptorImplRef::Dynamic(d) => *d.indices.index_by_number.get(&number)?,
        };
        Some(EnumValueDescriptor {
            enum_descriptor: self.clone(),
            index,
        })
    }

    /// Default enum value (first variant)
    pub fn get_default_value(&self) -> EnumValueDescriptor {
        EnumValueDescriptor {
            enum_descriptor: self.clone(),
            index: 0,
        }
    }

    /// Find enum variant by number or return default (first) enum value
    pub fn get_value_by_number_or_default(&self, number: i32) -> EnumValueDescriptor {
        match self.get_value_by_number(number) {
            Some(v) => v,
            None => self.get_default_value(),
        }
    }

    /// Check if this enum descriptor corresponds given enum type
    ///
    /// ```
    /// # use protobuf::ProtobufEnum;
    /// # use protobuf::descriptor::field_descriptor_proto::Label;
    /// # use protobuf::reflect::EnumDescriptor;
    ///
    /// let descriptor: EnumDescriptor = Label::enum_descriptor_static();
    ///
    /// assert!(descriptor.is::<Label>())
    /// ```
    pub fn is<E: ProtobufEnum>(&self) -> bool {
        match self.get_impl() {
            EnumDescriptorImplRef::Generated(g) => g.type_id == TypeId::of::<E>(),
            EnumDescriptorImplRef::Dynamic(..) => false,
        }
    }
}

enum EnumDescriptorImplRef<'a> {
    Generated(&'static GeneratedEnumDescriptor),
    Dynamic(&'a DynamicEnumDescriptor),
}
<commit_msg>Dead code<commit_after>use std::any::TypeId;
use std::fmt;
use std::hash::Hash;
use std::hash::Hasher;

use crate::descriptor::EnumDescriptorProto;
use crate::descriptor::EnumValueDescriptorProto;
use crate::enums::ProtobufEnum;
use crate::reflect::enums::dynamic::DynamicEnumDescriptor;
use crate::reflect::enums::generated::GeneratedEnumDescriptor;
use crate::reflect::file::FileDescriptorImpl;
use crate::reflect::FileDescriptor;

pub(crate) mod dynamic;
pub(crate) mod generated;
pub(crate) mod index;

/// Description for enum variant.
///
/// Used in reflection.
#[derive(Clone, Eq, PartialEq)]
pub struct EnumValueDescriptor {
    pub(crate) enum_descriptor: EnumDescriptor,
    pub(crate) index: usize,
}

impl Hash for EnumValueDescriptor {
    fn hash<H: Hasher>(&self, state: &mut H) {
        Hash::hash(&self.value(), state)
    }
}

fn _assert_send_sync() {
    fn _assert_send_sync<T: Send + Sync>() {}
    _assert_send_sync::<EnumValueDescriptor>();
}

impl fmt::Debug for EnumValueDescriptor {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("EnumValueDescriptor")
            // TODO: add something
            .field("value", &"...")
            .finish()
    }
}

impl EnumValueDescriptor {
    pub(crate) fn new(enum_descriptor: EnumDescriptor, index: usize) -> EnumValueDescriptor {
        EnumValueDescriptor {
            enum_descriptor,
            index,
        }
    }

    /// `.proto` object which declared this value.
    pub fn get_proto(&self) -> &EnumValueDescriptorProto {
        &self.enum_descriptor.get_proto().value[self.index as usize]
    }

    /// Name of enum variant as specified in proto file
    pub fn get_name(&self) -> &str {
        self.get_proto().get_name()
    }

    /// `i32` value of the enum variant
    pub fn value(&self) -> i32 {
        self.get_proto().get_number()
    }

    /// Get descriptor of enum holding this value.
    pub fn enum_descriptor(&self) -> &EnumDescriptor {
        &self.enum_descriptor
    }

    /// Convert this value descriptor into proper enum object.
    ///
    /// ```
    /// # use protobuf::well_known_types::NullValue;
    /// # use protobuf::ProtobufEnum;
    /// # use protobuf::reflect::EnumValueDescriptor;
    ///
    /// let value: EnumValueDescriptor = NullValue::NULL_VALUE.descriptor();
    /// let null: Option<NullValue> = value.cast();
    /// assert_eq!(Some(NullValue::NULL_VALUE), null);
    /// ```
    pub fn cast<E: ProtobufEnum>(&self) -> Option<E> {
        if self.enum_descriptor != E::enum_descriptor_static() {
            return None;
        }
        E::from_i32(self.value())
    }
}

/// Dynamic representation of enum type.
///
/// Can be used in reflective operations.
#[derive(Clone, Eq, PartialEq, Hash)]
pub struct EnumDescriptor {
    file_descriptor: FileDescriptor,
    index: usize,
}

impl fmt::Debug for EnumDescriptor {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("EnumDescriptor")
            // TODO
            //.field("full_name", &self.full_name)
            .field("..", &"..")
            .finish()
    }
}

impl EnumDescriptor {
    pub(crate) fn new(file_descriptor: FileDescriptor, index: usize) -> EnumDescriptor {
        EnumDescriptor {
            file_descriptor,
            index,
        }
    }

    fn get_impl(&self) -> EnumDescriptorImplRef {
        match &self.file_descriptor.imp {
            FileDescriptorImpl::Generated(g) => {
                EnumDescriptorImplRef::Generated(&g.enums[self.index])
            }
            FileDescriptorImpl::Dynamic(d) => EnumDescriptorImplRef::Dynamic(&d.enums[self.index]),
        }
    }

    /// Descriptor objects which defined this enum.
    pub fn get_proto(&self) -> &EnumDescriptorProto {
        match self.get_impl() {
            EnumDescriptorImplRef::Generated(g) => &g.proto,
            EnumDescriptorImplRef::Dynamic(d) => d.get_proto(),
        }
    }

    /// Enum name as given in `.proto` file
    pub fn get_name(&self) -> &str {
        // TODO: get_proto is inefficient
        self.get_proto().get_name()
    }

    /// Fully qualified protobuf name of enum
    pub fn full_name(&self) -> &str {
        match self.get_impl() {
            EnumDescriptorImplRef::Generated(g) => &g.full_name,
            EnumDescriptorImplRef::Dynamic(d) => &d.full_name,
        }
    }

    /// Get `EnumDescriptor` object for given enum type
    pub fn for_type<E: ProtobufEnum>() -> EnumDescriptor {
        E::enum_descriptor_static()
    }

    #[doc(hidden)]
    pub fn new_generated_2(file_descriptor: FileDescriptor, index: usize) -> EnumDescriptor {
        EnumDescriptor {
            file_descriptor,
            index,
        }
    }

    /// This enum values
    pub fn values<'a>(&'a self) -> impl Iterator<Item = EnumValueDescriptor> + 'a {
        let value_len = self.get_proto().value.len();
        (0..value_len).map(move |index| EnumValueDescriptor {
            enum_descriptor: self.clone(),
            index,
        })
    }

    /// First variant (also default in proto3).
    pub fn first_value(&self) -> EnumValueDescriptor {
        self.values().next().unwrap()
    }

    /// Find enum variant by name
    pub fn get_value_by_name<'a>(&'a self, name: &str) -> Option<EnumValueDescriptor> {
        let index = match self.get_impl() {
            EnumDescriptorImplRef::Generated(g) => *g.indices.index_by_name.get(name)?,
            EnumDescriptorImplRef::Dynamic(d) => *d.indices.index_by_name.get(name)?,
        };
        Some(EnumValueDescriptor {
            enum_descriptor: self.clone(),
            index,
        })
    }

    /// Find enum variant by number
    pub fn get_value_by_number(&self, number: i32) -> Option<EnumValueDescriptor> {
        let index = match self.get_impl() {
            EnumDescriptorImplRef::Generated(g) => *g.indices.index_by_number.get(&number)?,
            EnumDescriptorImplRef::Dynamic(d) => *d.indices.index_by_number.get(&number)?,
        };
        Some(EnumValueDescriptor {
            enum_descriptor: self.clone(),
            index,
        })
    }

    /// Default enum value (first variant)
    pub fn get_default_value(&self) -> EnumValueDescriptor {
        EnumValueDescriptor {
            enum_descriptor: self.clone(),
            index: 0,
        }
    }

    /// Find enum variant by number or return default (first) enum value
    pub fn get_value_by_number_or_default(&self, number: i32) -> EnumValueDescriptor {
        match self.get_value_by_number(number) {
            Some(v) => v,
            None => self.get_default_value(),
        }
    }

    /// Check if this enum descriptor corresponds given enum type
    ///
    /// ```
    /// # use protobuf::ProtobufEnum;
    /// # use protobuf::descriptor::field_descriptor_proto::Label;
    /// # use protobuf::reflect::EnumDescriptor;
    ///
    /// let descriptor: EnumDescriptor = Label::enum_descriptor_static();
    ///
    /// assert!(descriptor.is::<Label>())
    /// ```
    pub fn is<E: ProtobufEnum>(&self) -> bool {
        match self.get_impl() {
            EnumDescriptorImplRef::Generated(g) => g.type_id == TypeId::of::<E>(),
            EnumDescriptorImplRef::Dynamic(..) => false,
        }
    }
}

enum EnumDescriptorImplRef<'a> {
    Generated(&'static GeneratedEnumDescriptor),
    Dynamic(&'a DynamicEnumDescriptor),
}
<|endoftext|>


<commit_before>use common::problem::{ Problem };

pub static problem: Problem<'static> = Problem {
    id: 11,
    answer: "70600674",
    solver: solve
};

fn find_max_uint(ns: &[uint]) -> uint {
    vec::foldl(0u, ns, |acc, n| uint::max(acc, *n))
}

fn find_max_row(row: &[uint], prod_len: uint) -> uint {
    let wins = vec::windowed(prod_len, row);
    let prods = vec::map(wins, |ns| vec::foldl(1u, *ns, |acc, n| acc * *n ) );
    find_max_uint(prods)
}

fn find_max_grid(grid: &[~[uint]], prod_len: uint) -> uint {
    find_max_uint(vec::map(grid, |row| find_max_row(*row, prod_len)))
}

fn find_max_v(grid: &[~[uint]], prod_len: uint) -> uint {
    if vec::is_empty(grid) { return 0u; }

    let mut max = 0u;
    for uint::range(0u, vec::len(grid[0])) |i| {
        let col = vec::map(grid, |row| row[i]);
        max = uint::max(max, find_max_row(col, prod_len));
    }
    return max;
}

fn find_max_d(grid: &[~[uint]], prod_len: uint) -> uint {
    if vec::is_empty(grid) { return 0u; }
    let num_row = vec::len(grid);
    let num_col = vec::len(grid[0]);
    let mut max = 0u;
    for int::range(-(num_row as int) + 1, num_col as int) |i| {
        let mut tl_br = ~[];
        for uint::range(0u, uint::min(num_row, num_col)) |d| {
            let (x, y) = (i + (d as int), d);
            if x >= 0 && (x as uint) < num_col && y < num_row {
                tl_br += [ grid[y][x] ];
            }
        }
        max = uint::max(max, find_max_row(tl_br, prod_len));

        let mut bl_tr = ~[];
        for uint::range(0u, uint::min(num_row, num_col)) |d| {
            let (x, y) = (d, (num_col as int - 1 - i) - (d as int));
            if x < num_col && y >= 0 && (y as uint) < num_row {
                bl_tr += [ grid[y][x] ];
            }
        }
        max = uint::max(max, find_max_row(bl_tr, prod_len));
    }
    return max;
}

static input: &'static str = &"
08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48
";

fn solve() -> ~str {
    let grid = {
        let mut result = ~[];
        for str::each_line(input.trim()) |line| {
            let mut col = ~[];
            for str::each_word(line) |word| {
                col.push(uint::from_str(word).get())
            }
            result.push(col);
        }
        result
    };

    let mut max = find_max_grid(grid, 4u);
    max = uint::max(max, find_max_v(grid, 4u));
    max = uint::max(max, find_max_d(grid, 4u));
    return max.to_str();
}
<commit_msg>Modify problem #11<commit_after>use common::extvec::{ each_window };
use common::problem::{ Problem };

pub static problem: Problem<'static> = Problem {
    id: 11,
    answer: "70600674",
    solver: solve
};

fn find_max_uint(ns: &[uint]) -> uint {
    vec::foldl(0u, ns, |acc, n| uint::max(acc, *n))
}

fn find_max_row(row: &[uint], prod_len: uint) -> uint {
    let mut prods = ~[];
    for each_window(row, prod_len) |ns| {
        prods.push(ns.foldl(1u, |acc, n| acc * *n))
    }
    find_max_uint(prods)
}

fn find_max_grid(grid: &[~[uint]], prod_len: uint) -> uint {
    find_max_uint(vec::map(grid, |row| find_max_row(*row, prod_len)))
}

fn find_max_v(grid: &[~[uint]], prod_len: uint) -> uint {
    if vec::is_empty(grid) { return 0u; }

    let mut max = 0u;
    for uint::range(0u, vec::len(grid[0])) |i| {
        let col = vec::map(grid, |row| row[i]);
        max = uint::max(max, find_max_row(col, prod_len));
    }
    return max;
}

fn find_max_d(grid: &[~[uint]], prod_len: uint) -> uint {
    if vec::is_empty(grid) { return 0u; }
    let num_row = vec::len(grid);
    let num_col = vec::len(grid[0]);
    let mut max = 0u;
    for int::range(-(num_row as int) + 1, num_col as int) |i| {
        let mut tl_br = ~[];
        for uint::range(0u, uint::min(num_row, num_col)) |d| {
            let (x, y) = (i + (d as int), d);
            if x >= 0 && (x as uint) < num_col && y < num_row {
                tl_br += [ grid[y][x] ];
            }
        }
        max = uint::max(max, find_max_row(tl_br, prod_len));

        let mut bl_tr = ~[];
        for uint::range(0u, uint::min(num_row, num_col)) |d| {
            let (x, y) = (d, (num_col as int - 1 - i) - (d as int));
            if x < num_col && y >= 0 && (y as uint) < num_row {
                bl_tr += [ grid[y][x] ];
            }
        }
        max = uint::max(max, find_max_row(bl_tr, prod_len));
    }
    return max;
}

static input: &'static str = &"
08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48
";

fn solve() -> ~str {
    let grid = {
        let mut result = ~[];
        for str::each_line(input.trim()) |line| {
            let mut col = ~[];
            for str::each_word(line) |word| {
                col.push(uint::from_str(word).get())
            }
            result.push(col);
        }
        result
    };

    let mut max = find_max_grid(grid, 4u);
    max = uint::max(max, find_max_v(grid, 4u));
    max = uint::max(max, find_max_d(grid, 4u));
    return max.to_str();
}
<|endoftext|>