<commit_before>use std::f64;
use std::f64::consts::PI;

use rand::{Rand, Rng};

use radians::Radians;
use {Distance};

/// Represents the various supported speeds that the turtle can move at
///
/// See [`Turtle::set_speed` method](struct.Turtle.html#method.set_speed) for more information.
#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
pub enum Speed {
    One,
    Two,
    Three,
    Four,
    Five,
    Six,
    Seven,
    Eight,
    Nine,
    Ten,
    Instant,
}

impl Speed {
    /// Converts a speed to its value as pixels per second
    pub fn to_absolute(self) -> Distance {
        use self::Speed::*;
        // Arbitrary values that can be tweaked
        // Just make sure to keep invariants like Five > Three, etc.
        match self {
            One => 50.,
            Two => 100.,
            Three => 200.,
            Four => 300.,
            Five => 500.,
            Six => 600.,
            Seven => 700.,
            Eight => 800.,
            Nine => 900.,
            Ten => 1000.,
            Instant => f64::INFINITY,
        }
    }

    /// Converts a speed to its value as radians per second
    pub fn to_rotation(self) -> Radians {
        use self::Speed::*;
        // Arbitrary values that can be tweaked
        // Just make sure to keep invariants like Five > Three, etc.
        Radians::from_radians_value(match self {
            One => 0.7 * PI,
            Two => 0.9 * PI,
            Three => 1.1 * PI,
            Four => 1.3 * PI,
            Five =>  1.5 * PI,
            Six => 2.5 * PI,
            Seven => 3.5 * PI,
            Eight => 4.0 * PI,
            Nine => 8.0 * PI,
            Ten => 12.0 * PI,
            Instant => f64::INFINITY,
        })
    }
}

impl Rand for Speed {
    fn rand<R: Rng>(rng: &mut R) -> Self {
        (rng.gen::<i32>() % 10).into()
    }
}

impl<'a> From<&'a str> for Speed {
    fn from(s: &'a str) -> Self {
        use Speed::*;

        match s {
            "slowest" => One,
            "slow" => Three,
            "normal" => Six,
            "fast" => Eight,
            "fastest" => Ten,
            "instant" => Instant,
            _ => panic!("Invalid speed specified, use one of the words: 'slowest', 'slow', 'normal', 'fast', 'fastest', 'instant'"),
        }
    }
}

impl From<i32> for Speed {
    fn from(n: i32) -> Self {
        use Speed::*;

        match n {
            1 => One,
            2 => Two,
            3 => Three,
            4 => Four,
            5 => Five,
            6 => Six,
            7 => Seven,
            8 => Eight,
            9 => Nine,
            10 => Ten,
            _ => Instant,
        }
    }
}

// We include this implementation because we use f64 in the rest of the library.
// It makes sense to implement this so that they don't get messed up if they accidentally use a
// floating point literal with set_speed.
impl From<f64> for Speed {
    fn from(n: f64) -> Self {
        (n.round() as i32).into()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use {Turtle};

    #[test]
    fn speed_names() {
        let mut turtle = Turtle::new();
        turtle.set_speed("slowest");
        assert_eq!(turtle.speed(), Speed::One);
        turtle.set_speed("slow");
        assert_eq!(turtle.speed(), Speed::Three);
        turtle.set_speed("normal");
        assert_eq!(turtle.speed(), Speed::Six);
        turtle.set_speed("fast");
        assert_eq!(turtle.speed(), Speed::Eight);
        turtle.set_speed("fastest");
        assert_eq!(turtle.speed(), Speed::Ten);
        turtle.set_speed("instant");
        assert_eq!(turtle.speed(), Speed::Instant);
    }

    #[test]
    #[should_panic(expected = "Invalid speed specified, use one of the words: 'slowest', 'slow', 'normal', 'fast', 'fastest', 'instant'")]
    fn invalid_speed() {
        let mut turtle = Turtle::new();
        turtle.set_speed("wrong");
    }

    #[test]
    fn speed_values() {
        let mut turtle = Turtle::new();
        turtle.set_speed(0);
        assert_eq!(turtle.speed(), Speed::Instant);
        turtle.set_speed(1);
        assert_eq!(turtle.speed(), Speed::One);
        turtle.set_speed(2);
        assert_eq!(turtle.speed(), Speed::Two);
        turtle.set_speed(3);
        assert_eq!(turtle.speed(), Speed::Three);
        turtle.set_speed(4);
        assert_eq!(turtle.speed(), Speed::Four);
        turtle.set_speed(5);
        assert_eq!(turtle.speed(), Speed::Five);
        turtle.set_speed(6);
        assert_eq!(turtle.speed(), Speed::Six);
        turtle.set_speed(7);
        assert_eq!(turtle.speed(), Speed::Seven);
        turtle.set_speed(8);
        assert_eq!(turtle.speed(), Speed::Eight);
        turtle.set_speed(9);
        assert_eq!(turtle.speed(), Speed::Nine);
        turtle.set_speed(10);
        assert_eq!(turtle.speed(), Speed::Ten);
        turtle.set_speed(11);
        assert_eq!(turtle.speed(), Speed::Instant);
        turtle.set_speed(20394);
        assert_eq!(turtle.speed(), Speed::Instant);
    }

    #[test]
    fn speed_values_f64() {
        let mut turtle = Turtle::new();
        turtle.set_speed(0.4);
        assert_eq!(turtle.speed(), Speed::Instant);
        turtle.set_speed(1.4);
        assert_eq!(turtle.speed(), Speed::One);
        turtle.set_speed(2.4);
        assert_eq!(turtle.speed(), Speed::Two);
        turtle.set_speed(3.4);
        assert_eq!(turtle.speed(), Speed::Three);
        turtle.set_speed(4.4);
        assert_eq!(turtle.speed(), Speed::Four);
        turtle.set_speed(5.4);
        assert_eq!(turtle.speed(), Speed::Five);
        turtle.set_speed(6.4);
        assert_eq!(turtle.speed(), Speed::Six);
        turtle.set_speed(7.4);
        assert_eq!(turtle.speed(), Speed::Seven);
        turtle.set_speed(8.4);
        assert_eq!(turtle.speed(), Speed::Eight);
        turtle.set_speed(9.4);
        assert_eq!(turtle.speed(), Speed::Nine);
        turtle.set_speed(10.4);
        assert_eq!(turtle.speed(), Speed::Ten);
        turtle.set_speed(11.4);
        assert_eq!(turtle.speed(), Speed::Instant);
        turtle.set_speed(20394.4);
        assert_eq!(turtle.speed(), Speed::Instant);
    }
}
<commit_msg>Hiding the methods on Speed that are only to be used internally<commit_after>use std::f64;
use std::f64::consts::PI;

use rand::{Rand, Rng};

use radians::Radians;
use {Distance};

/// Represents the various supported speeds that the turtle can move at
///
/// See [`Turtle::set_speed` method](struct.Turtle.html#method.set_speed) for more information.
#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
pub enum Speed {
    One,
    Two,
    Three,
    Four,
    Five,
    Six,
    Seven,
    Eight,
    Nine,
    Ten,
    Instant,
}

impl Speed {
    /// Converts a speed to its value as pixels per second
    pub(crate) fn to_absolute(self) -> Distance {
        use self::Speed::*;
        // Arbitrary values that can be tweaked
        // Just make sure to keep invariants like Five > Three, etc.
        match self {
            One => 50.,
            Two => 100.,
            Three => 200.,
            Four => 300.,
            Five => 500.,
            Six => 600.,
            Seven => 700.,
            Eight => 800.,
            Nine => 900.,
            Ten => 1000.,
            Instant => f64::INFINITY,
        }
    }

