<commit_before>use std;
use std::io::prelude::*;
use std::io::{Error, ErrorKind};

/// Reads bytes from the TCP stream until CRLF is found or the given limit is
/// reached.
pub fn read_line<T: Read>(stream: T, limit: usize) -> std::io::Result<String> {
  let mut result = String::with_capacity(limit);

  for byte in stream.take(limit as u64).bytes() {
    let raw = try!(byte);
    let chr = raw as char;

    result.push(chr);

    if chr == '\n' {
      break;
    }
  }

  if result.ends_with("\r\n") {
    // .truncate() panics if the new length is not at char boundary. Since we
    // know the string ends with \r\n, that won't happen.
    let new_len = result.len() - 2;
    result.truncate(new_len);

    // Return the result.
    Ok(result)
  } else if result.len() == limit {
    // The line did not fit in the given limit.
    Err(Error::new(ErrorKind::Other, "Line too long."))
  } else {
    // The line ending was invalid or missing.
    Err(Error::new(ErrorKind::Other, "The line must end in CRLF sequence."))
  }
}

/// Reads the given number of bytes from the stream into a Vec<u8> or returns
/// an error if the exact number of bytes cannot be read.
pub fn read_bytes<T: Read>(stream: T, amount: usize) -> std::io::Result<Vec<u8>> {
  let mut buf: Vec<u8> = vec![];
  let read = try!(stream.take(amount as u64).read_to_end(&mut buf));

  if read < amount {
    Err(Error::new(ErrorKind::Other, "Unexpected end of stream."))
  } else {
    Ok(buf)
  }
}

/// Reads four bytes from the stream and combines them together to form a 32 bit
/// unsigned integer.
pub fn read_u32<T: Read>(stream: T) -> std::io::Result<u32> {
  let buf = try!(read_bytes(stream, 4));

  Ok(buf.iter().enumerate().fold(0, |result, (i, value)| {
    result | ((*value as u32) << (3 - i) * 8)
  }))
}

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

  #[test]
  fn test_readline_basic() {
    let stream = create_tcp_stream("foo\r\n".as_bytes());
    assert_eq!(read_line(&stream, 255).unwrap(), "foo");
  }

  #[test]
  fn test_readline_empty_line() {
    let stream = create_tcp_stream("\r\n".as_bytes());
    assert_eq!(read_line(&stream, 255).unwrap(), "");
  }

  #[test]
  fn test_readline_multiple_lines_reads_only_first() {
    let stream = create_tcp_stream("bar\r\nfoo\r\n".as_bytes());
    assert_eq!(read_line(&stream, 255).unwrap(), "bar");
    assert_eq!(read_line(&stream, 255).unwrap(), "foo");
  }

  #[test]
  fn test_readline_line_too_long() {
    let stream = create_tcp_stream("barbazfoo\r\n".as_bytes());
    assert!(read_line(&stream, 5).is_err());
  }

  #[test]
  fn test_readline_line_at_limit() {
    let stream = create_tcp_stream("123\r\n".as_bytes());
    assert_eq!(read_line(&stream, 5).unwrap(), "123");
  }

  #[test]
  fn test_readline_no_cr_before_lf() {
    let stream = create_tcp_stream("barbazfoo\n".as_bytes());
    assert!(read_line(&stream, 255).is_err());
  }

  #[test]
  fn test_readline_no_crlf() {
    let stream = create_tcp_stream("barbazfoo".as_bytes());
    assert!(read_line(&stream, 255).is_err());
  }

  #[test]
  fn test_readline_no_lf() {
    let stream = create_tcp_stream("barb\razfoo".as_bytes());
    assert!(read_line(&stream, 255).is_err());
  }

  #[test]
  fn test_readline_empty() {
    let stream = create_tcp_stream("".as_bytes());
    assert!(read_line(&stream, 255).is_err());
  }

  #[test]
  fn test_readline_only_lf() {
    let stream = create_tcp_stream("\n".as_bytes());
    assert!(read_line(&stream, 255).is_err());
  }

  #[test]
  fn test_read_u32_basic() {
    let stream = create_tcp_stream(&[0x29, 0xb7, 0xf4, 0xaa, 0xff, 0xff]);
    assert_eq!(read_u32(&stream).unwrap(), 0x29b7f4aa);
  }

  #[test]
  fn test_read_u32_basic_zeroes() {
    let stream = create_tcp_stream(&[0x29, 0x00, 0xf4, 0xaa, 0xff, 0xff]);
    assert_eq!(read_u32(&stream).unwrap(), 0x2900f4aa);
  }

  #[test]
  fn test_read_u32_too_little_data() {
    let stream = create_tcp_stream(&[0x29, 0xb7, 0xf4]);
    assert!(read_u32(&stream).is_err());
  }

  #[test]
  fn test_read_bytes_basic() {
    let stream = create_tcp_stream(&[1,2,3,4,5,6]);
    assert_eq!(read_bytes(&stream, 2).unwrap(), [1,2]);
    assert_eq!(read_bytes(&stream, 3).unwrap(), [3,4,5]);
    assert_eq!(read_bytes(&stream, 1).unwrap(), [6]);
  }

  #[test]
  fn test_read_bytes_too_little_data() {
    let stream = create_tcp_stream(&[1,2,3,4,5,6]);
    assert!(read_bytes(&stream, 10).is_err())
  }
}
<commit_msg>Add read_byte() method for reading a single byte.<commit_after>use std;
use std::io::prelude::*;
use std::io::{Error, ErrorKind};

/// Reads bytes from the TCP stream until CRLF is found or the given limit is
/// reached.
pub fn read_line<T: Read>(stream: T, limit: usize) -> std::io::Result<String> {
  let mut result = String::with_capacity(limit);

  for byte in stream.take(limit as u64).bytes() {
    let raw = try!(byte);
    let chr = raw as char;

    result.push(chr);

    if chr == '\n' {
      break;
    }
  }

  if result.ends_with("\r\n") {
    // .truncate() panics if the new length is not at char boundary. Since we
    // know the string ends with \r\n, that won't happen.
    let new_len = result.len() - 2;
    result.truncate(new_len);

    // Return the result.
    Ok(result)
  } else if result.len() == limit {
    // The line did not fit in the given limit.
    Err(Error::new(ErrorKind::Other, "Line too long."))
  } else {
    // The line ending was invalid or missing.
    Err(Error::new(ErrorKind::Other, "The line must end in CRLF sequence."))
  }
}

/// Reads a single by from the stream.
pub fn read_byte<T: Read>(stream: T) -> std::io::Result<u8> {
  Ok(try!(read_bytes(stream, 1)).pop().unwrap())
}

/// Reads the given number of bytes from the stream into a Vec<u8> or returns
/// an error if the exact number of bytes cannot be read.
pub fn read_bytes<T: Read>(stream: T, amount: usize) -> std::io::Result<Vec<u8>> {
  let mut buf: Vec<u8> = vec![];
  let read = try!(stream.take(amount as u64).read_to_end(&mut buf));

  if read < amount {
    Err(Error::new(ErrorKind::Other, "Unexpected end of stream."))
  } else {
    Ok(buf)
  }
}

/// Reads four bytes from the stream and combines them together to form a 32 bit
/// unsigned integer.
pub fn read_u32<T: Read>(stream: T) -> std::io::Result<u32> {
  let buf = try!(read_bytes(stream, 4));

  Ok(buf.iter().enumerate().fold(0, |result, (i, value)| {
    result | ((*value as u32) << (3 - i) * 8)
  }))
}

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

  #[test]
  fn test_readline_basic() {
    let stream = create_tcp_stream("foo\r\n".as_bytes());
    assert_eq!(read_line(&stream, 255).unwrap(), "foo");
  }

  #[test]
  fn test_readline_empty_line() {
    let stream = create_tcp_stream("\r\n".as_bytes());
    assert_eq!(read_line(&stream, 255).unwrap(), "");
  }

  #[test]
  fn test_readline_multiple_lines_reads_only_first() {
    let stream = create_tcp_stream("bar\r\nfoo\r\n".as_bytes());
    assert_eq!(read_line(&stream, 255).unwrap(), "bar");
    assert_eq!(read_line(&stream, 255).unwrap(), "foo");
  }

  #[test]
  fn test_readline_line_too_long() {
    let stream = create_tcp_stream("barbazfoo\r\n".as_bytes());
    assert!(read_line(&stream, 5).is_err());
  }

  #[test]
  fn test_readline_line_at_limit() {
    let stream = create_tcp_stream("123\r\n".as_bytes());
    assert_eq!(read_line(&stream, 5).unwrap(), "123");
  }

  #[test]
  fn test_readline_no_cr_before_lf() {
    let stream = create_tcp_stream("barbazfoo\n".as_bytes());
    assert!(read_line(&stream, 255).is_err());
  }

  #[test]
  fn test_readline_no_crlf() {
    let stream = create_tcp_stream("barbazfoo".as_bytes());
    assert!(read_line(&stream, 255).is_err());
  }

  #[test]
  fn test_readline_no_lf() {
    let stream = create_tcp_stream("barb\razfoo".as_bytes());
    assert!(read_line(&stream, 255).is_err());
  }

  #[test]
  fn test_readline_empty() {
    let stream = create_tcp_stream("".as_bytes());
    assert!(read_line(&stream, 255).is_err());
  }

  #[test]
  fn test_readline_only_lf() {
    let stream = create_tcp_stream("\n".as_bytes());
    assert!(read_line(&stream, 255).is_err());
  }

  #[test]
  fn test_read_u32_basic() {
    let stream = create_tcp_stream(&[0x29, 0xb7, 0xf4, 0xaa, 0xff, 0xff]);
    assert_eq!(read_u32(&stream).unwrap(), 0x29b7f4aa);
  }

  #[test]
  fn test_read_u32_basic_zeroes() {
    let stream = create_tcp_stream(&[0x29, 0x00, 0xf4, 0xaa, 0xff, 0xff]);
    assert_eq!(read_u32(&stream).unwrap(), 0x2900f4aa);
  }

  #[test]
  fn test_read_u32_too_little_data() {
    let stream = create_tcp_stream(&[0x29, 0xb7, 0xf4]);
    assert!(read_u32(&stream).is_err());
  }

  #[test]
  fn test_read_bytes_basic() {
    let stream = create_tcp_stream(&[1,2,3,4,5,6]);
    assert_eq!(read_bytes(&stream, 2).unwrap(), [1,2]);
    assert_eq!(read_bytes(&stream, 3).unwrap(), [3,4,5]);
    assert_eq!(read_bytes(&stream, 1).unwrap(), [6]);
  }

  #[test]
  fn test_read_bytes_too_little_data() {
    let stream = create_tcp_stream(&[1,2,3,4,5,6]);
    assert!(read_bytes(&stream, 10).is_err())
  }

  #[test]
  fn test_read_byte_basic() {
    let stream = create_tcp_stream(&[1,2,3,4,5,6]);
    assert_eq!(read_byte(&stream).unwrap(), 1);
    assert_eq!(read_byte(&stream).unwrap(), 2);
    assert_eq!(read_byte(&stream).unwrap(), 3);
  }

  #[test]
  fn test_read_byte_empty() {
    let stream = create_tcp_stream(&[]);
    assert!(read_byte(&stream).is_err())
  }
}
<|endoftext|>


<commit_before>//! Module containing `Result` type

use std::result::Result as RResult;

use error::TaskError;

pub type Result<T> = RResult<T, TaskError>;
<commit_msg>Add documentation for own Result type<commit_after>//! Module containing `Result` type

use std::result::Result as RResult;

use error::TaskError;

/// Result type wrapping the standard std::result::Result type
pub type Result<T> = RResult<T, TaskError>;
<|endoftext|>


<commit_before>use delay_line::{Buffer, DelayLine};
use dsp::{self, FromSample, Sample};
use num::traits::One;
use num::Float;

#[derive(Copy, Clone, Debug)]
struct OnePole {
    one: f32,
    a: f32,
    b: f32,
}

impl OnePole {

    /// Contructor for a new OnePole
    pub fn new() -> OnePole {
        OnePole {
            one: 0.0,
            a: 1.0,
            b: 0.0,
        }
    }

