<commit_before>use std::io::Write;
use super::P2d;

pub struct SvgCanvas {
    pub width: f32,
    pub height: f32,
    pub border: f32,
    pub radius: f32,
    pub scalex: f32,
    pub scaley: f32,
    pub offsetx: f32,
    pub offsety: f32,
    pub stroke_width: f32,
    pub stroke_color: String,
    pub fill_color: String,
}

impl SvgCanvas {
    /// If all graph coordinates are in [0,1].
    pub fn default_for_unit_layout() -> SvgCanvas {
        SvgCanvas {
            width: 1000.0,
            height: 1000.0,
            border: 40.0,
            radius: 10.0,
            scalex: 1000.0,
            scaley: 1000.0,
            offsetx: 0.0,
            offsety: 0.0,
            stroke_width: 1.0,
            stroke_color: "black".to_string(),
            fill_color: "red".to_string(),
        }
    }
}

pub struct SvgWriter<'a> {
    canvas: SvgCanvas,
    wr: &'a mut Write,
}

impl<'a> SvgWriter<'a> {
    pub fn new<'b>(canvas: SvgCanvas, wr: &'b mut Write) -> SvgWriter<'b> {
        SvgWriter {
            canvas: canvas,
            wr: wr,
        }
    }

    pub fn header(&mut self) {
        writeln!(&mut self.wr,
                 r#"<?xml version="1.0" encoding="UTF-8"?>
                <svg xmlns="http://www.w3.org/2000/svg"
                version="1.1" baseProfile="full"
                width="100%" height="100%"
                viewBox="{} {} {} {}">"#,
                 0,
                 0,
                 self.canvas.width + 2.0 * self.canvas.border,
                 self.canvas.height + 2.0 * self.canvas.border)
            .unwrap();
        writeln!(&mut self.wr, r##"
                <defs>
                <marker id="arrow" viewBox="0 0 10 10" refX="1" refY="5" markerUnits="strokeWidth" orient="auto"
                markerWidth="8" markerHeight="6"><polyline points="0,0 10,5 0,10 1,5" fill="darkblue" /></marker>
                </defs>"##).unwrap();
    }

    pub fn footer(&mut self) {
        writeln!(&mut self.wr, "</svg>").unwrap();
    }

    pub fn node(&mut self, pos: &P2d) {
        let x = self.canvas.border + (pos.0 * self.canvas.scalex) + self.canvas.offsetx;
        let y = self.canvas.border + (pos.1 * self.canvas.scaley) + self.canvas.offsety;
        writeln!(&mut self.wr,
                 r#"<circle cx="{}" cy="{}" r="{}" stroke="{}" stroke-width="{}px" fill="{}" />"#,
                 x,
                 y,
                 self.canvas.radius,
                 self.canvas.stroke_color,
                 self.canvas.stroke_width,
                 self.canvas.fill_color)
            .unwrap();
    }

    pub fn edge(&mut self, pos1: &P2d, pos2: &P2d, directed: bool) {
        let x1 = self.canvas.border + (pos1.0 * self.canvas.scalex) + self.canvas.offsetx;
        let y1 = self.canvas.border + (pos1.1 * self.canvas.scaley) + self.canvas.offsety;
        let x2 = self.canvas.border + (pos2.0 * self.canvas.scalex) + self.canvas.offsetx;
        let y2 = self.canvas.border + (pos2.1 * self.canvas.scaley) + self.canvas.offsety;

        let dx = x2 - x1;
        let dy = y2 - y1;

        if dx.abs() < 1.0 / self.canvas.width && dy.abs() < 1.0 / self.canvas.height {
            return;
        }

        let mx = x1 + 0.5 * dx;
        let my = y1 + 0.5 * dy;

        let marker = if directed {
            r##" marker-mid="url(#arrow)""##
        } else {
            ""
        };

        writeln!(&mut self.wr,
                 r#"<path d="M{} {} L{} {} L{} {}" stroke="{}" stroke-width="{}px" {}/>"#,
                 x1,
                 y1,
                 mx,
                 my,
                 x2,
                 y2,
                 self.canvas.stroke_color,
                 self.canvas.stroke_width,
                 marker)
            .unwrap();
    }

    pub fn draw_graph(mut self,
                      node_positions: &Vec<P2d>,
                      node_neighbors: &Vec<Vec<usize>>,
                      directed: bool) {
        self.header();

        // start with the edges
        for (i, pos1) in node_positions.iter().enumerate() {
            for &n in node_neighbors[i].iter() {
                let pos2 = &node_positions[n];
                self.edge(&pos1, &pos2, directed);
            }
        }

        // then with the nodes.
        for pos1 in node_positions.iter() {
            self.node(&pos1);
        }

        self.footer();
    }
}
<commit_msg>Remove 'px'<commit_after>use std::io::Write;
use super::P2d;

pub struct SvgCanvas {
    pub width: f32,
    pub height: f32,
    pub border: f32,
    pub radius: f32,
    pub scalex: f32,
    pub scaley: f32,
    pub offsetx: f32,
    pub offsety: f32,
    pub stroke_width: f32,
    pub stroke_color: String,
    pub fill_color: String,
}

impl SvgCanvas {
    /// If all graph coordinates are in [0,1].
    pub fn default_for_unit_layout() -> SvgCanvas {
        SvgCanvas {
            width: 1000.0,
            height: 1000.0,
            border: 40.0,
            radius: 10.0,
            scalex: 1000.0,
            scaley: 1000.0,
            offsetx: 0.0,
            offsety: 0.0,
            stroke_width: 1.0,
            stroke_color: "black".to_string(),
            fill_color: "red".to_string(),
        }
    }
}

pub struct SvgWriter<'a> {
    canvas: SvgCanvas,
    wr: &'a mut Write,
}

impl<'a> SvgWriter<'a> {
    pub fn new<'b>(canvas: SvgCanvas, wr: &'b mut Write) -> SvgWriter<'b> {
        SvgWriter {
            canvas: canvas,
            wr: wr,
        }
    }

    pub fn header(&mut self) {
        writeln!(&mut self.wr,
                 r#"<?xml version="1.0" encoding="UTF-8"?>
                <svg xmlns="http://www.w3.org/2000/svg"
                version="1.1" baseProfile="full"
                width="100%" height="100%"
                viewBox="{} {} {} {}">"#,
                 0,
                 0,
                 self.canvas.width + 2.0 * self.canvas.border,
                 self.canvas.height + 2.0 * self.canvas.border)
            .unwrap();
        writeln!(&mut self.wr, r##"
                <defs>
                <marker id="arrow" viewBox="0 0 10 10" refX="1" refY="5" markerUnits="strokeWidth" orient="auto"
                markerWidth="8" markerHeight="6"><polyline points="0,0 10,5 0,10 1,5" fill="darkblue" /></marker>
                </defs>"##).unwrap();
    }

    pub fn footer(&mut self) {
        writeln!(&mut self.wr, "</svg>").unwrap();
    }

    pub fn node(&mut self, pos: &P2d) {
        let x = self.canvas.border + (pos.0 * self.canvas.scalex) + self.canvas.offsetx;
        let y = self.canvas.border + (pos.1 * self.canvas.scaley) + self.canvas.offsety;
        writeln!(&mut self.wr,
                 r#"<circle cx="{}" cy="{}" r="{}" stroke="{}" stroke-width="{}" fill="{}" />"#,
                 x,
                 y,
                 self.canvas.radius,
                 self.canvas.stroke_color,
                 self.canvas.stroke_width,
                 self.canvas.fill_color)
            .unwrap();
    }

    pub fn edge(&mut self, pos1: &P2d, pos2: &P2d, directed: bool) {
        let x1 = self.canvas.border + (pos1.0 * self.canvas.scalex) + self.canvas.offsetx;
        let y1 = self.canvas.border + (pos1.1 * self.canvas.scaley) + self.canvas.offsety;
        let x2 = self.canvas.border + (pos2.0 * self.canvas.scalex) + self.canvas.offsetx;
        let y2 = self.canvas.border + (pos2.1 * self.canvas.scaley) + self.canvas.offsety;

        let dx = x2 - x1;
        let dy = y2 - y1;

        if dx.abs() < 1.0 / self.canvas.width && dy.abs() < 1.0 / self.canvas.height {
            return;
        }

        let mx = x1 + 0.5 * dx;
        let my = y1 + 0.5 * dy;

        let marker = if directed {
            r##" marker-mid="url(#arrow)""##
        } else {
            ""
        };

        writeln!(&mut self.wr,
                 r#"<path d="M{} {} L{} {} L{} {}" stroke="{}" stroke-width="{}" {}/>"#,
                 x1,
                 y1,
                 mx,
                 my,
                 x2,
                 y2,
                 self.canvas.stroke_color,
                 self.canvas.stroke_width,
                 marker)
            .unwrap();
    }

    pub fn draw_graph(mut self,
                      node_positions: &Vec<P2d>,
                      node_neighbors: &Vec<Vec<usize>>,
                      directed: bool) {
        self.header();

        // start with the edges
        for (i, pos1) in node_positions.iter().enumerate() {
            for &n in node_neighbors[i].iter() {
                let pos2 = &node_positions[n];
                self.edge(&pos1, &pos2, directed);
            }
        }

        // then with the nodes.
        for pos1 in node_positions.iter() {
            self.node(&pos1);
        }

        self.footer();
    }
}
<|endoftext|>


<commit_before>mod macros;

const NUM_BYTES: usize = 4096;
const NUM_REGISTERS: usize = 16;
const STACK_SIZE: usize = 48;

const VALUE_MASK: u16 = 0b0000_0000_1111_1111;
const REGISTER_ADDRESS_MASK: u16 = 0b0000_1111_0000_0000;

#[allow(dead_code)]
pub struct System {
    memory: [u8; NUM_BYTES],
    registers: [u8; NUM_REGISTERS],
    pc: u16,
    index: u16,
    stack: [u8; STACK_SIZE],
    sp: u8
}

#[allow(dead_code)]
impl System{
    pub fn new() -> Self {
        System {
            memory: [0; NUM_BYTES],
            registers: [0; NUM_REGISTERS],
            pc: 0,
            index: 0,
            stack: [0; STACK_SIZE],
            sp: 0
        }
    }

    /** Index into system memory at address and return word located there. */
    pub fn read_word(&self, address: usize) -> u16 {
        let left = self.memory[address] as u16;
        let right = self.memory[address + 1] as u16;
        (left << 8) | right
    }

    /** Execute the instruction. */
    pub fn execute(&mut self, opcode: u16) {
        match opcode {
            0x6000...0x7000 => {    // 0x6XNN : VX = NN
                let register = ((opcode & REGISTER_ADDRESS_MASK) >> 8) as usize;
                let value = (opcode & VALUE_MASK) as u8;
                self.registers[register] = value;
            },
            0x7000...0x8000 => {    // 0x7XNN : VX = VX + NN
                let register = ((opcode & REGISTER_ADDRESS_MASK) >> 8) as usize;
                let value = (opcode & VALUE_MASK) as u8;
                self.registers[register] = self.registers[register].wrapping_add(value);
            },
            0x8000...0x9000 => {
                match opcode & 0b0000_0000_0000_1111 {
                    0x0 => {    // 0x8XY0 : VX = VY
                        let left = ((opcode & 0b0000_1111_0000_0000) >> 8) as usize;
                        let right = ((opcode & 0b0000_0000_1111_0000) >> 4) as usize;
                        self.registers[left] = self.registers[right];
                    },
                    _ => {
                        eprintln!("Unrecognized instruction!");
                    }
                }
            }
            _ => {
                eprintln!("Unrecognized instruction!");
            }
        }
    }
}

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

    /** Load some test data into the system memory for the purposes of testing. */
    fn load_test_data(system: &mut System) {
        system.memory[0] = 0xAF;
        system.memory[1] = 0x7F;
        system.memory[NUM_BYTES / 2] = 0x77;
        system.memory[NUM_BYTES / 2 + 1] = 0x88;
        system.memory[NUM_BYTES - 2] = 0x3A;
        system.memory[NUM_BYTES - 1] = 0x01;
    }

    /** Read a word (two bytes) from the system memory. */
    #[test]
    fn read_word() {
        let mut system = System::new();
        load_test_data(&mut system);
        assert_eq!(0xAF7F, system.read_word(0));
        assert_eq!(0x7788, system.read_word(NUM_BYTES / 2));
        assert_eq!(0x3A01, system.read_word(NUM_BYTES - 2));
    }

    /** The opcode 0x6XNN should store the constant NN into register VX. */
    #[test]
    fn load_constant() {
        let mut system = System::new();
        system.execute(0x6015);
        assert_eq!(0x15, system.registers[0]);
        system.execute(0x6120);
        assert_eq!(0x20, system.registers[1]);
        system.execute(0x6225);
        assert_eq!(0x25, system.registers[2]);
        system.execute(0x6330);
        assert_eq!(0x30, system.registers[3]);
        system.execute(0x6435);
        assert_eq!(0x35, system.registers[4]);
        system.execute(0x6540);
        assert_eq!(0x40, system.registers[5]);
        system.execute(0x6645);
        assert_eq!(0x45, system.registers[6]);
        system.execute(0x6750);
        assert_eq!(0x50, system.registers[7]);
        system.execute(0x6855);
        assert_eq!(0x55, system.registers[8]);
        system.execute(0x6960);
        assert_eq!(0x60, system.registers[9]);
        system.execute(0x6A65);
        assert_eq!(0x65, system.registers[0xA]);
        system.execute(0x6B70);
        assert_eq!(0x70, system.registers[0xB]);
        system.execute(0x6C75);
        assert_eq!(0x75, system.registers[0xC]);
        system.execute(0x6D80);
        assert_eq!(0x80, system.registers[0xD]);
        system.execute(0x6E85);
        assert_eq!(0x85, system.registers[0xE]);
        system.execute(0x6F90);
        assert_eq!(0x90, system.registers[0xF]);
    }

    /** The opcode 0x7XNN should add the constant NN into register VX. */
    #[test]
    fn add_constant() {
        let mut system = System::new();
        system.execute(0x6015);
        system.execute(0x7015);
        assert_eq!(0x2A, system.registers[0]);

        system.execute(0x6A42);
        system.execute(0x7A42);
        assert_eq!(0x84, system.registers[0xA]);

        system.execute(0x6EFF);
        system.execute(0x7E01);
        // registers should overlow appropriately
        assert_eq!(0x00, system.registers[0xE]);
    }

    /** The opcode 0x8XY0 should copy the value from register VY into register VX. */
    #[test]
    fn copy_register() {
        let mut system = System::new();
        system.execute(0x6A42);
        system.execute(0x8EA0);
        assert_eq!(0x42, system.registers[0xA]);
        assert_eq!(0x42, system.registers[0xE]);

        system.execute(0x67DE);
        system.execute(0x8F70);
        assert_eq!(0xDE, system.registers[0x7]);
        assert_eq!(0xDE, system.registers[0xF]);
    }
}
<commit_msg>oring register<commit_after>mod macros;