    /// Converts a speed to its value as radians per second
    pub(crate) fn to_rotation(self) -> Radians {
        use self::Speed::*;
        // Arbitrary values that can be tweaked
        // Just make sure to keep invariants like Five > Three, etc.
        Radians::from_radians_value(match self {
            One => 0.7 * PI,
            Two => 0.9 * PI,
            Three => 1.1 * PI,
            Four => 1.3 * PI,
            Five =>  1.5 * PI,
            Six => 2.5 * PI,
            Seven => 3.5 * PI,
            Eight => 4.0 * PI,
            Nine => 8.0 * PI,
            Ten => 12.0 * PI,
            Instant => f64::INFINITY,
        })
    }
}

impl Rand for Speed {
    fn rand<R: Rng>(rng: &mut R) -> Self {
        (rng.gen::<i32>() % 10).into()
    }
}

impl<'a> From<&'a str> for Speed {
    fn from(s: &'a str) -> Self {
        use Speed::*;

        match s {
            "slowest" => One,
            "slow" => Three,
            "normal" => Six,
            "fast" => Eight,
            "fastest" => Ten,
            "instant" => Instant,
            _ => panic!("Invalid speed specified, use one of the words: 'slowest', 'slow', 'normal', 'fast', 'fastest', 'instant'"),
        }
    }
}

impl From<i32> for Speed {
    fn from(n: i32) -> Self {
        use Speed::*;

        match n {
            1 => One,
            2 => Two,
            3 => Three,
            4 => Four,
            5 => Five,
            6 => Six,
            7 => Seven,
            8 => Eight,
            9 => Nine,
            10 => Ten,
            _ => Instant,
        }
    }
}

// We include this implementation because we use f64 in the rest of the library.
// It makes sense to implement this so that they don't get messed up if they accidentally use a
// floating point literal with set_speed.
impl From<f64> for Speed {
    fn from(n: f64) -> Self {
        (n.round() as i32).into()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use {Turtle};

    #[test]
    fn speed_names() {
        let mut turtle = Turtle::new();
        turtle.set_speed("slowest");
        assert_eq!(turtle.speed(), Speed::One);
        turtle.set_speed("slow");
        assert_eq!(turtle.speed(), Speed::Three);
        turtle.set_speed("normal");
        assert_eq!(turtle.speed(), Speed::Six);
        turtle.set_speed("fast");
        assert_eq!(turtle.speed(), Speed::Eight);
        turtle.set_speed("fastest");
        assert_eq!(turtle.speed(), Speed::Ten);
        turtle.set_speed("instant");
        assert_eq!(turtle.speed(), Speed::Instant);
    }

    #[test]
    #[should_panic(expected = "Invalid speed specified, use one of the words: 'slowest', 'slow', 'normal', 'fast', 'fastest', 'instant'")]
    fn invalid_speed() {
        let mut turtle = Turtle::new();
        turtle.set_speed("wrong");
    }

    #[test]
    fn speed_values() {
        let mut turtle = Turtle::new();
        turtle.set_speed(0);
        assert_eq!(turtle.speed(), Speed::Instant);
        turtle.set_speed(1);
        assert_eq!(turtle.speed(), Speed::One);
        turtle.set_speed(2);
        assert_eq!(turtle.speed(), Speed::Two);
        turtle.set_speed(3);
        assert_eq!(turtle.speed(), Speed::Three);
        turtle.set_speed(4);
        assert_eq!(turtle.speed(), Speed::Four);
        turtle.set_speed(5);
        assert_eq!(turtle.speed(), Speed::Five);
        turtle.set_speed(6);
        assert_eq!(turtle.speed(), Speed::Six);
        turtle.set_speed(7);
        assert_eq!(turtle.speed(), Speed::Seven);
        turtle.set_speed(8);
        assert_eq!(turtle.speed(), Speed::Eight);
        turtle.set_speed(9);
        assert_eq!(turtle.speed(), Speed::Nine);
        turtle.set_speed(10);
        assert_eq!(turtle.speed(), Speed::Ten);
        turtle.set_speed(11);
        assert_eq!(turtle.speed(), Speed::Instant);
        turtle.set_speed(20394);
        assert_eq!(turtle.speed(), Speed::Instant);
    }

    #[test]
    fn speed_values_f64() {
        let mut turtle = Turtle::new();
        turtle.set_speed(0.4);
        assert_eq!(turtle.speed(), Speed::Instant);
        turtle.set_speed(1.4);
        assert_eq!(turtle.speed(), Speed::One);
        turtle.set_speed(2.4);
        assert_eq!(turtle.speed(), Speed::Two);
        turtle.set_speed(3.4);
        assert_eq!(turtle.speed(), Speed::Three);
        turtle.set_speed(4.4);
        assert_eq!(turtle.speed(), Speed::Four);
        turtle.set_speed(5.4);
        assert_eq!(turtle.speed(), Speed::Five);
        turtle.set_speed(6.4);
        assert_eq!(turtle.speed(), Speed::Six);
        turtle.set_speed(7.4);
        assert_eq!(turtle.speed(), Speed::Seven);
        turtle.set_speed(8.4);
        assert_eq!(turtle.speed(), Speed::Eight);
        turtle.set_speed(9.4);
        assert_eq!(turtle.speed(), Speed::Nine);
        turtle.set_speed(10.4);
        assert_eq!(turtle.speed(), Speed::Ten);
        turtle.set_speed(11.4);
        assert_eq!(turtle.speed(), Speed::Instant);
        turtle.set_speed(20394.4);
        assert_eq!(turtle.speed(), Speed::Instant);
    }
}
<|endoftext|>


<commit_before>use nom::{
  be_u8, be_u16,
  IResult,
  ErrorCode, Err,
};

use frame::{
  ChannelAssignment, NumberType,
  Frame,
  Header, Footer,
};

use metadata::StreamInfo;
use utility::{crc8, crc16, to_u32};

pub fn frame_parser<'a>(input: &'a [u8], stream_info: &StreamInfo)
                        -> IResult<'a, &'a [u8], Frame> {
  let result = chain!(input,
    frame_header: apply!(header, stream_info) ~
    frame_footer: footer,
    || {
      Frame {
        header: frame_header,
        footer: frame_footer,
      }
    }
  );

  match result {
    IResult::Done(i, frame)   => {
      // All frame bytes before the crc-16
      let end         = (input.len() - i.len()) - 2;
      let Footer(crc) = frame.footer;

      if crc16(&input[0..end]) == crc {
        IResult::Done(i, frame)
      } else {
        IResult::Error(Err::Position(ErrorCode::Digit as u32, input))
      }
    }
    IResult::Error(error)     => IResult::Error(error),
    IResult::Incomplete(need) => IResult::Incomplete(need),
  }
}

fn blocking_strategy(input: &[u8]) -> IResult<&[u8], bool> {
  match take!(input, 2) {
    IResult::Done(i, bytes)   => {
      let sync_code = ((bytes[0] as u16) << 6) +
                      ((bytes[1] as u16) >> 2);
      let is_valid  = ((bytes[1] >> 1) & 0b01) == 0;

      if sync_code == 0b11111111111110 && is_valid {
        let is_variable_block_size = (bytes[1] & 0b01) == 1;

        IResult::Done(i, is_variable_block_size)
      } else {
        IResult::Error(Err::Position(ErrorCode::Digit as u32, input))
      }
    }
    IResult::Error(error)     => IResult::Error(error),
    IResult::Incomplete(need) => IResult::Incomplete(need),
  }
}

fn block_sample(input: &[u8]) -> IResult<&[u8], (u8, u8)> {
  match be_u8(input) {
    IResult::Done(i, byte)    => {
      let block_byte  = byte >> 4;
      let sample_byte = byte & 0x0f;
      let is_valid    = block_byte != 0b0000 && sample_byte != 0b1111;

      if is_valid {
        IResult::Done(i, (block_byte, sample_byte))
      } else {
        IResult::Error(Err::Position(ErrorCode::Digit as u32, input))
      }
    }
    IResult::Error(error)     => IResult::Error(error),
    IResult::Incomplete(need) => IResult::Incomplete(need),
  }
}

fn channel_bits(input: &[u8]) -> IResult<&[u8], (ChannelAssignment, u8, u8)> {
  match be_u8(input) {
    IResult::Done(i, byte)    => {
      let mut channels       = 2;
      let channel_byte       = byte >> 4;
      let channel_assignment = match channel_byte {
        0b0000...0b0111 => {
          channels = channel_byte + 1;

          ChannelAssignment::Independent
        }
        0b1000          => ChannelAssignment::LeftSide,
        0b1001          => ChannelAssignment::RightSide,
        0b1010          => ChannelAssignment::MiddleSide,
        _               => ChannelAssignment::Independent,
      };
      let size_byte = (byte >> 1) & 0b0111;

      // Checks the validity of:
      //
      // * (4 bits) channel assignment
      // * (3 bits) sample size
      // * (1 bit) last bit
      //
      // All these checks are whether of not they are reserved and should
      // return an error if so.
      let is_valid = channel_byte < 0b1011 &&
                     (size_byte != 0b0011 && size_byte != 0b0111) &&
                     (byte & 0b01) == 0;

      if is_valid {
        IResult::Done(i, (channel_assignment, channels, size_byte))
      } else {
        IResult::Error(Err::Position(ErrorCode::Digit as u32, input))
      }
    }
    IResult::Error(error)     => IResult::Error(error),
    IResult::Incomplete(need) => IResult::Incomplete(need),
  }
}

fn utf8_size(input: &[u8], is_u64: bool)
             -> IResult<&[u8], Option<(usize, u8)>> {
  map!(input, be_u8, |utf8_header| {
    match utf8_header {
      0b00000000...0b01111111 => Some((0, utf8_header)),
      0b11000000...0b11011111 => Some((1, utf8_header & 0b00011111)),
      0b11100000...0b11101111 => Some((2, utf8_header & 0b00001111)),
      0b11110000...0b11110111 => Some((3, utf8_header & 0b00000111)),
      0b11111000...0b11111011 => Some((4, utf8_header & 0b00000011)),
      0b11111100...0b11111101 => Some((5, utf8_header & 0b00000001)),
      0b11111110              => if is_u64 { Some((6, 0)) } else { None },
      _                       => None,
    }
  })
}

fn number_type(input: &[u8], is_sample: bool,
               (size, value): (usize, u8))
               -> IResult<&[u8], NumberType> {
  let mut result   = value as u64;
  let mut is_error = false;

  match take!(input, size) {
    IResult::Done(i, bytes)   => {
      for i in 0..size {
        let byte = bytes[i] as u64;

        if byte >= 0b10000000 && byte <= 0b10111111 {
          result = (result << 6) + (byte & 0b00111111);
        } else {
          is_error = true;
          break;
        }
      }

      if is_error {
        IResult::Error(Err::Position(ErrorCode::Digit as u32, input))
      } else if is_sample {
        IResult::Done(i, NumberType::Sample(result))
      } else {
        IResult::Done(i, NumberType::Frame(result as u32))
      }
    }
    IResult::Error(error)     => IResult::Error(error),
    IResult::Incomplete(need) => IResult::Incomplete(need),
  }
}

fn secondary_block_size(input: &[u8], block_byte: u8)
                        -> IResult<&[u8], Option<u32>> {
  match block_byte {
    0b0110 => opt!(input, map!(take!(1), to_u32)),
    0b0111 => opt!(input, map!(take!(2), to_u32)),
    _      => IResult::Done(input, None)
  }
}

fn secondary_sample_rate(input: &[u8], sample_byte: u8)
                        -> IResult<&[u8], Option<u32>> {
  match sample_byte {
    0b1100          => opt!(input, map!(take!(1), to_u32)),
    0b1101 | 0b1110 => opt!(input, map!(take!(2), to_u32)),
    _               => IResult::Done(input, None)
  }
}

pub fn header<'a>(input: &'a [u8], stream_info: &StreamInfo)
                  -> IResult<'a, &'a [u8], Header> {
  let result = chain!(input,
    is_variable_block_size: blocking_strategy ~
    tuple0: block_sample ~
    tuple1: channel_bits ~
    number_opt: apply!(utf8_size, is_variable_block_size) ~
    number_length: expr_opt!(number_opt) ~
    number: apply!(number_type, is_variable_block_size, number_length) ~
    alt_block_size: apply!(secondary_block_size, tuple0.0) ~
    alt_sample_rate: apply!(secondary_sample_rate, tuple0.1) ~
    crc: be_u8,
    || {
      let (block_byte, sample_byte)                 = tuple0;
      let (channel_assignment, channels, size_byte) = tuple1;

      let block_size = match block_byte {
        0b0001          => 192,
        0b0010...0b0101 => 576 * 2_u32.pow(block_byte as u32 - 2),
        0b0110 | 0b0111 => alt_block_size.unwrap() + 1,
        0b1000...0b1111 => 256 * 2_u32.pow(block_byte as u32 - 8),
        _               => unreachable!(),
      };

      let sample_rate = match sample_byte {
        0b0000 => stream_info.sample_rate,
        0b0001 => 88200,
        0b0010 => 176400,
        0b0011 => 192000,
        0b0100 => 8000,
        0b0101 => 16000,
        0b0110 => 22050,
        0b0111 => 24000,
        0b1000 => 32000,
        0b1001 => 44100,
        0b1010 => 48000,
        0b1011 => 96000,
        0b1100 => alt_sample_rate.unwrap() * 1000,
        0b1101 => alt_sample_rate.unwrap(),
        0b1110 => alt_sample_rate.unwrap() * 10,
        _      => unreachable!(),
      };

      let bits_per_sample = match size_byte {
        0b0000 => stream_info.bits_per_sample as usize,
        0b0001 => 8,
        0b0010 => 12,
        0b0100 => 16,
        0b0101 => 20,
        0b0110 => 24,
        _      => unreachable!(),
      };

      Header {
        block_size: block_size,
        sample_rate: sample_rate,
        channels: channels,
        channel_assignment: channel_assignment,
        bits_per_sample: bits_per_sample,
        number: number,
        crc: crc,
      }
    }
  );

  match result {
    IResult::Done(i, frame_header) => {
      // All header bytes before the crc-8
      let end = (input.len() - i.len()) - 1;

      if crc8(&input[0..end]) == frame_header.crc {
        IResult::Done(i, frame_header)
      } else {
        IResult::Error(Err::Position(ErrorCode::Digit as u32, input))
      }
    }
    IResult::Error(error)          => IResult::Error(error),
    IResult::Incomplete(need)      => IResult::Incomplete(need),
  }
}

named!(pub footer <&[u8], Footer>, map!(be_u16, Footer));

#[cfg(test)]
mod tests {
  use super::*;
  use frame::{
    Header, Footer,
    ChannelAssignment, NumberType,
  };
  use metadata::StreamInfo;
  use nom::IResult;

  #[test]
  fn test_header() {
    let inputs   = [ &b"\xff\xf8\x53\x1c\xf0\x90\x80\x80\x2e"[..]
                   , &b"\xff\xf9\x7c\xa0\xfe\xbf\xbf\xbf\xbf\xbf\xbc\x01\xff\
                        \x01\x88"[..]
                   , &b"\xff\xf8\xc8\x72\x40\x19"[..]
                   ];
    let mut info = StreamInfo::new();
    let results  = [ IResult::Done(&[][..], Header {
                      block_size: 4608,
                      sample_rate: 192000,
                      channels: 2,
                      channel_assignment: ChannelAssignment::Independent,
                      bits_per_sample: 24,
                      number: NumberType::Frame(65536),
                      crc: 0x2e,
                    })
                  , IResult::Done(&[][..], Header {
                      block_size: 512,
                      sample_rate: 1000,
                      channels: 2,
                      channel_assignment: ChannelAssignment::MiddleSide,
                      bits_per_sample: 16,
                      number: NumberType::Sample(68719476732),
                      crc: 0x88,
                    })
                  , IResult::Done(&[][..], Header {
                      block_size: 4096,
                      sample_rate: 32000,
                      channels: 8,
                      channel_assignment: ChannelAssignment::Independent,
                      bits_per_sample: 8,
                      number: NumberType::Frame(64),
                      crc: 0x19,
                    })
                  ];

    info.bits_per_sample = 16;

    assert_eq!(header(inputs[0], &info), results[0]);
    assert_eq!(header(inputs[1], &info), results[1]);
    assert_eq!(header(inputs[2], &info), results[2]);
  }