    pub fn damping(&mut self, value: f32) {
        self.a = 1.0 - value.abs();
        self.b = value;
    }

    pub fn call(&mut self, i: f32) -> f32 {
        self.one = i * self.a + self.one * self.b;
        self.one
    }

}

/// Plate Reverberator
/// Design from:
/// Dattorro, J (1997). Effect design: Part 1: Reverberator and other filters.
/// Journal of Audio Engineering Society
/// [45(9):660-684](https://ccrma.stanford.edu/~dattorro/EffectDesignPart1.pdf)
#[derive(Clone, Debug)]
pub struct Reverb {
    delay_feed_1: f32,
    delay_feed_2: f32,
    decay_1: f32,
    decay_2: f32,
    decay: f32,

    pre_delay: DelayLine<[f32; 10]>,
    one_pole: OnePole,
    all_pass_in_1: DelayLine<[f32; 142]>,
    all_pass_in_2: DelayLine<[f32; 107]>,
    all_pass_in_3: DelayLine<[f32; 379]>,
    all_pass_in_4: DelayLine<[f32; 277]>,

    all_pass_decay_11: DelayLine<[f32; 672]>,
    all_pass_decay_12: DelayLine<[f32; 1800]>,

    delay_11: DelayLine<[f32; 4453]>,
    delay_12: DelayLine<[f32; 3720]>,

    one_pole_1: OnePole,
    all_pass_decay_21: DelayLine<[f32; 908]>,
    all_pass_decay_22: DelayLine<[f32; 2656]>,

    delay_21: DelayLine<[f32; 4217]>,
    delay_22: DelayLine<[f32; 3163]>,

    one_pole_2: OnePole,
}

impl Reverb {

    fn construct() -> Reverb {
        Reverb {
            delay_feed_1: 0.0,
            delay_feed_2: 0.0,
            decay_1: 0.0,
            decay_2: 0.0,
            decay: 0.0,

            pre_delay: DelayLine::new(),
            one_pole: OnePole::new(),
            all_pass_in_1: DelayLine::new(),
            all_pass_in_2: DelayLine::new(),
            all_pass_in_3: DelayLine::new(),
            all_pass_in_4: DelayLine::new(),

            all_pass_decay_11: DelayLine::new(),
            all_pass_decay_12: DelayLine::new(),

            delay_11: DelayLine::new(),
            delay_12: DelayLine::new(),

            one_pole_1: OnePole::new(),
            all_pass_decay_21: DelayLine::new(),
            all_pass_decay_22: DelayLine::new(),

            delay_21: DelayLine::new(),
            delay_22: DelayLine::new(),

            one_pole_2: OnePole::new(),
        }
    }

    /// Contructor default reverb
    pub fn new() -> Reverb {
        let mut verb = Reverb::construct();
        verb.bandwidth(0.9995);
        verb.decay(0.85);
        verb.damping(0.2);
        verb.diffusion(0.76, 0.666, 0.707, 0.517);
        verb
    }

    /// Set input signal bandwidth, in [0,1]
    /// This sets the cutoff frequency of a one-pole low-pass filter on the
    /// input signal.
    pub fn bandwidth(&mut self, value: f32) -> &mut Reverb {
        self.one_pole_1.damping(1.0 - value);
        self
    }

    /// Set high-frequency damping amount, in [0,1]
    /// Higher amounts will dampen the diffuse sound more quickly.
    /// rather than high frequencies.
    pub fn damping(&mut self, value: f32) -> &mut Reverb {
        self.one_pole_1.damping(value);
        self.one_pole_2.damping(value);
        self
    }

    /// Set decay factor, in [0,1]
    pub fn decay(&mut self, value: f32) -> &mut Reverb {
        self.decay = value;
        self
    }

    /// Set diffusion amounts, in [0, 1]
    /// Values near 0.7 are recommended. Moving further away from 0.7 will lead
    /// to more distinct echoes.
    pub fn diffusion(&mut self, in_1: f32, in_2: f32, decay_1: f32, decay_2: f32) -> &mut Reverb {
        self.delay_feed_1 = in_1;
        self.delay_feed_2 = in_2;
        self.decay_1 = decay_1;
        self.decay_2 = decay_2;
        self
    }

    /// Set input diffusion 1 amount, [0,1]
    pub fn diffusion1(&mut self, value: f32) -> &mut Reverb {
        self.delay_feed_1 = value;
        self
    }

    /// Set input diffusion 2 amount, [0,1]
    pub fn diffusion2(&mut self, value: f32) -> &mut Reverb {
        self.delay_feed_2 = value;
        self
    }

    /// Set tank decay diffusion 1 amount, [0,1]
    pub fn diffusion_decay_1(&mut self, value: f32) -> &mut Reverb {
        self.decay_1 = value;
        self
    }

    /// Set tank decay diffusion 2 amount, [0,1]
    pub fn diffusion_decay_2(&mut self, value: f32) -> &mut Reverb {
        self.decay_2 = value;
        self
    }

    /// Compute wet stereo output from dry mono input
    /// @param[ in] in      dry input sample
    /// @param[out] out1    wet output sample 1
    /// @param[out] out2    wet output sample 2
    /// @param[ in] gain    gain of output
    pub fn calc_frame(&mut self, input: f32, gain: f32) -> (f32, f32) {
        let mut value = self.pre_delay.get_write_and_step(input * 0.5);
        value = self.one_pole.call(value);
        value = self.all_pass_in_1.allpass(value, self.delay_feed_1);
        value = self.all_pass_in_2.allpass(value, self.delay_feed_1);
        value = self.all_pass_in_3.allpass(value, self.delay_feed_2);
        value = self.all_pass_in_4.allpass(value, self.delay_feed_2);

        let mut a = value + self.delay_22.back() * self.decay;
        let mut b = value + self.delay_12.back() * self.decay;

        a = self.all_pass_decay_11.allpass(a, -self.decay_1);
        a = self.delay_11.get_write_and_step(a);
        a = self.one_pole_1.call(a) * self.decay;
        a = self.all_pass_decay_12.allpass(a, self.decay_2);
        self.delay_12.write(a);

        b = self.all_pass_decay_21.allpass(b, -self.decay_1);
        b = self.delay_21.get_write_and_step(b);
        b = self.one_pole_2.call(b) * self.decay;
        b = self.all_pass_decay_22.allpass(b, self.decay_2);
        self.delay_22.write(b);

        let output_1 = {
            self.delay_21.read(266)
            + self.delay_21.read(2974)
            - self.all_pass_decay_22.read(1913)
            + self.delay_22.read(1996)
            - self.delay_11.read(1990)
            - self.all_pass_decay_12.read(187)
            - self.delay_12.read(1066)
        } * gain;

        let output_2 = {
            self.delay_11.read(353)
            + self.delay_11.read(3627)
            - self.all_pass_decay_12.read(1228)
            + self.delay_12.read(2673)
            - self.delay_21.read(2111)
            - self.all_pass_decay_22.read(335)
            - self.delay_22.read(121)
        } * gain;

        (output_1, output_2)
    }
}

impl<S> dsp::Node<S> for Reverb
    where S: Sample + FromSample<f32>,
          f32: FromSample<S>,
{
    fn audio_requested(&mut self, output: &mut [S], settings: dsp::Settings) {
        match settings.channels {
            // Mono.
            1 => for frame in output.iter_mut() {
                let dry = frame.to_sample();
                let (output_1, output_2) = self.calc_frame(dry, 0.6);
                *frame = ((output_1 + output_2) / 2.0).to_sample();
            },
            // Stereo.
            2 => for frame in output.chunks_mut(2) {
                let dry = (frame[0].to_sample::<f32>() + frame[1].to_sample::<f32>()) / 2.0;
                let (output_1, output_2) = self.calc_frame(dry, 0.6);
                frame[0] = output_1.to_sample();
                frame[1] = output_2.to_sample();
            },
            // No other number of channels is supported.
            n => panic!("The given number of channels ({:?}) is not supported by lanceverb", n),
        }
    }
}

/// Generates an implementation of Buffer for a fixed-size array with "$n" number of elements.
macro_rules! impl_buffer {
    ($n:expr) => (
        impl Buffer for [f32; $n] {
            fn zeroed() -> Self { [0.0; $n] }
            fn clone(&self) -> Self { *self }
            fn len(&self) -> usize { $n }
            fn index(&self, idx: usize) -> &f32 { &self[idx] }
            fn index_mut(&mut self, idx: usize) -> &mut f32 { &mut self[idx] }
        }
    )
}

impl_buffer!(10);
impl_buffer!(142);
impl_buffer!(107);
impl_buffer!(379);
impl_buffer!(277);
impl_buffer!(672);
impl_buffer!(1800);
impl_buffer!(4453);
impl_buffer!(3720);
impl_buffer!(908);
impl_buffer!(2656);
impl_buffer!(4217);
impl_buffer!(3163);

<commit_msg>Use sample::Duplex instead of FromSample<commit_after>use delay_line::{Buffer, DelayLine};
use dsp::{self, Sample};
use num::traits::One;
use num::Float;

#[derive(Copy, Clone, Debug)]
struct OnePole {
    one: f32,
    a: f32,
    b: f32,
}

impl OnePole {

    /// Contructor for a new OnePole
    pub fn new() -> OnePole {
        OnePole {
            one: 0.0,
            a: 1.0,
            b: 0.0,
        }
    }

    pub fn damping(&mut self, value: f32) {
        self.a = 1.0 - value.abs();
        self.b = value;
    }

    pub fn call(&mut self, i: f32) -> f32 {
        self.one = i * self.a + self.one * self.b;
        self.one
    }

}

/// Plate Reverberator
/// Design from:
/// Dattorro, J (1997). Effect design: Part 1: Reverberator and other filters.
/// Journal of Audio Engineering Society
/// [45(9):660-684](https://ccrma.stanford.edu/~dattorro/EffectDesignPart1.pdf)
#[derive(Clone, Debug)]
pub struct Reverb {
    delay_feed_1: f32,
    delay_feed_2: f32,
    decay_1: f32,
    decay_2: f32,
    decay: f32,

    pre_delay: DelayLine<[f32; 10]>,
    one_pole: OnePole,
    all_pass_in_1: DelayLine<[f32; 142]>,
    all_pass_in_2: DelayLine<[f32; 107]>,
    all_pass_in_3: DelayLine<[f32; 379]>,
    all_pass_in_4: DelayLine<[f32; 277]>,

    all_pass_decay_11: DelayLine<[f32; 672]>,
    all_pass_decay_12: DelayLine<[f32; 1800]>,

    delay_11: DelayLine<[f32; 4453]>,
    delay_12: DelayLine<[f32; 3720]>,

    one_pole_1: OnePole,
    all_pass_decay_21: DelayLine<[f32; 908]>,
    all_pass_decay_22: DelayLine<[f32; 2656]>,

    delay_21: DelayLine<[f32; 4217]>,
    delay_22: DelayLine<[f32; 3163]>,

    one_pole_2: OnePole,
}

impl Reverb {

    fn construct() -> Reverb {
        Reverb {
            delay_feed_1: 0.0,
            delay_feed_2: 0.0,
            decay_1: 0.0,
            decay_2: 0.0,
            decay: 0.0,

            pre_delay: DelayLine::new(),
            one_pole: OnePole::new(),
            all_pass_in_1: DelayLine::new(),
            all_pass_in_2: DelayLine::new(),
            all_pass_in_3: DelayLine::new(),
            all_pass_in_4: DelayLine::new(),

            all_pass_decay_11: DelayLine::new(),
            all_pass_decay_12: DelayLine::new(),

            delay_11: DelayLine::new(),
            delay_12: DelayLine::new(),

            one_pole_1: OnePole::new(),
            all_pass_decay_21: DelayLine::new(),
            all_pass_decay_22: DelayLine::new(),

            delay_21: DelayLine::new(),
            delay_22: DelayLine::new(),

            one_pole_2: OnePole::new(),
        }
    }

    /// Contructor default reverb
    pub fn new() -> Reverb {
        let mut verb = Reverb::construct();
        verb.bandwidth(0.9995);
        verb.decay(0.85);
        verb.damping(0.2);
        verb.diffusion(0.76, 0.666, 0.707, 0.517);
        verb
    }