const NUM_BYTES: usize = 4096;
const NUM_REGISTERS: usize = 16;
const STACK_SIZE: usize = 48;

const VALUE_MASK: u16 = 0b0000_0000_1111_1111;
const REGISTER_ADDRESS_MASK: u16 = 0b0000_1111_0000_0000;

const TYPE_MASK: u16 = 0b0000_0000_0000_1111;
const LEFT_MASK: u16 = 0b0000_1111_0000_0000;
const RIGHT_MASK: u16 = 0b0000_0000_1111_0000;

#[allow(dead_code)]
pub struct System {
    memory: [u8; NUM_BYTES],
    registers: [u8; NUM_REGISTERS],
    pc: u16,
    index: u16,
    stack: [u8; STACK_SIZE],
    sp: u8
}

#[allow(dead_code)]
impl System{
    pub fn new() -> Self {
        System {
            memory: [0; NUM_BYTES],
            registers: [0; NUM_REGISTERS],
            pc: 0,
            index: 0,
            stack: [0; STACK_SIZE],
            sp: 0
        }
    }

    /** Index into system memory at address and return word located there. */
    pub fn read_word(&self, address: usize) -> u16 {
        let left = self.memory[address] as u16;
        let right = self.memory[address + 1] as u16;
        (left << 8) | right
    }

    /** Execute the instruction. */
    pub fn execute(&mut self, opcode: u16) {
        match opcode {
            0x6000...0x7000 => {    // 0x6XNN : VX = NN
                let register = ((opcode & REGISTER_ADDRESS_MASK) >> 8) as usize;
                let value = (opcode & VALUE_MASK) as u8;
                self.registers[register] = value;
            },
            0x7000...0x8000 => {    // 0x7XNN : VX = VX + NN
                let register = ((opcode & REGISTER_ADDRESS_MASK) >> 8) as usize;
                let value = (opcode & VALUE_MASK) as u8;
                self.registers[register] = self.registers[register].wrapping_add(value);
            },
            0x8000...0x9000 => {
                let left = ((opcode & LEFT_MASK) >> 8) as usize;
                let right = ((opcode & RIGHT_MASK) >> 4) as usize;
                match opcode & TYPE_MASK {
                    0x0 => {    // 0x8XY0 : VX = VY
                        self.registers[left] = self.registers[right];
                    },
                    0x1 => {    // 0x8XY1 : VX = VX | VY
                        self.registers[left] |= self.registers[right];
                    },
                    _ => {
                        eprintln!("Unrecognized instruction!");
                    }
                }
            }
            _ => {
                eprintln!("Unrecognized instruction!");
            }
        }
    }
}

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

    /** Load some test data into the system memory for the purposes of testing. */
    fn load_test_data(system: &mut System) {
        system.memory[0] = 0xAF;
        system.memory[1] = 0x7F;
        system.memory[NUM_BYTES / 2] = 0x77;
        system.memory[NUM_BYTES / 2 + 1] = 0x88;
        system.memory[NUM_BYTES - 2] = 0x3A;
        system.memory[NUM_BYTES - 1] = 0x01;
    }

    /** Set some registers for the purposes of testing. */
    fn set_registers_for_test(system: &mut System) {
        system.execute(0x6064);
        system.execute(0x6127);
        system.execute(0x6212);
        system.execute(0x63AE);
        system.execute(0x64FF);
        system.execute(0x65B4);
        system.execute(0x6642);
        system.execute(0x6F25);
    }

    /** Read a word (two bytes) from the system memory. */
    #[test]
    fn read_word() {
        let mut system = System::new();
        load_test_data(&mut system);
        assert_eq!(0xAF7F, system.read_word(0));
        assert_eq!(0x7788, system.read_word(NUM_BYTES / 2));
        assert_eq!(0x3A01, system.read_word(NUM_BYTES - 2));
    }

    /** The opcode 0x6XNN should store the constant NN into register VX. */
    #[test]
    fn load_constant() {
        let mut system = System::new();

        system.execute(0x6015);
        assert_eq!(0x15, system.registers[0x0]);

        system.execute(0x6120);
        assert_eq!(0x20, system.registers[0x1]);

        system.execute(0x6225);
        assert_eq!(0x25, system.registers[0x2]);

        system.execute(0x6330);
        assert_eq!(0x30, system.registers[0x3]);

        system.execute(0x6435);
        assert_eq!(0x35, system.registers[0x4]);

        system.execute(0x6540);
        assert_eq!(0x40, system.registers[0x5]);

        system.execute(0x6645);
        assert_eq!(0x45, system.registers[0x6]);

        system.execute(0x6750);
        assert_eq!(0x50, system.registers[0x7]);

        system.execute(0x6855);
        assert_eq!(0x55, system.registers[0x8]);

        system.execute(0x6960);
        assert_eq!(0x60, system.registers[0x9]);

        system.execute(0x6A65);
        assert_eq!(0x65, system.registers[0xA]);

        system.execute(0x6B70);
        assert_eq!(0x70, system.registers[0xB]);

        system.execute(0x6C75);
        assert_eq!(0x75, system.registers[0xC]);

        system.execute(0x6D80);
        assert_eq!(0x80, system.registers[0xD]);

        system.execute(0x6E85);
        assert_eq!(0x85, system.registers[0xE]);

        system.execute(0x6F90);
        assert_eq!(0x90, system.registers[0xF]);
    }

    /** The opcode 0x7XNN should add the constant NN into register VX. */
    #[test]
    fn add_constant() {
        let mut system = System::new();

        system.execute(0x6015);
        system.execute(0x7015);
        assert_eq!(0x2A, system.registers[0x0]);

        system.execute(0x6A42);
        system.execute(0x7A42);
        assert_eq!(0x84, system.registers[0xA]);

        system.execute(0x6EFF);
        system.execute(0x7E01);
        // registers should overlow appropriately
        assert_eq!(0x00, system.registers[0xE]);
    }

    /** The opcode 0x8XY0 should copy the value from register VY into register VX. */
    #[test]
    fn copy_register() {
        let mut system = System::new();

        system.execute(0x6A42);
        system.execute(0x8EA0);
        assert_eq!(0x42, system.registers[0xA]);
        assert_eq!(0x42, system.registers[0xE]);

        system.execute(0x67DE);
        system.execute(0x8F70);
        assert_eq!(0xDE, system.registers[0x7]);
        assert_eq!(0xDE, system.registers[0xF]);
    }

    /** The opcode 0x8XY1 should set register VX to the value (VX OR VY). */
    #[test]
    fn oring_register() {
        let mut system = System::new();
        set_registers_for_test(&mut system);

        system.execute(0x8011);
        assert_eq!(0x67, system.registers[0x0]);
        assert_eq!(0x27, system.registers[0x1]);

        system.execute(0x8231);
        assert_eq!(0xBE, system.registers[0x2]);
        assert_eq!(0xAE, system.registers[0x3]);

        system.execute(0x8FE1);
        assert_eq!(0x25, system.registers[0xF]);
        assert_eq!(0x00, system.registers[0xE]);
    }
}
<|endoftext|>


<commit_before>extern crate dft;

#[derive(Clone, Debug)]
pub struct FrequencyBucket {
    pub min_freq: f64,
    pub max_freq: f64,
    pub intensity: f64
}

impl FrequencyBucket {
    pub fn ave_freq(&self) -> f64 {
        (self.min_freq + self.max_freq) / 2.0
    }
}

pub fn fft(input: &Vec<f64>, sample_rate: f64) -> Vec<FrequencyBucket> {
    let frames = input.len();
    let mean_input = input.iter().sum::<f64>()/input.len() as f64;

    let mut intensities = input.iter().map(|x|x-mean_input).collect::<Vec<_>>();
    let plan = dft::Plan::new(dft::Operation::Forward, frames);
    dft::transform(&mut intensities, &plan);

    let frequency_resolution = sample_rate / 2.0 / frames as f64;

    intensities.iter().enumerate().map(|(index, &value)| {
        let index = index as f64;
        FrequencyBucket {
            min_freq: index * frequency_resolution,
            max_freq: (index+1.0) * frequency_resolution,
            intensity: value
        }
    }).collect()
}

pub fn find_fundamental_frequency(frequency_domain: &Vec<FrequencyBucket>) -> Option<f64> {
    //TODO look at all significant frequencies, find fundamental
    //TODO return None is none of them are significant
    let positive_buckets = frequency_domain.iter().filter(|x| x.intensity > 0.0).cloned().collect::<Vec<_>>();
    let average_intensity = positive_buckets.iter().map(|x| x.intensity).sum::<f64>() / frequency_domain.len() as f64;
    let significant_buckets = positive_buckets.iter().filter(|x| x.intensity > average_intensity).cloned().collect::<Vec<_>>();

    let max_bucket = significant_buckets.iter()
        .fold(None as Option<::transforms::FrequencyBucket>, |max, next|
              if max.is_none() || max.clone().unwrap().intensity < next.intensity { Some(next.clone()) } else { max }
        ).unwrap();

    Some(max_bucket.ave_freq())
}

pub fn correlation(input: &Vec<f64>) -> Vec<f64> {
    let mut correlation = Vec::with_capacity(input.len());
    for offset in 0..input.len() {
        let mut c = 0.0;
        for i in 0..input.len()-offset {
            let j = i+offset;
            c += input[i] * input[j];
        }
        correlation.push(c);
    }
    correlation
}