  #[test]
  fn test_footer() {
    let input  = b"\x03\xe8";
    let result = IResult::Done(&[][..], Footer(0x03e8));

    assert_eq!(footer(input), result);
  }
}
<commit_msg>Make `blocking_strategy` parser public for testing<commit_after>use nom::{
  be_u8, be_u16,
  IResult,
  ErrorCode, Err,
};

use frame::{
  ChannelAssignment, NumberType,
  Frame,
  Header, Footer,
};

use metadata::StreamInfo;
use utility::{crc8, crc16, to_u32};

pub fn frame_parser<'a>(input: &'a [u8], stream_info: &StreamInfo)
                        -> IResult<'a, &'a [u8], Frame> {
  let result = chain!(input,
    frame_header: apply!(header, stream_info) ~
    frame_footer: footer,
    || {
      Frame {
        header: frame_header,
        footer: frame_footer,
      }
    }
  );

  match result {
    IResult::Done(i, frame)   => {
      // All frame bytes before the crc-16
      let end         = (input.len() - i.len()) - 2;
      let Footer(crc) = frame.footer;

      if crc16(&input[0..end]) == crc {
        IResult::Done(i, frame)
      } else {
        IResult::Error(Err::Position(ErrorCode::Digit as u32, input))
      }
    }
    IResult::Error(error)     => IResult::Error(error),
    IResult::Incomplete(need) => IResult::Incomplete(need),
  }
}

pub fn blocking_strategy(input: &[u8]) -> IResult<&[u8], bool> {
  match take!(input, 2) {
    IResult::Done(i, bytes)   => {
      let sync_code = ((bytes[0] as u16) << 6) +
                      ((bytes[1] as u16) >> 2);
      let is_valid  = ((bytes[1] >> 1) & 0b01) == 0;

      if sync_code == 0b11111111111110 && is_valid {
        let is_variable_block_size = (bytes[1] & 0b01) == 1;

        IResult::Done(i, is_variable_block_size)
      } else {
        IResult::Error(Err::Position(ErrorCode::Digit as u32, input))
      }
    }
    IResult::Error(error)     => IResult::Error(error),
    IResult::Incomplete(need) => IResult::Incomplete(need),
  }
}

fn block_sample(input: &[u8]) -> IResult<&[u8], (u8, u8)> {
  match be_u8(input) {
    IResult::Done(i, byte)    => {
      let block_byte  = byte >> 4;
      let sample_byte = byte & 0x0f;
      let is_valid    = block_byte != 0b0000 && sample_byte != 0b1111;

      if is_valid {
        IResult::Done(i, (block_byte, sample_byte))
      } else {
        IResult::Error(Err::Position(ErrorCode::Digit as u32, input))
      }
    }
    IResult::Error(error)     => IResult::Error(error),
    IResult::Incomplete(need) => IResult::Incomplete(need),
  }
}

fn channel_bits(input: &[u8]) -> IResult<&[u8], (ChannelAssignment, u8, u8)> {
  match be_u8(input) {
    IResult::Done(i, byte)    => {
      let mut channels       = 2;
      let channel_byte       = byte >> 4;
      let channel_assignment = match channel_byte {
        0b0000...0b0111 => {
          channels = channel_byte + 1;

          ChannelAssignment::Independent
        }
        0b1000          => ChannelAssignment::LeftSide,
        0b1001          => ChannelAssignment::RightSide,
        0b1010          => ChannelAssignment::MiddleSide,
        _               => ChannelAssignment::Independent,
      };
      let size_byte = (byte >> 1) & 0b0111;

      // Checks the validity of:
      //
      // * (4 bits) channel assignment
      // * (3 bits) sample size
      // * (1 bit) last bit
      //
      // All these checks are whether of not they are reserved and should
      // return an error if so.
      let is_valid = channel_byte < 0b1011 &&
                     (size_byte != 0b0011 && size_byte != 0b0111) &&
                     (byte & 0b01) == 0;

      if is_valid {
        IResult::Done(i, (channel_assignment, channels, size_byte))
      } else {
        IResult::Error(Err::Position(ErrorCode::Digit as u32, input))
      }
    }
    IResult::Error(error)     => IResult::Error(error),
    IResult::Incomplete(need) => IResult::Incomplete(need),
  }
}

fn utf8_size(input: &[u8], is_u64: bool)
             -> IResult<&[u8], Option<(usize, u8)>> {
  map!(input, be_u8, |utf8_header| {
    match utf8_header {
      0b00000000...0b01111111 => Some((0, utf8_header)),
      0b11000000...0b11011111 => Some((1, utf8_header & 0b00011111)),
      0b11100000...0b11101111 => Some((2, utf8_header & 0b00001111)),
      0b11110000...0b11110111 => Some((3, utf8_header & 0b00000111)),
      0b11111000...0b11111011 => Some((4, utf8_header & 0b00000011)),
      0b11111100...0b11111101 => Some((5, utf8_header & 0b00000001)),
      0b11111110              => if is_u64 { Some((6, 0)) } else { None },
      _                       => None,
    }
  })
}

fn number_type(input: &[u8], is_sample: bool,
               (size, value): (usize, u8))
               -> IResult<&[u8], NumberType> {
  let mut result   = value as u64;
  let mut is_error = false;

  match take!(input, size) {
    IResult::Done(i, bytes)   => {
      for i in 0..size {
        let byte = bytes[i] as u64;

        if byte >= 0b10000000 && byte <= 0b10111111 {
          result = (result << 6) + (byte & 0b00111111);
        } else {
          is_error = true;
          break;
        }
      }

      if is_error {
        IResult::Error(Err::Position(ErrorCode::Digit as u32, input))
      } else if is_sample {
        IResult::Done(i, NumberType::Sample(result))
      } else {
        IResult::Done(i, NumberType::Frame(result as u32))
      }
    }
    IResult::Error(error)     => IResult::Error(error),
    IResult::Incomplete(need) => IResult::Incomplete(need),
  }
}

fn secondary_block_size(input: &[u8], block_byte: u8)
                        -> IResult<&[u8], Option<u32>> {
  match block_byte {
    0b0110 => opt!(input, map!(take!(1), to_u32)),
    0b0111 => opt!(input, map!(take!(2), to_u32)),
    _      => IResult::Done(input, None)
  }
}

fn secondary_sample_rate(input: &[u8], sample_byte: u8)
                        -> IResult<&[u8], Option<u32>> {
  match sample_byte {
    0b1100          => opt!(input, map!(take!(1), to_u32)),
    0b1101 | 0b1110 => opt!(input, map!(take!(2), to_u32)),
    _               => IResult::Done(input, None)
  }
}

pub fn header<'a>(input: &'a [u8], stream_info: &StreamInfo)
                  -> IResult<'a, &'a [u8], Header> {
  let result = chain!(input,
    is_variable_block_size: blocking_strategy ~
    tuple0: block_sample ~
    tuple1: channel_bits ~
    number_opt: apply!(utf8_size, is_variable_block_size) ~
    number_length: expr_opt!(number_opt) ~
    number: apply!(number_type, is_variable_block_size, number_length) ~
    alt_block_size: apply!(secondary_block_size, tuple0.0) ~
    alt_sample_rate: apply!(secondary_sample_rate, tuple0.1) ~
    crc: be_u8,
    || {
      let (block_byte, sample_byte)                 = tuple0;
      let (channel_assignment, channels, size_byte) = tuple1;

      let block_size = match block_byte {
        0b0001          => 192,
        0b0010...0b0101 => 576 * 2_u32.pow(block_byte as u32 - 2),
        0b0110 | 0b0111 => alt_block_size.unwrap() + 1,
        0b1000...0b1111 => 256 * 2_u32.pow(block_byte as u32 - 8),
        _               => unreachable!(),
      };

      let sample_rate = match sample_byte {
        0b0000 => stream_info.sample_rate,
        0b0001 => 88200,
        0b0010 => 176400,
        0b0011 => 192000,
        0b0100 => 8000,
        0b0101 => 16000,
        0b0110 => 22050,
        0b0111 => 24000,
        0b1000 => 32000,
        0b1001 => 44100,
        0b1010 => 48000,
        0b1011 => 96000,
        0b1100 => alt_sample_rate.unwrap() * 1000,
        0b1101 => alt_sample_rate.unwrap(),
        0b1110 => alt_sample_rate.unwrap() * 10,
        _      => unreachable!(),
      };

      let bits_per_sample = match size_byte {
        0b0000 => stream_info.bits_per_sample as usize,
        0b0001 => 8,
        0b0010 => 12,
        0b0100 => 16,
        0b0101 => 20,
        0b0110 => 24,
        _      => unreachable!(),
      };

      Header {
        block_size: block_size,
        sample_rate: sample_rate,
        channels: channels,
        channel_assignment: channel_assignment,
        bits_per_sample: bits_per_sample,
        number: number,
        crc: crc,
      }
    }
  );

  match result {
    IResult::Done(i, frame_header) => {
      // All header bytes before the crc-8
      let end = (input.len() - i.len()) - 1;

      if crc8(&input[0..end]) == frame_header.crc {
        IResult::Done(i, frame_header)
      } else {
        IResult::Error(Err::Position(ErrorCode::Digit as u32, input))
      }
    }
    IResult::Error(error)          => IResult::Error(error),
    IResult::Incomplete(need)      => IResult::Incomplete(need),
  }
}

named!(pub footer <&[u8], Footer>, map!(be_u16, Footer));

#[cfg(test)]
mod tests {
  use super::*;
  use frame::{
    Header, Footer,
    ChannelAssignment, NumberType,
  };
  use metadata::StreamInfo;
  use nom::IResult;

  #[test]
  fn test_header() {
    let inputs   = [ &b"\xff\xf8\x53\x1c\xf0\x90\x80\x80\x2e"[..]
                   , &b"\xff\xf9\x7c\xa0\xfe\xbf\xbf\xbf\xbf\xbf\xbc\x01\xff\
                        \x01\x88"[..]
                   , &b"\xff\xf8\xc8\x72\x40\x19"[..]
                   ];
    let mut info = StreamInfo::new();
    let results  = [ IResult::Done(&[][..], Header {
                      block_size: 4608,
                      sample_rate: 192000,
                      channels: 2,
                      channel_assignment: ChannelAssignment::Independent,
                      bits_per_sample: 24,
                      number: NumberType::Frame(65536),
                      crc: 0x2e,
                    })
                  , IResult::Done(&[][..], Header {
                      block_size: 512,
                      sample_rate: 1000,
                      channels: 2,
                      channel_assignment: ChannelAssignment::MiddleSide,
                      bits_per_sample: 16,
                      number: NumberType::Sample(68719476732),
                      crc: 0x88,
                    })
                  , IResult::Done(&[][..], Header {
                      block_size: 4096,
                      sample_rate: 32000,
                      channels: 8,
                      channel_assignment: ChannelAssignment::Independent,
                      bits_per_sample: 8,
                      number: NumberType::Frame(64),
                      crc: 0x19,
                    })
                  ];

    info.bits_per_sample = 16;

    assert_eq!(header(inputs[0], &info), results[0]);
    assert_eq!(header(inputs[1], &info), results[1]);
    assert_eq!(header(inputs[2], &info), results[2]);
  }