    /// Set input signal bandwidth, in [0,1]
    /// This sets the cutoff frequency of a one-pole low-pass filter on the
    /// input signal.
    pub fn bandwidth(&mut self, value: f32) -> &mut Reverb {
        self.one_pole_1.damping(1.0 - value);
        self
    }

    /// Set high-frequency damping amount, in [0,1]
    /// Higher amounts will dampen the diffuse sound more quickly.
    /// rather than high frequencies.
    pub fn damping(&mut self, value: f32) -> &mut Reverb {
        self.one_pole_1.damping(value);
        self.one_pole_2.damping(value);
        self
    }

    /// Set decay factor, in [0,1]
    pub fn decay(&mut self, value: f32) -> &mut Reverb {
        self.decay = value;
        self
    }

    /// Set diffusion amounts, in [0, 1]
    /// Values near 0.7 are recommended. Moving further away from 0.7 will lead
    /// to more distinct echoes.
    pub fn diffusion(&mut self, in_1: f32, in_2: f32, decay_1: f32, decay_2: f32) -> &mut Reverb {
        self.delay_feed_1 = in_1;
        self.delay_feed_2 = in_2;
        self.decay_1 = decay_1;
        self.decay_2 = decay_2;
        self
    }

    /// Set input diffusion 1 amount, [0,1]
    pub fn diffusion1(&mut self, value: f32) -> &mut Reverb {
        self.delay_feed_1 = value;
        self
    }

    /// Set input diffusion 2 amount, [0,1]
    pub fn diffusion2(&mut self, value: f32) -> &mut Reverb {
        self.delay_feed_2 = value;
        self
    }

    /// Set tank decay diffusion 1 amount, [0,1]
    pub fn diffusion_decay_1(&mut self, value: f32) -> &mut Reverb {
        self.decay_1 = value;
        self
    }

    /// Set tank decay diffusion 2 amount, [0,1]
    pub fn diffusion_decay_2(&mut self, value: f32) -> &mut Reverb {
        self.decay_2 = value;
        self
    }

    /// Compute wet stereo output from dry mono input
    /// @param[ in] in      dry input sample
    /// @param[out] out1    wet output sample 1
    /// @param[out] out2    wet output sample 2
    /// @param[ in] gain    gain of output
    pub fn calc_frame(&mut self, input: f32, gain: f32) -> (f32, f32) {
        let mut value = self.pre_delay.get_write_and_step(input * 0.5);
        value = self.one_pole.call(value);
        value = self.all_pass_in_1.allpass(value, self.delay_feed_1);
        value = self.all_pass_in_2.allpass(value, self.delay_feed_1);
        value = self.all_pass_in_3.allpass(value, self.delay_feed_2);
        value = self.all_pass_in_4.allpass(value, self.delay_feed_2);

        let mut a = value + self.delay_22.back() * self.decay;
        let mut b = value + self.delay_12.back() * self.decay;

        a = self.all_pass_decay_11.allpass(a, -self.decay_1);
        a = self.delay_11.get_write_and_step(a);
        a = self.one_pole_1.call(a) * self.decay;
        a = self.all_pass_decay_12.allpass(a, self.decay_2);
        self.delay_12.write(a);

        b = self.all_pass_decay_21.allpass(b, -self.decay_1);
        b = self.delay_21.get_write_and_step(b);
        b = self.one_pole_2.call(b) * self.decay;
        b = self.all_pass_decay_22.allpass(b, self.decay_2);
        self.delay_22.write(b);

        let output_1 = {
            self.delay_21.read(266)
            + self.delay_21.read(2974)
            - self.all_pass_decay_22.read(1913)
            + self.delay_22.read(1996)
            - self.delay_11.read(1990)
            - self.all_pass_decay_12.read(187)
            - self.delay_12.read(1066)
        } * gain;

        let output_2 = {
            self.delay_11.read(353)
            + self.delay_11.read(3627)
            - self.all_pass_decay_12.read(1228)
            + self.delay_12.read(2673)
            - self.delay_21.read(2111)
            - self.all_pass_decay_22.read(335)
            - self.delay_22.read(121)
        } * gain;

        (output_1, output_2)
    }
}

impl<S> dsp::Node<S> for Reverb
    where S: Sample + dsp::sample::Duplex<f32>,
{
    fn audio_requested(&mut self, output: &mut [S], settings: dsp::Settings) {
        match settings.channels {
            // Mono.
            1 => for frame in output.iter_mut() {
                let dry = frame.to_sample();
                let (output_1, output_2) = self.calc_frame(dry, 0.6);
                *frame = ((output_1 + output_2) / 2.0).to_sample();
            },
            // Stereo.
            2 => for frame in output.chunks_mut(2) {
                let dry = (frame[0].to_sample::<f32>() + frame[1].to_sample::<f32>()) / 2.0;
                let (output_1, output_2) = self.calc_frame(dry, 0.6);
                frame[0] = output_1.to_sample();
                frame[1] = output_2.to_sample();
            },
            // No other number of channels is supported.
            n => panic!("The given number of channels ({:?}) is not supported by lanceverb", n),
        }
    }
}

/// Generates an implementation of Buffer for a fixed-size array with "$n" number of elements.
macro_rules! impl_buffer {
    ($n:expr) => (
        impl Buffer for [f32; $n] {
            fn zeroed() -> Self { [0.0; $n] }
            fn clone(&self) -> Self { *self }
            fn len(&self) -> usize { $n }
            fn index(&self, idx: usize) -> &f32 { &self[idx] }
            fn index_mut(&mut self, idx: usize) -> &mut f32 { &mut self[idx] }
        }
    )
}

impl_buffer!(10);
impl_buffer!(142);
impl_buffer!(107);
impl_buffer!(379);
impl_buffer!(277);
impl_buffer!(672);
impl_buffer!(1800);
impl_buffer!(4453);
impl_buffer!(3720);
impl_buffer!(908);
impl_buffer!(2656);
impl_buffer!(4217);
impl_buffer!(3163);

<|endoftext|>


<commit_before>//! Printer for displaying crate as a graoh.

use petgraph::{
    graph::NodeIndex,
    visit::{IntoNodeReferences, NodeRef},
};
use ra_ap_ide::RootDatabase;

use crate::{
    format::{kind::FormattedKind, visibility::FormattedVisibility},
    graph::{Edge, Graph, Node, NodeKind},
    theme::{color_palette, colors, Rgb},
};

const INDENTATION: &str = "    ";

#[derive(Clone, Debug)]
pub struct Options {
    pub absolute_paths: bool,
    pub layout: String,
}

pub struct Printer<'a> {
    options: Options,
    db: &'a RootDatabase,
}

impl<'a> Printer<'a> {
    pub fn new(options: Options, db: &'a RootDatabase) -> Self {
        Self { options, db }
    }

    pub fn print(&self, graph: &Graph, start_node_idx: NodeIndex) -> Result<(), anyhow::Error> {
        let root_node = &graph[start_node_idx];
        let crate_name = root_node.name();
        let layout_name = &self.options.layout[..];

        println!("digraph {} {{", crate_name);

        println!();

        indoc::printdoc!(
            r#"
            {i}graph [
            {i}    label="{label}",
            {i}    labelloc=t,

            {i}    pad=0.4,

            {i}    // Consider rendering the graph using a different layout algorithm, such as:
            {i}    // [dot, neato, twopi, circo, fdp, sfdp]
            {i}    layout={layout},
            {i}    overlap=false,
            {i}    splines="line",
            {i}    rankdir=LR,

            {i}    fontname="Helvetica",
            {i}    fontsize="36",
            {i}];
            "#,
            i = INDENTATION,
            label = crate_name,
            layout = layout_name,
        );

        println!();

        indoc::printdoc!(
            r#"
            {i}node [
            {i}    fontname="monospace",
            {i}    fontsize="10",
            {i}    shape="record",
            {i}    style="filled",
            {i}];
            "#,
            i = INDENTATION,
        );

        println!();

        indoc::printdoc!(
            r#"
            {i}edge [
            {i}    fontname="monospace",
            {i}    fontsize="10",
            {i}];
            "#,
            i = INDENTATION,
        );

        println!();

        self.print_nodes(graph, start_node_idx);

        println!();

        self.print_edges(graph);

        println!();

        println!("}}");

        Ok(())
    }

    fn print_nodes(&self, graph: &Graph, start_node_idx: NodeIndex) {
        for node_ref in graph.node_references() {
            let node: &Node = node_ref.weight();
            let node_idx: NodeIndex = node_ref.id();

            let id = node_idx.index();
            let kind = node.kind(self.db);

            let is_highlighted = node_idx == start_node_idx;

            let label = self.node_label(node);
            let attributes = self.node_attributes(node, is_highlighted);

            println!(
                r#"{i}{id} [label="{label}"{attributes}]; // "{kind}" node"#,
                i = INDENTATION,
                id = id,
                label = label,
                attributes = attributes,
                kind = kind,
            );
        }
    }

    fn print_edges(&self, graph: &Graph) {
        for edge_idx in graph.edge_indices() {
            let edge = &graph[edge_idx];
            let (source, target) = graph
                .edge_endpoints(edge_idx)
                .map(|(source, target)| (source.index(), target.index()))
                .unwrap();

            let kind = edge.kind();

            let label = self.edge_label(edge);
            let attributes = self.edge_attributes(edge);

            println!(
                r#"{i}{source} -> {target} [label="{label}"{attributes}]; // "{kind}" edge"#,
                i = INDENTATION,
                source = source,
                target = target,
                label = label,
                attributes = attributes,
                kind = kind,
            );
        }
    }

    fn node_label(&self, node: &Node) -> String {
        let header = self.node_header(node);
        let body = self.node_body(node);

        format!("{}|{}", header, body)
    }

    fn node_header(&self, node: &Node) -> String {
        match node.hir {
            Some(module_def) => {
                let absolute_paths = self.options.absolute_paths;

                let visibility = if node.is_external & !absolute_paths {
                    FormattedVisibility::Public
                } else {
                    FormattedVisibility::new(module_def, self.db)
                };
                let node_kind = node.kind(self.db);
                let kind = match (node_kind, node.is_external, absolute_paths) {
                    (NodeKind::Crate, _, _) => FormattedKind::Crate,
                    (NodeKind::Module, true, false) => FormattedKind::Crate,
                    _ => FormattedKind::new(module_def),
                };
                format!("{} {}", visibility, kind)
            }
            None => format!("orphan {}", FormattedKind::Module),
        }
    }

    fn node_body(&self, node: &Node) -> String {
        if self.options.absolute_paths {
            node.path.clone()
        } else {
            if node.is_external {
                node.crate_name()
            } else {
                node.name()
            }
        }
    }

    fn node_attributes(&self, node: &Node, is_highlighted: bool) -> String {
        let fill_color = match is_highlighted {
            true => self.node_highlight_color(node),
            false => self.node_color(node),
        };
        format!(r#", fillcolor="{}""#, fill_color)
    }

    fn node_color(&self, node: &Node) -> String {
        let colors = colors();
        let color_palette = color_palette();

        let rgb = if node.is_external {
            color_palette.blue
        } else {
            match node.hir {
                Some(module_def) => match FormattedVisibility::new(module_def, self.db) {
                    FormattedVisibility::Crate => colors.visibility.pub_crate,
                    FormattedVisibility::Module(_) => colors.visibility.pub_module,
                    FormattedVisibility::Private => colors.visibility.pub_private,
                    FormattedVisibility::Public => colors.visibility.pub_global,
                    FormattedVisibility::Super => colors.visibility.pub_super,
                },
                None => colors.orphan,
            }
        };

        self.hex_color(rgb)
    }

    fn node_highlight_color(&self, _node: &Node) -> String {
        let color_palette = color_palette();

        self.hex_color(color_palette.cyan)
    }

    fn edge_label(&self, edge: &Edge) -> String {
        match edge {
            Edge::UsesA => "uses".to_owned(),
            Edge::HasA => "has".to_owned(),
        }
    }

    fn edge_attributes(&self, edge: &Edge) -> String {
        // NOTE: To ignore edge in layout add: [constraint=false]

        match edge {
            Edge::UsesA => r#", color="gray", style="dashed", weight="0.5""#.to_string(),
            Edge::HasA => r#", color="black", style="solid", weight="1.0""#.to_string(),
        }
    }

    fn hex_color(&self, rgb: Rgb) -> String {
        let Rgb { r, g, b, .. } = rgb;
        format!("#{:02x}{:02x}{:02x}", r, g, b)
    }
}
<commit_msg>Removed 'weight=' from edges in dot file<commit_after>//! Printer for displaying crate as a graoh.

use petgraph::{
    graph::NodeIndex,
    visit::{IntoNodeReferences, NodeRef},
};
use ra_ap_ide::RootDatabase;

use crate::{
    format::{kind::FormattedKind, visibility::FormattedVisibility},
    graph::{Edge, Graph, Node, NodeKind},
    theme::{color_palette, colors, Rgb},
};

const INDENTATION: &str = "    ";

#[derive(Clone, Debug)]
pub struct Options {
    pub absolute_paths: bool,
    pub layout: String,
}

pub struct Printer<'a> {
    options: Options,
    db: &'a RootDatabase,
}