pub fn find_fundamental_frequency_correlation(input: &Vec<f64>, sample_rate: f64) -> Option<f64> {
    let mut correlation = correlation(&input);

    //at offset = 0, we have union, so we want to remove that peak
    for offset in 1..correlation.len() {
        if correlation[offset-1] < correlation[offset] {
            break;
        }
        correlation[offset-1] = 0.0;
    }

    let peak = correlation.iter()
        .enumerate()
        .fold((0, 0.0 as f64), |(xi, xmag), (yi, &ymag)| if ymag > xmag { (yi, ymag) } else { (xi, xmag) });

    let (peak_index, _) = peak;
    Some(sample_rate / peak_index as f64)
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::f64::consts::PI;

    const SAMPLE_RATE: f64 = 44100.0;
    const FRAMES: usize = 512;

    fn frequency_resolution() -> f64 {
        SAMPLE_RATE / 2.0 / FRAMES as f64
    }

    fn sin_arg(f: f64, t: f64, phase: f64) -> f64 {
        2.0 as f64 * PI * f * t + phase
    }

    fn sample_sinusoud(amplitude: f64, frequency: f64, phase: f64) -> Vec<f64> {
        (0..FRAMES)
            .map(|x| {
                let t = x as f64 / SAMPLE_RATE;
                sin_arg(frequency, t, phase).sin() * amplitude
            }).collect()
    }

    #[test]
    fn fft_on_sine_wave() {
        let frequency = 440.0 as f64; //concert A

        let samples = sample_sinusoud(1.0, frequency, 0.0);
        let frequency_domain = fft(&samples, SAMPLE_RATE);
        let fundamental = find_fundamental_frequency(&frequency_domain).unwrap();

        assert!((fundamental-frequency).abs() < frequency_resolution(), "expected={}, actual={}", frequency, fundamental);
    }

    #[test]
    fn fft_on_two_sine_waves() {
        //Unfortunately, real signals won't be this neat
        let samples1a = sample_sinusoud(2.0, 440.0, 0.0);
        let samples2a = sample_sinusoud(1.0, 880.0, 0.0);
        let expected_fundamental = 440.0;

        let samples = samples1a.iter().zip(samples2a.iter())
            .map(|(a, b)| a+b)
            .collect();
        let frequency_domain = fft(&samples, SAMPLE_RATE);

        let fundamental = find_fundamental_frequency(&frequency_domain).unwrap();

        assert!((fundamental-expected_fundamental).abs() < frequency_resolution(), "expected_fundamental={}, actual={}", expected_fundamental, fundamental);
    }

    #[test]
    fn correlation_on_sine_wave() {
        let frequency = 440.0 as f64; //concert A

        let samples = sample_sinusoud(1.0, frequency, 0.0);
        let fundamental = find_fundamental_frequency_correlation(&samples, SAMPLE_RATE).unwrap();
        assert!((fundamental-frequency).abs() < frequency_resolution(), "expected={}, actual={}", frequency, fundamental);
    }

    #[test]
    fn correlation_on_two_sine_waves() {
        //Unfortunately, real signals won't be this neat
        let samples1a = sample_sinusoud(2.0, 440.0, 0.0);
        let samples2a = sample_sinusoud(1.0, 880.0, 0.0);
        let expected_fundamental = 440.0;

        let samples = samples1a.iter().zip(samples2a.iter())
            .map(|(a, b)| a+b)
            .collect();

        let fundamental = find_fundamental_frequency_correlation(&samples, SAMPLE_RATE).unwrap();

        assert!((fundamental-expected_fundamental).abs() < frequency_resolution(), "expected_fundamental={}, actual={}", expected_fundamental, fundamental);
    }
}

pub fn hz_to_midi_number(hz: f64) -> f64 {
    69.0 + 12.0 * (hz / 440.0).log2()
}

pub fn hz_to_cents_error(hz: f64) -> f64 {
    let midi_number = hz_to_midi_number(hz);
    let cents = (midi_number * 100.0).round() % 100.0;
    if cents >= 50.0 {
        cents - 100.0
    }
    else {
        cents
    }
}

pub fn hz_to_pitch(hz: f64) -> String {
    let pitch_names = [
        "C",
        "C#",
        "D",
        "Eb",
        "E",
        "F",
        "F#",
        "G",
        "G#",
        "A",
        "Bb",
        "B"
    ];

    let midi_number = hz_to_midi_number(hz);
    //midi_number of 0 is C-1.

    let rounded_pitch = midi_number.round() as i32;
    let name = pitch_names[rounded_pitch as usize % pitch_names.len()].to_string();
    let octave = rounded_pitch / pitch_names.len() as i32 - 1; //0 is C-1
    if octave < 0 {
        return "< C1".to_string();
    }

    let mut cents = ((midi_number * 100.0).round() % 100.0) as i32;
    if cents >= 50 {
        //don't need to adjust pitch here, that's already been done by the round above
        cents -= 100;
    }

    format!("{}{} {:+}", name, octave, cents)
}

#[test]
fn a4_is_correct() {
    assert_eq!(hz_to_pitch(440.0), "A4 +0");
}

#[test]
fn a2_is_correct() {
    assert_eq!(hz_to_pitch(110.0), "A2 +0");
}

#[test]
fn c4_is_correct() {
    assert_eq!(hz_to_pitch(261.63), "C4 +0");
}

#[test]
fn f5_is_correct() {
    assert_eq!(hz_to_pitch(698.46), "F5 +0");
}

pub fn align_to_rising_edge(samples: &Vec<f64>) -> Vec<f64> {
    samples.iter()
        .skip_while(|x| !x.is_sign_negative())
        .skip_while(|x| x.is_sign_negative())
        .cloned()
        .collect()
}
<commit_msg>Added function for linear interpolation<commit_after>extern crate dft;

#[derive(Clone, Debug)]
pub struct FrequencyBucket {
    pub min_freq: f64,
    pub max_freq: f64,
    pub intensity: f64
}

impl FrequencyBucket {
    pub fn ave_freq(&self) -> f64 {
        (self.min_freq + self.max_freq) / 2.0
    }
}

pub fn fft(input: &Vec<f64>, sample_rate: f64) -> Vec<FrequencyBucket> {
    let frames = input.len();
    let mean_input = input.iter().sum::<f64>()/input.len() as f64;

    let mut intensities = input.iter().map(|x|x-mean_input).collect::<Vec<_>>();
    let plan = dft::Plan::new(dft::Operation::Forward, frames);
    dft::transform(&mut intensities, &plan);

    let frequency_resolution = sample_rate / 2.0 / frames as f64;

    intensities.iter().enumerate().map(|(index, &value)| {
        let index = index as f64;
        FrequencyBucket {
            min_freq: index * frequency_resolution,
            max_freq: (index+1.0) * frequency_resolution,
            intensity: value
        }
    }).collect()
}

pub fn find_fundamental_frequency(frequency_domain: &Vec<FrequencyBucket>) -> Option<f64> {
    //TODO look at all significant frequencies, find fundamental
    //TODO return None is none of them are significant
    let positive_buckets = frequency_domain.iter().filter(|x| x.intensity > 0.0).cloned().collect::<Vec<_>>();
    let average_intensity = positive_buckets.iter().map(|x| x.intensity).sum::<f64>() / frequency_domain.len() as f64;
    let significant_buckets = positive_buckets.iter().filter(|x| x.intensity > average_intensity).cloned().collect::<Vec<_>>();

    let max_bucket = significant_buckets.iter()
        .fold(None as Option<::transforms::FrequencyBucket>, |max, next|
              if max.is_none() || max.clone().unwrap().intensity < next.intensity { Some(next.clone()) } else { max }
        ).unwrap();

    Some(max_bucket.ave_freq())
}

pub fn correlation(input: &Vec<f64>) -> Vec<f64> {
    let mut correlation = Vec::with_capacity(input.len());
    for offset in 0..input.len() {
        let mut c = 0.0;
        for i in 0..input.len()-offset {
            let j = i+offset;
            c += input[i] * input[j];
        }
        correlation.push(c);
    }
    correlation
}

pub fn find_fundamental_frequency_correlation(input: &Vec<f64>, sample_rate: f64) -> Option<f64> {
    let correlation = correlation(&input);

    let mut first_peak_width = 0;
    for offset in 0..correlation.len() {
        if correlation[offset] < 0.0 {
            first_peak_width = offset;
            break;
        }
    }
    if first_peak_width == 0 {
        return None;
    }

    let peak = correlation.iter()
        .enumerate()
        .skip(first_peak_width)
        .fold((first_peak_width, 0.0 as f64), |(xi, xmag), (yi, &ymag)| if ymag > xmag { (yi, ymag) } else { (xi, xmag) });

    let (peak_index, _) = peak;
    Some(sample_rate / peak_index as f64)
}

fn interpolate(correlation: &Vec<f64>, x: f64) -> f64 {
    if x < 0.0 {
        println!("<0");
        correlation[0]
    }
    else if x >= correlation.len() as f64 {
        println!(">len");
        correlation[correlation.len()-1]
    }
    else {
        let x0 = x.floor();
        let y0 = correlation[x0 as usize];
        let x1 = x.ceil();
        let y1 = correlation[x1 as usize];

        (y0*(x1-x) + y1*(x-x0)) / (x1-x0)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::f64::consts::PI;

    const SAMPLE_RATE: f64 = 44100.0;
    const FRAMES: usize = 512;

    fn frequency_resolution() -> f64 {
        SAMPLE_RATE / 2.0 / FRAMES as f64
    }

    fn sin_arg(f: f64, t: f64, phase: f64) -> f64 {
        2.0 as f64 * PI * f * t + phase
    }

    fn sample_sinusoud(amplitude: f64, frequency: f64, phase: f64) -> Vec<f64> {
        (0..FRAMES)
            .map(|x| {
                let t = x as f64 / SAMPLE_RATE;
                sin_arg(frequency, t, phase).sin() * amplitude
            }).collect()
    }

    #[test]
    fn fft_on_sine_wave() {
        let frequency = 440.0 as f64; //concert A

        let samples = sample_sinusoud(1.0, frequency, 0.0);
        let frequency_domain = fft(&samples, SAMPLE_RATE);
        let fundamental = find_fundamental_frequency(&frequency_domain).unwrap();

        assert!((fundamental-frequency).abs() < frequency_resolution(), "expected={}, actual={}", frequency, fundamental);
    }

    #[test]
    fn fft_on_two_sine_waves() {
        //Unfortunately, real signals won't be this neat
        let samples1a = sample_sinusoud(2.0, 440.0, 0.0);
        let samples2a = sample_sinusoud(1.0, 880.0, 0.0);
        let expected_fundamental = 440.0;

        let samples = samples1a.iter().zip(samples2a.iter())
            .map(|(a, b)| a+b)
            .collect();
        let frequency_domain = fft(&samples, SAMPLE_RATE);

        let fundamental = find_fundamental_frequency(&frequency_domain).unwrap();

        assert!((fundamental-expected_fundamental).abs() < frequency_resolution(), "expected_fundamental={}, actual={}", expected_fundamental, fundamental);
    }

    #[test]
    fn correlation_on_sine_wave() {
        let frequency = 440.0 as f64; //concert A

        let samples = sample_sinusoud(1.0, frequency, 0.0);
        let fundamental = find_fundamental_frequency_correlation(&samples, SAMPLE_RATE).unwrap();
        assert!((fundamental-frequency).abs() < frequency_resolution(), "expected={}, actual={}", frequency, fundamental);
    }

    #[test]
    fn correlation_on_two_sine_waves() {
        //Unfortunately, real signals won't be this neat
        let samples1a = sample_sinusoud(2.0, 440.0, 0.0);
        let samples2a = sample_sinusoud(1.0, 880.0, 0.0);
        let expected_fundamental = 440.0;

        let samples = samples1a.iter().zip(samples2a.iter())
            .map(|(a, b)| a+b)
            .collect();

        let fundamental = find_fundamental_frequency_correlation(&samples, SAMPLE_RATE).unwrap();

        assert!((fundamental-expected_fundamental).abs() < frequency_resolution(), "expected_fundamental={}, actual={}", expected_fundamental, fundamental);
    }

    #[test]
    fn interpolate_half_way() {
        assert_eq!(0.5, interpolate(&vec!(0.0, 1.0), 0.5))
    }
}

pub fn hz_to_midi_number(hz: f64) -> f64 {
    69.0 + 12.0 * (hz / 440.0).log2()
}

pub fn hz_to_cents_error(hz: f64) -> f64 {
    let midi_number = hz_to_midi_number(hz);
    let cents = (midi_number * 100.0).round() % 100.0;
    if cents >= 50.0 {
        cents - 100.0
    }
    else {
        cents
    }
}

pub fn hz_to_pitch(hz: f64) -> String {
    let pitch_names = [
        "C",
        "C#",
        "D",
        "Eb",
        "E",
        "F",
        "F#",
        "G",
        "G#",
        "A",
        "Bb",
        "B"
    ];

    let midi_number = hz_to_midi_number(hz);
    //midi_number of 0 is C-1.

    let rounded_pitch = midi_number.round() as i32;
    let name = pitch_names[rounded_pitch as usize % pitch_names.len()].to_string();
    let octave = rounded_pitch / pitch_names.len() as i32 - 1; //0 is C-1
    if octave < 0 {
        return "< C1".to_string();
    }

    let mut cents = ((midi_number * 100.0).round() % 100.0) as i32;
    if cents >= 50 {
        //don't need to adjust pitch here, that's already been done by the round above
        cents -= 100;
    }

    format!("{}{} {:+}", name, octave, cents)
}

#[test]
fn a4_is_correct() {
    assert_eq!(hz_to_pitch(440.0), "A4 +0");
}

#[test]
fn a2_is_correct() {
    assert_eq!(hz_to_pitch(110.0), "A2 +0");
}

#[test]
fn c4_is_correct() {
    assert_eq!(hz_to_pitch(261.63), "C4 +0");
}

#[test]
fn f5_is_correct() {
    assert_eq!(hz_to_pitch(698.46), "F5 +0");
}

pub fn align_to_rising_edge(samples: &Vec<f64>) -> Vec<f64> {
    samples.iter()
        .skip_while(|x| !x.is_sign_negative())
        .skip_while(|x| x.is_sign_negative())
        .cloned()
        .collect()
}
<|endoftext|>


<commit_before>use crate::command_prelude::*;
use cargo::ops::tree;
use std::str::FromStr;

pub fn cli() -> App {
    subcommand("tree")
        .about("Display a tree visualization of a dependency graph")
        .arg(opt("quiet", "Suppress status messages").short("q"))
        .arg_manifest_path()
        .arg_package_spec_no_all(
            "Package to be used as the root of the tree",
            "Display the tree for all packages in the workspace",
            "Exclude specific workspace members",
        )
        .arg_features()
        .arg_target_triple(
            "Filter dependencies matching the given target-triple (default host platform)",
        )
        .arg(opt("no-dev-dependencies", "Skip dev dependencies"))
        .arg(opt("invert", "Invert the tree direction").short("i"))
        .arg(Arg::with_name("no-indent").long("no-indent").hidden(true))
        .arg(
            Arg::with_name("prefix-depth")
                .long("prefix-depth")
                .hidden(true),
        )
        .arg(
            opt(
                "prefix",
                "Change the prefix (indentation) of how each entry is displayed",
            )
            .value_name("PREFIX")
            .possible_values(&["depth", "indent", "none"])
            .default_value("indent"),
        )
        .arg(opt(
            "no-dedupe",
            "Do not de-duplicate (repeats all shared dependencies)",
        ))
        .arg(
            opt(
                "duplicates",
                "Show only dependencies which come in multiple versions (implies -i)",
            )
            .short("d")
            .alias("duplicate"),
        )
        .arg(
            opt("charset", "Character set to use in output: utf8, ascii")
                .value_name("CHARSET")
                .possible_values(&["utf8", "ascii"])
                .default_value("utf8"),
        )
        .arg(
            opt("format", "Format string used for printing dependencies")
                .value_name("FORMAT")
                .short("f")
                .default_value("{p}"),
        )
        .arg(opt("graph-features", "Include features in the tree"))
}

pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
    if args.is_present("no-indent") {
        return Err(
            anyhow::format_err!("the --no-indent flag has been changed to --prefix=none").into(),
        );
    }
    if args.is_present("prefix-depth") {
        return Err(anyhow::format_err!(
            "the --prefix-depth flag has been changed to --prefix=depth"
        )
        .into());
    }
    let ws = args.workspace(config)?;
    let charset = tree::Charset::from_str(args.value_of("charset").unwrap())
        .map_err(|e| anyhow::anyhow!("{}", e))?;
    let prefix = tree::Prefix::from_str(args.value_of("prefix").unwrap())
        .map_err(|e| anyhow::anyhow!("{}", e))?;
    let target = tree::Target::from_cli(args.value_of("target"));
    let opts = tree::TreeOptions {
        features: values(args, "features"),
        all_features: args.is_present("all-features"),
        no_default_features: args.is_present("no-default-features"),
        packages: args.packages_from_flags()?,
        target,
        no_dev_dependencies: args.is_present("no-dev-dependencies"),
        invert: args.is_present("invert"),
        prefix,
        no_dedupe: args.is_present("no-dedupe"),
        duplicates: args.is_present("duplicates"),
        charset,
        format: args.value_of("format").unwrap().to_string(),
        graph_features: args.is_present("graph-features"),
    };

    tree::build_and_print(&ws, &opts)?;
    Ok(())
}
<commit_msg>Catch and display error about the --all flag.<commit_after>use crate::command_prelude::*;
use cargo::ops::tree;
use std::str::FromStr;