  #[test]
  fn test_footer() {
    let input  = b"\x03\xe8";
    let result = IResult::Done(&[][..], Footer(0x03e8));

    assert_eq!(footer(input), result);
  }
}
<|endoftext|>


<commit_before>// FIXME: Most of these should be uints.

const int rc_base_field_refcnt = 0;

// FIXME: import from std::dbg when imported consts work.
const uint const_refcount = 0x7bad_face_u;

const int task_field_refcnt = 0;
const int task_field_stk = 2;
const int task_field_runtime_sp = 3;
const int task_field_rust_sp = 4;
const int task_field_gc_alloc_chain = 5;
const int task_field_dom = 6;
const int n_visible_task_fields = 7;

const int dom_field_interrupt_flag = 1;

const int frame_glue_fns_field_mark = 0;
const int frame_glue_fns_field_drop = 1;
const int frame_glue_fns_field_reloc = 2;

const int box_rc_field_refcnt = 0;
const int box_rc_field_body = 1;

const int general_code_alignment = 16;

const int vec_elt_rc = 0;
const int vec_elt_alloc = 1;
const int vec_elt_fill = 2;
const int vec_elt_pad = 3;
const int vec_elt_data = 4;

const int tydesc_field_first_param = 0;
const int tydesc_field_size = 1;
const int tydesc_field_align = 2;
const int tydesc_field_take_glue = 3;
const int tydesc_field_drop_glue = 4;
const int tydesc_field_free_glue = 5;
const int tydesc_field_sever_glue = 6;
const int tydesc_field_mark_glue = 7;
// FIXME no longer used in rustc, drop when rustboot is gone
const int tydesc_field_obj_drop_glue = 8;
const int tydesc_field_is_stateful = 9;
const int tydesc_field_cmp_glue = 10;
const int n_tydesc_fields = 11;

const uint cmp_glue_op_eq = 0u;
const uint cmp_glue_op_lt = 1u;
const uint cmp_glue_op_le = 2u;

const int obj_field_vtbl = 0;
const int obj_field_box = 1;

const int obj_body_elt_tydesc = 0;
const int obj_body_elt_typarams = 1;
const int obj_body_elt_fields = 2;
const int obj_body_elt_with_obj = 3; /* The base object to which an anonymous
                                      * object is attached */

const int fn_field_code = 0;
const int fn_field_box = 1;

const int closure_elt_tydesc = 0;
const int closure_elt_target = 1;
const int closure_elt_bindings = 2;
const int closure_elt_ty_params = 3;

const uint ivec_default_size = 16u;

const uint ivec_elt_len = 0u;
const uint ivec_elt_alen = 1u;
const uint ivec_elt_elems = 2u;
const uint ivec_heap_stub_elt_zero = 0u;
const uint ivec_heap_stub_elt_alen = 1u;
const uint ivec_heap_stub_elt_ptr = 2u;
const uint ivec_heap_elt_len = 0u;
const uint ivec_heap_elt_elems = 1u;

const int worst_case_glue_call_args = 7;

fn memcpy_glue_name() -> str {
    ret "rust_memcpy_glue";
}

fn bzero_glue_name() -> str {
    ret "rust_bzero_glue";
}

fn vec_append_glue_name() -> str {
    ret "rust_vec_append_glue";
}

fn yield_glue_name() -> str {
    ret "rust_yield_glue";
}