impl<'a> Printer<'a> {
    pub fn new(options: Options, db: &'a RootDatabase) -> Self {
        Self { options, db }
    }

    pub fn print(&self, graph: &Graph, start_node_idx: NodeIndex) -> Result<(), anyhow::Error> {
        let root_node = &graph[start_node_idx];
        let crate_name = root_node.name();
        let layout_name = &self.options.layout[..];

        println!("digraph {} {{", crate_name);

        println!();

        indoc::printdoc!(
            r#"
            {i}graph [
            {i}    label="{label}",
            {i}    labelloc=t,

            {i}    pad=0.4,

            {i}    // Consider rendering the graph using a different layout algorithm, such as:
            {i}    // [dot, neato, twopi, circo, fdp, sfdp]
            {i}    layout={layout},
            {i}    overlap=false,
            {i}    splines="line",
            {i}    rankdir=LR,

            {i}    fontname="Helvetica",
            {i}    fontsize="36",
            {i}];
            "#,
            i = INDENTATION,
            label = crate_name,
            layout = layout_name,
        );

        println!();

        indoc::printdoc!(
            r#"
            {i}node [
            {i}    fontname="monospace",
            {i}    fontsize="10",
            {i}    shape="record",
            {i}    style="filled",
            {i}];
            "#,
            i = INDENTATION,
        );

        println!();

        indoc::printdoc!(
            r#"
            {i}edge [
            {i}    fontname="monospace",
            {i}    fontsize="10",
            {i}];
            "#,
            i = INDENTATION,
        );

        println!();

        self.print_nodes(graph, start_node_idx);

        println!();

        self.print_edges(graph);

        println!();

        println!("}}");

        Ok(())
    }

    fn print_nodes(&self, graph: &Graph, start_node_idx: NodeIndex) {
        for node_ref in graph.node_references() {
            let node: &Node = node_ref.weight();
            let node_idx: NodeIndex = node_ref.id();

            let id = node_idx.index();
            let kind = node.kind(self.db);

            let is_highlighted = node_idx == start_node_idx;

            let label = self.node_label(node);
            let attributes = self.node_attributes(node, is_highlighted);

            println!(
                r#"{i}{id} [label="{label}"{attributes}]; // "{kind}" node"#,
                i = INDENTATION,
                id = id,
                label = label,
                attributes = attributes,
                kind = kind,
            );
        }
    }

    fn print_edges(&self, graph: &Graph) {
        for edge_idx in graph.edge_indices() {
            let edge = &graph[edge_idx];
            let (source, target) = graph
                .edge_endpoints(edge_idx)
                .map(|(source, target)| (source.index(), target.index()))
                .unwrap();

            let kind = edge.kind();

            let label = self.edge_label(edge);
            let attributes = self.edge_attributes(edge);

            println!(
                r#"{i}{source} -> {target} [label="{label}"{attributes}]; // "{kind}" edge"#,
                i = INDENTATION,
                source = source,
                target = target,
                label = label,
                attributes = attributes,
                kind = kind,
            );
        }
    }

    fn node_label(&self, node: &Node) -> String {
        let header = self.node_header(node);
        let body = self.node_body(node);

        format!("{}|{}", header, body)
    }

    fn node_header(&self, node: &Node) -> String {
        match node.hir {
            Some(module_def) => {
                let absolute_paths = self.options.absolute_paths;

                let visibility = if node.is_external & !absolute_paths {
                    FormattedVisibility::Public
                } else {
                    FormattedVisibility::new(module_def, self.db)
                };
                let node_kind = node.kind(self.db);
                let kind = match (node_kind, node.is_external, absolute_paths) {
                    (NodeKind::Crate, _, _) => FormattedKind::Crate,
                    (NodeKind::Module, true, false) => FormattedKind::Crate,
                    _ => FormattedKind::new(module_def),
                };
                format!("{} {}", visibility, kind)
            }
            None => format!("orphan {}", FormattedKind::Module),
        }
    }

    fn node_body(&self, node: &Node) -> String {
        if self.options.absolute_paths {
            node.path.clone()
        } else {
            if node.is_external {
                node.crate_name()
            } else {
                node.name()
            }
        }
    }

    fn node_attributes(&self, node: &Node, is_highlighted: bool) -> String {
        let fill_color = match is_highlighted {
            true => self.node_highlight_color(node),
            false => self.node_color(node),
        };
        format!(r#", fillcolor="{}""#, fill_color)
    }

    fn node_color(&self, node: &Node) -> String {
        let colors = colors();
        let color_palette = color_palette();

        let rgb = if node.is_external {
            color_palette.blue
        } else {
            match node.hir {
                Some(module_def) => match FormattedVisibility::new(module_def, self.db) {
                    FormattedVisibility::Crate => colors.visibility.pub_crate,
                    FormattedVisibility::Module(_) => colors.visibility.pub_module,
                    FormattedVisibility::Private => colors.visibility.pub_private,
                    FormattedVisibility::Public => colors.visibility.pub_global,
                    FormattedVisibility::Super => colors.visibility.pub_super,
                },
                None => colors.orphan,
            }
        };

        self.hex_color(rgb)
    }

    fn node_highlight_color(&self, _node: &Node) -> String {
        let color_palette = color_palette();

        self.hex_color(color_palette.cyan)
    }

    fn edge_label(&self, edge: &Edge) -> String {
        match edge {
            Edge::UsesA => "uses".to_owned(),
            Edge::HasA => "has".to_owned(),
        }
    }

    fn edge_attributes(&self, edge: &Edge) -> String {
        match edge {
            Edge::UsesA => r#", color="gray", style="dashed""#.to_string(),
            Edge::HasA => r#", color="black", style="solid""#.to_string(),
        }
    }

    fn hex_color(&self, rgb: Rgb) -> String {
        let Rgb { r, g, b, .. } = rgb;
        format!("#{:02x}{:02x}{:02x}", r, g, b)
    }
}
<|endoftext|>


<commit_before>use std::fmt;
use std::cmp;
use std::os;
use term::color;

fn col_cmd(c: &fmt::String) -> String{
    format!("\\[{}[{}\\]", '\x1B', c)
}

pub fn col(c: u16) -> String {
    col_cmd(&format!("{}m", c + 30))
}

pub fn bcol(c: u16) -> String {
    col_cmd(&format!("1;{}m", c + 30))
}

pub fn reset() -> String {
    col_cmd(&"0m")
}

#[derive(Clone)]
enum PromptLineType {
    Boxed,
    Free
}

/// PromptBox
///
/// The smallest component of a prompt line
///
/// Contains a color, text, and "is bold" flag
#[derive(Clone)]
struct PromptBox {
    color: color::Color,
    text: String,
    is_bold: bool
}

#[allow(unstable)] impl fmt::String for PromptBox {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}{}{}", if self.is_bold { bcol(self.color) } else { col(self.color) }, self.text, reset())
    }
}

/// PromptLine
///
/// The small pieces used to display prompt lines
#[derive(Clone)]
pub struct PromptLine {
    level: u8,
    line_type: PromptLineType,
    parts: Vec<PromptBox>,
}

impl PromptLine {
    fn new() -> PromptLine {
        PromptLine {
            level: 0,
            line_type: PromptLineType::Boxed,
            parts: Vec::new(),
        }
    }

    fn new_free() -> PromptLine {
        let mut r = PromptLine::new();
        r.line_type = PromptLineType::Free;
        r
    }
}

/// PromptLineBuilder
///
/// Used to easily construct PromptLines
pub struct PromptLineBuilder {
    line: PromptLine
}

impl PromptLineBuilder {
    pub fn new() -> PromptLineBuilder {
        PromptLineBuilder {
            line: PromptLine::new()
        }
    }

    pub fn new_free() -> PromptLineBuilder {
        PromptLineBuilder {
            line: PromptLine::new_free()
        }
    }

    pub fn indent_by(mut self, amt: u8) -> PromptLineBuilder {
        self.line.level += amt;

        self
    }

    pub fn indent(self) -> PromptLineBuilder {
        self.indent_by(1)
    }

    fn add_block(mut self, s: &fmt::String, c: u16, bold: bool) -> PromptLineBuilder {
        self.line.parts.push(
            PromptBox {
                color: c,
                text: format!("{}", s),
                is_bold: bold
            }
        );

        self
    }

    pub fn block(self, s: &fmt::String) -> PromptLineBuilder {
        self.add_block(s, color::MAGENTA, false)
    }

    pub fn colored_block(self, s: &fmt::String, c: u16) -> PromptLineBuilder {
        self.add_block(s, c, false)
    }

    pub fn bold_colored_block(self, s: &fmt::String, c: u16) -> PromptLineBuilder {
        self.add_block(s, c, true)
    }

    pub fn build(self) -> PromptLine {
        self.line
    }
}

const TOP       : i16 = 8;
const BOTTOM    : i16 = 4;
const LEFT      : i16 = 2;
const RIGHT     : i16 = 1;

/// PromptBuffer
///
/// Used to contain a list of PromptLines
/// Knows how to format a serise of PromptLines in a pretty way
pub struct PromptBuffer {
    plugins: Vec<Box<PromptBufferPlugin+Send>>,
    path: Path
}

impl PromptBuffer {
    pub fn new() -> PromptBuffer {
        #![allow(unstable)]
        PromptBuffer {
            plugins: Vec::new(),
            path: os::make_absolute(&Path::new(".")).unwrap()
        }
    }

    fn get_line(flags: i16) -> char {
        return match flags {
            0b1111 => '┼',
            0b1110 => '┤',
            0b1101 => '├',
            0b1100 => '│',
            0b1011 => '┴',
            0b1010 => '┘',
            0b1001 => '└',
            0b0110 => '┐',
            0b0101 => '┌',
            0b0111 => '┬',
            0b0011 => '─',
            _      => ' '
        }
    }

    fn trail_off() -> String {
        let mut retval = String::new();
        for _ in 0..10 {
            retval = format!("{}{}", retval, PromptBuffer::get_line(LEFT|RIGHT));
        }
        retval
    }

    pub fn start(&self, lines: &mut Vec<PromptLine>) {
        lines.push(PromptLineBuilder::new()
            .block(&"\\w")
            .block(&"\\H")
            .build());
    }

    pub fn add_plugin(&mut self, plugin: Box<PromptBufferPlugin+Send>) {
        self.plugins.push(plugin);
    }

    pub fn set_path(&mut self, p: Path) {
        self.path = p;
    }