pub fn cli() -> App {
    subcommand("tree")
        .about("Display a tree visualization of a dependency graph")
        .arg(opt("quiet", "Suppress status messages").short("q"))
        .arg_manifest_path()
        .arg_package_spec_no_all(
            "Package to be used as the root of the tree",
            "Display the tree for all packages in the workspace",
            "Exclude specific workspace members",
        )
        .arg(Arg::with_name("all").long("all").short("a").hidden(true))
        .arg_features()
        .arg_target_triple(
            "Filter dependencies matching the given target-triple (default host platform)",
        )
        .arg(opt("no-dev-dependencies", "Skip dev dependencies"))
        .arg(opt("invert", "Invert the tree direction").short("i"))
        .arg(Arg::with_name("no-indent").long("no-indent").hidden(true))
        .arg(
            Arg::with_name("prefix-depth")
                .long("prefix-depth")
                .hidden(true),
        )
        .arg(
            opt(
                "prefix",
                "Change the prefix (indentation) of how each entry is displayed",
            )
            .value_name("PREFIX")
            .possible_values(&["depth", "indent", "none"])
            .default_value("indent"),
        )
        .arg(opt(
            "no-dedupe",
            "Do not de-duplicate (repeats all shared dependencies)",
        ))
        .arg(
            opt(
                "duplicates",
                "Show only dependencies which come in multiple versions (implies -i)",
            )
            .short("d")
            .alias("duplicate"),
        )
        .arg(
            opt("charset", "Character set to use in output: utf8, ascii")
                .value_name("CHARSET")
                .possible_values(&["utf8", "ascii"])
                .default_value("utf8"),
        )
        .arg(
            opt("format", "Format string used for printing dependencies")
                .value_name("FORMAT")
                .short("f")
                .default_value("{p}"),
        )
        .arg(opt("graph-features", "Include features in the tree"))
}

pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
    if args.is_present("no-indent") {
        return Err(
            anyhow::format_err!("the --no-indent flag has been changed to --prefix=none").into(),
        );
    }
    if args.is_present("prefix-depth") {
        return Err(anyhow::format_err!(
            "the --prefix-depth flag has been changed to --prefix=depth"
        )
        .into());
    }
    if args.is_present("all") {
        return Err(anyhow::format_err!(
            "The `cargo tree` --all flag has been changed to --no-dedupe.\n\
            If you are looking to display all workspace members, use the --workspace flag."
        )
        .into());
    }
    let ws = args.workspace(config)?;
    let charset = tree::Charset::from_str(args.value_of("charset").unwrap())
        .map_err(|e| anyhow::anyhow!("{}", e))?;
    let prefix = tree::Prefix::from_str(args.value_of("prefix").unwrap())
        .map_err(|e| anyhow::anyhow!("{}", e))?;
    let target = tree::Target::from_cli(args.value_of("target"));
    let opts = tree::TreeOptions {
        features: values(args, "features"),
        all_features: args.is_present("all-features"),
        no_default_features: args.is_present("no-default-features"),
        packages: args.packages_from_flags()?,
        target,
        no_dev_dependencies: args.is_present("no-dev-dependencies"),
        invert: args.is_present("invert"),
        prefix,
        no_dedupe: args.is_present("no-dedupe"),
        duplicates: args.is_present("duplicates"),
        charset,
        format: args.value_of("format").unwrap().to_string(),
        graph_features: args.is_present("graph-features"),
    };

    tree::build_and_print(&ws, &opts)?;
    Ok(())
}
<|endoftext|>


<commit_before>use regex::Regex;
use std::collections::HashMap;

lazy_static! {
    static ref LINK_TOKEN_RE: Regex = Regex::new(
        r#"(?x)
        (?:
            <(?P<link>[^>]+)>
        ) | (?:
            (?P<key>[a-z]+)
               \s*=\s*
            (?:
                "(?P<qvalue>[^"]+)" |
                (?P<value>[^\s,.]+)
            )
        ) | (?:
            \s*
                (?:
                    (?P<comma>,) |
                    (?P<semi>;)
                )
            \s*
        )
    "#
    ).unwrap();
}

/// Parses a link header into a vector of hash maps.
///
/// The implied `link` tag is stored as `_link`.
pub fn parse_link_header<'a>(s: &'a str) -> Vec<HashMap<&'a str, &'a str>> {
    let mut rv = vec![];
    let mut item = HashMap::new();

    for caps in LINK_TOKEN_RE.captures_iter(s) {
        if let Some(link) = caps.name("_link") {
            item.insert("link", link.as_str());
        } else if let Some(key) = caps.name("key") {
            item.insert(
                key.as_str(),
                caps.name("qvalue")
                    .unwrap_or_else(|| caps.name("value").unwrap())
                    .as_str(),
            );
        } else if caps.name("comma").is_some() {
            rv.push(item);
            item = HashMap::new();
        }
    }

    if !item.is_empty() {
        rv.push(item);
    }

    rv
}

#[test]
fn test_parse_link_header() {
    let rv = parse_link_header("<https://sentry.io/api/0/organizations/sentry/releases/?&cursor=100:-1:1>; rel=\"previous\"; results=\"false\"; cursor=\"100:-1:1\", <https://sentry.io/api/0/organizations/sentry/releases/?&cursor=100:1:0>; rel=\"next\"; results=\"true\"; cursor=\"100:1:0\"");
    assert_eq!(rv.len(), 2);

    let a = &rv[0];
    let b = &rv[1];

    assert_eq!(
        a.get("_link").unwrap(),
        &"https://sentry.io/api/0/organizations/sentry/releases/?&cursor=100:-1:1"
    );
    assert_eq!(a.get("cursor").unwrap(), &"100:-1:1");
    assert_eq!(a.get("rel").unwrap(), &"previous");
    assert_eq!(a.get("results").unwrap(), &"false");

    assert_eq!(
        b.get("_link").unwrap(),
        &"https://sentry.io/api/0/organizations/sentry/releases/?&cursor=100:1:0"
    );
    assert_eq!(b.get("cursor").unwrap(), &"100:1:0");
    assert_eq!(b.get("rel").unwrap(), &"next");
    assert_eq!(b.get("results").unwrap(), &"true");
}
<commit_msg>fix: Fixed a broken test<commit_after>use regex::Regex;
use std::collections::HashMap;

lazy_static! {
    static ref LINK_TOKEN_RE: Regex = Regex::new(
        r#"(?x)
        (?:
            <(?P<link>[^>]+)>
        ) | (?:
            (?P<key>[a-z]+)
               \s*=\s*
            (?:
                "(?P<qvalue>[^"]+)" |
                (?P<value>[^\s,.]+)
            )
        ) | (?:
            \s*
                (?:
                    (?P<comma>,) |
                    (?P<semi>;)
                )
            \s*
        )
    "#
    ).unwrap();
}

/// Parses a link header into a vector of hash maps.
///
/// The implied `link` tag is stored as `_link`.
pub fn parse_link_header<'a>(s: &'a str) -> Vec<HashMap<&'a str, &'a str>> {
    let mut rv = vec![];
    let mut item = HashMap::new();

    for caps in LINK_TOKEN_RE.captures_iter(s) {
        if let Some(link) = caps.name("link") {
            item.insert("_link", link.as_str());
        } else if let Some(key) = caps.name("key") {
            item.insert(
                key.as_str(),
                caps.name("qvalue")
                    .unwrap_or_else(|| caps.name("value").unwrap())
                    .as_str(),
            );
        } else if caps.name("comma").is_some() {
            rv.push(item);
            item = HashMap::new();
        }
    }

    if !item.is_empty() {
        rv.push(item);
    }

    rv
}

#[test]
fn test_parse_link_header() {
    let rv = parse_link_header("<https://sentry.io/api/0/organizations/sentry/releases/?&cursor=100:-1:1>; rel=\"previous\"; results=\"false\"; cursor=\"100:-1:1\", <https://sentry.io/api/0/organizations/sentry/releases/?&cursor=100:1:0>; rel=\"next\"; results=\"true\"; cursor=\"100:1:0\"");
    assert_eq!(rv.len(), 2);

    let a = &rv[0];
    let b = &rv[1];

    assert_eq!(
        a.get("_link").unwrap(),
        &"https://sentry.io/api/0/organizations/sentry/releases/?&cursor=100:-1:1"
    );
    assert_eq!(a.get("cursor").unwrap(), &"100:-1:1");
    assert_eq!(a.get("rel").unwrap(), &"previous");
    assert_eq!(a.get("results").unwrap(), &"false");

    assert_eq!(
        b.get("_link").unwrap(),
        &"https://sentry.io/api/0/organizations/sentry/releases/?&cursor=100:1:0"
    );
    assert_eq!(b.get("cursor").unwrap(), &"100:1:0");
    assert_eq!(b.get("rel").unwrap(), &"next");
    assert_eq!(b.get("results").unwrap(), &"true");
}
<|endoftext|>


<commit_before>// Copyright 2017 Serde Developers
//
// 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::borrow::Cow;

use super::Value;
use map::Map;
use number::Number;

macro_rules! from_integer {
    ($($ty:ident)*) => {
        $(
            impl From<$ty> for Value {
                fn from(n: $ty) -> Self {
                    Value::Number(n.into())
                }
            }
        )*
    };
}

from_integer! {
    i8 i16 i32 i64 isize
    u8 u16 u32 u64 usize
}