fn no_op_type_glue_name() -> str {
    ret "rust_no_op_type_glue";
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<commit_msg>rustc: Bump the default interior vector size up to 64 bytes<commit_after>// FIXME: Most of these should be uints.

const int rc_base_field_refcnt = 0;

// FIXME: import from std::dbg when imported consts work.
const uint const_refcount = 0x7bad_face_u;

const int task_field_refcnt = 0;
const int task_field_stk = 2;
const int task_field_runtime_sp = 3;
const int task_field_rust_sp = 4;
const int task_field_gc_alloc_chain = 5;
const int task_field_dom = 6;
const int n_visible_task_fields = 7;

const int dom_field_interrupt_flag = 1;

const int frame_glue_fns_field_mark = 0;
const int frame_glue_fns_field_drop = 1;
const int frame_glue_fns_field_reloc = 2;

const int box_rc_field_refcnt = 0;
const int box_rc_field_body = 1;

const int general_code_alignment = 16;

const int vec_elt_rc = 0;
const int vec_elt_alloc = 1;
const int vec_elt_fill = 2;
const int vec_elt_pad = 3;
const int vec_elt_data = 4;

const int tydesc_field_first_param = 0;
const int tydesc_field_size = 1;
const int tydesc_field_align = 2;
const int tydesc_field_take_glue = 3;
const int tydesc_field_drop_glue = 4;
const int tydesc_field_free_glue = 5;
const int tydesc_field_sever_glue = 6;
const int tydesc_field_mark_glue = 7;
// FIXME no longer used in rustc, drop when rustboot is gone
const int tydesc_field_obj_drop_glue = 8;
const int tydesc_field_is_stateful = 9;
const int tydesc_field_cmp_glue = 10;
const int n_tydesc_fields = 11;

const uint cmp_glue_op_eq = 0u;
const uint cmp_glue_op_lt = 1u;
const uint cmp_glue_op_le = 2u;

const int obj_field_vtbl = 0;
const int obj_field_box = 1;

const int obj_body_elt_tydesc = 0;
const int obj_body_elt_typarams = 1;
const int obj_body_elt_fields = 2;
const int obj_body_elt_with_obj = 3; /* The base object to which an anonymous
                                      * object is attached */

const int fn_field_code = 0;
const int fn_field_box = 1;

const int closure_elt_tydesc = 0;
const int closure_elt_target = 1;
const int closure_elt_bindings = 2;
const int closure_elt_ty_params = 3;

const uint ivec_default_size = 64u;

const uint ivec_elt_len = 0u;
const uint ivec_elt_alen = 1u;
const uint ivec_elt_elems = 2u;
const uint ivec_heap_stub_elt_zero = 0u;
const uint ivec_heap_stub_elt_alen = 1u;
const uint ivec_heap_stub_elt_ptr = 2u;
const uint ivec_heap_elt_len = 0u;
const uint ivec_heap_elt_elems = 1u;

const int worst_case_glue_call_args = 7;

fn memcpy_glue_name() -> str {
    ret "rust_memcpy_glue";
}

fn bzero_glue_name() -> str {
    ret "rust_bzero_glue";
}

fn vec_append_glue_name() -> str {
    ret "rust_vec_append_glue";
}

fn yield_glue_name() -> str {
    ret "rust_yield_glue";
}

fn no_op_type_glue_name() -> str {
    ret "rust_no_op_type_glue";
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<|endoftext|>


<commit_before>use geom::{Rect, Tri};
use math::{self, BaseNum, Point2};
use math::num_traits::{Float, NumCast};
use std;
use std::ops::Neg;

/// A simple ellipse type with helper methods around the `ellipse` module's functions.
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
pub struct Ellipse<S = f64> {
    /// The width and height off the `Ellipse`.
    pub rect: Rect<S>,
    /// The resolution (number of sides) of the `Ellipse`.
    pub resolution: usize,
}

/// A subsection of an `Ellipse`.
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
pub struct Section<S = f64> {
    /// The ellipse from which this section is produced.
    pub ellipse: Ellipse<S>,
    /// The angle in radians of the start of the section.
    pub offset_radians: S,
    /// The section of the circumference in radians.
    pub section_radians: S,
}

/// An iterator yielding the edges of an ellipse (or some section of an `ellipse`) as a series of
/// points.
#[derive(Clone, Debug)]
#[allow(missing_copy_implementations)]
pub struct Circumference<S = f64> {
    index: usize,
    num_points: usize,
    point: Point2<S>,
    rad_step: S,
    rad_offset: S,
    half_w: S,
    half_h: S,
}

/// An iterator yielding triangles that describe an oval or some section of an oval.
#[derive(Clone, Debug)]
pub struct Triangles<S> {
    // The last circumference point yielded by the `CircumferenceOffset` iterator.
    last: Point2<S>,
    // The circumference points used to yield yielded by the `CircumferenceOffset` iterator.
    points: Circumference<S>,
}

impl<S> Ellipse<S>
where
    S: BaseNum + Neg<Output=S>,
{
    /// Construct a new ellipse from its bounding rect and resolution (number of sides).
    pub fn new(rect: Rect<S>, resolution: usize) -> Self {
        Ellipse { rect, resolution }
    }

    /// A section of the `Ellipse`.
    ///
    /// `offset_radians` describes the angle at which the offset begins.
    ///
    /// `section_radians` describes how large the section is as an angle.
    pub fn section(self, offset_radians: S, section_radians: S) -> Section<S> {
        Section {
            ellipse: self,
            offset_radians,
            section_radians,
        }
    }

    /// Produces an iterator yielding the points of the ellipse circumference.
    pub fn circumference(self) -> Circumference<S> {
        let Ellipse { rect, resolution } = self;
        Circumference::new(rect, resolution)
    }

    /// Produces an iterator yielding the triangles that describe the ellipse.
    ///
    /// TODO: Describe the order.
    pub fn triangles(self) -> Triangles<S>
    where
        S: Float,
    {
        self.circumference().triangles()
    }
}

impl<S> Section<S>
where
    S: BaseNum + Neg<Output=S>,
{
    /// Produces an iterator yielding the points of the ellipse circumference.
    pub fn circumference(self) -> Circumference<S> {
        let Section { ellipse, offset_radians, section_radians } = self;
        let circ = Circumference::new_section(ellipse.rect, ellipse.resolution, section_radians);
        circ.offset_radians(offset_radians)
    }

    /// Produces an iterator yielding the triangles that describe the ellipse section.
    ///
    /// TODO: Describe the order.
    pub fn trangles(self) -> Triangles<S>
    where
        S: Float,
    {
        self.circumference().triangles()
    }
}

impl<S> Circumference<S>
where
    S: BaseNum + Neg<Output=S>,
{
    fn new_inner(rect: Rect<S>, num_points: usize, rad_step: S) -> Self {
        let (x, y, w, h) = rect.x_y_w_h();
        let two = math::two();
        Circumference {
            index: 0,
            num_points: num_points,
            point: [x, y].into(),
            half_w: w / two,
            half_h: h / two,
            rad_step: rad_step,
            rad_offset: S::zero(),
        }
    }

    /// An iterator yielding the ellipse's edges as a circumference represented as a series of
    /// points.
    ///
    /// `resolution` is clamped to a minimum of `1` as to avoid creating a `Circumference` that
    /// produces `NaN` values.
    pub fn new(rect: Rect<S>, mut resolution: usize) -> Self {
        resolution = std::cmp::max(resolution, 1);
        use std::f64::consts::PI;
        let radians = S::from(2.0 * PI).unwrap();
        Self::new_section(rect, resolution, radians)
    }

    /// Produces a new iterator that yields only a section of the ellipse's circumference, where
    /// the section is described via its angle in radians.
    ///
    /// `resolution` is clamped to a minimum of `1` as to avoid creating a `Circumference` that
    /// produces `NaN` values.
    pub fn new_section(rect: Rect<S>, resolution: usize, radians: S) -> Self
    where
        S: BaseNum,
    {
        let res = S::from(resolution).unwrap();
        Self::new_inner(rect, resolution + 1, radians / res)
    }

    /// Produces a new iterator that yields only a section of the ellipse's circumference, where
    /// the section is described via its angle in radians.
    pub fn section(mut self, radians: S) -> Self {
        let resolution = self.num_points - 1;
        let res = S::from(resolution).unwrap();
        self.rad_step = radians / res;
        self
    }

    /// Rotates the position at which the iterator starts yielding points by the given radians.
    ///
    /// This is particularly useful for yielding a different section of the circumference when
    /// using `circumference_section`
    pub fn offset_radians(mut self, radians: S) -> Self {
        self.rad_offset = radians;
        self
    }

    /// Produces an `Iterator` yielding `Triangle`s.
    ///
    /// Triangles are created by joining each edge yielded by the inner `Circumference` to the
    /// middle of the ellipse.
    pub fn triangles(mut self) -> Triangles<S>
    where
        S: Float,
    {
        let last = self.next().unwrap_or(self.point);
        Triangles { last, points: self }
    }
}

impl<S> Iterator for Circumference<S>
where
    S: BaseNum + Float,
{
    type Item = Point2<S>;
    fn next(&mut self) -> Option<Self::Item> {
        let Circumference {
            ref mut index,
            num_points,
            point,
            rad_step,
            rad_offset,
            half_w,
            half_h,
        } = *self;
        if *index >= num_points {
            return None;
        }
        let index_s: S = NumCast::from(*index).unwrap();
        let x = point.x + half_w * (rad_offset + rad_step * index_s).cos();
        let y = point.y + half_h * (rad_offset + rad_step * index_s).sin();
        *index += 1;
        Some([x, y].into())
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = self.len();
        (len, Some(len))
    }
}

// TODO:
// impl<S> DoubleEndedIterator for Circumference<S>
// where
//     S: BaseNum + Float,
// {
// }

impl<S> ExactSizeIterator for Circumference<S>
where
    S: BaseNum + Float,
{
    fn len(&self) -> usize {
        self.num_points - self.index
    }
}

impl<S> Iterator for Triangles<S>
where
    S: BaseNum + Float,
{
    type Item = Tri<Point2<S>>;
    fn next(&mut self) -> Option<Self::Item> {
        let Triangles { ref mut points, ref mut last } = *self;
        points.next().map(|next| {
            let triangle = Tri([points.point, *last, next]);
            *last = next;
            triangle
        })
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = self.len();
        (len, Some(len))
    }
}

impl<S> ExactSizeIterator for Triangles<S>
where
    S: BaseNum + Float,
{
    fn len(&self) -> usize {
        self.points.len()
    }
}
<commit_msg>Rename ellipse::Circumference point field to middle for clarity<commit_after>use geom::{Rect, Tri};
use math::{self, BaseNum, Point2};
use math::num_traits::{Float, NumCast};
use std;
use std::ops::Neg;

/// A simple ellipse type with helper methods around the `ellipse` module's functions.
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
pub struct Ellipse<S = f64> {
    /// The width and height off the `Ellipse`.
    pub rect: Rect<S>,
    /// The resolution (number of sides) of the `Ellipse`.
    pub resolution: usize,
}

/// A subsection of an `Ellipse`.
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
pub struct Section<S = f64> {
    /// The ellipse from which this section is produced.
    pub ellipse: Ellipse<S>,
    /// The angle in radians of the start of the section.
    pub offset_radians: S,
    /// The section of the circumference in radians.
    pub section_radians: S,
}

/// An iterator yielding the edges of an ellipse (or some section of an `ellipse`) as a series of
/// points.
#[derive(Clone, Debug)]
#[allow(missing_copy_implementations)]
pub struct Circumference<S = f64> {
    index: usize,
    num_points: usize,
    middle: Point2<S>,
    rad_step: S,
    rad_offset: S,
    half_w: S,
    half_h: S,
}

/// An iterator yielding triangles that describe an oval or some section of an oval.
#[derive(Clone, Debug)]
pub struct Triangles<S> {
    // The last circumference point yielded by the `CircumferenceOffset` iterator.
    last: Point2<S>,
    // The circumference points used to yield yielded by the `CircumferenceOffset` iterator.
    points: Circumference<S>,
}

impl<S> Ellipse<S>
where
    S: BaseNum + Neg<Output=S>,
{
    /// Construct a new ellipse from its bounding rect and resolution (number of sides).
    pub fn new(rect: Rect<S>, resolution: usize) -> Self {
        Ellipse { rect, resolution }
    }

    /// A section of the `Ellipse`.
    ///
    /// `offset_radians` describes the angle at which the offset begins.
    ///
    /// `section_radians` describes how large the section is as an angle.
    pub fn section(self, offset_radians: S, section_radians: S) -> Section<S> {
        Section {
            ellipse: self,
            offset_radians,
            section_radians,
        }
    }

    /// Produces an iterator yielding the points of the ellipse circumference.
    pub fn circumference(self) -> Circumference<S> {
        let Ellipse { rect, resolution } = self;
        Circumference::new(rect, resolution)
    }

    /// Produces an iterator yielding the triangles that describe the ellipse.
    ///
    /// TODO: Describe the order.
    pub fn triangles(self) -> Triangles<S>
    where
        S: Float,
    {
        self.circumference().triangles()
    }
}

impl<S> Section<S>
where
    S: BaseNum + Neg<Output=S>,
{
    /// Produces an iterator yielding the points of the ellipse circumference.
    pub fn circumference(self) -> Circumference<S> {
        let Section { ellipse, offset_radians, section_radians } = self;
        let circ = Circumference::new_section(ellipse.rect, ellipse.resolution, section_radians);
        circ.offset_radians(offset_radians)
    }

    /// Produces an iterator yielding the triangles that describe the ellipse section.
    ///
    /// TODO: Describe the order.
    pub fn trangles(self) -> Triangles<S>
    where
        S: Float,
    {
        self.circumference().triangles()
    }
}

impl<S> Circumference<S>
where
    S: BaseNum + Neg<Output=S>,
{
    fn new_inner(rect: Rect<S>, num_points: usize, rad_step: S) -> Self {
        let (x, y, w, h) = rect.x_y_w_h();
        let two = math::two();
        Circumference {
            index: 0,
            num_points: num_points,
            middle: [x, y].into(),
            half_w: w / two,
            half_h: h / two,
            rad_step: rad_step,
            rad_offset: S::zero(),
        }
    }

    /// An iterator yielding the ellipse's edges as a circumference represented as a series of
    /// points.
    ///
    /// `resolution` is clamped to a minimum of `1` as to avoid creating a `Circumference` that
    /// produces `NaN` values.
    pub fn new(rect: Rect<S>, mut resolution: usize) -> Self {
        resolution = std::cmp::max(resolution, 1);
        use std::f64::consts::PI;
        let radians = S::from(2.0 * PI).unwrap();
        Self::new_section(rect, resolution, radians)
    }

    /// Produces a new iterator that yields only a section of the ellipse's circumference, where
    /// the section is described via its angle in radians.
    ///
    /// `resolution` is clamped to a minimum of `1` as to avoid creating a `Circumference` that
    /// produces `NaN` values.
    pub fn new_section(rect: Rect<S>, resolution: usize, radians: S) -> Self
    where
        S: BaseNum,
    {
        let res = S::from(resolution).unwrap();
        Self::new_inner(rect, resolution + 1, radians / res)
    }

    /// Produces a new iterator that yields only a section of the ellipse's circumference, where
    /// the section is described via its angle in radians.
    pub fn section(mut self, radians: S) -> Self {
        let resolution = self.num_points - 1;
        let res = S::from(resolution).unwrap();
        self.rad_step = radians / res;
        self
    }

    /// Rotates the position at which the iterator starts yielding points by the given radians.
    ///
    /// This is particularly useful for yielding a different section of the circumference when
    /// using `circumference_section`
    pub fn offset_radians(mut self, radians: S) -> Self {
        self.rad_offset = radians;
        self
    }

    /// Produces an `Iterator` yielding `Triangle`s.
    ///
    /// Triangles are created by joining each edge yielded by the inner `Circumference` to the
    /// middle of the ellipse.
    pub fn triangles(mut self) -> Triangles<S>
    where
        S: Float,
    {
        let last = self.next().unwrap_or(self.middle);
        Triangles { last, points: self }
    }
}

impl<S> Iterator for Circumference<S>
where
    S: BaseNum + Float,
{
    type Item = Point2<S>;
    fn next(&mut self) -> Option<Self::Item> {
        let Circumference {
            ref mut index,
            num_points,
            middle,
            rad_step,
            rad_offset,
            half_w,
            half_h,
        } = *self;
        if *index >= num_points {
            return None;
        }
        let index_s: S = NumCast::from(*index).unwrap();
        let x = middle.x + half_w * (rad_offset + rad_step * index_s).cos();
        let y = middle.y + half_h * (rad_offset + rad_step * index_s).sin();
        *index += 1;
        Some([x, y].into())
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = self.len();
        (len, Some(len))
    }
}

// TODO:
// impl<S> DoubleEndedIterator for Circumference<S>
// where
//     S: BaseNum + Float,
// {
// }

impl<S> ExactSizeIterator for Circumference<S>
where
    S: BaseNum + Float,
{
    fn len(&self) -> usize {
        self.num_points - self.index
    }
}

impl<S> Iterator for Triangles<S>
where
    S: BaseNum + Float,
{
    type Item = Tri<Point2<S>>;
    fn next(&mut self) -> Option<Self::Item> {
        let Triangles { ref mut points, ref mut last } = *self;
        points.next().map(|next| {
            let triangle = Tri([points.middle, *last, next]);
            *last = next;
            triangle
        })
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = self.len();
        (len, Some(len))
    }
}

impl<S> ExactSizeIterator for Triangles<S>
where
    S: BaseNum + Float,
{
    fn len(&self) -> usize {
        self.points.len()
    }
}
<|endoftext|>


<commit_before>use uuid::Uuid;
use std::rc::Rc;
use std::time::Duration;

use message::MessageBuilder;
use timer::TimerEvent;
use context::LinearContext;
use conditions::ConditionsBuilder;

#[test]
fn test_given_close_condition_with_timeout_when_the_timeout_expires_then_the_condition_is_met() {
    let timeout = Duration::from_millis(100);
    let msg_id = "11eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
    let patterns = vec![
        msg_id.clone(),
    ];
    let mut context = LinearContext::new(Uuid::new_v4(),
                                         ConditionsBuilder::new(timeout)
                                             .patterns(patterns)
                                             .build());
    let msg1 = MessageBuilder::new(&msg_id, "message").build();
    let event = Rc::new(msg1);
    assert_false!(context.is_open());
    context.on_message(event);
    assert_true!(context.is_open());
    context.on_timer(&mut TimerEvent(50));
    assert_true!(context.is_open());
    context.on_timer(&mut TimerEvent(49));
    assert_true!(context.is_open());
    context.on_timer(&mut TimerEvent(1));
    assert_false!(context.is_open());
}

#[test]
fn test_given_close_condition_with_max_size_when_the_max_size_reached_then_the_condition_is_met
                                                                                () {
    let timeout = Duration::from_millis(100);
    let max_size = 3;
    let msg_id = "11eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
    let patterns = vec![
        msg_id.clone(),
    ];
    let mut context = LinearContext::new(Uuid::new_v4(),
                                         ConditionsBuilder::new(timeout)
                                             .max_size(max_size)
                                             .patterns(patterns)
                                             .build());
    let msg1 = MessageBuilder::new(&msg_id, "message").build();
    let event = Rc::new(msg1);
    context.on_message(event.clone());
    assert_true!(context.is_open());
    context.on_message(event.clone());
    assert_true!(context.is_open());
    context.on_message(event.clone());
    assert_false!(context.is_open());
}

#[test]
fn test_given_close_condition_with_renew_timeout_when_the_timeout_expires_without_renewing_messages_then_the_condition_is_met
    () {
    let timeout = Duration::from_millis(100);
    let renew_timeout = Duration::from_millis(10);
    let msg_id = "11eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
    let patterns = vec![
        msg_id.clone(),
    ];
    let mut context = LinearContext::new(Uuid::new_v4(),
                                         ConditionsBuilder::new(timeout)
                                             .renew_timeout(renew_timeout)
                                             .patterns(patterns)
                                             .build());
    let msg1 = MessageBuilder::new(&msg_id, "message").build();
    let event = Rc::new(msg1);
    context.on_message(event.clone());
    assert_true!(context.is_open());
    context.on_timer(&mut TimerEvent(8));
    assert_true!(context.is_open());
    context.on_timer(&mut TimerEvent(1));
    assert_true!(context.is_open());
    context.on_timer(&mut TimerEvent(1));
    assert_false!(context.is_open());
}

#[test]
fn test_given_close_condition_with_renew_timeout_when_the_timeout_expires_with_renewing_messages_then_the_context_is_not_closed
    () {
    let timeout = Duration::from_millis(100);
    let renew_timeout = Duration::from_millis(10);
    let msg_id = "11eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
    let patterns = vec![
        msg_id.clone(),
    ];
    let mut context = LinearContext::new(Uuid::new_v4(),
                                         ConditionsBuilder::new(timeout)
                                             .renew_timeout(renew_timeout)
                                             .patterns(patterns)
                                             .build());
    let msg1 = MessageBuilder::new(&msg_id, "message").build();
    let event = Rc::new(msg1);
    assert_false!(context.is_open());
    context.on_message(event.clone());
    assert_true!(context.is_open());
    context.on_timer(&mut TimerEvent(8));
    assert_true!(context.is_open());
    context.on_timer(&mut TimerEvent(1));
    assert_true!(context.is_open());
    context.on_message(event.clone());
    assert_true!(context.is_open());
    context.on_timer(&mut TimerEvent(1));
    assert_true!(context.is_open());
}
<commit_msg>tests: use TimerEvent::from_millis() method<commit_after>use uuid::Uuid;
use std::rc::Rc;
use std::time::Duration;

use message::MessageBuilder;
use timer::TimerEvent;
use context::LinearContext;
use conditions::ConditionsBuilder;

#[test]
fn test_given_close_condition_with_timeout_when_the_timeout_expires_then_the_condition_is_met() {
    let timeout = Duration::from_millis(100);
    let msg_id = "11eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
    let patterns = vec![
        msg_id.clone(),
    ];
    let mut context = LinearContext::new(Uuid::new_v4(),
                                         ConditionsBuilder::new(timeout)
                                             .patterns(patterns)
                                             .build());
    let msg1 = MessageBuilder::new(&msg_id, "message").build();
    let event = Rc::new(msg1);
    assert_false!(context.is_open());
    context.on_message(event);
    assert_true!(context.is_open());
    context.on_timer(&mut TimerEvent::from_millis(50));
    assert_true!(context.is_open());
    context.on_timer(&mut TimerEvent::from_millis(49));
    assert_true!(context.is_open());
    context.on_timer(&mut TimerEvent::from_millis(1));
    assert_false!(context.is_open());
}

#[test]
fn test_given_close_condition_with_max_size_when_the_max_size_reached_then_the_condition_is_met
                                                                                () {
    let timeout = Duration::from_millis(100);
    let max_size = 3;
    let msg_id = "11eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
    let patterns = vec![
        msg_id.clone(),
    ];
    let mut context = LinearContext::new(Uuid::new_v4(),
                                         ConditionsBuilder::new(timeout)
                                             .max_size(max_size)
                                             .patterns(patterns)
                                             .build());
    let msg1 = MessageBuilder::new(&msg_id, "message").build();
    let event = Rc::new(msg1);
    context.on_message(event.clone());
    assert_true!(context.is_open());
    context.on_message(event.clone());
    assert_true!(context.is_open());
    context.on_message(event.clone());
    assert_false!(context.is_open());
}

#[test]
fn test_given_close_condition_with_renew_timeout_when_the_timeout_expires_without_renewing_messages_then_the_condition_is_met
    () {
    let timeout = Duration::from_millis(100);
    let renew_timeout = Duration::from_millis(10);
    let msg_id = "11eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
    let patterns = vec![
        msg_id.clone(),
    ];
    let mut context = LinearContext::new(Uuid::new_v4(),
                                         ConditionsBuilder::new(timeout)
                                             .renew_timeout(renew_timeout)
                                             .patterns(patterns)
                                             .build());
    let msg1 = MessageBuilder::new(&msg_id, "message").build();
    let event = Rc::new(msg1);
    context.on_message(event.clone());
    assert_true!(context.is_open());
    context.on_timer(&mut TimerEvent::from_millis(8));
    assert_true!(context.is_open());
    context.on_timer(&mut TimerEvent::from_millis(1));
    assert_true!(context.is_open());
    context.on_timer(&mut TimerEvent::from_millis(1));
    assert_false!(context.is_open());
}

#[test]
fn test_given_close_condition_with_renew_timeout_when_the_timeout_expires_with_renewing_messages_then_the_context_is_not_closed
    () {
    let timeout = Duration::from_millis(100);
    let renew_timeout = Duration::from_millis(10);
    let msg_id = "11eaf6f8-0640-460f-aee2-a72d2f2ab258".to_string();
    let patterns = vec![
        msg_id.clone(),
    ];
    let mut context = LinearContext::new(Uuid::new_v4(),
                                         ConditionsBuilder::new(timeout)
                                             .renew_timeout(renew_timeout)
                                             .patterns(patterns)
                                             .build());
    let msg1 = MessageBuilder::new(&msg_id, "message").build();
    let event = Rc::new(msg1);
    assert_false!(context.is_open());
    context.on_message(event.clone());
    assert_true!(context.is_open());
    context.on_timer(&mut TimerEvent::from_millis(8));
    assert_true!(context.is_open());
    context.on_timer(&mut TimerEvent::from_millis(1));
    assert_true!(context.is_open());
    context.on_message(event.clone());
    assert_true!(context.is_open());
    context.on_timer(&mut TimerEvent::from_millis(1));
    assert_true!(context.is_open());
}
<|endoftext|>


<commit_before>
#![cfg(test)]

mod tests {

    use crypto::sha3::Sha3;

    use MerkleTree;
    use MerkleDigest;
    use Hashable;

    #[test]
    fn test_from_vec3() {
        let mut digest = Sha3::sha3_256();

        let values = vec![1, 2, 3];
        let hashes = vec![digest.hash_bytes(&1.to_bytes()), digest.hash_bytes(&2.to_bytes()), digest.hash_bytes(&3.to_bytes())];

        let tree   = MerkleTree::from_vec(digest, values);

        let root_hash = Sha3::sha3_256().combine_hashes(
            &Sha3::sha3_256().combine_hashes(&hashes[0], &hashes[1]),
            &Sha3::sha3_256().hash_bytes(&hashes[2])
        );

        assert_eq!(tree.count, 3);
        assert_eq!(tree.height, 2);
        assert_eq!(tree.root_hash().as_slice(), root_hash.as_slice());
    }

    #[test]
    fn test_from_vec9() {
        let mut digest = Sha3::sha3_256();

        let values = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];
        let hashes = values.clone().iter().map(|v| digest.hash_bytes(&v.to_bytes())).collect::<Vec<_>>();
        let count  = values.len();

        let tree   = MerkleTree::from_vec(digest, values);

        let root_hash = Sha3::sha3_256().combine_hashes(
            &Sha3::sha3_256().combine_hashes(
                &Sha3::sha3_256().combine_hashes(
                    &Sha3::sha3_256().combine_hashes(&hashes[0], &hashes[1]),
                    &Sha3::sha3_256().combine_hashes(&hashes[2], &hashes[3])
                ),
                &Sha3::sha3_256().combine_hashes(
                    &Sha3::sha3_256().combine_hashes(&hashes[4], &hashes[5]),
                    &Sha3::sha3_256().combine_hashes(&hashes[6], &hashes[7])
                )
            ),
            &Sha3::sha3_256().hash_bytes(&hashes[8])
        );

        assert_eq!(tree.count, count);
        assert_eq!(tree.height, 4);
        assert_eq!(tree.root_hash().as_slice(), root_hash.as_slice());
    }

}

<commit_msg>Fix tests. Still failing but now they're right.<commit_after>
#![cfg(test)]

mod tests {

    use crypto::sha3::Sha3;

    use MerkleTree;
    use MerkleDigest;
    use Hashable;

    #[test]
    fn test_from_vec3() {
        let mut digest = Sha3::sha3_256();

        let values = vec![1, 2, 3];
        let hashes = vec![digest.hash_bytes(&1.to_bytes()), digest.hash_bytes(&2.to_bytes()), digest.hash_bytes(&3.to_bytes())];

        let tree   = MerkleTree::from_vec(digest, values);

        let root_hash = Sha3::sha3_256().combine_hashes(
            &Sha3::sha3_256().combine_hashes(&hashes[0], &hashes[1]),
            &hashes[2]
        );

        assert_eq!(tree.count, 3);
        assert_eq!(tree.height, 2);
        assert_eq!(tree.root_hash().as_slice(), root_hash.as_slice());
    }

    #[test]
    fn test_from_vec9() {
        let mut digest = Sha3::sha3_256();

        let values = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];
        let hashes = values.clone().iter().map(|v| digest.hash_bytes(&v.to_bytes())).collect::<Vec<_>>();
        let count  = values.len();

        let tree   = MerkleTree::from_vec(digest, values);

        let root_hash = Sha3::sha3_256().combine_hashes(
            &Sha3::sha3_256().combine_hashes(
                &Sha3::sha3_256().combine_hashes(
                    &Sha3::sha3_256().combine_hashes(&hashes[0], &hashes[1]),
                    &Sha3::sha3_256().combine_hashes(&hashes[2], &hashes[3])
                ),
                &Sha3::sha3_256().combine_hashes(
                    &Sha3::sha3_256().combine_hashes(&hashes[4], &hashes[5]),
                    &Sha3::sha3_256().combine_hashes(&hashes[6], &hashes[7])
                )
            ),
            &hashes[8]
        );

        assert_eq!(tree.count, count);
        assert_eq!(tree.height, 4);
        assert_eq!(tree.root_hash().as_slice(), root_hash.as_slice());
    }

}