    pub fn to_string_ext(&mut self, fast: bool) -> String {
        let mut retval = String::new();
        let mut lines = Vec::new();

        self.start(&mut lines);

        if !fast {
            let mut pl = self.plugins.as_mut_slice();
            for i in 0 .. pl.len() {
                pl[i].run(&self.path, &mut lines);
            }
        }

        for ix in 0 .. lines.len() {
            let ref line = lines[ix];
            let current = line.level;
            let (after, start, end) = if ix + 1 < lines.len() {
                let a = lines[ix + 1].level;
                (a, cmp::min(current, a), cmp::max(current, a))
            } else {
                (0, 0, current)
            };

            let mut line_text = String::new();

            // FIXME: change when range syntax is fixed
            for _ in (0..start) {
                line_text = format!(" {}", line_text);
            }

            for i in start .. end + 1 {
                line_text = format!("{}{}", line_text,
                    PromptBuffer::get_line(
                        if i == current && ix > 0 { TOP } else { 0 } |
                        if i == after { BOTTOM } else { 0 } |
                        if i > start { LEFT } else { 0 } |
                        match line.line_type {
                            PromptLineType::Boxed => RIGHT,
                            PromptLineType::Free => if i == current {
                                0
                            } else {
                                RIGHT
                            }
                        }
                    )
                );
            }

            for b in line.parts.iter() {
                line_text = match line.line_type {
                    PromptLineType::Boxed => format!("{}{}{}{}{}",
                        line_text,
                        PromptBuffer::get_line(LEFT|RIGHT),
                        PromptBuffer::get_line(LEFT|TOP|BOTTOM),
                        b,
                        PromptBuffer::get_line(TOP|BOTTOM|RIGHT)),
                    PromptLineType::Free => format!("{} {}", line_text, b)
                };
            }

            match line.line_type {
                PromptLineType::Boxed => {
                    line_text = format!("{}{}", line_text, PromptBuffer::trail_off());
                },
                _ => {}
            }

            retval = format!("{}{}\n", retval, line_text);
        }

        format!("{}{}{}{} ",
            retval,
            PromptBuffer::get_line(TOP|RIGHT), PromptBuffer::get_line(LEFT|RIGHT),
            PromptBox {
                text: "\\$".to_string(),
                color: color::RED,
                is_bold: false
            })
    }

    pub fn to_string(&mut self) -> String {
        self.to_string_ext(false)
    }

    pub fn print(&mut self) {
        println!("{}", self.to_string());
    }

    pub fn print_fast(&mut self) {
        println!("{}", self.to_string_ext(true));
    }
}

pub trait PromptBufferPlugin {
    fn run(&mut self, path: &Path, lines: &mut Vec<PromptLine>);
}
<commit_msg>Clear up get_line<commit_after>use std::fmt;
use std::cmp;
use std::os;
use term::color;

fn col_cmd(c: &fmt::String) -> String{
    format!("\\[{}[{}\\]", '\x1B', c)
}

pub fn col(c: u16) -> String {
    col_cmd(&format!("{}m", c + 30))
}

pub fn bcol(c: u16) -> String {
    col_cmd(&format!("1;{}m", c + 30))
}

pub fn reset() -> String {
    col_cmd(&"0m")
}

#[derive(Clone)]
enum PromptLineType {
    Boxed,
    Free
}

/// PromptBox
///
/// The smallest component of a prompt line
///
/// Contains a color, text, and "is bold" flag
#[derive(Clone)]
struct PromptBox {
    color: color::Color,
    text: String,
    is_bold: bool
}

#[allow(unstable)] impl fmt::String for PromptBox {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}{}{}", if self.is_bold { bcol(self.color) } else { col(self.color) }, self.text, reset())
    }
}

/// PromptLine
///
/// The small pieces used to display prompt lines
#[derive(Clone)]
pub struct PromptLine {
    level: u8,
    line_type: PromptLineType,
    parts: Vec<PromptBox>,
}

impl PromptLine {
    fn new() -> PromptLine {
        PromptLine {
            level: 0,
            line_type: PromptLineType::Boxed,
            parts: Vec::new(),
        }
    }

    fn new_free() -> PromptLine {
        let mut r = PromptLine::new();
        r.line_type = PromptLineType::Free;
        r
    }
}

/// PromptLineBuilder
///
/// Used to easily construct PromptLines
pub struct PromptLineBuilder {
    line: PromptLine
}

impl PromptLineBuilder {
    pub fn new() -> PromptLineBuilder {
        PromptLineBuilder {
            line: PromptLine::new()
        }
    }

    pub fn new_free() -> PromptLineBuilder {
        PromptLineBuilder {
            line: PromptLine::new_free()
        }
    }

    pub fn indent_by(mut self, amt: u8) -> PromptLineBuilder {
        self.line.level += amt;

        self
    }

    pub fn indent(self) -> PromptLineBuilder {
        self.indent_by(1)
    }

    fn add_block(mut self, s: &fmt::String, c: u16, bold: bool) -> PromptLineBuilder {
        self.line.parts.push(
            PromptBox {
                color: c,
                text: format!("{}", s),
                is_bold: bold
            }
        );

        self
    }

    pub fn block(self, s: &fmt::String) -> PromptLineBuilder {
        self.add_block(s, color::MAGENTA, false)
    }

    pub fn colored_block(self, s: &fmt::String, c: u16) -> PromptLineBuilder {
        self.add_block(s, c, false)
    }

    pub fn bold_colored_block(self, s: &fmt::String, c: u16) -> PromptLineBuilder {
        self.add_block(s, c, true)
    }

    pub fn build(self) -> PromptLine {
        self.line
    }
}

const TOP       : i16 = 8;
const BOTTOM    : i16 = 4;
const LEFT      : i16 = 2;
const RIGHT     : i16 = 1;

/// PromptBuffer
///
/// Used to contain a list of PromptLines
/// Knows how to format a serise of PromptLines in a pretty way
pub struct PromptBuffer {
    plugins: Vec<Box<PromptBufferPlugin+Send>>,
    path: Path
}

impl PromptBuffer {
    pub fn new() -> PromptBuffer {
        PromptBuffer {
            plugins: Vec::new(),
            path: os::make_absolute(&Path::new(".")).unwrap()
        }
    }

    fn get_line(flags: i16) -> char {
        return match flags {
            c if c == TOP | BOTTOM | LEFT | RIGHT => '┼',
            c if c == TOP | BOTTOM | LEFT         => '┤',
            c if c == TOP | BOTTOM        | RIGHT => '├',
            c if c == TOP | BOTTOM                => '│',
            c if c == TOP          | LEFT | RIGHT => '┴',
            c if c == TOP          | LEFT         => '┘',
            c if c == TOP                 | RIGHT => '└',
            c if c ==       BOTTOM | LEFT         => '┐',
            c if c ==       BOTTOM        | RIGHT => '┌',
            c if c ==       BOTTOM | LEFT | RIGHT => '┬',
            c if c ==                LEFT | RIGHT => '─',
            _      => panic!("Passed invalid value to get_line")
        }
    }

    fn trail_off() -> String {
        let mut retval = String::new();
        for _ in 0..10 {
            retval = format!("{}{}", retval, PromptBuffer::get_line(LEFT|RIGHT));
        }
        retval
    }

    pub fn start(&self, lines: &mut Vec<PromptLine>) {
        lines.push(PromptLineBuilder::new()
            .block(&"\\w")
            .block(&"\\H")
            .build());
    }

    pub fn add_plugin(&mut self, plugin: Box<PromptBufferPlugin+Send>) {
        self.plugins.push(plugin);
    }

    pub fn set_path(&mut self, p: Path) {
        self.path = p;
    }

    pub fn to_string_ext(&mut self, fast: bool) -> String {
        let mut retval = String::new();
        let mut lines = Vec::new();

        self.start(&mut lines);

        if !fast {
            let mut pl = self.plugins.as_mut_slice();
            for i in 0 .. pl.len() {
                pl[i].run(&self.path, &mut lines);
            }
        }

        for ix in 0 .. lines.len() {
            let ref line = lines[ix];
            let current = line.level;
            let (after, start, end) = if ix + 1 < lines.len() {
                let a = lines[ix + 1].level;
                (a, cmp::min(current, a), cmp::max(current, a))
            } else {
                (0, 0, current)
            };

            let mut line_text = String::new();

            // FIXME: change when range syntax is fixed
            for _ in (0..start) {
                line_text = format!(" {}", line_text);
            }

            for i in start .. end + 1 {
                line_text = format!("{}{}", line_text,
                    PromptBuffer::get_line(
                        if i == current && ix > 0 { TOP } else { 0 } |
                        if i == after { BOTTOM } else { 0 } |
                        if i > start { LEFT } else { 0 } |
                        match line.line_type {
                            PromptLineType::Boxed => RIGHT,
                            PromptLineType::Free => if i == current {
                                0
                            } else {
                                RIGHT
                            }
                        }
                    )
                );
            }

            for b in line.parts.iter() {
                line_text = match line.line_type {
                    PromptLineType::Boxed => format!("{}{}{}{}{}",
                        line_text,
                        PromptBuffer::get_line(LEFT|RIGHT),
                        PromptBuffer::get_line(LEFT|TOP|BOTTOM),
                        b,
                        PromptBuffer::get_line(TOP|BOTTOM|RIGHT)),
                    PromptLineType::Free => format!("{} {}", line_text, b)
                };
            }

            match line.line_type {
                PromptLineType::Boxed => {
                    line_text = format!("{}{}", line_text, PromptBuffer::trail_off());
                },
                _ => {}
            }

            retval = format!("{}{}\n", retval, line_text);
        }

        format!("{}{}{}{} ",
            retval,
            PromptBuffer::get_line(TOP|RIGHT), PromptBuffer::get_line(LEFT|RIGHT),
            PromptBox {
                text: "\\$".to_string(),
                color: color::RED,
                is_bold: false
            })
    }

    pub fn to_string(&mut self) -> String {
        self.to_string_ext(false)
    }

    pub fn print(&mut self) {
        println!("{}", self.to_string());
    }

    pub fn print_fast(&mut self) {
        println!("{}", self.to_string_ext(true));
    }
}

pub trait PromptBufferPlugin {
    fn run(&mut self, path: &Path, lines: &mut Vec<PromptLine>);
}
<|endoftext|>


<commit_before>use std::convert::From;
use std::fmt;
use std::ops::Deref;
use std::path::{Path, PathBuf};

#[derive(Debug, PartialEq)]
pub struct Text {
    text: String,
}

pub trait Textable {
    fn to_text(self) -> Text;
}

// impl<T> Textable for T where String: From<T> {
//     fn to_text(self) -> Text {
//         Text { text: String::from(self) }
//     }
// }

impl<'a> Textable for &'a str {
    fn to_text(self) -> Text {
        Text { text: self.to_owned() }
    }
}

impl Textable for String {
    fn to_text(self) -> Text {
        Text { text: self }
    }
}

impl<'a> Textable for &'a Path {
    fn to_text(self) -> Text {
        Text { text: self.to_string_lossy().into_owned() }
    }
}

impl Textable for PathBuf {
    fn to_text(self) -> Text {
        Text { text: self.to_string_lossy().into_owned() }
    }
}

impl Text {
    pub fn new() -> Self {
        Text { text: String::new() }
    }

    pub fn len(&self) -> usize {
        self.text.len()
    }

    pub fn is_empty(&self) -> bool {
        self.text.is_empty()
    }
}

impl fmt::Display for Text {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad(&self.text)
    }
}

impl Deref for Text {
    type Target = str;
    fn deref(&self) -> &str {
        &self.text
    }
}

// DOES NOT WORK
// impl<T> PartialEq<T> for Text where T: Textable + Clone {
//     fn eq(&self, other: &T) -> bool {
//         let other = Text::from(other.clone());
//         self.text == other.text
//     }
// }

impl PartialEq<str> for Text {
    fn eq(&self, other: &str) -> bool {
        *self == Text::from(other)
    }
}

impl<'a> PartialEq<&'a str> for Text {
    fn eq(&self, other: &&'a str) -> bool {
        self.text == *other
    }
}

impl PartialEq<String> for Text {
    fn eq(&self, other: &String) -> bool {
        &self.text == other
    }
}

impl<'a> PartialEq<String> for &'a Text {
    fn eq(&self, other: &String) -> bool {
        self.text == *other
    }
}

// impl<'a, T> PartialEq<T> for Text
//     where Text: From<&'a T>,
//           T: 'a
// {
//     fn eq(&self, other: &T) -> bool {
//         let other = Text::from(other);
//         self.text == other.text
//     }
// }

impl PartialEq<Path> for Text {
    fn eq(&self, other: &Path) -> bool {
        match other.to_str() {
            Some(s) => self.text == s,
            None => false,
        }
    }
}

impl<'a> PartialEq<&'a Path> for Text {
    fn eq(&self, other: &&'a Path) -> bool {
        match other.to_str() {
            Some(s) => self.text == s,
            None => false,
        }
    }
}