impl From<f32> for Value {
    /// Convert 32-bit floating point number to `Value`
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::Value;
    ///
    /// let f: f32 = 13.37;
    /// let x: Value = f.into();
    /// # }
    /// ```
    fn from(f: f32) -> Self {
        From::from(f as f64)
    }
}

impl From<f64> for Value {
    /// Convert 64-bit floating point number to `Value`
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::Value;
    ///
    /// let f: f64 = 13.37;
    /// let x: Value = f.into();
    /// # }
    /// ```
    fn from(f: f64) -> Self {
        Number::from_f64(f).map_or(Value::Null, Value::Number)
    }
}

impl From<bool> for Value {
    /// Convert boolean to `Value`
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::Value;
    ///
    /// let b = false;
    /// let x: Value = b.into();
    /// # }
    /// ```
    fn from(f: bool) -> Self {
        Value::Bool(f)
    }
}

impl From<String> for Value {
    /// Convert `String` to `Value`
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::Value;
    ///
    /// let s: String = "lorem".to_string();
    /// let x: Value = s.into();
    /// # }
    /// ```
    fn from(f: String) -> Self {
        Value::String(f)
    }
}

impl<'a> From<&'a str> for Value {
    /// Convert string slice to `Value`
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::Value;
    ///
    /// let s: &str = "lorem";
    /// let x: Value = s.into();
    /// # }
    /// ```
    fn from(f: &str) -> Self {
        Value::String(f.to_string())
    }
}

impl<'a> From<Cow<'a, str>> for Value {
    /// Convert copy-on-write string to `Value`
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::Value;
    /// use std::borrow::Cow;
    ///
    /// let s: Cow<str> = Cow::Borrowed("lorem");
    /// let x: Value = s.into();
    /// # }
    /// ```
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::Value;
    /// use std::borrow::Cow;
    ///
    /// let s: Cow<str> = Cow::Owned("lorem".to_string());
    /// let x: Value = s.into();
    /// # }
    /// ```
    fn from(f: Cow<'a, str>) -> Self {
        Value::String(f.into_owned())
    }
}

impl From<Map<String, Value>> for Value {
    /// Convert map (with string keys) to `Value`
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::{Map, Value};
    ///
    /// let mut m = Map::new();
    /// m.insert("Lorem".to_string(), "ipsum".into());
    /// let x: Value = m.into();
    /// # }
    /// ```
    fn from(f: Map<String, Value>) -> Self {
        Value::Object(f)
    }
}

impl<T: Into<Value>> From<Vec<T>> for Value {
    /// Convert a `Vec` to `Value`
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::Value;
    ///
    /// let v = vec!["lorem", "ipsum", "dolor"];
    /// let x: Value = v.into();
    /// # }
    /// ```
    fn from(f: Vec<T>) -> Self {
        Value::Array(f.into_iter().map(Into::into).collect())
    }
}

impl<'a, T: Clone + Into<Value>> From<&'a [T]> for Value {
    /// Convert a slice to `Value`
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::Value;
    ///
    /// let v: &[&str] = &["lorem", "ipsum", "dolor"];
    /// let x: Value = v.into();
    /// # }
    /// ```
    fn from(f: &'a [T]) -> Self {
        Value::Array(f.into_iter().cloned().map(Into::into).collect())
    }
}

impl<T: Into<Value>> ::std::iter::FromIterator<T> for Value {
    /// Convert an iteratable type to a `Value`
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::Value;
    ///
    /// let v = std::iter::repeat(42).take(5);
    /// let x: Value = v.collect();
    /// # }
    /// ```
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::Value;
    ///
    /// let v: Vec<_> = vec!["lorem", "ipsum", "dolor"];
    /// let x: Value = v.into_iter().collect();
    /// # }
    /// ```
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use std::iter::FromIterator;
    /// use serde_json::Value;
    ///
    /// let x: Value = Value::from_iter(vec!["lorem", "ipsum", "dolor"]);
    /// # }
    /// ```
    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
        let vec: Vec<Value> = iter.into_iter().map(|x| x.into()).collect();

        Value::Array(vec)
    }
}
<commit_msg>Simplify impl FromIterator for Value::Array, and make it look consistent with the rest of the From<Collection> impls<commit_after>// Copyright 2017 Serde Developers
//
// 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::borrow::Cow;

use super::Value;
use map::Map;
use number::Number;

macro_rules! from_integer {
    ($($ty:ident)*) => {
        $(
            impl From<$ty> for Value {
                fn from(n: $ty) -> Self {
                    Value::Number(n.into())
                }
            }
        )*
    };
}

from_integer! {
    i8 i16 i32 i64 isize
    u8 u16 u32 u64 usize
}

impl From<f32> for Value {
    /// Convert 32-bit floating point number to `Value`
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::Value;
    ///
    /// let f: f32 = 13.37;
    /// let x: Value = f.into();
    /// # }
    /// ```
    fn from(f: f32) -> Self {
        From::from(f as f64)
    }
}

impl From<f64> for Value {
    /// Convert 64-bit floating point number to `Value`
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::Value;
    ///
    /// let f: f64 = 13.37;
    /// let x: Value = f.into();
    /// # }
    /// ```
    fn from(f: f64) -> Self {
        Number::from_f64(f).map_or(Value::Null, Value::Number)
    }
}

impl From<bool> for Value {
    /// Convert boolean to `Value`
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::Value;
    ///
    /// let b = false;
    /// let x: Value = b.into();
    /// # }
    /// ```
    fn from(f: bool) -> Self {
        Value::Bool(f)
    }
}

impl From<String> for Value {
    /// Convert `String` to `Value`
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::Value;
    ///
    /// let s: String = "lorem".to_string();
    /// let x: Value = s.into();
    /// # }
    /// ```
    fn from(f: String) -> Self {
        Value::String(f)
    }
}

impl<'a> From<&'a str> for Value {
    /// Convert string slice to `Value`
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::Value;
    ///
    /// let s: &str = "lorem";
    /// let x: Value = s.into();
    /// # }
    /// ```
    fn from(f: &str) -> Self {
        Value::String(f.to_string())
    }
}

impl<'a> From<Cow<'a, str>> for Value {
    /// Convert copy-on-write string to `Value`
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::Value;
    /// use std::borrow::Cow;
    ///
    /// let s: Cow<str> = Cow::Borrowed("lorem");
    /// let x: Value = s.into();
    /// # }
    /// ```
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::Value;
    /// use std::borrow::Cow;
    ///
    /// let s: Cow<str> = Cow::Owned("lorem".to_string());
    /// let x: Value = s.into();
    /// # }
    /// ```
    fn from(f: Cow<'a, str>) -> Self {
        Value::String(f.into_owned())
    }
}

impl From<Map<String, Value>> for Value {
    /// Convert map (with string keys) to `Value`
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::{Map, Value};
    ///
    /// let mut m = Map::new();
    /// m.insert("Lorem".to_string(), "ipsum".into());
    /// let x: Value = m.into();
    /// # }
    /// ```
    fn from(f: Map<String, Value>) -> Self {
        Value::Object(f)
    }
}

impl<T: Into<Value>> From<Vec<T>> for Value {
    /// Convert a `Vec` to `Value`
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::Value;
    ///
    /// let v = vec!["lorem", "ipsum", "dolor"];
    /// let x: Value = v.into();
    /// # }
    /// ```
    fn from(f: Vec<T>) -> Self {
        Value::Array(f.into_iter().map(Into::into).collect())
    }
}

impl<'a, T: Clone + Into<Value>> From<&'a [T]> for Value {
    /// Convert a slice to `Value`
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::Value;
    ///
    /// let v: &[&str] = &["lorem", "ipsum", "dolor"];
    /// let x: Value = v.into();
    /// # }
    /// ```
    fn from(f: &'a [T]) -> Self {
        Value::Array(f.into_iter().cloned().map(Into::into).collect())
    }
}