<|endoftext|>


<commit_before>#[cfg(test)]
mod tests {

    use *;
    use Drain;

    /// ensure o! macro expands without error inside a module
    #[test]
    fn test_o_macro_expansion() {
        let _ = Logger::root(Discard, o!("a" => "aa"));
    }

    #[test]
    fn logger_fmt_debug_sanity() {

        let root = Logger::root(Discard, o!("a" => "aa"));
        let log = root.new(o!("b" => "bb", "c" => "cc"));

        assert_eq!(format!("{:?}", log), "Logger(c, b, a)");
    }

    #[test]
    fn multichain() {
        struct CheckOwned;

        impl Drain for CheckOwned {
            type Error = Never;
            fn log(&self,
                   record: &Record,
                   values: &OwnedKeyValueList)
                   -> result::Result<(), Self::Error> {
                assert_eq!(format!("{}", record.msg()), format!("{:?}", values));
                Ok(())
            }
        }

        let root = Logger::root(CheckOwned, o!("a" => "aa"));
        let log = root.new(o!("b1" => "bb", "b2" => "bb"));

        info!(log, "(b2, b1, a)");

        let log = Logger::root(log, o!("c" => "cc"));
        info!(log, "(c, b2, b1, a)");
        let log = Logger::root(log, o!("d1" => "dd", "d2" => "dd"));
        info!(log, "(d2, d1, c, b2, b1, a)");
    }
}
<commit_msg>Fix tests for old 1.12.<commit_after>#[cfg(test)]
mod tests {

    use std;
    use super::super::*;