//////////////////////

impl<T> From<T> for Text
    where T: Textable
{
    fn from(s: T) -> Self {
        s.to_text()
    }
}

// impl<'a> From<&'a str> for Text {
//     fn from(s: &'a str) -> Self {
//         Text { text: s.to_owned() }
//     }
// }

// impl<T> From<T> for Text
//     where T: Into<String>
// {
//     default fn from(s: T) -> Self {
//         Text { text: s.into() }
//     }
// }

// impl<T> From<&T> for Text
//     where String: From<&T>
// {
//     fn from(s: &T) -> Self {
//         Text { text: String::from(s) }
//     }
// }

// impl<'a, T> From<T> for Text
//     where String: From<&'a T>,
//         T: 'a
// {
//     fn from(ref s: T) -> Self {
//         Text { text: String::from(s) }
//     }
// }

// impl From<String> for Text {
//     fn from(s: String) -> Self {
//         Text { text: s }
//     }
// }

// impl<'a> From<&'a Path> for Text {
//     fn from(s: &'a Path) -> Self {
//         Text { text: s.to_string_lossy().into_owned() }
//     }
// }
//
// impl From<PathBuf> for Text {
//     fn from(s: PathBuf) -> Self {
//         Text { text: s.to_string_lossy().into_owned() }
//     }
// }

// impl From<Text> for String {
//     fn from(t: Text) -> Self {
//         t.text
//     }
// }
<commit_msg>Drop unused commented out code<commit_after>use std::convert::From;
use std::fmt;
use std::ops::Deref;
use std::path::{Path, PathBuf};

#[derive(Debug, PartialEq)]
pub struct Text {
    text: String,
}

pub trait Textable {
    fn to_text(self) -> Text;
}

// impl<T> Textable for T where String: From<T> {
//     fn to_text(self) -> Text {
//         Text { text: String::from(self) }
//     }
// }

impl<'a> Textable for &'a str {
    fn to_text(self) -> Text {
        Text { text: self.to_owned() }
    }
}

impl Textable for String {
    fn to_text(self) -> Text {
        Text { text: self }
    }
}

impl<'a> Textable for &'a Path {
    fn to_text(self) -> Text {
        Text { text: self.to_string_lossy().into_owned() }
    }
}

impl Textable for PathBuf {
    fn to_text(self) -> Text {
        Text { text: self.to_string_lossy().into_owned() }
    }
}

impl Text {
    pub fn new() -> Self {
        Text { text: String::new() }
    }

    pub fn len(&self) -> usize {
        self.text.len()
    }

    pub fn is_empty(&self) -> bool {
        self.text.is_empty()
    }
}

impl fmt::Display for Text {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad(&self.text)
    }
}

impl Deref for Text {
    type Target = str;
    fn deref(&self) -> &str {
        &self.text
    }
}

impl PartialEq<str> for Text {
    fn eq(&self, other: &str) -> bool {
        *self == Text::from(other)
    }
}

impl<'a> PartialEq<&'a str> for Text {
    fn eq(&self, other: &&'a str) -> bool {
        self.text == *other
    }
}

impl PartialEq<String> for Text {
    fn eq(&self, other: &String) -> bool {
        &self.text == other
    }
}

impl<'a> PartialEq<String> for &'a Text {
    fn eq(&self, other: &String) -> bool {
        self.text == *other
    }
}

impl PartialEq<Path> for Text {
    fn eq(&self, other: &Path) -> bool {
        match other.to_str() {
            Some(s) => self.text == s,
            None => false,
        }
    }
}

impl<'a> PartialEq<&'a Path> for Text {
    fn eq(&self, other: &&'a Path) -> bool {
        match other.to_str() {
            Some(s) => self.text == s,
            None => false,
        }
    }
}

impl<T> From<T> for Text
    where T: Textable
{
    fn from(s: T) -> Self {
        s.to_text()
    }
}

/////

impl From<Text> for String {
    fn from(t: Text) -> Self {
        t.text
    }
}
<|endoftext|>


<commit_before>use seed::prelude::*;
use crate::Msg;

extern crate num_bigint;
extern crate num_traits;

use num_bigint::{BigUint};

pub fn set_panic_hook() {
    // When the `console_error_panic_hook` feature is enabled, we can call the
    // `set_panic_hook` function at least once during initialization, and then
    // we will get better error messages if our code ever panics.
    //
    // For more details see
    // https://github.com/rustwasm/console_error_panic_hook#readme
    #[cfg(feature = "console_error_panic_hook")]
    console_error_panic_hook::set_once();
}

pub fn nth(num: usize) -> String {
    //format a number to say 1st, 2nd, 3rd etc
    format!("{}{}", num, match (num % 10, num % 100) {
        (1, 11) | (2, 12) | (3, 13) => "th",
        (1, _) => "st",
        (2, _) => "nd",
        (3, _) => "rd",
        _ => "th",
    })
}

pub fn save_as_file(filename:String, filecontent:String) -> seed::dom_types::Node<Msg> {
        let href:String = format!("data:text/plain,{}",&filecontent);
        a![attrs!{At::Download => &filename, At::Href => &href}, "TXT"]
}

pub fn generate_file(n:u64, value:BigUint) -> seed::dom_types::Node<Msg> {
    let download_filename:String = format!("P{}.txt",&n.to_string());
    save_as_file(download_filename, value.to_string())
}

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

    #[test]
    fn nth_test() {
        assert_eq!(nth(7), "7th");
        assert_ne!(nth(7), "1st");
        assert_eq!(nth(7000000000000000000), "7000000000000000000th");
        assert_eq!(nth(7000000000000000001), "7000000000000000001st");
        assert_eq!(nth(7000000000000000002), "7000000000000000002nd");
        assert_eq!(nth(7000000000000000003), "7000000000000000003rd");
        assert_eq!(nth(7000000000000000011), "7000000000000000011th");
        assert_eq!(nth(7000000000000000012), "7000000000000000012th");
        assert_eq!(nth(7000000000000000013), "7000000000000000013th");
    }

    #[test]
    fn save_as_file_test() {
        let test_file = save_as_file(
            String::from("example name"),
            String::from("some content")
        );

        assert_eq!(test_file.get_text(), "TXT");
        //todo: we are only testing the link text currently
    }
}
<commit_msg>Added unit test for link text returned by generate_file()<commit_after>use seed::prelude::*;
use crate::Msg;

extern crate num_bigint;
extern crate num_traits;

use num_bigint::{BigUint};

pub fn set_panic_hook() {
    // When the `console_error_panic_hook` feature is enabled, we can call the
    // `set_panic_hook` function at least once during initialization, and then
    // we will get better error messages if our code ever panics.
    //
    // For more details see
    // https://github.com/rustwasm/console_error_panic_hook#readme
    #[cfg(feature = "console_error_panic_hook")]
    console_error_panic_hook::set_once();
}

pub fn nth(num: usize) -> String {
    //format a number to say 1st, 2nd, 3rd etc
    format!("{}{}", num, match (num % 10, num % 100) {
        (1, 11) | (2, 12) | (3, 13) => "th",
        (1, _) => "st",
        (2, _) => "nd",
        (3, _) => "rd",
        _ => "th",
    })
}

pub fn save_as_file(filename:String, filecontent:String) -> seed::dom_types::Node<Msg> {
        let href:String = format!("data:text/plain,{}",&filecontent);
        a![attrs!{At::Download => &filename, At::Href => &href}, "TXT"]
}

pub fn generate_file(n:u64, value:BigUint) -> seed::dom_types::Node<Msg> {
    let download_filename:String = format!("P{}.txt",&n.to_string());
    save_as_file(download_filename, value.to_string())
}

#[cfg(test)]
mod tests {
    extern crate num_bigint;
    extern crate num_traits;

    use num_bigint::{BigUint,ToBigUint};

    use super::*;

    #[test]
    fn nth_test() {
        assert_eq!(nth(7), "7th");
        assert_ne!(nth(7), "1st");
        assert_eq!(nth(7000000000000000000), "7000000000000000000th");
        assert_eq!(nth(7000000000000000001), "7000000000000000001st");
        assert_eq!(nth(7000000000000000002), "7000000000000000002nd");
        assert_eq!(nth(7000000000000000003), "7000000000000000003rd");
        assert_eq!(nth(7000000000000000011), "7000000000000000011th");
        assert_eq!(nth(7000000000000000012), "7000000000000000012th");
        assert_eq!(nth(7000000000000000013), "7000000000000000013th");
    }

    #[test]
    fn save_as_file_test() {
        let test_file = save_as_file(
            String::from("example name"),
            String::from("some content")
        );

        assert_eq!(test_file.get_text(), "TXT");
        //todo: we are only testing the link text currently
    }

    #[test]
    fn generate_file_test() {
        let two:BigUint = 2.to_biguint().unwrap();

        assert_eq!(generate_file(8, two).get_text(), "TXT");
        //TODO: this test is not checking download value, or the <a> attributes. Just link text.
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::cmp::Ordering;

use syntax::ast::{self, Visibility, Attribute, MetaItem, MetaItem_};
use syntax::codemap::{CodeMap, Span, BytePos};
use syntax::abi;

use Indent;
use comment::FindUncommented;
use rewrite::{Rewrite, RewriteContext};

use SKIP_ANNOTATION;

// Computes the length of a string's last line, minus offset.
#[inline]
pub fn extra_offset(text: &str, offset: Indent) -> usize {
    match text.rfind('\n') {
        // 1 for newline character
        Some(idx) => text.len() - idx - 1 - offset.width(),
        None => text.len(),
    }
}

#[inline]
pub fn span_after(original: Span, needle: &str, codemap: &CodeMap) -> BytePos {
    let snippet = codemap.span_to_snippet(original).unwrap();
    let offset = snippet.find_uncommented(needle).unwrap() + needle.len();

    original.lo + BytePos(offset as u32)
}

#[inline]
pub fn format_visibility(vis: Visibility) -> &'static str {
    match vis {
        Visibility::Public => "pub ",
        Visibility::Inherited => "",
    }
}

#[inline]
pub fn format_unsafety(unsafety: ast::Unsafety) -> &'static str {
    match unsafety {
        ast::Unsafety::Unsafe => "unsafe ",
        ast::Unsafety::Normal => "",
    }
}

#[inline]
pub fn format_mutability(mutability: ast::Mutability) -> &'static str {
    match mutability {
        ast::Mutability::MutMutable => "mut ",
        ast::Mutability::MutImmutable => "",
    }
}

#[inline]
// FIXME(#451): include "C"?
pub fn format_abi(abi: abi::Abi) -> String {
    format!("extern {} ", abi)
}

// The width of the first line in s.
#[inline]
pub fn first_line_width(s: &str) -> usize {
    match s.find('\n') {
        Some(n) => n,
        None => s.len(),
    }
}

// The width of the last line in s.
#[inline]
pub fn last_line_width(s: &str) -> usize {
    match s.rfind('\n') {
        Some(n) => s.len() - n - 1,
        None => s.len(),
    }
}

#[inline]
fn is_skip(meta_item: &MetaItem) -> bool {
    match meta_item.node {
        MetaItem_::MetaWord(ref s) => *s == SKIP_ANNOTATION,
        MetaItem_::MetaList(ref s, ref l) => *s == "cfg_attr" && l.len() == 2 && is_skip(&l[1]),
        _ => false,
    }
}

#[inline]
pub fn contains_skip(attrs: &[Attribute]) -> bool {
    attrs.iter().any(|a| is_skip(&a.node.value))
}

// Find the end of a TyParam
#[inline]
pub fn end_typaram(typaram: &ast::TyParam) -> BytePos {
    typaram.bounds
           .last()
           .map(|bound| {
               match *bound {
                   ast::RegionTyParamBound(ref lt) => lt.span,
                   ast::TraitTyParamBound(ref prt, _) => prt.span,
               }
           })
           .unwrap_or(typaram.span)
           .hi
}

#[inline]
pub fn semicolon_for_expr(expr: &ast::Expr) -> bool {
    match expr.node {
        ast::Expr_::ExprRet(..) |
        ast::Expr_::ExprAgain(..) |
        ast::Expr_::ExprBreak(..) => true,
        _ => false,
    }
}