impl<T: Into<Value>> ::std::iter::FromIterator<T> for Value {
    /// Convert an iteratable type to a `Value`
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::Value;
    ///
    /// let v = std::iter::repeat(42).take(5);
    /// let x: Value = v.collect();
    /// # }
    /// ```
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use serde_json::Value;
    ///
    /// let v: Vec<_> = vec!["lorem", "ipsum", "dolor"];
    /// let x: Value = v.into_iter().collect();
    /// # }
    /// ```
    ///
    /// ```rust
    /// # extern crate serde_json;
    /// #
    /// # fn main() {
    /// use std::iter::FromIterator;
    /// use serde_json::Value;
    ///
    /// let x: Value = Value::from_iter(vec!["lorem", "ipsum", "dolor"]);
    /// # }
    /// ```
    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
        Value::Array(iter.into_iter().map(Into::into).collect())
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2017-2018, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

#[macro_use]
extern crate criterion;
extern crate rand;
extern crate rav1e;

mod predict;
mod transform;
mod me;

use std::time::Duration;
use criterion::*;
use rav1e::cdef::cdef_filter_frame;
use rav1e::context::*;
use rav1e::ec;
use rav1e::partition::*;
use rav1e::predict::*;
use rav1e::rdo::rdo_cfl_alpha;
use rav1e::*;

use transform::transform;

#[cfg(feature = "comparative_bench")]
mod comparative;

fn write_b(c: &mut Criterion) {
  for &tx_size in &[TxSize::TX_4X4, TxSize::TX_8X8] {
    for &qi in &[20, 55] {
      let n = format!("write_b_bench({:?}, {})", tx_size, qi);
      c.bench_function(&n, move |b| write_b_bench(b, tx_size, qi));
    }
  }
}

fn write_b_bench(b: &mut Bencher, tx_size: TxSize, qindex: usize) {
  #[cfg(feature = "aom")]
  unsafe {
    av1_rtcd();
    aom_dsp_rtcd();
  }
  let config =
    EncoderConfig { quantizer: qindex, speed_settings: SpeedSettings::from_preset(10), ..Default::default() };
  let mut fi = FrameInvariants::new(1024, 1024, config);
  let mut w = ec::WriterEncoder::new();
  let fc = CDFContext::new(fi.base_q_idx);
  let bc = BlockContext::new(fi.sb_width * 16, fi.sb_height * 16);
  let mut fs = FrameState::new(&fi);
  // For now, restoration unit size is locked to superblock size.
  let rc = RestorationContext::new(fi.sb_width, fi.sb_height);
  let mut cw = ContextWriter::new(fc, bc, rc);

  let tx_type = TxType::DCT_DCT;

  let sbx = 0;
  let sby = 0;
  let ac = &[0i16; 32 * 32];

  b.iter(|| {
    for &mode in RAV1E_INTRA_MODES {
      let sbo = SuperBlockOffset { x: sbx, y: sby };
      fs.qc.update(fi.base_q_idx, tx_size, mode.is_intra(), 8);
      for p in 1..3 {
        for by in 0..8 {
          for bx in 0..8 {
            // For ex, 8x8 tx should be applied to even numbered (bx,by)
            if (tx_size.width_mi() >> 1) & bx != 0
              || (tx_size.height_mi() >> 1) & by != 0
            {
              continue;
            };
            let bo = sbo.block_offset(bx, by);
            let tx_bo = BlockOffset { x: bo.x + bx, y: bo.y + by };
            let po = tx_bo.plane_offset(&fs.input.planes[p].cfg);
            encode_tx_block(
              &mut fi,
              &mut fs,
              &mut cw,
              &mut w,
              p,
              &bo,
              mode,
              tx_size,
              tx_type,
              tx_size.block_size(),
              &po,
              false,
              8,
              ac,
              0,
              false
            );
          }
        }
      }
    }
  });
}

fn cdef_frame(c: &mut Criterion) {
  let w = 128;
  let h = 128;
  let n = format!("cdef_frame({}, {})", w, h);
  c.bench_function(&n, move |b| cdef_frame_bench(b, w, h));
}

fn cdef_frame_bench(b: &mut Bencher, w: usize, h: usize) {
  let config =
    EncoderConfig { quantizer: 100, speed_settings: SpeedSettings::from_preset(10), ..Default::default() };
  let fi = FrameInvariants::new(w, h, config);
  let mut bc = BlockContext::new(fi.sb_width * 16, fi.sb_height * 16);
  let mut fs = FrameState::new(&fi);

  b.iter(|| cdef_filter_frame(&fi, &mut fs.rec, &mut bc, 8));
}

fn cfl_rdo(c: &mut Criterion) {
  for &bsize in &[
    BlockSize::BLOCK_4X4,
    BlockSize::BLOCK_8X8,
    BlockSize::BLOCK_16X16,
    BlockSize::BLOCK_32X32
  ] {
    let n = format!("cfl_rdo({:?})", bsize);
    c.bench_function(&n, move |b| cfl_rdo_bench(b, bsize));
  }
}

fn cfl_rdo_bench(b: &mut Bencher, bsize: BlockSize) {
  let config =
    EncoderConfig { quantizer: 100, speed_settings: SpeedSettings::from_preset(10), ..Default::default() };
  let fi = FrameInvariants::new(1024, 1024, config);
  let mut fs = FrameState::new(&fi);
  let offset = BlockOffset { x: 1, y: 1 };
  b.iter(|| rdo_cfl_alpha(&mut fs, &offset, bsize, 8, Default::default()))
}

criterion_group!(intra_prediction, predict::pred_bench,);

criterion_group!(cfl, cfl_rdo);
criterion_group!(cdef, cdef_frame);
criterion_group!(write_block, write_b);
criterion_group!{ name = me;
                  config = Criterion::default().warm_up_time(Duration::new(1,0));
                  targets = me::get_sad
}

#[cfg(feature = "comparative_bench")]
criterion_main!(comparative::intra_prediction);

#[cfg(not(feature = "comparative_bench"))]
criterion_main!(write_block, intra_prediction, cdef, cfl, me, transform);
<commit_msg>Update bench.rs<commit_after>// Copyright (c) 2017-2018, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

extern crate criterion;
extern crate rand;
extern crate rav1e;

mod predict;
mod transform;
mod me;

use std::time::Duration;
use criterion::*;
use rav1e::cdef::cdef_filter_frame;
use rav1e::context::*;
use rav1e::ec;
use rav1e::partition::*;
use rav1e::predict::*;
use rav1e::rdo::rdo_cfl_alpha;
use rav1e::*;

use transform::transform;

#[cfg(feature = "comparative_bench")]
mod comparative;

fn write_b(c: &mut Criterion) {
  for &tx_size in &[TxSize::TX_4X4, TxSize::TX_8X8] {
    for &qi in &[20, 55] {
      let n = format!("write_b_bench({:?}, {})", tx_size, qi);
      c.bench_function(&n, move |b| write_b_bench(b, tx_size, qi));
    }
  }
}

fn write_b_bench(b: &mut Bencher, tx_size: TxSize, qindex: usize) {
  #[cfg(feature = "aom")]
  unsafe {
    av1_rtcd();
    aom_dsp_rtcd();
  }
  let config =
    EncoderConfig { quantizer: qindex, speed_settings: SpeedSettings::from_preset(10), ..Default::default() };
  let mut fi = FrameInvariants::new(1024, 1024, config);
  let mut w = ec::WriterEncoder::new();
  let fc = CDFContext::new(fi.base_q_idx);
  let bc = BlockContext::new(fi.sb_width * 16, fi.sb_height * 16);
  let mut fs = FrameState::new(&fi);
  // For now, restoration unit size is locked to superblock size.
  let rc = RestorationContext::new(fi.sb_width, fi.sb_height);
  let mut cw = ContextWriter::new(fc, bc, rc);

  let tx_type = TxType::DCT_DCT;

  let sbx = 0;
  let sby = 0;
  let ac = &[0i16; 32 * 32];

  b.iter(|| {
    for &mode in RAV1E_INTRA_MODES {
      let sbo = SuperBlockOffset { x: sbx, y: sby };
      fs.qc.update(fi.base_q_idx, tx_size, mode.is_intra(), 8);
      for p in 1..3 {
        for by in 0..8 {
          for bx in 0..8 {
            // For ex, 8x8 tx should be applied to even numbered (bx,by)
            if (tx_size.width_mi() >> 1) & bx != 0
              || (tx_size.height_mi() >> 1) & by != 0
            {
              continue;
            };
            let bo = sbo.block_offset(bx, by);
            let tx_bo = BlockOffset { x: bo.x + bx, y: bo.y + by };
            let po = tx_bo.plane_offset(&fs.input.planes[p].cfg);
            encode_tx_block(
              &mut fi,
              &mut fs,
              &mut cw,
              &mut w,
              p,
              &bo,
              mode,
              tx_size,
              tx_type,
              tx_size.block_size(),
              &po,
              false,
              8,
              ac,
              0,
              false
            );
          }
        }
      }
    }
  });
}

fn cdef_frame(c: &mut Criterion) {
  let w = 128;
  let h = 128;
  let n = format!("cdef_frame({}, {})", w, h);
  c.bench_function(&n, move |b| cdef_frame_bench(b, w, h));
}

fn cdef_frame_bench(b: &mut Bencher, w: usize, h: usize) {
  let config =
    EncoderConfig { quantizer: 100, speed_settings: SpeedSettings::from_preset(10), ..Default::default() };
  let fi = FrameInvariants::new(w, h, config);
  let mut bc = BlockContext::new(fi.sb_width * 16, fi.sb_height * 16);
  let mut fs = FrameState::new(&fi);

  b.iter(|| cdef_filter_frame(&fi, &mut fs.rec, &mut bc, 8));
}

fn cfl_rdo(c: &mut Criterion) {
  for &bsize in &[
    BlockSize::BLOCK_4X4,
    BlockSize::BLOCK_8X8,
    BlockSize::BLOCK_16X16,
    BlockSize::BLOCK_32X32
  ] {
    let n = format!("cfl_rdo({:?})", bsize);
    c.bench_function(&n, move |b| cfl_rdo_bench(b, bsize));
  }
}

fn cfl_rdo_bench(b: &mut Bencher, bsize: BlockSize) {
  let config =
    EncoderConfig { quantizer: 100, speed_settings: SpeedSettings::from_preset(10), ..Default::default() };
  let fi = FrameInvariants::new(1024, 1024, config);
  let mut fs = FrameState::new(&fi);
  let offset = BlockOffset { x: 1, y: 1 };
  b.iter(|| rdo_cfl_alpha(&mut fs, &offset, bsize, 8, Default::default()))
}

criterion_group!(intra_prediction, predict::pred_bench,);

criterion_group!(cfl, cfl_rdo);
criterion_group!(cdef, cdef_frame);
criterion_group!(write_block, write_b);
criterion_group!{ name = me;
                  config = Criterion::default().warm_up_time(Duration::new(1,0));
                  targets = me::get_sad
}

#[cfg(feature = "comparative_bench")]
criterion_main!(comparative::intra_prediction);

#[cfg(not(feature = "comparative_bench"))]
criterion_main!(write_block, intra_prediction, cdef, cfl, me, transform);
<|endoftext|>


<commit_before>#![feature(test)]
#[macro_use]
extern crate abomonation;
extern crate test;

use test::Bencher;
use abomonation::{Abomonation, encode, decode};

#[bench]
fn bench_populate(b: &mut Bencher) {
    b.iter(|| {
        Log::new()
    });
}

#[bench]
fn bench_serialize(b: &mut Bencher) {
    let log = Log::new();
    let mut bytes = vec![];
    unsafe { encode(&log, &mut bytes); }
    b.bytes = bytes.len() as u64;
    b.iter(|| {
        bytes.clear();
        encode(&log, &mut bytes);
        test::black_box(&bytes);
    });
}

#[bench]
fn bench_deserialize(b: &mut Bencher) {
    let log = Log::new();
    let mut bytes = vec![];
    unsafe { encode(&log, &mut bytes); }
    b.bytes = bytes.len() as u64;
    b.iter(|| {
        test::black_box(unsafe { decode::<Log>(&mut bytes) });
    });
}

#[bench]
fn bench_deserialize_assert(b: &mut Bencher) {
    let log = Log::new();
    let mut bytes = vec![];
    unsafe { encode(&log, &mut bytes); }
    b.bytes = bytes.len() as u64;
    b.iter(|| {
        assert!(unsafe { decode::<Log>(&mut bytes) }.unwrap().0 == &log);
    });
}

unsafe_abomonate!(Http : content_type, user_agent, referer, request_uri);
unsafe_abomonate!(Origin : ip, hostname);
unsafe_abomonate!(Log : http, origin, server_ip, server_name, remote_ip, ray_id);

#[derive(Eq, PartialEq)]
pub struct Http {
    protocol: HttpProtocol,
    status: u32,
    host_status: u32,
    up_status: u32,
    method: HttpMethod,
    content_type: String,
    user_agent: String,
    referer: String,
    request_uri: String,
}

#[allow(non_camel_case_types)]
#[derive(Eq, PartialEq)]
pub enum HttpProtocol {
    HTTP_PROTOCOL_UNKNOWN,
    HTTP10,
    HTTP11,
}

#[allow(non_camel_case_types)]
#[derive(Eq, PartialEq)]
pub enum HttpMethod {
    METHOD_UNKNOWN,
    GET,
    POST,
    DELETE,
    PUT,
    HEAD,
    PURGE,
    OPTIONS,
    PROPFIND,
    MKCOL,
    PATCH,
}

#[allow(non_camel_case_types)]
#[derive(Eq, PartialEq)]
pub enum CacheStatus {
    CACHESTATUS_UNKNOWN,
    Miss,
    Expired,
    Hit,
}

#[derive(Eq, PartialEq)]
pub struct Origin {
    ip: String,
    port: u32,
    hostname: String,
    protocol: OriginProtocol,
}

#[allow(non_camel_case_types)]
#[derive(Eq, PartialEq)]
pub enum OriginProtocol {
    ORIGIN_PROTOCOL_UNKNOWN,
    HTTP,
    HTTPS,
}

#[allow(non_camel_case_types)]
#[derive(Eq, PartialEq)]
pub enum ZonePlan {
    ZONEPLAN_UNKNOWN,
    FREE,
    PRO,
    BIZ,
    ENT,
}

#[derive(Eq, PartialEq)]
pub enum Country {
	UNKNOWN,
	A1,
	A2,
	O1,
	AD,
	AE,
	AF,
	AG,
	AI,
	AL,
	AM,
	AO,
	AP,
	AQ,
	AR,
	AS,
	AT,
	AU,
	AW,
	AX,
	AZ,
	BA,
	BB,
	BD,
	BE,
	BF,
	BG,
	BH,
	BI,
	BJ,
	BL,
	BM,
	BN,
	BO,
	BQ,
	BR,
	BS,
	BT,
	BV,
	BW,
	BY,
	BZ,
	CA,
	CC,
	CD,
	CF,
	CG,
	CH,
	CI,
	CK,
	CL,
	CM,
	CN,
	CO,
	CR,
	CU,
	CV,
	CW,
	CX,
	CY,
	CZ,
	DE,
	DJ,
	DK,
	DM,
	DO,
	DZ,
	EC,
	EE,
	EG,
	EH,
	ER,
	ES,
	ET,
	EU,
	FI,
	FJ,
	FK,
	FM,
	FO,
	FR,
	GA,
	GB,
	GD,
	GE,
	GF,
	GG,
	GH,
	GI,
	GL,
	GM,
	GN,
	GP,
	GQ,
	GR,
	GS,
	GT,
	GU,
	GW,
	GY,
	HK,
	HM,
	HN,
	HR,
	HT,
	HU,
	ID,
	IE,
	IL,
	IM,
	IN,
	IO,
	IQ,
	IR,
	IS,
	IT,
	JE,
	JM,
	JO,
	JP,
	KE,
	KG,
	KH,
	KI,
	KM,
	KN,
	KP,
	KR,
	KW,
	KY,
	KZ,
	LA,
	LB,
	LC,
	LI,
	LK,
	LR,
	LS,
	LT,
	LU,
	LV,
	LY,
	MA,
	MC,
	MD,
	ME,
	MF,
	MG,
	MH,
	MK,
	ML,
	MM,
	MN,
	MO,
	MP,
	MQ,
	MR,
	MS,
	MT,
	MU,
	MV,
	MW,
	MX,
	MY,
	MZ,
	NA,
	NC,
	NE,
	NF,
	NG,
	NI,
	NL,
	NO,
	NP,
	NR,
	NU,
	NZ,
	OM,
	PA,
	PE,
	PF,
	PG,
	PH,
	PK,
	PL,
	PM,
	PN,
	PR,
	PS,
	PT,
	PW,
	PY,
	QA,
	RE,
	RO,
	RS,
	RU,
	RW,
	SA,
	SB,
	SC,
	SD,
	SE,
	SG,
	SH,
	SI,
	SJ,
	SK,
	SL,
	SM,
	SN,
	SO,
	SR,
	SS,
	ST,
	SV,
	SX,
	SY,
	SZ,
	TC,
	TD,
	TF,
	TG,
	TH,
	TJ,
	TK,
	TL,
	TM,
	TN,
	TO,
	TR,
	TT,
	TV,
	TW,
	TZ,
	UA,
	UG,
	UM,
	US,
	UY,
	UZ,
	VA,
	VC,
	VE,
	VG,
	VI,
	VN,
	VU,
	WF,
	WS,
	XX,
	YE,
	YT,
	ZA,
	ZM,
	ZW,
}

#[derive(Eq, PartialEq)]
pub struct Log {
    timestamp: i64,
    zone_id: u32,
    zone_plan: ZonePlan,
    http: Http,
    origin: Origin,
    country: Country,
    cache_status: CacheStatus,
    server_ip: String,
    server_name: String,
    remote_ip: String,
    bytes_dlv: u64,
    ray_id: String,
}

impl Log {
    pub fn new() -> Log {
        Log {
            timestamp: 2837513946597,
            zone_id: 123456,
            zone_plan: ZonePlan::FREE,
            http: Http {
                protocol: HttpProtocol::HTTP11,
                status: 200,
                host_status: 503,
                up_status: 520,
                method: HttpMethod::GET,
                content_type: "text/html".to_string(),
                user_agent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36".to_string(),
                referer: "https://www.cloudflare.com/".to_string(),
                request_uri: "/cdn-cgi/trace".to_string(),
            },
            origin: Origin {
                ip: "1.2.3.4".to_string(),
                port: 8000,
                hostname: "www.example.com".to_string(),
                protocol: OriginProtocol::HTTPS,
            },
            country: Country::US,
            cache_status: CacheStatus::Hit,
            server_ip: "192.168.1.1".to_string(),
            server_name: "metal.cloudflare.com".to_string(),
            remote_ip: "10.1.2.3".to_string(),
            bytes_dlv: 123456,
            ray_id: "10c73629cce30078-LAX".to_string(),
        }
    }
}
<commit_msg>added unsafe, change to_string to to_owned<commit_after>#![feature(test)]
#[macro_use]
extern crate abomonation;
extern crate test;

use test::Bencher;
use abomonation::{Abomonation, encode, decode};

#[bench]
fn bench_populate(b: &mut Bencher) {
    b.iter(|| {
        Log::new()
    });
}

#[bench]
fn bench_serialize(b: &mut Bencher) {
    let log = Log::new();
    let mut bytes = vec![];
    unsafe { encode(&log, &mut bytes); }
    b.bytes = bytes.len() as u64;
    b.iter(|| {
        bytes.clear();
        unsafe { encode(&log, &mut bytes); }
        test::black_box(&bytes);
    });
}

#[bench]
fn bench_deserialize(b: &mut Bencher) {
    let log = Log::new();
    let mut bytes = vec![];
    unsafe { encode(&log, &mut bytes); }
    b.bytes = bytes.len() as u64;
    b.iter(|| {
        test::black_box(unsafe { decode::<Log>(&mut bytes) });
    });
}

#[bench]
fn bench_deserialize_assert(b: &mut Bencher) {
    let log = Log::new();
    let mut bytes = vec![];
    unsafe { encode(&log, &mut bytes); }
    b.bytes = bytes.len() as u64;
    b.iter(|| {
        assert!(unsafe { decode::<Log>(&mut bytes) }.unwrap().0 == &log);
    });
}

unsafe_abomonate!(Http : content_type, user_agent, referer, request_uri);
unsafe_abomonate!(Origin : ip, hostname);
unsafe_abomonate!(Log : http, origin, server_ip, server_name, remote_ip, ray_id);

#[derive(Eq, PartialEq)]
pub struct Http {
    protocol: HttpProtocol,
    status: u32,
    host_status: u32,
    up_status: u32,
    method: HttpMethod,
    content_type: String,
    user_agent: String,
    referer: String,
    request_uri: String,
}

#[allow(non_camel_case_types)]
#[derive(Eq, PartialEq)]
pub enum HttpProtocol {
    HTTP_PROTOCOL_UNKNOWN,
    HTTP10,
    HTTP11,
}

#[allow(non_camel_case_types)]
#[derive(Eq, PartialEq)]
pub enum HttpMethod {
    METHOD_UNKNOWN,
    GET,
    POST,
    DELETE,
    PUT,
    HEAD,
    PURGE,
    OPTIONS,
    PROPFIND,
    MKCOL,
    PATCH,
}

#[allow(non_camel_case_types)]
#[derive(Eq, PartialEq)]
pub enum CacheStatus {
    CACHESTATUS_UNKNOWN,
    Miss,
    Expired,
    Hit,
}

#[derive(Eq, PartialEq)]
pub struct Origin {
    ip: String,
    port: u32,
    hostname: String,
    protocol: OriginProtocol,
}

#[allow(non_camel_case_types)]
#[derive(Eq, PartialEq)]
pub enum OriginProtocol {
    ORIGIN_PROTOCOL_UNKNOWN,
    HTTP,
    HTTPS,
}

#[allow(non_camel_case_types)]
#[derive(Eq, PartialEq)]
pub enum ZonePlan {
    ZONEPLAN_UNKNOWN,
    FREE,
    PRO,
    BIZ,
    ENT,
}

#[derive(Eq, PartialEq)]
pub enum Country {
	UNKNOWN,
	A1,
	A2,
	O1,
	AD,
	AE,
	AF,
	AG,
	AI,
	AL,
	AM,
	AO,
	AP,
	AQ,
	AR,
	AS,
	AT,
	AU,
	AW,
	AX,
	AZ,
	BA,
	BB,
	BD,
	BE,
	BF,
	BG,
	BH,
	BI,
	BJ,
	BL,
	BM,
	BN,
	BO,
	BQ,
	BR,
	BS,
	BT,
	BV,
	BW,
	BY,
	BZ,
	CA,
	CC,
	CD,
	CF,
	CG,
	CH,
	CI,
	CK,
	CL,
	CM,
	CN,
	CO,
	CR,
	CU,
	CV,
	CW,
	CX,
	CY,
	CZ,
	DE,
	DJ,
	DK,
	DM,
	DO,
	DZ,
	EC,
	EE,
	EG,
	EH,
	ER,
	ES,
	ET,
	EU,
	FI,
	FJ,
	FK,
	FM,
	FO,
	FR,
	GA,
	GB,
	GD,
	GE,
	GF,
	GG,
	GH,
	GI,
	GL,
	GM,
	GN,
	GP,
	GQ,
	GR,
	GS,
	GT,
	GU,
	GW,
	GY,
	HK,
	HM,
	HN,
	HR,
	HT,
	HU,
	ID,
	IE,
	IL,
	IM,
	IN,
	IO,
	IQ,
	IR,
	IS,
	IT,
	JE,
	JM,
	JO,
	JP,
	KE,
	KG,
	KH,
	KI,
	KM,
	KN,
	KP,
	KR,
	KW,
	KY,
	KZ,
	LA,
	LB,
	LC,
	LI,
	LK,
	LR,
	LS,
	LT,
	LU,
	LV,
	LY,
	MA,
	MC,
	MD,
	ME,
	MF,
	MG,
	MH,
	MK,
	ML,
	MM,
	MN,
	MO,
	MP,
	MQ,
	MR,
	MS,
	MT,
	MU,
	MV,
	MW,
	MX,
	MY,
	MZ,
	NA,
	NC,
	NE,
	NF,
	NG,
	NI,
	NL,
	NO,
	NP,
	NR,
	NU,
	NZ,
	OM,
	PA,
	PE,
	PF,
	PG,
	PH,
	PK,
	PL,
	PM,
	PN,
	PR,
	PS,
	PT,
	PW,
	PY,
	QA,
	RE,
	RO,
	RS,
	RU,
	RW,
	SA,
	SB,
	SC,
	SD,
	SE,
	SG,
	SH,
	SI,
	SJ,
	SK,
	SL,
	SM,
	SN,
	SO,
	SR,
	SS,
	ST,
	SV,
	SX,
	SY,
	SZ,
	TC,
	TD,
	TF,
	TG,
	TH,
	TJ,
	TK,
	TL,
	TM,
	TN,
	TO,
	TR,
	TT,
	TV,
	TW,
	TZ,
	UA,
	UG,
	UM,
	US,
	UY,
	UZ,
	VA,
	VC,
	VE,
	VG,
	VI,
	VN,
	VU,
	WF,
	WS,
	XX,
	YE,
	YT,
	ZA,
	ZM,
	ZW,
}

#[derive(Eq, PartialEq)]
pub struct Log {
    timestamp: i64,
    zone_id: u32,
    zone_plan: ZonePlan,
    http: Http,
    origin: Origin,
    country: Country,
    cache_status: CacheStatus,
    server_ip: String,
    server_name: String,
    remote_ip: String,
    bytes_dlv: u64,
    ray_id: String,
}

impl Log {
    pub fn new() -> Log {
        Log {
            timestamp: 2837513946597,
            zone_id: 123456,
            zone_plan: ZonePlan::FREE,
            http: Http {
                protocol: HttpProtocol::HTTP11,
                status: 200,
                host_status: 503,
                up_status: 520,
                method: HttpMethod::GET,
                content_type: "text/html".to_owned(),
                user_agent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36".to_string(),
                referer: "https://www.cloudflare.com/".to_owned(),
                request_uri: "/cdn-cgi/trace".to_owned(),
            },
            origin: Origin {
                ip: "1.2.3.4".to_owned(),
                port: 8000,
                hostname: "www.example.com".to_owned(),
                protocol: OriginProtocol::HTTPS,
            },
            country: Country::US,
            cache_status: CacheStatus::Hit,
            server_ip: "192.168.1.1".to_owned(),
            server_name: "metal.cloudflare.com".to_owned(),
            remote_ip: "10.1.2.3".to_owned(),
            bytes_dlv: 123456,
            ray_id: "10c73629cce30078-LAX".to_owned(),
        }
    }
}
<|endoftext|>


<commit_before>use super::Rope;
use std::iter;

#[test]
fn rebalance_test_1() {
    let mut r = Rope::from("This is a large string \
                        that will need to be rebalanced.".to_string());
    r.rebalance();
    assert!(r.is_balanced());
}

#[test]
fn rebalance_test_2() {
    let mut r =
        Rope::from("Lorem ipsum dolor sit amet, consectetur adipiscing eli\
                    t, sed do eiusmod tempor incididunt ut labore et dolor\
                    e magna aliqua. Ut enim ad minim veniam, quis nostrud \
                    exercitation ullamco laboris nisi ut aliquip ex ea com\
                    modo consequat. Duis aute irure dolor in reprehenderit\
                     in voluptate velit esse cillum dolore eu fugiat nulla\
                     pariatur. Excepteur sint occaecat cupidatat non proid\
                    ent, sunt in culpa qui officia deserunt mollit anim id\
                     est laborum.".to_string());
    r.rebalance();
    assert!(r.is_balanced());
}

#[test]
fn big_rebalance() {
    let s: String = iter::repeat('a').take(10_000).collect();
    let mut r = Rope::from(s);
    r.rebalance();
    assert!(r.is_balanced());
}

#[test]
fn repeated_concat_left_rebalance() {
    let s: String = iter::repeat('a').take(10_000).collect();
    let mut r = Rope::from(s);
    for _ in 1..1000 {
        r = r + iter::repeat('a').take(100).collect::<String>();
    }
    assert!(r.is_balanced());
}

#[test]
fn repeated_concat_right_rebalance() {
    let s: String = iter::repeat('a').take(10_000).collect();
    let mut r = Rope::from(s);
    for _ in 1..1000 {
        let s2 = iter::repeat('a').take(100).collect::<String>();
        r = Rope::from(s2) + r;
    }
    assert!(r.is_balanced());
}

#[test]
fn merge_rebalance_test() {
    let s = "Lorem ipsum dolor sit amet, consectetur adipiscing eli\
             t, sed do eiusmod tempor incididunt ut labore et dolor\
             e magna aliqua. Ut enim ad minim veniam, quis nostrud \
             exercitation ullamco laboris nisi ut aliquip ex ea com\
             modo consequat. Duis aute irure dolor in reprehenderit\
              in voluptate velit esse cillum dolore eu fugiat nulla\
              pariatur. Excepteur sint occaecat cupidatat non proid\
             ent, sunt in culpa qui officia deserunt mollit anim id\
              est laborum.";

     let t = Rope::from(s.to_owned());
     let mut u = t + s;
     u.rebalance();
     assert!(u.is_balanced());
}

#[test]
fn with_insert_rope_balance_test() {
    let s: String = iter::repeat('a').take(10).collect();
    let mut r_1 = Rope::from(s);
    for _ in 0..99 {
        let t: String = iter::repeat('a').take(10).collect();
        r_1 = r_1.with_insert_rope(5, Rope::from(t));
    }
    //  this isn't necessary, with_insert_rope() will automatically rebalance
    //      - eliza, 12/18/2016
    // r_1.rebalance();
    assert!(r_1.is_balanced());
}

#[test]
fn with_insert_rope_test_1() {
    let s: String = iter::repeat('a').take(1_000).collect();
    let r_1 = Rope::from(s);
    let mut r_2 = Rope::new();
    for _ in 0..100 {
        let t: String = iter::repeat('a').take(10).collect();
        r_2 = r_2.with_insert_rope(0, Rope::from(t));
    }
    assert_eq!(r_1, r_2);
}

#[test]
fn with_insert_rope_test_2() {
    let s: String = iter::repeat('a').take(10).collect();
    let mut r_1 = Rope::from(s);
    for _ in 0..99 {
        let t: String = iter::repeat('a').take(10).collect();
        r_1 = r_1.with_insert_rope(5, Rope::from(t));
    }

    let q: String = iter::repeat('a').take(1_000).collect();
    let r_2 = Rope::from(q);
    assert_eq!(r_1, r_2);
}

#[test]
fn mutable_insert_rope_test_1() {
    let mut s_1 = Rope::from(String::from("aaaaa"));
    let mut s_2 = Rope::from(String::from("bbbbb"));
    let s_3 = Rope::from(String::from("ccccc"));
    s_2.insert_rope(0, s_3);
    s_1.insert_rope(0, s_2);
    assert_eq!(&s_1, "cccccbbbbbaaaaa");
}

#[test]
fn mutable_insert_str_test_1() {
    let mut s = Rope::from("aaaaa");
    s.insert_str(0, "bbbbb");
    s.insert_str(10, "ccccc");
    assert_eq!(&s, "bbbbbaaaaaccccc");
}

#[test]
fn mutable_insert_char_test_1() {
    let mut s = Rope::from("aaaaa");
    for _ in 0..5 { s.insert(0, 'b')}
    for _ in 0..5 { s.insert(10, 'c')}
    assert_eq!(&s, "bbbbbaaaaaccccc");
}

#[test]
fn mutable_insert_char_test_2() {
    // this is the same as with_insert_char_test1() except mutable
    let mut s = Rope::from("aaaaa");
    assert_eq!(&s, "aaaaa");
    s.insert(5, 'b');
    assert_eq!(&s, "aaaaab");
    s.insert(4, 'b');
    assert_eq!(&s, "aaaabab");
    s.insert(3, 'b');
    assert_eq!(&s, "aaababab");
    s.insert(2, 'b');
    assert_eq!(&s, "aabababab");
    s.insert(1, 'b');
    assert_eq!(&s, "ababababab");

}

#[test]
fn with_insert_char_test_1() {
    let s = Rope::from("aaaaa");
    let s_1 = s.with_insert(5, 'b');
    let s_2 = s_1.with_insert(4, 'b');
    let s_3 = s_2.with_insert(3, 'b');
    let s_4 = s_3.with_insert(2, 'b');
    let s_5 = s_4.with_insert(1, 'b');
    assert_eq!(&s, "aaaaa");
    assert_eq!(&s_1, "aaaaab");
    assert_eq!(&s_2, "aaaabab");
    assert_eq!(&s_3, "aaababab");
    assert_eq!(&s_4, "aabababab");
    assert_eq!(&s_5, "ababababab");

}

#[test]
fn with_insert_str_test_1() {
    let s = Rope::from("aaaaa");
    let s_1 = s.with_insert_str(5, "ccccc");
    let s_2 = s_1.with_insert_str(5, "bbbbb");
    assert_eq!(&s, "aaaaa");
    assert_eq!(&s_1, "aaaaaccccc");
    assert_eq!(&s_2, "aaaaabbbbbccccc");
}

#[test]
fn rope_char_indices() {
    let rope = Rope::from("aaaaa")
        .with_append(Rope::from("bbbbbb"))
        .with_append(Rope::from("cccccccccccc"))
        .with_append(Rope::from("defgdefgaabababab"));
    let string = String::from("aaaaabbbbbbccccccccccccdefgdefgaabababab");
    let indices = rope.char_indices().zip(string.char_indices());
    for ((ridx, rch), (sidx, sch)) in indices {
        assert_eq!(rch, sch);
        assert_eq!(ridx, sidx);
    }
}

#[test]
fn rope_slice_char_indices() {
    let string = "aaaaabbbbbbccccccccccccdefgdefgaabababab";
    let rope = Rope::from(string);
    let rope_slice = rope.slice(4..8);
    let string_slice = &string[4..8];
    let indices = rope_slice.char_indices().zip(string_slice.char_indices());
    for ((ridx, rch), (sidx, sch)) in indices {
        assert_eq!(rch, sch);
        assert_eq!(ridx, sidx);
    }
}
<commit_msg>rope: unit tests for RopeSlice<commit_after>use super::Rope;
use std::iter;

#[test]
fn rebalance_test_1() {
    let mut r = Rope::from("This is a large string \
                        that will need to be rebalanced.".to_string());
    r.rebalance();
    assert!(r.is_balanced());
}

#[test]
fn rebalance_test_2() {
    let mut r =
        Rope::from("Lorem ipsum dolor sit amet, consectetur adipiscing eli\
                    t, sed do eiusmod tempor incididunt ut labore et dolor\
                    e magna aliqua. Ut enim ad minim veniam, quis nostrud \
                    exercitation ullamco laboris nisi ut aliquip ex ea com\
                    modo consequat. Duis aute irure dolor in reprehenderit\
                     in voluptate velit esse cillum dolore eu fugiat nulla\
                     pariatur. Excepteur sint occaecat cupidatat non proid\
                    ent, sunt in culpa qui officia deserunt mollit anim id\
                     est laborum.".to_string());
    r.rebalance();
    assert!(r.is_balanced());
}

#[test]
fn big_rebalance() {
    let s: String = iter::repeat('a').take(10_000).collect();
    let mut r = Rope::from(s);
    r.rebalance();
    assert!(r.is_balanced());
}

#[test]
fn repeated_concat_left_rebalance() {
    let s: String = iter::repeat('a').take(10_000).collect();
    let mut r = Rope::from(s);
    for _ in 1..1000 {
        r = r + iter::repeat('a').take(100).collect::<String>();
    }
    assert!(r.is_balanced());
}

#[test]
fn repeated_concat_right_rebalance() {
    let s: String = iter::repeat('a').take(10_000).collect();
    let mut r = Rope::from(s);
    for _ in 1..1000 {
        let s2 = iter::repeat('a').take(100).collect::<String>();
        r = Rope::from(s2) + r;
    }
    assert!(r.is_balanced());
}

#[test]
fn merge_rebalance_test() {
    let s = "Lorem ipsum dolor sit amet, consectetur adipiscing eli\
             t, sed do eiusmod tempor incididunt ut labore et dolor\
             e magna aliqua. Ut enim ad minim veniam, quis nostrud \
             exercitation ullamco laboris nisi ut aliquip ex ea com\
             modo consequat. Duis aute irure dolor in reprehenderit\
              in voluptate velit esse cillum dolore eu fugiat nulla\
              pariatur. Excepteur sint occaecat cupidatat non proid\
             ent, sunt in culpa qui officia deserunt mollit anim id\
              est laborum.";

     let t = Rope::from(s.to_owned());
     let mut u = t + s;
     u.rebalance();
     assert!(u.is_balanced());
}

#[test]
fn with_insert_rope_balance_test() {
    let s: String = iter::repeat('a').take(10).collect();
    let mut r_1 = Rope::from(s);
    for _ in 0..99 {
        let t: String = iter::repeat('a').take(10).collect();
        r_1 = r_1.with_insert_rope(5, Rope::from(t));
    }
    //  this isn't necessary, with_insert_rope() will automatically rebalance
    //      - eliza, 12/18/2016
    // r_1.rebalance();
    assert!(r_1.is_balanced());
}

#[test]
fn with_insert_rope_test_1() {
    let s: String = iter::repeat('a').take(1_000).collect();
    let r_1 = Rope::from(s);
    let mut r_2 = Rope::new();
    for _ in 0..100 {
        let t: String = iter::repeat('a').take(10).collect();
        r_2 = r_2.with_insert_rope(0, Rope::from(t));
    }
    assert_eq!(r_1, r_2);
}

#[test]
fn with_insert_rope_test_2() {
    let s: String = iter::repeat('a').take(10).collect();
    let mut r_1 = Rope::from(s);
    for _ in 0..99 {
        let t: String = iter::repeat('a').take(10).collect();
        r_1 = r_1.with_insert_rope(5, Rope::from(t));
    }

    let q: String = iter::repeat('a').take(1_000).collect();
    let r_2 = Rope::from(q);
    assert_eq!(r_1, r_2);
}

#[test]
fn mutable_insert_rope_test_1() {
    let mut s_1 = Rope::from(String::from("aaaaa"));
    let mut s_2 = Rope::from(String::from("bbbbb"));
    let s_3 = Rope::from(String::from("ccccc"));
    s_2.insert_rope(0, s_3);
    s_1.insert_rope(0, s_2);
    assert_eq!(&s_1, "cccccbbbbbaaaaa");
}

#[test]
fn mutable_insert_str_test_1() {
    let mut s = Rope::from("aaaaa");
    s.insert_str(0, "bbbbb");
    s.insert_str(10, "ccccc");
    assert_eq!(&s, "bbbbbaaaaaccccc");
}

#[test]
fn mutable_insert_char_test_1() {
    let mut s = Rope::from("aaaaa");
    for _ in 0..5 { s.insert(0, 'b')}
    for _ in 0..5 { s.insert(10, 'c')}
    assert_eq!(&s, "bbbbbaaaaaccccc");
}

#[test]
fn mutable_insert_char_test_2() {
    // this is the same as with_insert_char_test1() except mutable
    let mut s = Rope::from("aaaaa");
    assert_eq!(&s, "aaaaa");
    s.insert(5, 'b');
    assert_eq!(&s, "aaaaab");
    s.insert(4, 'b');
    assert_eq!(&s, "aaaabab");
    s.insert(3, 'b');
    assert_eq!(&s, "aaababab");
    s.insert(2, 'b');
    assert_eq!(&s, "aabababab");
    s.insert(1, 'b');
    assert_eq!(&s, "ababababab");

}

#[test]
fn with_insert_char_test_1() {
    let s = Rope::from("aaaaa");
    let s_1 = s.with_insert(5, 'b');
    let s_2 = s_1.with_insert(4, 'b');
    let s_3 = s_2.with_insert(3, 'b');
    let s_4 = s_3.with_insert(2, 'b');
    let s_5 = s_4.with_insert(1, 'b');
    assert_eq!(&s, "aaaaa");
    assert_eq!(&s_1, "aaaaab");
    assert_eq!(&s_2, "aaaabab");
    assert_eq!(&s_3, "aaababab");
    assert_eq!(&s_4, "aabababab");
    assert_eq!(&s_5, "ababababab");

}

#[test]
fn with_insert_str_test_1() {
    let s = Rope::from("aaaaa");
    let s_1 = s.with_insert_str(5, "ccccc");
    let s_2 = s_1.with_insert_str(5, "bbbbb");
    assert_eq!(&s, "aaaaa");
    assert_eq!(&s_1, "aaaaaccccc");
    assert_eq!(&s_2, "aaaaabbbbbccccc");
}

#[test]
fn rope_char_indices() {
    let rope = Rope::from("aaaaa")
        .with_append(Rope::from("bbbbbb"))
        .with_append(Rope::from("cccccccccccc"))
        .with_append(Rope::from("defgdefgaabababab"));
    let string = String::from("aaaaabbbbbbccccccccccccdefgdefgaabababab");
    let indices = rope.char_indices().zip(string.char_indices());
    for ((ridx, rch), (sidx, sch)) in indices {
        assert_eq!(rch, sch);
        assert_eq!(ridx, sidx);
    }
}

#[test]
fn rope_slice_char_indices() {
    let string = "aaaaabbbbbbccccccccccccdefgdefgaabababab";
    let rope = Rope::from(string);
    let rope_slice = rope.slice(4..8);
    let string_slice = &string[4..8];
    let indices = rope_slice.char_indices().zip(string_slice.char_indices());
    for ((ridx, rch), (sidx, sch)) in indices {
        assert_eq!(rch, sch);
        assert_eq!(ridx, sidx);
    }
}

#[test]
fn rope_slice_to() {
    let string = "aaaaabbbbbbccccccccccccdefgdefgaabababab";
    let rope = Rope::from(string);
    let rope_slice = rope.slice(1..10);
    let string_slice = &string[1..10];
    assert_eq!(&rope_slice, string_slice)
}

// #[test]
// fn rope_slice_between() {
//     let string = "aaaaabbbbbbccccccccccccdefgdefgaabababab";
//     let rope = Rope::from(string);
//     let rope_slice = rope.slice(1...10usize);
//     let string_slice = &string[1...10];
//     assert_eq!(&rope_slice, string_slice)
// }

#[test]
fn rope_slice_until() {
    let string = "aaaaabbbbbbccccccccccdefgdefgaabababab";
    let rope = Rope::from(string);
    let rope_slice = rope.slice(..10);
    let string_slice = &string[..10];
    assert_eq!(&rope_slice, string_slice)
}

#[test]
fn rope_slice_from() {
    let string = "aaaaabbbbbbccccccccccccdefgdefgaabababab";
    let rope = Rope::from(string);
    let rope_slice = rope.slice(5..);
    let string_slice = &string[5..];
    assert_eq!(&rope_slice, string_slice)
}

#[test]
fn rope_slice_full() {
    let string = "aaaaabbbbbbccccccccccccdefgdefgaabababab";
    let rope = Rope::from(string);
    let rope_slice = rope.slice(..);
    let string_slice = &string[..];
    assert_eq!(&rope_slice, string_slice)
}
<|endoftext|>