    /// ensure o! macro expands without error inside a module
    #[test]
    fn test_o_macro_expansion() {
        let _ = Logger::root(Discard, o!("a" => "aa"));
    }

    #[test]
    fn logger_fmt_debug_sanity() {

        let root = Logger::root(Discard, o!("a" => "aa"));
        let log = root.new(o!("b" => "bb", "c" => "cc"));

        assert_eq!(format!("{:?}", log), "Logger(c, b, a)");
    }

    #[test]
    fn multichain() {
        struct CheckOwned;

        impl Drain for CheckOwned {
            type Error = Never;
            fn log(&self,
                   record: &Record,
                   values: &OwnedKeyValueList)
                   -> std::result::Result<(), Self::Error> {
                assert_eq!(format!("{}", record.msg()), format!("{:?}", values));
                Ok(())
            }
        }

        let root = Logger::root(CheckOwned, o!("a" => "aa"));
        let log = root.new(o!("b1" => "bb", "b2" => "bb"));

        info!(log, "(b2, b1, a)");

        let log = Logger::root(log, o!("c" => "cc"));
        info!(log, "(c, b2, b1, a)");
        let log = Logger::root(log, o!("d1" => "dd", "d2" => "dd"));
        info!(log, "(d2, d1, c, b2, b1, a)");
    }
}
<|endoftext|>


<commit_before>extern crate futures;
extern crate tokio_core;
extern crate tokio_proto;
extern crate tokio_service;

use std::io;
use std::str;
use std::collections::BTreeMap;
use tokio_core::io::{Codec, EasyBuf};
use tokio_core::io::{Io, Framed};
use tokio_proto::pipeline::ServerProto;
use tokio_proto::TcpServer;
use tokio_service::Service;
use futures::{future, Future, BoxFuture};

#[derive(Default)]
pub struct CliCodec {
    /// Offset within the incoming EasyBuf at which newline search last ended
    search_offset: usize,
}

impl Codec for CliCodec {
    /// Input type is a tuple with the command name and an optional argument string
    type In = (String, Option<String>);

    /// Response type is just a string
    type Out = String;

    /// Find a newline, decode to a tuple of command name and argument string
    fn decode(&mut self, buf: &mut EasyBuf) -> io::Result<Option<Self::In>> {
        // Find newline
        let m = buf
            .as_slice()
            .iter()
            .skip(self.search_offset)
            .position(|&b| b == b'\n');

        match m {
            // Process the line if a newline was found
            Some(idx) => {
                println!("Found newline at position {}, started at {}", idx, self.search_offset); // XXX

                let line = buf.drain_to(self.search_offset + idx);
                buf.drain_to(1);

                self.search_offset = 0;

                match str::from_utf8(line.as_slice()) {
                    // Return the string on successful UTF-8 decode
                    // (TODO: ignore blank lines)
                    Ok(s) => {
                        // TODO: Find a better way to split the string
                        let s = s.trim();

                        let request = match s.find(' ') {
                            Some(i) => {
                                let (cmd, args) = s.split_at(i);
                                (cmd.trim().to_string(), Some(args.trim().to_string()))
                            },
                            None => (s.to_string(), None)
                        };

                        Ok(Some(request))
                    },

                    // Return an error if invalid UTF-8 is received
                    Err(e) => Err(io::Error::new(io::ErrorKind::Other, format!("invalid UTF-8: {:?}", e))),
                }
            },

            // Save our position if a newline wasn't found
            _ => {
                println!("Haven't received newline yet!  We started at offset {}, now at {}", self.search_offset, buf.len()); // XXX

                self.search_offset = buf.len();

                Ok(None)
            }
        }
    }

    /// Append the String to the outgoing buffer
    fn encode(&mut self, msg: String, buf: &mut Vec<u8>) -> io::Result<()> {
        buf.extend(msg.as_bytes());
        buf.push(b'\n');
        Ok(())
    }
}

pub struct CliProto;

impl<T: Io + 'static> ServerProto<T> for CliProto {
    type Request = (String, Option<String>);
    type Response = String;

    type Transport = Framed<T, CliCodec>;
    type BindTransport = Result<Self::Transport, io::Error>;

    fn bind_transport(&self, io: T) -> Self::BindTransport {
        Ok(io.framed(CliCodec::default()))
    }
}

trait CliCommand {
    fn name(&self) -> &str;
    fn description(&self) -> &str;
    fn call(&self, args: Option<String>) -> String;
}

#[derive(Default)]
pub struct CliServer<'a> {
    commands: BTreeMap<&'a str, &'a CliCommand>,
}

impl<'a> CliServer<'a> {
    fn add_command(&mut self, cmd: &'a CliCommand) {
        self.commands.insert(cmd.name(), cmd);
    }
}

impl<'a> Service for CliServer<'a> {
    type Request = (String, Option<String>);
    type Response = String;

    type Error = io::Error;

    type Future = BoxFuture<Self::Response, Self::Error>;

    fn call(&self, req: Self::Request) -> Self::Future {
        match self.commands.get(&req.0[..]) {
            Some(cmd) => {
                println!("Calling command {}", req.0);
                // TODO: have commands return futures?
                future::ok(cmd.call(req.1)).boxed()
            },
            None => {
                println!("No match found for command {}", req.0);
                future::ok(format!("Received: {:?}", req)).boxed()
            }
        }
    }
}

fn main() {
    let addr = "0.0.0.0:14311".parse().unwrap();
    let server = TcpServer::new(CliProto, addr);

    println!("Serving on {}", addr);
    server.serve(|| Ok(CliServer::default()));
}
<commit_msg>Respond with "Unknown command" like cliserver for unknown commands.<commit_after>extern crate futures;
extern crate tokio_core;
extern crate tokio_proto;
extern crate tokio_service;

use std::io;
use std::str;
use std::collections::BTreeMap;
use tokio_core::io::{Codec, EasyBuf};
use tokio_core::io::{Io, Framed};
use tokio_proto::pipeline::ServerProto;
use tokio_proto::TcpServer;
use tokio_service::Service;
use futures::{future, Future, BoxFuture};

#[derive(Default)]
pub struct CliCodec {
    /// Offset within the incoming EasyBuf at which newline search last ended
    search_offset: usize,
}

impl Codec for CliCodec {
    /// Input type is a tuple with the command name and an optional argument string
    type In = (String, Option<String>);

    /// Response type is just a string
    type Out = String;

    /// Find a newline, decode to a tuple of command name and argument string
    fn decode(&mut self, buf: &mut EasyBuf) -> io::Result<Option<Self::In>> {
        // Find newline
        let m = buf
            .as_slice()
            .iter()
            .skip(self.search_offset)
            .position(|&b| b == b'\n');

        match m {
            // Process the line if a newline was found
            Some(idx) => {
                println!("Found newline at position {}, started at {}", idx, self.search_offset); // XXX

                let line = buf.drain_to(self.search_offset + idx);
                buf.drain_to(1);

                self.search_offset = 0;

                match str::from_utf8(line.as_slice()) {
                    // Return the string on successful UTF-8 decode
                    // (TODO: ignore blank lines)
                    Ok(s) => {
                        // TODO: Find a better way to split the string
                        let s = s.trim();

                        let request = match s.find(' ') {
                            Some(i) => {
                                let (cmd, args) = s.split_at(i);
                                (cmd.trim().to_string(), Some(args.trim().to_string()))
                            },
                            None => (s.to_string(), None)
                        };

                        Ok(Some(request))
                    },

                    // Return an error if invalid UTF-8 is received
                    Err(e) => Err(io::Error::new(io::ErrorKind::Other, format!("invalid UTF-8: {:?}", e))),
                }
            },

            // Save our position if a newline wasn't found
            _ => {
                println!("Haven't received newline yet!  We started at offset {}, now at {}", self.search_offset, buf.len()); // XXX

                self.search_offset = buf.len();

                Ok(None)
            }
        }
    }

    /// Append the String to the outgoing buffer
    fn encode(&mut self, msg: String, buf: &mut Vec<u8>) -> io::Result<()> {
        buf.extend(msg.as_bytes());
        buf.push(b'\n');
        Ok(())
    }
}

pub struct CliProto;

impl<T: Io + 'static> ServerProto<T> for CliProto {
    type Request = (String, Option<String>);
    type Response = String;

    type Transport = Framed<T, CliCodec>;
    type BindTransport = Result<Self::Transport, io::Error>;

    fn bind_transport(&self, io: T) -> Self::BindTransport {
        Ok(io.framed(CliCodec::default()))
    }
}

trait CliCommand {
    fn name(&self) -> &str;
    fn description(&self) -> &str;
    fn call(&self, args: Option<String>) -> String;
}

#[derive(Default)]
pub struct CliServer<'a> {
    commands: BTreeMap<&'a str, &'a CliCommand>,
}

impl<'a> CliServer<'a> {
    fn add_command(&mut self, cmd: &'a CliCommand) {
        self.commands.insert(cmd.name(), cmd);
    }
}

impl<'a> Service for CliServer<'a> {
    type Request = (String, Option<String>);
    type Response = String;

    type Error = io::Error;

    type Future = BoxFuture<Self::Response, Self::Error>;

    fn call(&self, req: Self::Request) -> Self::Future {
        match self.commands.get(&req.0[..]) {
            Some(cmd) => {
                println!("Calling command {}", req.0);
                // TODO: have commands return futures?
                future::ok(cmd.call(req.1)).boxed()
            },
            None => {
                println!("No match found for command {}", req.0);
                future::ok(format!("Unknown command: {}", req.0)).boxed()
            }
        }
    }
}

fn main() {
    let addr = "0.0.0.0:14311".parse().unwrap();
    let server = TcpServer::new(CliProto, addr);

    println!("Serving on {}", addr);
    server.serve(|| Ok(CliServer::default()));
}
<|endoftext|>


<commit_before>fn main() {
    let s = "I am a &str.";

    // &str => String
    let st: String = s.to_string();

    // String => &str
    let str: &str = st.as_slice();
}

fn int_to_string(x: int) -> String {
    x.to_string()
}

fn string_to_int(x: String) -> int {
    x.parse().unwrap()
}
<commit_msg>Explaining the purpose of this file a bit<commit_after>// This should fail to compile if any of these code examples are wrong.

fn main() {
    // Doing the string conversions all in main so that the lifetimes can be inferred.

    let s = "I am a &str.";

    // &str => String
    let st: String = s.to_string();

    // String => &str
    let str: &str = st.as_slice();
}

fn int_to_string(x: int) -> String {
    x.to_string()
}

fn string_to_int(x: String) -> int {
    x.parse().unwrap()
}
<|endoftext|>


<commit_before>#![cfg_attr(test, allow(dead_code))]
#![feature(collections, env, io, std_misc, libc)]
#![cfg_attr(not(windows), feature(path, fs))]

extern crate libc;

mod args;
mod matching;
mod screen;
#[cfg(not(windows))] mod ansi;

use std::env;
use std::old_io;
use std::cmp::min;
use screen::Screen;
use screen::Key;
use screen::Key::*;
use self::SearchState::*;

fn main() {
    let args = match args::parse_args() {
        Some(args) => args,
        None => {
            env::set_exit_status(1);
            return;
        },
    };

    if args.help { return; }

    let choices = read_choices();
    let initial_search = args.initial_search.clone();
    let choices = choices.iter().map(|x| &x[]).collect::<Vec<&str>>();
    if args.use_first {
        let matches = matching::compute_matches(&choices, &initial_search);
        println!("{}", matches.get(0).unwrap_or(&""));
        return;
    } else {
        event_loop(&choices, &initial_search);
    }
}