#[inline]
pub fn semicolon_for_stmt(stmt: &ast::Stmt) -> bool {
    match stmt.node {
        ast::Stmt_::StmtSemi(ref expr, _) => {
            match expr.node {
                ast::Expr_::ExprWhile(..) |
                ast::Expr_::ExprWhileLet(..) |
                ast::Expr_::ExprLoop(..) |
                ast::Expr_::ExprForLoop(..) => false,
                _ => true,
            }
        }
        ast::Stmt_::StmtExpr(..) => false,
        _ => true,
    }
}

#[inline]
pub fn trim_newlines(input: &str) -> &str {
    let start = input.find(|c| c != '\n' && c != '\r').unwrap_or(0);
    let end = input.rfind(|c| c != '\n' && c != '\r').unwrap_or(0) + 1;
    if start == 0 && end == 1 {
        input
    } else {
        &input[start..end]
    }
}

#[inline]
#[cfg(target_pointer_width="64")]
// Based on the trick layed out at
// http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
pub fn round_up_to_power_of_two(mut x: usize) -> usize {
    x = x.wrapping_sub(1);
    x |= x >> 1;
    x |= x >> 2;
    x |= x >> 4;
    x |= x >> 8;
    x |= x >> 16;
    x |= x >> 32;
    x.wrapping_add(1)
}

#[inline]
#[cfg(target_pointer_width="32")]
pub fn round_up_to_power_of_two(mut x: usize) -> usize {
    x = x.wrapping_sub(1);
    x |= x >> 1;
    x |= x >> 2;
    x |= x >> 4;
    x |= x >> 8;
    x |= x >> 16;
    x.wrapping_add(1)
}

// Macro for deriving implementations of Decodable for enums
#[macro_export]
macro_rules! impl_enum_decodable {
    ( $e:ident, $( $x:ident ),* ) => {
        impl ::rustc_serialize::Decodable for $e {
            fn decode<D: ::rustc_serialize::Decoder>(d: &mut D) -> Result<Self, D::Error> {
                let s = try!(d.read_str());
                match &*s {
                    $(
                        stringify!($x) => Ok($e::$x),
                    )*
                    _ => Err(d.error("Bad variant")),
                }
            }
        }

        impl ::std::str::FromStr for $e {
            type Err = &'static str;

            fn from_str(s: &str) -> Result<Self, Self::Err> {
                match &*s {
                    $(
                        stringify!($x) => Ok($e::$x),
                    )*
                    _ => Err("Bad variant"),
                }
            }
        }

        impl ::config::ConfigType for $e {
            fn get_variant_names() -> String {
                let mut variants = Vec::new();
                $(
                    variants.push(stringify!($x));
                )*
                format!("[{}]", variants.join("|"))
            }
        }
    };
}

// Same as try!, but for Option
#[macro_export]
macro_rules! try_opt {
    ($expr:expr) => (match $expr {
        Some(val) => val,
        None => { return None; }
    })
}

// Wraps string-like values in an Option. Returns Some when the string adheres
// to the Rewrite constraints defined for the Rewrite trait and else otherwise.
pub fn wrap_str<S: AsRef<str>>(s: S, max_width: usize, width: usize, offset: Indent) -> Option<S> {
    {
        let snippet = s.as_ref();

        if !snippet.contains('\n') && snippet.len() > width {
            return None;
        } else {
            let mut lines = snippet.lines();

            // The caller of this function has already placed `offset`
            // characters on the first line.
            let first_line_max_len = try_opt!(max_width.checked_sub(offset.width()));
            if lines.next().unwrap().len() > first_line_max_len {
                return None;
            }

            // The other lines must fit within the maximum width.
            if lines.find(|line| line.len() > max_width).is_some() {
                return None;
            }

            // `width` is the maximum length of the last line, excluding
            // indentation.
            // A special check for the last line, since the caller may
            // place trailing characters on this line.
            if snippet.lines().rev().next().unwrap().len() > offset.width() + width {
                return None;
            }
        }
    }

    Some(s)
}

impl Rewrite for String {
    fn rewrite(&self, context: &RewriteContext, width: usize, offset: Indent) -> Option<String> {
        wrap_str(self, context.config.max_width, width, offset).map(ToOwned::to_owned)
    }
}

// Binary search in integer range. Returns the first Ok value returned by the
// callback.
// The callback takes an integer and returns either an Ok, or an Err indicating
// whether the `guess' was too high (Ordering::Less), or too low.
// This function is guaranteed to try to the hi value first.
pub fn binary_search<C, T>(mut lo: usize, mut hi: usize, callback: C) -> Option<T>
    where C: Fn(usize) -> Result<T, Ordering>
{
    let mut middle = hi;

    while lo <= hi {
        match callback(middle) {
            Ok(val) => return Some(val),
            Err(Ordering::Less) => {
                hi = middle - 1;
            }
            Err(..) => {
                lo = middle + 1;
            }
        }
        middle = (hi + lo) / 2;
    }

    None
}

#[test]
fn bin_search_test() {
    let closure = |i| {
        match i {
            4 => Ok(()),
            j if j > 4 => Err(Ordering::Less),
            j if j < 4 => Err(Ordering::Greater),
            _ => unreachable!(),
        }
    };

    assert_eq!(Some(()), binary_search(1, 10, &closure));
    assert_eq!(None, binary_search(1, 3, &closure));
    assert_eq!(Some(()), binary_search(0, 44, &closure));
    assert_eq!(Some(()), binary_search(4, 125, &closure));
    assert_eq!(None, binary_search(6, 100, &closure));
}

#[test]
fn power_rounding() {
    assert_eq!(0, round_up_to_power_of_two(0));
    assert_eq!(1, round_up_to_power_of_two(1));
    assert_eq!(64, round_up_to_power_of_two(33));
    assert_eq!(256, round_up_to_power_of_two(256));
}
<commit_msg>Reformat trim_newlines<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::cmp::Ordering;

use syntax::ast::{self, Visibility, Attribute, MetaItem, MetaItem_};
use syntax::codemap::{CodeMap, Span, BytePos};
use syntax::abi;

use Indent;
use comment::FindUncommented;
use rewrite::{Rewrite, RewriteContext};

use SKIP_ANNOTATION;

// Computes the length of a string's last line, minus offset.
#[inline]
pub fn extra_offset(text: &str, offset: Indent) -> usize {
    match text.rfind('\n') {
        // 1 for newline character
        Some(idx) => text.len() - idx - 1 - offset.width(),
        None => text.len(),
    }
}

#[inline]
pub fn span_after(original: Span, needle: &str, codemap: &CodeMap) -> BytePos {
    let snippet = codemap.span_to_snippet(original).unwrap();
    let offset = snippet.find_uncommented(needle).unwrap() + needle.len();

    original.lo + BytePos(offset as u32)
}

#[inline]
pub fn format_visibility(vis: Visibility) -> &'static str {
    match vis {
        Visibility::Public => "pub ",
        Visibility::Inherited => "",
    }
}

#[inline]
pub fn format_unsafety(unsafety: ast::Unsafety) -> &'static str {
    match unsafety {
        ast::Unsafety::Unsafe => "unsafe ",
        ast::Unsafety::Normal => "",
    }
}

#[inline]
pub fn format_mutability(mutability: ast::Mutability) -> &'static str {
    match mutability {
        ast::Mutability::MutMutable => "mut ",
        ast::Mutability::MutImmutable => "",
    }
}

#[inline]
// FIXME(#451): include "C"?
pub fn format_abi(abi: abi::Abi) -> String {
    format!("extern {} ", abi)
}

// The width of the first line in s.
#[inline]
pub fn first_line_width(s: &str) -> usize {
    match s.find('\n') {
        Some(n) => n,
        None => s.len(),
    }
}

// The width of the last line in s.
#[inline]
pub fn last_line_width(s: &str) -> usize {
    match s.rfind('\n') {
        Some(n) => s.len() - n - 1,
        None => s.len(),
    }
}

#[inline]
fn is_skip(meta_item: &MetaItem) -> bool {
    match meta_item.node {
        MetaItem_::MetaWord(ref s) => *s == SKIP_ANNOTATION,
        MetaItem_::MetaList(ref s, ref l) => *s == "cfg_attr" && l.len() == 2 && is_skip(&l[1]),
        _ => false,
    }
}

#[inline]
pub fn contains_skip(attrs: &[Attribute]) -> bool {
    attrs.iter().any(|a| is_skip(&a.node.value))
}

// Find the end of a TyParam
#[inline]
pub fn end_typaram(typaram: &ast::TyParam) -> BytePos {
    typaram.bounds
           .last()
           .map(|bound| {
               match *bound {
                   ast::RegionTyParamBound(ref lt) => lt.span,
                   ast::TraitTyParamBound(ref prt, _) => prt.span,
               }
           })
           .unwrap_or(typaram.span)
           .hi
}

#[inline]
pub fn semicolon_for_expr(expr: &ast::Expr) -> bool {
    match expr.node {
        ast::Expr_::ExprRet(..) |
        ast::Expr_::ExprAgain(..) |
        ast::Expr_::ExprBreak(..) => true,
        _ => false,
    }
}

#[inline]
pub fn semicolon_for_stmt(stmt: &ast::Stmt) -> bool {
    match stmt.node {
        ast::Stmt_::StmtSemi(ref expr, _) => {
            match expr.node {
                ast::Expr_::ExprWhile(..) |
                ast::Expr_::ExprWhileLet(..) |
                ast::Expr_::ExprLoop(..) |
                ast::Expr_::ExprForLoop(..) => false,
                _ => true,
            }
        }
        ast::Stmt_::StmtExpr(..) => false,
        _ => true,
    }
}

#[inline]
pub fn trim_newlines(input: &str) -> &str {
    match input.find(|c| c != '\n' && c != '\r') {
        Some(start) => {
            let end = input.rfind(|c| c != '\n' && c != '\r').unwrap_or(0) + 1;
            &input[start..end]
        }
        None => "",
    }
}

#[inline]
#[cfg(target_pointer_width="64")]
// Based on the trick layed out at
// http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
pub fn round_up_to_power_of_two(mut x: usize) -> usize {
    x = x.wrapping_sub(1);
    x |= x >> 1;
    x |= x >> 2;
    x |= x >> 4;
    x |= x >> 8;
    x |= x >> 16;
    x |= x >> 32;
    x.wrapping_add(1)
}

#[inline]
#[cfg(target_pointer_width="32")]
pub fn round_up_to_power_of_two(mut x: usize) -> usize {
    x = x.wrapping_sub(1);
    x |= x >> 1;
    x |= x >> 2;
    x |= x >> 4;
    x |= x >> 8;
    x |= x >> 16;
    x.wrapping_add(1)
}

// Macro for deriving implementations of Decodable for enums
#[macro_export]
macro_rules! impl_enum_decodable {
    ( $e:ident, $( $x:ident ),* ) => {
        impl ::rustc_serialize::Decodable for $e {
            fn decode<D: ::rustc_serialize::Decoder>(d: &mut D) -> Result<Self, D::Error> {
                let s = try!(d.read_str());
                match &*s {
                    $(
                        stringify!($x) => Ok($e::$x),
                    )*
                    _ => Err(d.error("Bad variant")),
                }
            }
        }

        impl ::std::str::FromStr for $e {
            type Err = &'static str;

            fn from_str(s: &str) -> Result<Self, Self::Err> {
                match &*s {
                    $(
                        stringify!($x) => Ok($e::$x),
                    )*
                    _ => Err("Bad variant"),
                }
            }
        }

        impl ::config::ConfigType for $e {
            fn get_variant_names() -> String {
                let mut variants = Vec::new();
                $(
                    variants.push(stringify!($x));
                )*
                format!("[{}]", variants.join("|"))
            }
        }
    };
}

// Same as try!, but for Option
#[macro_export]
macro_rules! try_opt {
    ($expr:expr) => (match $expr {
        Some(val) => val,
        None => { return None; }
    })
}