fn event_loop(choices: &[&str], initial_search: &str) {
    let mut search = Search::new(choices, initial_search.to_string());
    let mut screen = Screen::open_screen();

    loop {
        search.recompute_matches();

        match search.state {
            InProgress => draw_screen(&mut screen, &search),
            _ => break,
        }

        let keys = screen.get_buffered_keys();
        for key in keys.iter() {
            handle_key(&mut search, key, screen.visible_choices);
        }
    }

    screen.move_cursor_to_bottom();
    println!("{}", search.get_selection());
}

fn handle_key(search: &mut Search, key: &Key, visible_choices: u16) {
    match *key {
        Char(x) => search.append(x),
        Backspace => search.backspace(),
        Control('h') => search.backspace(),
        Control('w') => search.delete_word(),
        Control('u') => search.clear_query(),
        Control('c') => search.cancel(),
        Control('g') => search.cancel(),
        Control('n') => search.down(visible_choices),
        Control('p') => search.up(),
        Enter => search.done(),
        _ => {}
    }
}

struct Search<'a> {
    choices: &'a [&'a str],
    query: String,
    matches: Vec<&'a str>,
    stale: bool,
    index: usize,
    state: SearchState,
}

#[derive(PartialEq, Eq)]
enum SearchState {
    InProgress,
    Done,
    Canceled,
}

impl<'a> Search<'a> {
    fn new(choices: &'a [&'a str], initial_search: String) -> Search<'a> {
        let matches = choices.to_vec();
        Search {
            choices: choices,
            query: initial_search,
            matches: matches,
            stale: true,
            index: 0,
            state: InProgress,
        }
    }

    fn up(&mut self) {
        self.index = if self.index == 0 { 0 } else { self.index - 1 };
    }

    fn down(&mut self, visible_choices: u16) {
        let limit = min(visible_choices as usize - 1, self.matches.len() - 1);
        self.index = min(self.index + 1, limit);
    }

    fn backspace(&mut self) {
        self.query.pop();
        self.stale = true;
        self.index = 0;
        self.matches = self.choices.to_vec();
    }

    fn delete_word(&mut self) {
        self.stale = true;
        delete_last_word(&mut self.query);
        self.matches = self.choices.to_vec();
    }

    fn append(&mut self, c: char) {
        self.query.push(c);
        self.stale = true;
        self.index = 0;
    }

    fn clear_query(&mut self) {
        self.query.clear();
        self.matches = self.choices.to_vec();
    }

    fn recompute_matches(&mut self) {
        if self.stale {
            self.matches = matching::compute_matches(&self.matches, &self.query);
            self.stale = false;
        }
    }

    fn get_selection(&mut self) -> String {
        if self.state == Canceled {
            "".to_string()
        } else {
            self.recompute_matches();
            self.matches.get(self.index).unwrap_or(&"").to_string()
        }
    }

    fn cancel(&mut self) {
        self.state = Canceled
    }

    fn done(&mut self) {
        self.state = Done
    }
}

fn draw_screen(screen: &mut Screen, search: &Search) {
    screen.hide_cursor();
    screen.blank_screen();
    screen.write(&format!("> {} ({}/{} choices)\n", search.query, search.matches.len(), search.choices.len()));

    print_matches(screen, &search.matches, search.index);

    let start = screen.start_line;
    screen.move_cursor(start, 2 + search.query.len() as u16);
    screen.show_cursor();
}

fn print_matches(screen: &mut Screen, matches: &Vec<&str>, index: usize) {
    let mut i = 1;
    let max_width = screen.width as usize;
    for choice in matches.iter() {
        let choice = choice.slice_chars(0, min(max_width, choice.chars().count()));
        if i == index + 1 {
            screen.write_inverted(&choice);
        } else {
            screen.write(&choice);
        }
        if i >= screen.visible_choices as usize {
            return;
        } else {
            screen.write("\n");
        }
        i += 1;
    }
}

fn read_choices() -> Vec<String> {
    let mut stdin = old_io::stdio::stdin();
    let mut lines = Vec::new();

    while let Ok(mut s) = stdin.read_line() {
        trim(&mut s);
        lines.push(s);
    }

    lines
}

pub fn trim(s: &mut String) {
    while let Some(x) = s.pop() {
        if x != '\n' {
            s.push(x);
            return;
        }
    }
}

fn delete_last_word(s: &mut String) {
    let mut deleted_something = false;
    while let Some(x) = s.pop() {
        if x == ' ' {
            if deleted_something {
                s.push(x);
                return;
            }
        } else {
            deleted_something = true;
        }
    }
}

#[test]
fn trim_test() {
    fn should_become(before: &str, after: &str) {
        let mut x = before.to_string();
        trim(&mut x);
        assert_eq!(after.to_string(), x);
    }
    should_become("", "");
    should_become("\n", "");
    should_become("\n\n", "");
    should_become("asdf", "asdf");
    should_become("asdf\n", "asdf");
    should_become("asdf\nasdf\n", "asdf\nasdf");
}

#[test]
fn delete_word_test() {
    fn should_become(before: &str, after: &str) {
        let mut x = before.to_string();
        delete_last_word(&mut x);
        assert_eq!(after.to_string(), x);
    }
    should_become("", "");
    should_become("a", "");
    should_become("asdf", "");
    should_become("asdf asdf asdf", "asdf asdf ");
    should_become("asdf asdf asdf ", "asdf asdf ");
    should_become("asdf asdf asdf  ", "asdf asdf ");
}
<commit_msg>Wrap around selection<commit_after>#![cfg_attr(test, allow(dead_code))]
#![feature(collections, env, io, std_misc, libc)]
#![cfg_attr(not(windows), feature(path, fs))]

extern crate libc;

mod args;
mod matching;
mod screen;
#[cfg(not(windows))] mod ansi;

use std::env;
use std::old_io;
use std::cmp::min;
use screen::Screen;
use screen::Key;
use screen::Key::*;
use self::SearchState::*;

fn main() {
    let args = match args::parse_args() {
        Some(args) => args,
        None => {
            env::set_exit_status(1);
            return;
        },
    };

    if args.help { return; }

    let choices = read_choices();
    let initial_search = args.initial_search.clone();
    let choices = choices.iter().map(|x| &x[]).collect::<Vec<&str>>();
    if args.use_first {
        let matches = matching::compute_matches(&choices, &initial_search);
        println!("{}", matches.get(0).unwrap_or(&""));
        return;
    } else {
        event_loop(&choices, &initial_search);
    }
}

fn event_loop(choices: &[&str], initial_search: &str) {
    let mut search = Search::new(choices, initial_search.to_string());
    let mut screen = Screen::open_screen();

    loop {
        search.recompute_matches();

        match search.state {
            InProgress => draw_screen(&mut screen, &search),
            _ => break,
        }

        let keys = screen.get_buffered_keys();
        for key in keys.iter() {
            handle_key(&mut search, key, screen.visible_choices);
        }
    }

    screen.move_cursor_to_bottom();
    println!("{}", search.get_selection());
}

fn handle_key(search: &mut Search, key: &Key, visible_choices: u16) {
    match *key {
        Char(x) => search.append(x),
        Backspace => search.backspace(),
        Control('h') => search.backspace(),
        Control('w') => search.delete_word(),
        Control('u') => search.clear_query(),
        Control('c') => search.cancel(),
        Control('g') => search.cancel(),
        Control('n') => search.down(visible_choices),
        Control('p') => search.up(visible_choices),
        Enter => search.done(),
        _ => {}
    }
}

struct Search<'a> {
    choices: &'a [&'a str],
    query: String,
    matches: Vec<&'a str>,
    stale: bool,
    index: usize,
    state: SearchState,
}

#[derive(PartialEq, Eq)]
enum SearchState {
    InProgress,
    Done,
    Canceled,
}

impl<'a> Search<'a> {
    fn new(choices: &'a [&'a str], initial_search: String) -> Search<'a> {
        let matches = choices.to_vec();
        Search {
            choices: choices,
            query: initial_search,
            matches: matches,
            stale: true,
            index: 0,
            state: InProgress,
        }
    }

    fn up(&mut self, visible_choices: u16) {
        let limit = min(visible_choices as usize - 1, self.matches.len() - 1);
        self.index = if self.index == 0 { limit } else { self.index - 1 };
    }

    fn down(&mut self, visible_choices: u16) {
        let limit = min(visible_choices as usize - 1, self.matches.len() - 1);
        self.index = if self.index == limit { 0 } else { self.index + 1 }
    }

    fn backspace(&mut self) {
        self.query.pop();
        self.stale = true;
        self.index = 0;
        self.matches = self.choices.to_vec();
    }

    fn delete_word(&mut self) {
        self.stale = true;
        delete_last_word(&mut self.query);
        self.matches = self.choices.to_vec();
    }

    fn append(&mut self, c: char) {
        self.query.push(c);
        self.stale = true;
        self.index = 0;
    }

    fn clear_query(&mut self) {
        self.query.clear();
        self.matches = self.choices.to_vec();
    }

    fn recompute_matches(&mut self) {
        if self.stale {
            self.matches = matching::compute_matches(&self.matches, &self.query);
            self.stale = false;
        }
    }

    fn get_selection(&mut self) -> String {
        if self.state == Canceled {
            "".to_string()
        } else {
            self.recompute_matches();
            self.matches.get(self.index).unwrap_or(&"").to_string()
        }
    }

    fn cancel(&mut self) {
        self.state = Canceled
    }

    fn done(&mut self) {
        self.state = Done
    }
}

fn draw_screen(screen: &mut Screen, search: &Search) {
    screen.hide_cursor();
    screen.blank_screen();
    screen.write(&format!("> {} ({}/{} choices)\n", search.query, search.matches.len(), search.choices.len()));

    print_matches(screen, &search.matches, search.index);

    let start = screen.start_line;
    screen.move_cursor(start, 2 + search.query.len() as u16);
    screen.show_cursor();
}

fn print_matches(screen: &mut Screen, matches: &Vec<&str>, index: usize) {
    let mut i = 1;
    let max_width = screen.width as usize;
    for choice in matches.iter() {
        let choice = choice.slice_chars(0, min(max_width, choice.chars().count()));
        if i == index + 1 {
            screen.write_inverted(&choice);
        } else {
            screen.write(&choice);
        }
        if i >= screen.visible_choices as usize {
            return;
        } else {
            screen.write("\n");
        }
        i += 1;
    }
}

fn read_choices() -> Vec<String> {
    let mut stdin = old_io::stdio::stdin();
    let mut lines = Vec::new();

    while let Ok(mut s) = stdin.read_line() {
        trim(&mut s);
        lines.push(s);
    }

    lines
}

pub fn trim(s: &mut String) {
    while let Some(x) = s.pop() {
        if x != '\n' {
            s.push(x);
            return;
        }
    }
}

fn delete_last_word(s: &mut String) {
    let mut deleted_something = false;
    while let Some(x) = s.pop() {
        if x == ' ' {
            if deleted_something {
                s.push(x);
                return;
            }
        } else {
            deleted_something = true;
        }
    }
}

#[test]
fn trim_test() {
    fn should_become(before: &str, after: &str) {
        let mut x = before.to_string();
        trim(&mut x);
        assert_eq!(after.to_string(), x);
    }
    should_become("", "");
    should_become("\n", "");
    should_become("\n\n", "");
    should_become("asdf", "asdf");
    should_become("asdf\n", "asdf");
    should_become("asdf\nasdf\n", "asdf\nasdf");
}

#[test]
fn delete_word_test() {
    fn should_become(before: &str, after: &str) {
        let mut x = before.to_string();
        delete_last_word(&mut x);
        assert_eq!(after.to_string(), x);
    }
    should_become("", "");
    should_become("a", "");
    should_become("asdf", "");
    should_become("asdf asdf asdf", "asdf asdf ");
    should_become("asdf asdf asdf ", "asdf asdf ");
    should_become("asdf asdf asdf  ", "asdf asdf ");
}
<|endoftext|>