// Wraps string-like values in an Option. Returns Some when the string adheres
// to the Rewrite constraints defined for the Rewrite trait and else otherwise.
pub fn wrap_str<S: AsRef<str>>(s: S, max_width: usize, width: usize, offset: Indent) -> Option<S> {
    {
        let snippet = s.as_ref();

        if !snippet.contains('\n') && snippet.len() > width {
            return None;
        } else {
            let mut lines = snippet.lines();

            // The caller of this function has already placed `offset`
            // characters on the first line.
            let first_line_max_len = try_opt!(max_width.checked_sub(offset.width()));
            if lines.next().unwrap().len() > first_line_max_len {
                return None;
            }

            // The other lines must fit within the maximum width.
            if lines.find(|line| line.len() > max_width).is_some() {
                return None;
            }

            // `width` is the maximum length of the last line, excluding
            // indentation.
            // A special check for the last line, since the caller may
            // place trailing characters on this line.
            if snippet.lines().rev().next().unwrap().len() > offset.width() + width {
                return None;
            }
        }
    }

    Some(s)
}

impl Rewrite for String {
    fn rewrite(&self, context: &RewriteContext, width: usize, offset: Indent) -> Option<String> {
        wrap_str(self, context.config.max_width, width, offset).map(ToOwned::to_owned)
    }
}

// Binary search in integer range. Returns the first Ok value returned by the
// callback.
// The callback takes an integer and returns either an Ok, or an Err indicating
// whether the `guess' was too high (Ordering::Less), or too low.
// This function is guaranteed to try to the hi value first.
pub fn binary_search<C, T>(mut lo: usize, mut hi: usize, callback: C) -> Option<T>
    where C: Fn(usize) -> Result<T, Ordering>
{
    let mut middle = hi;

    while lo <= hi {
        match callback(middle) {
            Ok(val) => return Some(val),
            Err(Ordering::Less) => {
                hi = middle - 1;
            }
            Err(..) => {
                lo = middle + 1;
            }
        }
        middle = (hi + lo) / 2;
    }

    None
}

#[test]
fn bin_search_test() {
    let closure = |i| {
        match i {
            4 => Ok(()),
            j if j > 4 => Err(Ordering::Less),
            j if j < 4 => Err(Ordering::Greater),
            _ => unreachable!(),
        }
    };

    assert_eq!(Some(()), binary_search(1, 10, &closure));
    assert_eq!(None, binary_search(1, 3, &closure));
    assert_eq!(Some(()), binary_search(0, 44, &closure));
    assert_eq!(Some(()), binary_search(4, 125, &closure));
    assert_eq!(None, binary_search(6, 100, &closure));
}

#[test]
fn power_rounding() {
    assert_eq!(0, round_up_to_power_of_two(0));
    assert_eq!(1, round_up_to_power_of_two(1));
    assert_eq!(64, round_up_to_power_of_two(33));
    assert_eq!(256, round_up_to_power_of_two(256));
}
<|endoftext|>


<commit_before>// This file comes mostly from https://github.com/alexcrichton/futures-rs/blob/71801dcd0aaf5049ab901127a01e8a1d869bdf10/futures-minihttp/src/lib.rs
// It has some modifications to make it work with a protocol that's not http(s?)
use std::io::{self, Read, Write};
use std::net::SocketAddr;
use std::sync::Arc;
use std::thread;

use net2;
use futures::{self, Future};
use futures::stream::Stream;
use futures_io::{IoFuture, TaskIo};
use futures_mio::{Loop, LoopHandle, TcpStream, TcpListener};

// pub use protocol_protobuf::request::Request;
// pub use self::response::Response;

pub use io2::{Parse, Serialize};
use io2::{ParseStream, StreamWriter};

pub trait Service<Req, Resp>: Send + Sync + 'static
    where Req: Send + 'static,
          Resp: Send + 'static
{
    type Fut: Future<Item = Resp> + Send;

    fn process(&self, req: Req) -> Self::Fut;
}

impl<Req, Resp, Fut, F> Service<Req, Resp> for F
    where F: Fn(Req) -> Fut + Send + Sync + 'static,
          Fut: Future<Item = Resp> + Send,
          Req: Send + 'static,
          Resp: Send + 'static
{
    type Fut = Fut;

    fn process(&self, req: Req) -> Fut {
        (self)(req)
    }
}

pub struct Server {
    addr: SocketAddr,
    workers: u32,
}

struct ServerData<S> {
    service: S,
}

impl Server {
    pub fn new(addr: &SocketAddr) -> Server {
        Server {
            addr: *addr,
            workers: 1,
        }
    }

    pub fn workers(&mut self, workers: u32) -> &mut Server {
        if cfg!(unix) {
            self.workers = workers;
        }
        self
    }

    pub fn serve<Req, Resp, S>(&mut self, s: S) -> io::Result<()>
        where Req: Parse,
              Resp: Serialize,
              S: Service<Req, Resp>,
              <S::Fut as Future>::Error: From<Req::Error> + From<io::Error>, // TODO: simplify this?
    {
        let data = Arc::new(ServerData {
            service: s,
        });

        let threads = (0..self.workers - 1).map(|i| {
            let (addr, workers) = (self.addr, self.workers);
            let data = data.clone();
            thread::Builder::new().name(format!("worker{}", i)).spawn(move || {
                let mut lp = Loop::new().unwrap();
                let listener = listener(&addr, workers, lp.handle());
                lp.run(listener.and_then(move |l| {
                    l.incoming().for_each(move |(stream, _)| {
                        handle(stream, data.clone());
                        Ok(()) // TODO: error handling
                    })
                }))
            }).unwrap()
        }).collect::<Vec<_>>();

        let mut lp = Loop::new().unwrap();
        let listener = listener(&self.addr, self.workers, lp.handle());
        lp.run(listener.and_then(move |l| {
            l.incoming().for_each(move |(stream, _)| {
                handle(stream, data.clone());
                Ok(()) // TODO: error handling
            })
        })).unwrap();

        for thread in threads {
            thread.join().unwrap().unwrap();
        }

        Ok(())
    }
}

fn listener(addr: &SocketAddr,
            workers: u32,
            handle: LoopHandle) -> IoFuture<TcpListener> {
    let listener = (|| {
        let listener = try!(net2::TcpBuilder::new_v4());
        try!(configure_tcp(workers, &listener));
        try!(listener.reuse_address(true));
        try!(listener.bind(addr));
        listener.listen(1024)
    })();

    match listener {
        Ok(l) => TcpListener::from_listener(l, addr, handle),
        Err(e) => futures::failed(e).boxed()
    }
}

#[cfg(unix)]
fn configure_tcp(workers: u32, tcp: &net2::TcpBuilder) -> io::Result<()> {
    use net2::unix::*;

    if workers > 1 {
        try!(tcp.reuse_port(true));
    }

    Ok(())
}

#[cfg(windows)]
fn configure_tcp(workers: u32, _tcp: &net2::TcpBuilder) -> io::Result<()> {
    Ok(())
}

trait IoStream: Read + Write + 'static {}

impl<T: ?Sized> IoStream for T
    where T: Read + Write + 'static
{}

fn handle<Req, Resp, S>(stream: TcpStream, data: Arc<ServerData<S>>)
    where Req: Parse,
          Resp: Serialize,
          S: Service<Req, Resp>,
          <S::Fut as Future>::Error: From<Req::Error> + From<io::Error>,
{
    let io = TaskIo::new(stream).map_err(From::from).and_then(|io| {
        let (reader, writer) = io.split();

        let input = ParseStream::new(reader).map_err(From::from);
        let responses = input.and_then(move |req| data.service.process(req));
        StreamWriter::new(writer, responses)
    });
    io.forget();
}
<commit_msg>Remove commented code<commit_after>// This file comes mostly from https://github.com/alexcrichton/futures-rs/blob/71801dcd0aaf5049ab901127a01e8a1d869bdf10/futures-minihttp/src/lib.rs
// It has some modifications to make it work with a protocol that's not http(s?)
use std::io::{self, Read, Write};
use std::net::SocketAddr;
use std::sync::Arc;
use std::thread;

use net2;
use futures::{self, Future};
use futures::stream::Stream;
use futures_io::{IoFuture, TaskIo};
use futures_mio::{Loop, LoopHandle, TcpStream, TcpListener};

pub use io2::{Parse, Serialize};
use io2::{ParseStream, StreamWriter};

pub trait Service<Req, Resp>: Send + Sync + 'static
    where Req: Send + 'static,
          Resp: Send + 'static
{
    type Fut: Future<Item = Resp> + Send;

    fn process(&self, req: Req) -> Self::Fut;
}

impl<Req, Resp, Fut, F> Service<Req, Resp> for F
    where F: Fn(Req) -> Fut + Send + Sync + 'static,
          Fut: Future<Item = Resp> + Send,
          Req: Send + 'static,
          Resp: Send + 'static
{
    type Fut = Fut;

    fn process(&self, req: Req) -> Fut {
        (self)(req)
    }
}

pub struct Server {
    addr: SocketAddr,
    workers: u32,
}

struct ServerData<S> {
    service: S,
}

impl Server {
    pub fn new(addr: &SocketAddr) -> Server {
        Server {
            addr: *addr,
            workers: 1,
        }
    }

    pub fn workers(&mut self, workers: u32) -> &mut Server {
        if cfg!(unix) {
            self.workers = workers;
        }
        self
    }

    pub fn serve<Req, Resp, S>(&mut self, s: S) -> io::Result<()>
        where Req: Parse,
              Resp: Serialize,
              S: Service<Req, Resp>,
              <S::Fut as Future>::Error: From<Req::Error> + From<io::Error>, // TODO: simplify this?
    {
        let data = Arc::new(ServerData {
            service: s,
        });

        let threads = (0..self.workers - 1).map(|i| {
            let (addr, workers) = (self.addr, self.workers);
            let data = data.clone();
            thread::Builder::new().name(format!("worker{}", i)).spawn(move || {
                let mut lp = Loop::new().unwrap();
                let listener = listener(&addr, workers, lp.handle());
                lp.run(listener.and_then(move |l| {
                    l.incoming().for_each(move |(stream, _)| {
                        handle(stream, data.clone());
                        Ok(()) // TODO: error handling
                    })
                }))
            }).unwrap()
        }).collect::<Vec<_>>();

        let mut lp = Loop::new().unwrap();
        let listener = listener(&self.addr, self.workers, lp.handle());
        lp.run(listener.and_then(move |l| {
            l.incoming().for_each(move |(stream, _)| {
                handle(stream, data.clone());
                Ok(()) // TODO: error handling
            })
        })).unwrap();

        for thread in threads {
            thread.join().unwrap().unwrap();
        }

        Ok(())
    }
}

fn listener(addr: &SocketAddr,
            workers: u32,
            handle: LoopHandle) -> IoFuture<TcpListener> {
    let listener = (|| {
        let listener = try!(net2::TcpBuilder::new_v4());
        try!(configure_tcp(workers, &listener));
        try!(listener.reuse_address(true));
        try!(listener.bind(addr));
        listener.listen(1024)
    })();

    match listener {
        Ok(l) => TcpListener::from_listener(l, addr, handle),
        Err(e) => futures::failed(e).boxed()
    }
}

#[cfg(unix)]
fn configure_tcp(workers: u32, tcp: &net2::TcpBuilder) -> io::Result<()> {
    use net2::unix::*;

    if workers > 1 {
        try!(tcp.reuse_port(true));
    }

    Ok(())
}

#[cfg(windows)]
fn configure_tcp(workers: u32, _tcp: &net2::TcpBuilder) -> io::Result<()> {
    Ok(())
}

trait IoStream: Read + Write + 'static {}

impl<T: ?Sized> IoStream for T
    where T: Read + Write + 'static
{}

fn handle<Req, Resp, S>(stream: TcpStream, data: Arc<ServerData<S>>)
    where Req: Parse,
          Resp: Serialize,
          S: Service<Req, Resp>,
          <S::Fut as Future>::Error: From<Req::Error> + From<io::Error>,
{
    let io = TaskIo::new(stream).map_err(From::from).and_then(|io| {
        let (reader, writer) = io.split();

        let input = ParseStream::new(reader).map_err(From::from);
        let responses = input.and_then(move |req| data.service.process(req));
        StreamWriter::new(writer, responses)
    });
    io.forget();
}
<|endoftext|>