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

//! A module for representing a set of breaks, typically used for
//! storing the result of line breaking.

use interval::Interval;
use std::cmp::min;
use std::mem;
use tree::{Leaf, Metric, Node, NodeInfo, TreeBuilder};

// Breaks represents a set of indexes. A motivating use is storing line breaks.
pub type Breaks = Node<BreaksInfo>;

// Here the base units are arbitrary, but most commonly match the base units
// of the rope storing the underlying string.

#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct BreaksLeaf {
    len: usize,       // measured in base units
    data: Vec<usize>, // each is a delta relative to start of leaf; sorted
}

#[derive(Clone)]
pub struct BreaksInfo(usize); // number of breaks

impl Leaf for BreaksLeaf {
    fn len(&self) -> usize {
        self.len
    }

    fn is_ok_child(&self) -> bool {
        self.data.len() >= 32
    }

    fn push_maybe_split(&mut self, other: &BreaksLeaf, iv: Interval) -> Option<BreaksLeaf> {
        //eprintln!("push_maybe_split {:?} {:?} {}", self, other, iv);
        let (start, end) = iv.start_end();
        for &v in &other.data {
            if start < v && v <= end {
                self.data.push(v - start + self.len);
            }
        }
        // the min with other.len() shouldn't be needed
        self.len += min(end, other.len()) - start;

        if self.data.len() <= 64 {
            None
        } else {
            let splitpoint = self.data.len() / 2; // number of breaks
            let splitpoint_units = self.data[splitpoint - 1];
            // TODO: use Vec::split_off(), it's nicer
            let mut new = Vec::with_capacity(self.data.len() - splitpoint);
            for i in splitpoint..self.data.len() {
                new.push(self.data[i] - splitpoint_units);
            }
            let new_len = self.len - splitpoint_units;
            self.len = splitpoint_units;
            self.data.truncate(splitpoint);
            Some(BreaksLeaf { len: new_len, data: new })
        }
    }
}

impl NodeInfo for BreaksInfo {
    type L = BreaksLeaf;

    fn accumulate(&mut self, other: &Self) {
        self.0 += other.0;
    }

    fn compute_info(l: &BreaksLeaf) -> BreaksInfo {
        BreaksInfo(l.data.len())
    }
}

#[derive(Copy, Clone)]
pub struct BreaksMetric(());

impl Metric<BreaksInfo> for BreaksMetric {
    fn measure(info: &BreaksInfo, _: usize) -> usize {
        info.0
    }

    fn to_base_units(l: &BreaksLeaf, in_measured_units: usize) -> usize {
        if in_measured_units > l.data.len() {
            l.len + 1
        } else if in_measured_units == 0 {
            0
        } else {
            l.data[in_measured_units - 1]
        }
    }

    fn from_base_units(l: &BreaksLeaf, in_base_units: usize) -> usize {
        match l.data.binary_search(&in_base_units) {
            Ok(n) => n + 1,
            Err(n) => n,
        }
    }

    fn is_boundary(l: &BreaksLeaf, offset: usize) -> bool {
        l.data.binary_search(&offset).is_ok()
    }

    fn prev(l: &BreaksLeaf, offset: usize) -> Option<usize> {
        for i in 0..l.data.len() {
            if offset <= l.data[i] {
                if i == 0 {
                    return None;
                } else {
                    return Some(l.data[i - 1]);
                }
            }
        }
        l.data.last().cloned()
    }

    fn next(l: &BreaksLeaf, offset: usize) -> Option<usize> {
        let n = match l.data.binary_search(&offset) {
            Ok(n) => n + 1,
            Err(n) => n,
        };

        if n == l.data.len() {
            None
        } else {
            Some(l.data[n])
        }
    }

    fn can_fragment() -> bool {
        true
    }
}

#[derive(Copy, Clone)]
pub struct BreaksBaseMetric(());

impl Metric<BreaksInfo> for BreaksBaseMetric {
    fn measure(_: &BreaksInfo, len: usize) -> usize {
        len
    }

    fn to_base_units(_: &BreaksLeaf, in_measured_units: usize) -> usize {
        in_measured_units
    }

    fn from_base_units(_: &BreaksLeaf, in_base_units: usize) -> usize {
        in_base_units
    }

    fn is_boundary(l: &BreaksLeaf, offset: usize) -> bool {
        BreaksMetric::is_boundary(l, offset)
    }

    fn prev(l: &BreaksLeaf, offset: usize) -> Option<usize> {
        BreaksMetric::prev(l, offset)
    }

    fn next(l: &BreaksLeaf, offset: usize) -> Option<usize> {
        BreaksMetric::next(l, offset)
    }

    fn can_fragment() -> bool {
        true
    }
}

// Additional functions specific to breaks

impl Breaks {
    // a length with no break, useful in edit operations; for
    // other use cases, use the builder.
    pub fn new_no_break(len: usize) -> Breaks {
        let leaf = BreaksLeaf { len, data: vec![] };
        Node::from_leaf(leaf)
    }
}

pub struct BreakBuilder {
    b: TreeBuilder<BreaksInfo>,
    leaf: BreaksLeaf,
}

impl Default for BreakBuilder {
    fn default() -> BreakBuilder {
        BreakBuilder { b: TreeBuilder::new(), leaf: BreaksLeaf::default() }
    }
}

impl BreakBuilder {
    pub fn new() -> BreakBuilder {
        BreakBuilder::default()
    }

    pub fn add_break(&mut self, len: usize) {
        if self.leaf.data.len() == 64 {
            let leaf = mem::replace(&mut self.leaf, BreaksLeaf::default());
            self.b.push(Node::from_leaf(leaf));
        }
        self.leaf.len += len;
        self.leaf.data.push(self.leaf.len);
    }

    pub fn add_no_break(&mut self, len: usize) {
        self.leaf.len += len;
    }

    pub fn build(mut self) -> Breaks {
        self.b.push(Node::from_leaf(self.leaf));
        self.b.build()
    }
}

#[cfg(test)]
mod tests {
    use breaks::{BreakBuilder, BreaksInfo, BreaksLeaf, BreaksMetric};
    use interval::Interval;
    use tree::{Cursor, Node};

    fn gen(n: usize) -> Node<BreaksInfo> {
        let mut node = Node::default();
        let mut b = BreakBuilder::new();
        b.add_break(10);
        let testnode = b.build();
        if n == 1 {
            return testnode;
        }
        for _ in 0..n {
            let len = node.len();
            let empty_interval_at_end = Interval::new(len, len);
            node.edit(empty_interval_at_end, testnode.clone());
        }
        node
    }

    #[test]
    fn empty() {
        let n = gen(0);
        assert_eq!(0, n.len());
    }

    #[test]
    fn fromleaf() {
        let testnode = gen(1);
        assert_eq!(10, testnode.len());
    }

    #[test]
    fn one() {
        let testleaf = BreaksLeaf { len: 10, data: vec![10] };
        let testnode = Node::<BreaksInfo>::from_leaf(testleaf.clone());
        assert_eq!(10, testnode.len());
        let mut c = Cursor::new(&testnode, 0);
        assert_eq!(c.get_leaf().unwrap().0, &testleaf);
        assert_eq!(10, c.next::<BreaksMetric>().unwrap());
        assert!(c.next::<BreaksMetric>().is_none());
        c.set(0);
        assert!(c.is_boundary::<BreaksMetric>());
        c.set(1);
        assert!(!c.is_boundary::<BreaksMetric>());
        c.set(10);
        assert!(c.is_boundary::<BreaksMetric>());
        assert_eq!(0, c.prev::<BreaksMetric>().unwrap());
        assert!(c.prev::<BreaksMetric>().is_none());
    }

    #[test]
    fn concat() {
        let left = gen(1);
        let right = gen(1);
        let node = Node::concat(left.clone(), right);
        assert_eq!(node.len(), 20);
        let mut c = Cursor::new(&node, 0);
        assert_eq!(10, c.next::<BreaksMetric>().unwrap());
        assert_eq!(20, c.next::<BreaksMetric>().unwrap());
        assert!(c.next::<BreaksMetric>().is_none());
    }

    #[test]
    fn larger() {
        let node = gen(100);
        assert_eq!(node.len(), 1000);
    }
}
<commit_msg>Use Vec::split_off instead of ad-hoc code<commit_after>// Copyright 2016 The xi-editor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! A module for representing a set of breaks, typically used for
//! storing the result of line breaking.

use interval::Interval;
use std::cmp::min;
use std::mem;
use tree::{Leaf, Metric, Node, NodeInfo, TreeBuilder};

// Breaks represents a set of indexes. A motivating use is storing line breaks.
pub type Breaks = Node<BreaksInfo>;

// Here the base units are arbitrary, but most commonly match the base units
// of the rope storing the underlying string.

#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct BreaksLeaf {
    len: usize,       // measured in base units
    data: Vec<usize>, // each is a delta relative to start of leaf; sorted
}

#[derive(Clone)]
pub struct BreaksInfo(usize); // number of breaks

impl Leaf for BreaksLeaf {
    fn len(&self) -> usize {
        self.len
    }

    fn is_ok_child(&self) -> bool {
        self.data.len() >= 32
    }

    fn push_maybe_split(&mut self, other: &BreaksLeaf, iv: Interval) -> Option<BreaksLeaf> {
        //eprintln!("push_maybe_split {:?} {:?} {}", self, other, iv);
        let (start, end) = iv.start_end();
        for &v in &other.data {
            if start < v && v <= end {
                self.data.push(v - start + self.len);
            }
        }
        // the min with other.len() shouldn't be needed
        self.len += min(end, other.len()) - start;

        if self.data.len() <= 64 {
            None
        } else {
            let splitpoint = self.data.len() / 2; // number of breaks
            let splitpoint_units = self.data[splitpoint - 1];

            let mut new = self.data.split_off(splitpoint);
            for x in &mut new {
                *x -= splitpoint_units;
            }

            let new_len = self.len - splitpoint_units;
            self.len = splitpoint_units;
            Some(BreaksLeaf { len: new_len, data: new })
        }
    }
}

impl NodeInfo for BreaksInfo {
    type L = BreaksLeaf;

    fn accumulate(&mut self, other: &Self) {
        self.0 += other.0;
    }

    fn compute_info(l: &BreaksLeaf) -> BreaksInfo {
        BreaksInfo(l.data.len())
    }
}

#[derive(Copy, Clone)]
pub struct BreaksMetric(());

impl Metric<BreaksInfo> for BreaksMetric {
    fn measure(info: &BreaksInfo, _: usize) -> usize {
        info.0
    }

    fn to_base_units(l: &BreaksLeaf, in_measured_units: usize) -> usize {
        if in_measured_units > l.data.len() {
            l.len + 1
        } else if in_measured_units == 0 {
            0
        } else {
            l.data[in_measured_units - 1]
        }
    }

    fn from_base_units(l: &BreaksLeaf, in_base_units: usize) -> usize {
        match l.data.binary_search(&in_base_units) {
            Ok(n) => n + 1,
            Err(n) => n,
        }
    }

    fn is_boundary(l: &BreaksLeaf, offset: usize) -> bool {
        l.data.binary_search(&offset).is_ok()
    }

    fn prev(l: &BreaksLeaf, offset: usize) -> Option<usize> {
        for i in 0..l.data.len() {
            if offset <= l.data[i] {
                if i == 0 {
                    return None;
                } else {
                    return Some(l.data[i - 1]);
                }
            }
        }
        l.data.last().cloned()
    }

    fn next(l: &BreaksLeaf, offset: usize) -> Option<usize> {
        let n = match l.data.binary_search(&offset) {
            Ok(n) => n + 1,
            Err(n) => n,
        };

        if n == l.data.len() {
            None
        } else {
            Some(l.data[n])
        }
    }

    fn can_fragment() -> bool {
        true
    }
}

#[derive(Copy, Clone)]
pub struct BreaksBaseMetric(());

impl Metric<BreaksInfo> for BreaksBaseMetric {
    fn measure(_: &BreaksInfo, len: usize) -> usize {
        len
    }

    fn to_base_units(_: &BreaksLeaf, in_measured_units: usize) -> usize {
        in_measured_units
    }

    fn from_base_units(_: &BreaksLeaf, in_base_units: usize) -> usize {
        in_base_units
    }

    fn is_boundary(l: &BreaksLeaf, offset: usize) -> bool {
        BreaksMetric::is_boundary(l, offset)
    }

    fn prev(l: &BreaksLeaf, offset: usize) -> Option<usize> {
        BreaksMetric::prev(l, offset)
    }

    fn next(l: &BreaksLeaf, offset: usize) -> Option<usize> {
        BreaksMetric::next(l, offset)
    }

    fn can_fragment() -> bool {
        true
    }
}

// Additional functions specific to breaks

impl Breaks {
    // a length with no break, useful in edit operations; for
    // other use cases, use the builder.
    pub fn new_no_break(len: usize) -> Breaks {
        let leaf = BreaksLeaf { len, data: vec![] };
        Node::from_leaf(leaf)
    }
}

pub struct BreakBuilder {
    b: TreeBuilder<BreaksInfo>,
    leaf: BreaksLeaf,
}

impl Default for BreakBuilder {
    fn default() -> BreakBuilder {
        BreakBuilder { b: TreeBuilder::new(), leaf: BreaksLeaf::default() }
    }
}

impl BreakBuilder {
    pub fn new() -> BreakBuilder {
        BreakBuilder::default()
    }

    pub fn add_break(&mut self, len: usize) {
        if self.leaf.data.len() == 64 {
            let leaf = mem::replace(&mut self.leaf, BreaksLeaf::default());
            self.b.push(Node::from_leaf(leaf));
        }
        self.leaf.len += len;
        self.leaf.data.push(self.leaf.len);
    }

    pub fn add_no_break(&mut self, len: usize) {
        self.leaf.len += len;
    }

    pub fn build(mut self) -> Breaks {
        self.b.push(Node::from_leaf(self.leaf));
        self.b.build()
    }
}

#[cfg(test)]
mod tests {
    use breaks::{BreakBuilder, BreaksInfo, BreaksLeaf, BreaksMetric};
    use interval::Interval;
    use tree::{Cursor, Node};

    fn gen(n: usize) -> Node<BreaksInfo> {
        let mut node = Node::default();
        let mut b = BreakBuilder::new();
        b.add_break(10);
        let testnode = b.build();
        if n == 1 {
            return testnode;
        }
        for _ in 0..n {
            let len = node.len();
            let empty_interval_at_end = Interval::new(len, len);
            node.edit(empty_interval_at_end, testnode.clone());
        }
        node
    }

    #[test]
    fn empty() {
        let n = gen(0);
        assert_eq!(0, n.len());
    }

    #[test]
    fn fromleaf() {
        let testnode = gen(1);
        assert_eq!(10, testnode.len());
    }

    #[test]
    fn one() {
        let testleaf = BreaksLeaf { len: 10, data: vec![10] };
        let testnode = Node::<BreaksInfo>::from_leaf(testleaf.clone());
        assert_eq!(10, testnode.len());
        let mut c = Cursor::new(&testnode, 0);
        assert_eq!(c.get_leaf().unwrap().0, &testleaf);
        assert_eq!(10, c.next::<BreaksMetric>().unwrap());
        assert!(c.next::<BreaksMetric>().is_none());
        c.set(0);
        assert!(c.is_boundary::<BreaksMetric>());
        c.set(1);
        assert!(!c.is_boundary::<BreaksMetric>());
        c.set(10);
        assert!(c.is_boundary::<BreaksMetric>());
        assert_eq!(0, c.prev::<BreaksMetric>().unwrap());
        assert!(c.prev::<BreaksMetric>().is_none());
    }

    #[test]
    fn concat() {
        let left = gen(1);
        let right = gen(1);
        let node = Node::concat(left.clone(), right);
        assert_eq!(node.len(), 20);
        let mut c = Cursor::new(&node, 0);
        assert_eq!(10, c.next::<BreaksMetric>().unwrap());
        assert_eq!(20, c.next::<BreaksMetric>().unwrap());
        assert!(c.next::<BreaksMetric>().is_none());
    }

    #[test]
    fn larger() {
        let node = gen(100);
        assert_eq!(node.len(), 1000);
    }
}
<|endoftext|>


<commit_before>extern crate rmpv;

use rmpv::Value;
use rmpv::decode::{read_value, Error};

#[test]
fn from_null_decode_value() {
    let buf = [0xc0];
    assert_eq!(Value::Nil, read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_pfix_decode_value() {
    let buf = [0x1f];
    assert_eq!(Value::from(31), read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_bool_decode_value() {
    let buf = [0xc3, 0xc2];
    assert_eq!(Value::Boolean(true), read_value(&mut &buf[..]).unwrap());
    assert_eq!(Value::Boolean(false), read_value(&mut &buf[1..]).unwrap());
}

#[test]
fn from_i32_decode_value() {
    let buf = [0xd2, 0xff, 0xff, 0xff, 0xff];
    assert_eq!(Value::from(-1), read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_f64_decode_value() {
    let buf = [0xcb, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
    assert_eq!(Value::F64(::std::f64::NEG_INFINITY), read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_strfix_decode_value() {
    let buf = [0xaa, 0x6c, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65];
    assert_eq!(Value::String("le message".into()), read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_fixarray_decode_value() {
    let buf = [
        0x93,
        0x00, 0x2a, 0xf7
    ];

    let expected = Value::Array(vec![
        Value::from(0),
        Value::from(42),
        Value::from(-9),
    ]);

    assert_eq!(expected, read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_fixarray_incomplete_decode_value() {
    let buf = [
        0x93,
        0x00, 0x2a
    ];

    match read_value(&mut &buf[..]) {
        Err(Error::InvalidMarkerRead(..)) => {}
        other => panic!("unexpected result: {:?}", other)
    }
}

#[test]
fn from_fixmap_decode_value() {
    let buf = [
        0x82,
        0x2a,
        0xce, 0x0, 0x1, 0x88, 0x94,
        0xa3, 0x6b, 0x65, 0x79,
        0xa5, 0x76, 0x61, 0x6c, 0x75, 0x65
    ];

    let expected = Value::Map(vec![
        (Value::from(42), Value::from(100500)),
        (Value::String("key".into()), Value::String("value".into())),
    ]);

    assert_eq!(expected, read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_fixext1_decode_value() {
    let buf = [0xd4, 0x01, 0x02];
    assert_eq!(Value::Ext(1, vec![2]), read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_str8_decode_value() {
    let buf: &[u8] = &[
        0xd9,
        0x20,
        0x42,
        0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
        0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
        0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
        0x45
    ];

    assert_eq!(Value::String("B123456789012345678901234567890E".into()),
        read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_str8_invalid_utf8() {
    // Invalid 2 Octet Sequence.
    let buf: &[u8] = &[0xd9, 0x02, 0xc3, 0x28];

    match read_value(&mut &buf[..]).unwrap() {
        Value::String(s) => {
            assert!(s.is_err());
            assert_eq!(vec![0xc3, 0x28], s.into_bytes());
        }
        _ => panic!("wrong type"),
    }
}

#[test]
fn from_array_of_two_integers() {
    let buf: &[u8] = &[0x92, 0x04, 0x2a];

    let vec = vec![Value::from(4), Value::from(42)];
    assert_eq!(Value::Array(vec), read_value(&mut &buf[..]).unwrap());
}
<commit_msg>chore: coverage for decoding value (#136)<commit_after>extern crate rmpv;

use rmpv::Value;
use rmpv::decode::{read_value, Error};

#[test]
fn from_null_decode_value() {
    let buf = [0xc0];
    assert_eq!(Value::Nil, read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_pfix_decode_value() {
    let buf = [0x1f];
    assert_eq!(Value::from(31), read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_bool_decode_value() {
    let buf = [0xc3, 0xc2];
    assert_eq!(Value::Boolean(true), read_value(&mut &buf[..]).unwrap());
    assert_eq!(Value::Boolean(false), read_value(&mut &buf[1..]).unwrap());
}

#[test]
fn from_bin8_decode_value() {
    let buf: &[u8] = &[
        0xc4,
        0x08,
        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];

    let expected = Value::Binary(vec!(0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08));

    assert_eq!(expected, read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_bin16_decode_value() {
    let buf: &[u8] = &[
        0xc5,
        0x00, 0x08,
        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];

    let expected = Value::Binary(vec!(0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08));

    assert_eq!(expected, read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_bin32_decode_value() {
    let buf: &[u8] = &[
        0xc6,
        0x00, 0x00, 0x00, 0x08,
        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];

    let expected = Value::Binary(vec!(0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08));

    assert_eq!(expected, read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_i32_decode_value() {
    let buf = [0xd2, 0xff, 0xff, 0xff, 0xff];
    assert_eq!(Value::from(-1), read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_f64_decode_value() {
    let buf = [0xcb, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
    assert_eq!(Value::F64(::std::f64::NEG_INFINITY), read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_strfix_decode_value() {
    let buf = [0xaa, 0x6c, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65];
    assert_eq!(Value::String("le message".into()), read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_fixarray_decode_value() {
    let buf = [
        0x93,
        0x00, 0x2a, 0xf7
    ];

    let expected = Value::Array(vec![
        Value::from(0),
        Value::from(42),
        Value::from(-9),
    ]);

    assert_eq!(expected, read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_fixarray_incomplete_decode_value() {
    let buf = [
        0x93,
        0x00, 0x2a
    ];

    match read_value(&mut &buf[..]) {
        Err(Error::InvalidMarkerRead(..)) => {}
        other => panic!("unexpected result: {:?}", other)
    }
}

#[test]
fn from_fixarray_decode_empty() {
    let buf: &[u8] = &[0x90];

    assert_eq!(Value::Array(vec![]), read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_fixarray_of_decode_max_length() {
    let buf: &[u8] = &[0x9f, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
                       0x0b, 0x0c, 0x0d, 0x0e, 0x0f];

    let expected = Value::Array(vec![Value::from(1), Value::from(2), Value::from(3),
                                     Value::from(4), Value::from(5), Value::from(6),
                                     Value::from(7), Value::from(8), Value::from(9),
                                     Value::from(10), Value::from(11), Value::from(12),
                                     Value::from(13), Value::from(14), Value::from(15)]);
    assert_eq!(expected, read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_array16_decode_value() {
    let buf: &[u8] = &[
        0xdc,
        0x00, 0x06,
        0x01, 0x02, 0x03, 0x04, 0x05, 0x06];

    let expected = Value::Array(vec![Value::from(1), Value::from(2), Value::from(3),
                                     Value::from(4), Value::from(5), Value::from(6)]);

    assert_eq!(expected, read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_array32_decode_value() {
    let buf: &[u8] = &[
        0xdd,
        0x00, 0x00, 0x00, 0x06,
        0x01, 0x02, 0x03, 0x04, 0x05, 0x06];

    let expected = Value::Array(vec![Value::from(1), Value::from(2), Value::from(3),
                                     Value::from(4), Value::from(5), Value::from(6)]);

    assert_eq!(expected, read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_fixmap_decode_value() {
    let buf = [
        0x82,
        0x2a,
        0xce, 0x0, 0x1, 0x88, 0x94,
        0xa3, 0x6b, 0x65, 0x79,
        0xa5, 0x76, 0x61, 0x6c, 0x75, 0x65
    ];

    let expected = Value::Map(vec![
        (Value::from(42), Value::from(100500)),
        (Value::String("key".into()), Value::String("value".into())),
    ]);

    assert_eq!(expected, read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_map16_decode_value() {
    let buf = [
        0xde,
        0x00, 0x02,
        0x2a,
        0xce, 0x0, 0x1, 0x88, 0x94,
        0xa3, 0x6b, 0x65, 0x79,
        0xa5, 0x76, 0x61, 0x6c, 0x75, 0x65
    ];

    let expected = Value::Map(vec![
        (Value::from(42), Value::from(100500)),
        (Value::String("key".into()), Value::String("value".into())),
    ]);

    assert_eq!(expected, read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_map32_decode_value() {
    let buf = [
        0xdf,
        0x00, 0x00, 0x00, 0x02,
        0x2a,
        0xce, 0x0, 0x1, 0x88, 0x94,
        0xa3, 0x6b, 0x65, 0x79,
        0xa5, 0x76, 0x61, 0x6c, 0x75, 0x65
    ];

    let expected = Value::Map(vec![
        (Value::from(42), Value::from(100500)),
        (Value::String("key".into()), Value::String("value".into())),
    ]);

    assert_eq!(expected, read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_fixext1_decode_value() {
    let buf = [0xd4, 0x01, 0x02];
    assert_eq!(Value::Ext(1, vec![2]), read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_fixext2_decode_value() {
    let buf = [0xd5, 0x01, 0x02, 0x03];
    assert_eq!(Value::Ext(1, vec![2, 3]), read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_fixext4_decode_value() {
    let buf = [0xd6, 0x01, 0x02, 0x03, 0x04, 0x05];
    assert_eq!(Value::Ext(1, vec![2, 3, 4, 5]), read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_fixext8_decode_value() {
    let buf = [0xd7, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09];
    assert_eq!(Value::Ext(1, vec![2, 3, 4, 5, 6, 7, 8, 9]), read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_fixext16_decode_value() {
    let buf = [0xd8, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
                           0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09];
    assert_eq!(Value::Ext(1, vec![2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5, 6, 7, 8, 9]),
               read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_ext8_decode_value() {
    let buf = [0xc7, 0x04, 0x01, 0x02, 0x03, 0x04, 0x05];
    assert_eq!(Value::Ext(1, vec![2, 3, 4, 5]),
               read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_ext16_decode_value() {
    let buf = [0xc8, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04, 0x05];
    assert_eq!(Value::Ext(1, vec![2, 3, 4, 5]),
               read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_ext32_decode_value() {
    let buf = [0xc9, 0x00, 0x00, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04, 0x05];
    assert_eq!(Value::Ext(1, vec![2, 3, 4, 5]),
               read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_str8_decode_value() {
    let buf: &[u8] = &[
        0xd9,
        0x20,
        0x42,
        0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
        0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
        0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
        0x45
    ];

    assert_eq!(Value::String("B123456789012345678901234567890E".into()),
        read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_str8_invalid_utf8() {
    // Invalid 2 Octet Sequence.
    let buf: &[u8] = &[0xd9, 0x02, 0xc3, 0x28];

    match read_value(&mut &buf[..]).unwrap() {
        Value::String(s) => {
            assert!(s.is_err());
            assert_eq!(vec![0xc3, 0x28], s.into_bytes());
        }
        _ => panic!("wrong type"),
    }
}

#[test]
fn from_str16_decode_value() {
    let buf: &[u8] = &[
        0xda,
        0x00,
        0x20,
        0x42,
        0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
        0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
        0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
        0x45
    ];

    assert_eq!(Value::String("B123456789012345678901234567890E".into()),
        read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_str16_invalid_utf8() {
    // Invalid 2 Octet Sequence.
    let buf: &[u8] = &[0xda, 0x00, 0x02, 0xc3, 0x28];

    match read_value(&mut &buf[..]).unwrap() {
        Value::String(s) => {
            assert!(s.is_err());
            assert_eq!(vec![0xc3, 0x28], s.into_bytes());
        }
        _ => panic!("wrong type"),
    }
}

#[test]
fn from_str32_decode_value() {
    let buf: &[u8] = &[
        0xdb,
        0x00,
        0x00,
        0x00,
        0x20,
        0x42,
        0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
        0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
        0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
        0x45
    ];

    assert_eq!(Value::String("B123456789012345678901234567890E".into()),
        read_value(&mut &buf[..]).unwrap());
}

#[test]
fn from_str32_invalid_utf8() {
    // Invalid 2 Octet Sequence.
    let buf: &[u8] = &[0xdb, 0x00, 0x00, 0x00, 0x02, 0xc3, 0x28];

    match read_value(&mut &buf[..]).unwrap() {
        Value::String(s) => {
            assert!(s.is_err());
            assert_eq!(vec![0xc3, 0x28], s.into_bytes());
        }
        _ => panic!("wrong type"),
    }
}

#[test]
fn from_array_of_two_integers() {
    let buf: &[u8] = &[0x92, 0x04, 0x2a];

    let vec = vec![Value::from(4), Value::from(42)];
    assert_eq!(Value::Array(vec), read_value(&mut &buf[..]).unwrap());
}
<|endoftext|>


<commit_before>use std::sync::atomic::{self, AtomicPtr};

static GARBAGE: Stack<Box<Drop>> = Stack::new();
static READERS: Stack<RawReader> = Stack::new();
static STATE: State = State::new();

fn gc() {
    // Start the garbage collection.
    if !STATE.start_gc() {
        // Another thread is garbage collecting, so we short-circuit.
        return;
    }

    // Initially, every garbage is marked unused.
    let mut unused = GARBAGE.collect();

    // Traverse the readers and update the reference counts.
    READERS.take_each(|reader| {
        if reader.active.load() {
            // The reader is not released yet, and is thus considered active.

            // Remove the reader from the unused set and insert it back into the log (if it
            // exists in the unused set), as the garbage is active.
            unused.remove(reader.ptr).map(|x| GARBAGE.insert(x));
            // Put the reader back in the structure.
            READERS.insert(reader);
        } else {
            // The reader was released. Destroy it.
            reader.destroy();
        }
    });

    // End the garbage collection cycle.
    STATE.end_gc();
}

pub struct Stack<T> {
    head: AtomicPtr<Node<T>>,
}

struct Node<T> {
    data: T,
    next: *mut Node<T>,
}

impl<T> Stack<T> {
    const fn new() -> Stack<T> {
        Stack {
            head: AtomicPtr::new(0 as *const T),
        }
    }

    fn push(&self, t: T) {
        // Allocate the node, and immediately turn it into a `*mut` pointer.
        let n = Box::into_raw(Box::new(Node {
            data: t,
            next: null_mut(),
        }));

        loop {
            // Snapshot current head.
            let head = self.head.load(atomic::Ordering::Relaxed);

            // Update `next` pointer with snapshot.
            unsafe { (*n).next = head; }

            // If snapshot is still good, link in new node.
            if self.head.compare_and_swap(head, n, atomic::Ordering::Release) == head {
                break
            }
        }
    }

    fn take_each(&self, f: F)
    where F: Fn(T) {
        // Replace the old head with a null pointer.
        let mut node = self.head.swap(AtomicPtr::default(), atomic::Ordering::Acquire);

        // We traverse every node until the pointer is null.
        while !node.is_null() {
            // Read the node into an owned box.
            let bx = unsafe { Box::from_raw(head) };
            // Apply the provided closure.
            f(bx.data);
            // Go to the next link.
            node = bx.next;
        }
    }

    fn collect(&self) -> HashSet<T> {
        let mut hs = HashSet::new();
        self.take_each(|x| hs.insert(x));

        hs
    }
}

struct RawReader {
    active: *const AtomicBool,
    ptr: *const T,
}

impl RawReader {
    unsafe fn destroy(self) {
        // Drop the atomic boolean stored on the heap.
        mem::drop_in_place(self.active);
    }
}

struct Reader<'a, T> {
    raw: RawReader,
    _marker: PhantomData<'a>,
}

impl<'a, T> Reader<'a, T> {
    fn drop(&mut self) {
        self.raw.active.store(true);
    }
}

#[derive(Default)]
struct State {
    flags: AtomicUsize,
}

impl State {
    fn start_gc(&self) -> false {
        // Mark that a garbage collection is pending.
        if self.flags.fetch_or(1, atomic::Ordering::Relaxed) & 1 != 0 {
            // Another thread is pending to or currently garbage collecting, so we won't do the
            // same.
            return false;
        }

        // Spin until no thread is currently modifying the stacks. This prevents premature frees in
        // the thread which is currently pushing to `self.readers`.
        loop {
            // Read the flags, and if no readers or garbage collectors, activate garbage
            // collection.
            let flags = self.flags.compare_and_swap(1, 0b11, atomic::Ordering::Relaxed);
            if flags == 1 {
                // Currently, no one accesses the readers stack and the CAS above means that the
                // lowest bitflag have been set, indicating that a garbage collection is now
                // active.
                return true;
            }
        }
    }

    fn end_gc(&self) {
        self.flags.fetch_sub(1, atomic::Ordering::Relaxed);
    }

    fn start_read(&self) {
        // Increment the number of threads currently pushing to the readers stack. We add two to
        // account for the LSB being a separate bitflag.
        self.flags.fetch_add(2, atomic::Ordering::Relaxed);
    }

    fn end_read(&self) {
        self.flags.fetch_sub(2, atomic::Ordering::Relaxed);
    }
}

struct Atomic<T> {
    inner: AtomicPtr<T>,
    snapshots: Stack<Box<T>>,
    readers: Stack<RawReader>,
    state: State,
}

impl<T> Atomic<T> {
    fn new(inner: T) -> Atomic<T> {
        Atomic {
            inner: AtomicPtr::new(Box::into_raw(Box::new(inner))),
            snapshots: Stack::new(),
            readers: Stack::new(),
            flags: State::default(),
        }
    }

    fn get(&self) -> Reader {
        // To avoid another thread freeing between reading and inserting into the readers stack, we
        // change the state to block garbage collecting for awhile.
        STATE.start_read();

        // Construct the raw reader.
        let reader = RawReader {
            // Load a snapshot of the pointer.
            ptr: self.inner.load(atomic::Ordering::Relaxed),
            // We allocate the atomic boolean on the heap as it is shared between the returned RAII
            // guard and the reader stack.
            released: Box::into_raw(Box::new(AtomicBool::new(false))),
        };

        // Register the reader through the reader stack, ensuring that it is not freed before the
        // RAII guard drops (`reader.release` is set to `true`).
        READERS.push(reader);

        // Revert the original increment.
        STATE.end_read();

        Reader {
            raw: reader,
            _marker: PhantomData,
        }
    }

    fn set(&self, new: Box<T>) {
        // Replace the inner by the new value.
        let old = self.inner.swap(Box::into_raw(new), atomic::Ordering::Relaxed);
        // Push the old pointer to the garbage stack.
        GARBAGE.push(Box::from_raw(old));
    }
}
<commit_msg>Add a way to do multiple loads in `reclaim` with only one state change.<commit_after>use std::sync::atomic::{self, AtomicPtr};

static GARBAGE: Stack<Box<Drop>> = Stack::new();
static READERS: Stack<RawReader> = Stack::new();
static STATE: State = State::new();

fn gc() {
    // Start the garbage collection.
    if !STATE.start_gc() {
        // Another thread is garbage collecting, so we short-circuit.
        return;
    }

    // Initially, every garbage is marked unused.
    let mut unused = GARBAGE.collect();

    // Traverse the readers and update the reference counts.
    READERS.take_each(|reader| {
        if reader.active.load() {
            // The reader is not released yet, and is thus considered active.

            // Remove the reader from the unused set and insert it back into the log (if it
            // exists in the unused set), as the garbage is active.
            unused.remove(reader.ptr).map(|x| GARBAGE.insert(x));
            // Put the reader back in the structure.
            READERS.insert(reader);
        } else {
            // The reader was released. Destroy it.
            reader.destroy();
        }
    });

    // End the garbage collection cycle.
    STATE.end_gc();
}

pub struct Stack<T> {
    head: AtomicPtr<Node<T>>,
}

struct Node<T> {
    data: T,
    next: *mut Node<T>,
}

impl<T> Stack<T> {
    const fn new() -> Stack<T> {
        Stack {
            head: AtomicPtr::new(0 as *const T),
        }
    }

    fn push(&self, t: T) {
        // Allocate the node, and immediately turn it into a `*mut` pointer.
        let n = Box::into_raw(Box::new(Node {
            data: t,
            next: null_mut(),
        }));

        loop {
            // Snapshot current head.
            let head = self.head.load(atomic::Ordering::Relaxed);

            // Update `next` pointer with snapshot.
            unsafe { (*n).next = head; }

            // If snapshot is still good, link in new node.
            if self.head.compare_and_swap(head, n, atomic::Ordering::Release) == head {
                break
            }
        }
    }

    fn take_each(&self, f: F)
    where F: Fn(T) {
        // Replace the old head with a null pointer.
        let mut node = self.head.swap(AtomicPtr::default(), atomic::Ordering::Acquire);

        // We traverse every node until the pointer is null.
        while !node.is_null() {
            // Read the node into an owned box.
            let bx = unsafe { Box::from_raw(head) };
            // Apply the provided closure.
            f(bx.data);
            // Go to the next link.
            node = bx.next;
        }
    }

    fn collect(&self) -> HashSet<T> {
        let mut hs = HashSet::new();
        self.take_each(|x| hs.insert(x));

        hs
    }
}

struct RawReader {
    active: *const AtomicBool,
    ptr: *const T,
}

impl RawReader {
    unsafe fn destroy(self) {
        // Drop the atomic boolean stored on the heap.
        mem::drop_in_place(self.active);
    }
}

struct Reader<'a, T> {
    raw: RawReader,
    _marker: PhantomData<'a>,
}

impl<'a, T> Reader<'a, T> {
    fn drop(&mut self) {
        self.raw.active.store(true);
    }
}

#[derive(Default)]
struct State {
    flags: AtomicUsize,
}

impl State {
    fn start_gc(&self) -> bool {
        // Mark that a garbage collection is pending.
        if self.flags.fetch_or(1, atomic::Ordering::Relaxed) & 1 != 0 {
            // Another thread is pending to or currently garbage collecting, so we won't do the
            // same.
            return false;
        }

        // Spin until no thread is currently modifying the stacks. This prevents premature frees in
        // the thread which is currently pushing to `self.readers`.
        loop {
            // Read the flags, and if no readers or garbage collectors, activate garbage
            // collection.
            let flags = self.flags.compare_and_swap(1, 0b11, atomic::Ordering::Relaxed);
            if flags == 1 {
                // Currently, no one accesses the readers stack and the CAS above means that the
                // lowest bitflag have been set, indicating that a garbage collection is now
                // active.
                return true;
            }
        }
    }

    fn end_gc(&self) {
        self.flags.fetch_sub(1, atomic::Ordering::Relaxed);
    }

    fn start_read(&self) {
        // Increment the number of threads currently pushing to the readers stack. We add two to
        // account for the LSB being a separate bitflag.
        self.flags.fetch_add(2, atomic::Ordering::Relaxed);
    }

    fn end_read(&self) {
        self.flags.fetch_sub(2, atomic::Ordering::Relaxed);
    }
}

pub struct Reading;

impl Reading {
    pub fn obtain() -> Reading {
        STATE.start_read();

        Reading
    }

    pub fn load<T>(&self, a: &Atomic<T>) -> Reader<T> {
        // Construct the raw reader.
        let reader = RawReader {
            // Load a snapshot of the pointer.
            ptr: self.inner.load(atomic::Ordering::Relaxed),
            // We allocate the atomic boolean on the heap as it is shared between the returned RAII
            // guard and the reader stack.
            released: Box::into_raw(Box::new(AtomicBool::new(false))),
        };

        // Register the reader through the reader stack, ensuring that it is not freed before the
        // RAII guard drops (`reader.release` is set to `true`).
        READERS.push(reader);

        Reader {
            raw: reader,
            _marker: PhantomData,
        }
    }
}

impl Drop for Reading {
    fn drop(&mut self) {
        STATE.end_read();
    }
}

pub struct Atomic<T> {
    inner: AtomicPtr<T>,
    snapshots: Stack<Box<T>>,
    readers: Stack<RawReader>,
    state: State,
}

impl<T> Atomic<T> {
    pub fn new(inner: T) -> Atomic<T> {
        Atomic {
            inner: AtomicPtr::new(Box::into_raw(Box::new(inner))),
            snapshots: Stack::new(),
            readers: Stack::new(),
            flags: State::default(),
        }
    }

    pub fn load(&self) -> Reader<T> {
        let guard = Reading::obtain();
        guard.load(self)
    }

    pub fn store(&self, new: Box<T>) {
        // Replace the inner by the new value.
        let old = self.inner.swap(Box::into_raw(new), atomic::Ordering::Relaxed);
        // Push the old pointer to the garbage stack.
        GARBAGE.push(Box::from_raw(old));
    }
}
<|endoftext|>


<commit_before>use std::ops::{Add};

fn main() {
    let search_term = "picture";
    let quote = "Every face, every shop, bedroom window, public-house, and
    dark square is a picture feverishly turned--in search of what?
    It is the same with books. What do we seek through millions of pages?";
    let mut line_num: usize = 1;

    for line in quote.lines() {
        if line.contains(search_term) {
            println!("{}: {}", line_num, line);
        }
        line_num += 1;
    }
    println!("");

    let (a, b) = (1.2, 3.4);
    let (x, y) = (10, 20);

    let c = add(a,b);
    let z = add(x, y);

    println!("{} + {} = {}", a, b, c);
    println!("{} + {} = {}", x, y, z);
    println!("");

    let haystack = [1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862];

    for reference in haystack.iter() {
        let item = *reference;

        let result = match item {
            42 | 132 => "hit!",
            _ => "miss",
        };

        if result == "hit!" {
            println!("{}: {}", item, result);
        }
    }
    println!("");

    let three = 0b11;
    let thirty = 0o36;
    let three_hundred = 0x12C;

    println!("{} {} {}", three, thirty, three_hundred);
    println!("{:b} {:b} {:b}", three, thirty, three_hundred);
    println!("{:o} {:o} {:o}", three, thirty, three_hundred);
    println!("{:x} {:x} {:x}", three, thirty, three_hundred);
    println!("");

    let twenty = 20;
    let twenty_one: i32 = twenty + 1;
    let floats_okay = 21.0;
    let one_million = 1_000_000;

    println!("{}; {}; {}; {}", twenty, twenty_one, floats_okay, one_million);
    println!("");

    let a = 10;
    let b: i32 = 20;

    let c = add(a, b);
    println!("a + b = {}", c);
}

fn add<T: Add<Output = T>>(i: T, j: T) -> T {
    i + j
}
<commit_msg>replace countig with enumerate<commit_after>use std::ops::{Add};

fn main() {
    let search_term = "picture";
    let quote = "Every face, every shop, bedroom window, public-house, and
    dark square is a picture feverishly turned--in search of what?
    It is the same with books. What do we seek through millions of pages?";

    for (idx, line) in quote.lines().enumerate() {
        if line.contains(search_term) {
            let line_num = idx + 1;
            println!("{}: {}", line_num, line);
        }
    }
    println!("");

    let (a, b) = (1.2, 3.4);
    let (x, y) = (10, 20);

    let c = add(a,b);
    let z = add(x, y);

    println!("{} + {} = {}", a, b, c);
    println!("{} + {} = {}", x, y, z);
    println!("");

    let haystack = [1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862];

    for reference in haystack.iter() {
        let item = *reference;

        let result = match item {
            42 | 132 => "hit!",
            _ => "miss",
        };

        if result == "hit!" {
            println!("{}: {}", item, result);
        }
    }
    println!("");

    let three = 0b11;
    let thirty = 0o36;
    let three_hundred = 0x12C;

    println!("{} {} {}", three, thirty, three_hundred);
    println!("{:b} {:b} {:b}", three, thirty, three_hundred);
    println!("{:o} {:o} {:o}", three, thirty, three_hundred);
    println!("{:x} {:x} {:x}", three, thirty, three_hundred);
    println!("");

    let twenty = 20;
    let twenty_one: i32 = twenty + 1;
    let floats_okay = 21.0;
    let one_million = 1_000_000;

    println!("{}; {}; {}; {}", twenty, twenty_one, floats_okay, one_million);
    println!("");

    let a = 10;
    let b: i32 = 20;

    let c = add(a, b);
    println!("a + b = {}", c);
}

fn add<T: Add<Output = T>>(i: T, j: T) -> T {
    i + j
}
<|endoftext|>


<commit_before>//! An example of using `peg` with `codespan_reporting`.
//!
//! To run this example execute the following command from the top level of this repository:
//!
//! ```sh
//! cargo run --example peg_calculator
//! ```

use codespan_reporting::diagnostic::{Diagnostic, Label};
use codespan_reporting::files::SimpleFile;
use codespan_reporting::term;
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
use rustyline::error::ReadlineError;
use rustyline::Editor;

peg::parser! {
    grammar arithmetic() for str {
        rule number() -> i64
            = n:$(['0'..='9']+) { n.parse().unwrap() }

        pub rule calculate() -> i64 = precedence!{
            x:(@) "+" y:@ { x + y }
            x:(@) "-" y:@ { x - y }
                  "-" v:@ { - v }
            --
            x:(@) "*" y:@ { x * y }
            x:(@) "/" y:@ { x / y }
            --
            x:@   "^" y:(@) { i64::pow(x, y as u32) }
            v:@   "!"       { (1..v+1).product() }
            --
            "(" v:calculate() ")" { v }
            n:number() {n}
        }
    }
}

fn main() -> anyhow::Result<()> {
    let writer = StandardStream::stderr(ColorChoice::Always);
    let config = codespan_reporting::term::Config::default();
    let mut editor = Editor::<()>::new();

    loop {
        let line = match editor.readline(&"> ") {
            Ok(line) => line,
            Err(ReadlineError::Interrupted) | Err(ReadlineError::Eof) => return Ok(()),
            Err(error) => return Err(error.into()),
        };

        match arithmetic::calculate(&line) {
            Ok(number) => println!("{}", number),
            Err(error) => {
                let file = SimpleFile::new("input", line);

                let start = error.location.offset;
                let diagnostic = Diagnostic::error()
                    .with_message("parse error")
                    .with_labels(vec![
                        Label::primary((), start..start).with_message("parse error")
                    ])
                    .with_notes(vec![format!("expected: {}", error.expected)]);

                term::emit(&mut writer.lock(), &config, &file, &diagnostic)?;
            }
        }
    }
}
<commit_msg>Style improvements<commit_after>//! An example of using `peg` with `codespan_reporting`.
//!
//! To run this example execute the following command from the top level of this repository:
//!
//! ```sh
//! cargo run --example peg_calculator
//! ```

use codespan_reporting::diagnostic::{Diagnostic, Label};
use codespan_reporting::files::SimpleFile;
use codespan_reporting::term;
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
use rustyline::error::ReadlineError;
use rustyline::Editor;

peg::parser! {
    grammar arithmetic() for str {
        rule number() -> i64
            = n:$(['0'..='9']+) { n.parse().unwrap() }

        pub rule calculate() -> i64 = precedence!{
            x:(@) "+" y:@ { x + y }
            x:(@) "-" y:@ { x - y }
                  "-" v:@ { - v }
            --
            x:(@) "*" y:@ { x * y }
            x:(@) "/" y:@ { x / y }
            --
            x:@   "^" y:(@) { i64::pow(x, y as u32) }
            v:@   "!"       { (1..v+1).product() }
            --
            "(" v:calculate() ")" { v }
            n:number() { n }
        }
    }
}

fn main() -> anyhow::Result<()> {
    let writer = StandardStream::stderr(ColorChoice::Always);
    let config = codespan_reporting::term::Config::default();
    let mut editor = Editor::<()>::new();

    loop {
        let line = match editor.readline("> ") {
            Ok(line) => line,
            Err(ReadlineError::Interrupted) | Err(ReadlineError::Eof) => return Ok(()),
            Err(error) => return Err(error.into()),
        };

        match arithmetic::calculate(&line) {
            Ok(number) => println!("{}", number),
            Err(error) => {
                let file = SimpleFile::new("input", line);

                let start = error.location.offset;
                let diagnostic = Diagnostic::error()
                    .with_message("parse error")
                    .with_labels(vec![
                        Label::primary((), start..start).with_message("parse error")
                    ])
                    .with_notes(vec![format!("expected: {}", error.expected)]);

                term::emit(&mut writer.lock(), &config, &file, &diagnostic)?;
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate blip_buf;

use std::time::Duration;
use blip_buf::BlipBuf;

const CLOCK_RATE : f64 = 1000000.0;
const SAMPLE_RATE : u32 = 48000;

fn main() {
    let mut blip = BlipBuf::new(SAMPLE_RATE / 10);
    blip.set_rates(CLOCK_RATE, SAMPLE_RATE as f64 );

    let mut time  = 0;      // number of clocks until next wave delta
    let mut delta = 10000;  // amplitude of next delta
    let mut period = 400;   // clocks between deltas

    for _n in 0..60 {
        // Slowly lower pitch every frame
        period = period + 3;

        // Generate 1/60 second of input clocks. We could generate
        // any number of clocks here, all the way down to 1.
        let clocks = CLOCK_RATE as i32 / 60;
        while time < clocks
        {
            blip.add_delta( time as u32, delta );
            delta = -delta; // square wave deltas alternate sign
            time = time + period;
        }

        // Add those clocks to buffer and adjust time for next frame
        time = time - clocks;
        blip.end_frame( clocks as u32 );

        // Read and play any output samples now available
        while blip.samples_avail() > 0
        {
            let mut temp = &mut [0i16; 1024];
            let count = blip.read_samples( temp, false );
            play_samples( &temp[..count] );
        }
    }

    // wait until the sound finishes
    std::thread::sleep(Duration::from_secs(1));
}

fn play_samples(_buf: &[i16]) {
    // play contents of _buf
}
<commit_msg>Fix warning<commit_after>extern crate blip_buf;

use std::time::Duration;
use blip_buf::BlipBuf;

const CLOCK_RATE : f64 = 1000000.0;
const SAMPLE_RATE : u32 = 48000;

fn main() {
    let mut blip = BlipBuf::new(SAMPLE_RATE / 10);
    blip.set_rates(CLOCK_RATE, SAMPLE_RATE as f64 );

    let mut time  = 0;      // number of clocks until next wave delta
    let mut delta = 10000;  // amplitude of next delta
    let mut period = 400;   // clocks between deltas

    for _n in 0..60 {
        // Slowly lower pitch every frame
        period = period + 3;

        // Generate 1/60 second of input clocks. We could generate
        // any number of clocks here, all the way down to 1.
        let clocks = CLOCK_RATE as i32 / 60;
        while time < clocks
        {
            blip.add_delta( time as u32, delta );
            delta = -delta; // square wave deltas alternate sign
            time = time + period;
        }

        // Add those clocks to buffer and adjust time for next frame
        time = time - clocks;
        blip.end_frame( clocks as u32 );

        // Read and play any output samples now available
        while blip.samples_avail() > 0
        {
            let temp = &mut [0i16; 1024];
            let count = blip.read_samples( temp, false );
            play_samples( &temp[..count] );
        }
    }

    // wait until the sound finishes
    std::thread::sleep(Duration::from_secs(1));
}

fn play_samples(_buf: &[i16]) {
    // play contents of _buf
}
<|endoftext|>


<commit_before>
extern crate linux_ip;

//use std::io::prelude::*;

#[cfg(test)]
mod tests {
    use std::fs::File;
    use std::io::Read;
    use std::path::Path;

    fn ip_addr_show() -> String {
        let mut f = File::open(Path::new("tests/ip_addr.out")).unwrap();
        let mut s = String::new();
        f.read_to_string(&mut s).ok();
        return s
    }
    #[test]
    fn test_me() {
      let ip_addr = ::linux_ip::addr::parse_from_string(&ip_addr_show());
      assert_eq!(26, ip_addr.length());
      assert_eq!("br995", ip_addr.find("br995").unwrap().name);
      assert_eq!(vec!["10.10.95.11/22", "10.10.95.12/22", "fe80::d227:88ff:fed1:16d/64"], ip_addr.find("br995").unwrap().ips);
    }
#[test]
   fn test_as_commands() {
    let ip_addr = ::linux_ip::addr::parse_from_string(&ip_addr_show());
    for i in ip_addr.as_commands("add") {
        println!("cmd:{}", &i);
    }
    assert!(ip_addr.as_commands("add").iter().find(|s| *s == "ip addr add fe80::d227:88ff:fed1:16d/64 dev p1p1.402").is_some());
    assert!(ip_addr.as_commands("del").iter().find(|s| *s == "ip addr del 10.1.0.11/16 dev br110").is_some());
  }
#[test]
  fn test_from_scratch() {
    let mut ip_addr = ::linux_ip::addr::IpAddr {
        interfaces: Vec::new()
    };
    let idx = ip_addr.add_interface(&"eth0".to_string());
    ip_addr.interfaces[idx].add_ip("47.11.1.1/26".to_string());
    assert!(ip_addr.as_commands("del").iter().find(|s| *s == "ip addr del 47.11.1.1/26 dev eth0").is_some())
  }

}

  //   fn test_find() {
  //   require 'ipaddress'
  //   map = [{:net => IPAddress.parse("10.10.95.0/22"), :result => "huhu" }]
  //   ip_addr = Linux::Ip::Addr.parse_from_lines(@ip_addr_show.lines)
  //   ret = map.find do |matcher|
  //     ip_addr.interfaces.find do |iface|
  //       iface.ips.find do |ip|
  //         ip = IPAddress.parse(ip)
  //         ip.ipv4? && matcher[:net].include?(ip)
  //       end
  //     end
  //   end
  //   assert_equal "huhu", ret[:result]
  // end
<commit_msg>better tests<commit_after>
extern crate linux_ip;

// use std::io::prelude::*;

#[cfg(test)]
mod tests {
    use std::fs::File;
    use std::io::Read;
    use std::path::Path;

    fn ip_addr_show() -> String {
        let mut f = File::open(Path::new("tests/ip_addr.out")).unwrap();
        let mut s = String::new();
        f.read_to_string(&mut s).ok();
        return s;
    }
    #[test]
    fn test_me() {
        let ip_addr = ::linux_ip::addr::parse_from_string(&ip_addr_show());
        assert_eq!(26, ip_addr.length());
        assert_eq!("br995", ip_addr.find("br995").unwrap().name);
        assert_eq!(vec!["10.10.95.11/22", "10.10.95.12/22", "fe80::d227:88ff:fed1:16d/64"],
                   ip_addr.find("br995").unwrap().ips);
    }
    #[test]
    fn test_as_commands() {
        let ip_addr = ::linux_ip::addr::parse_from_string(&ip_addr_show());
        for i in ip_addr.as_commands("add") {
            println!("cmd:{}", &i);
        }
        assert!(ip_addr.as_commands("add")
            .iter()
            .find(|s| *s == "ip addr add fe80::d227:88ff:fed1:16d/64 dev p1p1.402")
            .is_some());
        assert!(ip_addr.as_commands("del")
            .iter()
            .find(|s| *s == "ip addr del 10.1.0.11/16 dev br110")
            .is_some());
    }
    #[test]
    fn test_from_scratch() {
        let mut ip_addr = ::linux_ip::addr::IpAddr { interfaces: Vec::new() };
        let idx = ip_addr.add_interface(&"eth0".to_string());
        ip_addr.interfaces[idx].add_ip("47.11.1.1/26".to_string());
        assert!(ip_addr.as_commands("del")
            .iter()
            .find(|s| *s == "ip addr del 47.11.1.1/26 dev eth0")
            .is_some())
    }

}

//   fn test_find() {
//   require 'ipaddress'
//   map = [{:net => IPAddress.parse("10.10.95.0/22"), :result => "huhu" }]
//   ip_addr = Linux::Ip::Addr.parse_from_lines(@ip_addr_show.lines)
//   ret = map.find do |matcher|
//     ip_addr.interfaces.find do |iface|
//       iface.ips.find do |ip|
//         ip = IPAddress.parse(ip)
//         ip.ipv4? && matcher[:net].include?(ip)
//       end
//     end
//   end
//   assert_equal "huhu", ret[:result]
// end
<|endoftext|>


<commit_before>use regex::Regex;
use std::fs::File;
use std::io::{self, BufRead};
use std::str::FromStr;

#[macro_use]
extern crate lazy_static;

struct State<T>(Box<dyn Iterator<Item = T>>, Option<T>);
pub struct Merge<T> {
    max: T, // TODO
    count: usize,
    states: Vec<State<T>>,
}

impl<T: 'static + FromStr> Merge<T> {
    pub fn new(filename: &str, max: T) -> Self {
        let count = get_number(filename).unwrap();
        let states = (0..count).map(|i| {
            let collection = Box::new(get_collection(filename, i).unwrap());
            State(collection, None)
        }).collect();
        Merge {
            count: count,
            states: states,
            max: max,
        }
    }
}

impl<T: 'static + PartialOrd + Copy> Iterator for Merge<T> {
    type Item = T;
    fn next(&mut self) -> Option<Self::Item> {
        let count = self.count;
        let max = self.max;
        let states = &mut self.states;
        loop {
            for i in 0..count {
                let state = &mut states[i];
                if state.1.is_none() {
                    state.1 = state.0.next();
                }
            }
            let not_done = states.iter().any(|s| s.1.is_some());
            if !not_done {
                return None;
            }

            let (mut min, mut min_index) = (max, usize::MIN);
            for i in 0..count {
                if let Some(val) = states[i].1 {
                    if val < min {
                        min = val;
                        min_index = i;
                    }
                }
            }
            states[min_index].1 = None;
            return Some(min);
        }
    }
}

pub fn get_number(filename: &str) -> io::Result<usize> {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"NUMBER=(\d+)").unwrap();
    }
    let mut matches = match_lines(filename, &*RE)?;
    return Ok(matches.next().unwrap().parse().unwrap());
}

pub fn get_output<T: FromStr>(filename: &str) -> io::Result<impl Iterator<Item = T>> {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"OUTPUT:(.*)").unwrap();
    }
    get_numbers(filename, &*RE)
}

pub fn get_collection<T: FromStr>(filename: &str, idx: usize) -> io::Result<impl Iterator<Item = T>> {
    let regex: Regex = {
        let r = format!("COLLECTION{}:(.*)", idx);
        Regex::new(&r).unwrap()
    };
    get_numbers(filename, &regex)
}

fn get_numbers<T: FromStr>(filename: &str, regex: &Regex) -> io::Result<impl Iterator<Item = T>> {
    let matches = match_lines(filename, regex)?;
    let to_int = |v: &str| -> Option<T> {
        if let Ok(i) = v.parse::<T>() {
            Some(i)
        } else {
            None
        }
    };
    let values = matches
        .map(move |s| {
            let numbers = s.split(',').filter_map(|v| to_int(&v));
            numbers.collect::<Vec<_>>()
        })
        .flatten();
    Ok(values)
}

fn match_lines(filename: &str, regex: &Regex) -> io::Result<impl Iterator<Item = String>> {
    let read_lines = move || -> io::Result<_> {
        let file = File::open(filename)?;
        Ok(io::BufReader::new(file).lines().map(|line| line.unwrap()))
    };
    let lines = read_lines()?;
    let r = regex.clone(); // TODO
    let matches =
        lines.filter_map(move |line| r.captures(&line).map(|captures| captures[1].to_string()));
    Ok(matches)
}

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

    #[test]
    fn test_number() {
        assert_eq!(get_number("../data/test.txt").unwrap(), 3);
    }

    #[test]
    fn test_output() {
        let output = [1, 1, 2, 2, 3, 4, 4, 6, 7, 9, 9, 20, 21];
        assert_eq!(
            get_output("../data/test.txt").unwrap().collect::<Vec<u32>>(),
            output
        );
    }

    #[test]
    fn test_collection() {
        let output = [2, 4, 6, 9, 20];
        assert_eq!(
            get_collection("../data/test.txt", 1)
                .unwrap()
                .collect::<Vec<u32>>(),
            output
        );
    }

    fn merge(filename: &str) -> (impl Iterator<Item = u32>, impl Iterator<Item = u32>) {
        let result = Merge::new(filename, u32::MAX);
        let output = get_output(filename).unwrap();
        (result, output)
    }

    fn assert_iterator(
        iter1: &mut impl Iterator<Item = u32>,
        iter2: &mut impl Iterator<Item = u32>,
    ) -> bool {
        loop {
            match (iter1.next(), iter2.next()) {
                (None, None) => return true,
                (Some(v1), Some(v2)) if v1 == v2 => continue,
                _ => return false,
            }
        }
    }

    #[test]
    fn test_merge() {
        let filename = "../data/test.txt";
        let (mut result, mut output) = merge(filename);
        assert!(assert_iterator(&mut result, &mut output));
    }

    #[test]
    #[should_panic]
    fn test_bad_merge() {
        let filename = "../data/bad.txt";
        let (_result, _output) = merge(filename);
    }

    #[test]
    fn test_zero_merge() {
        let filename = "../data/zero.txt";
        let (mut result, mut output) = merge(filename);
        assert!(result.next().is_none());
        assert!(output.next().is_none());
    }

    #[test]
    fn test_err() {
        let filename = "../data/err.txt";
        let (mut result, mut output) = merge(filename);
        assert!(!assert_iterator(&mut result, &mut output));
    }
}
<commit_msg>More generic<commit_after>use regex::Regex;
use std::fs::File;
use std::io::{self, BufRead};
use std::str::FromStr;

#[macro_use]
extern crate lazy_static;

struct State<T>(Box<dyn Iterator<Item = T>>, Option<T>);
pub struct Merge<T> {
    max: T, // TODO
    count: usize,
    states: Vec<State<T>>,
}

impl<T: 'static + FromStr> Merge<T> {
    pub fn new(filename: &str, max: T) -> Self {
        let count = get_number(filename).unwrap();
        let states = (0..count).map(|i| {
            let collection = Box::new(get_collection(filename, i).unwrap());
            State(collection, None)
        }).collect();
        Merge {
            count: count,
            states: states,
            max: max,
        }
    }
}

impl<T: 'static + PartialOrd + Copy> Iterator for Merge<T> {
    type Item = T;
    fn next(&mut self) -> Option<Self::Item> {
        let count = self.count;
        let max = self.max;
        let states = &mut self.states;
        loop {
            for i in 0..count {
                let state = &mut states[i];
                if state.1.is_none() {
                    state.1 = state.0.next();
                }
            }
            let not_done = states.iter().any(|s| s.1.is_some());
            if !not_done {
                return None;
            }

            let (mut min, mut min_index) = (max, usize::MIN);
            for i in 0..count {
                if let Some(val) = states[i].1 {
                    if val < min {
                        min = val;
                        min_index = i;
                    }
                }
            }
            states[min_index].1 = None;
            return Some(min);
        }
    }
}

pub fn get_number(filename: &str) -> io::Result<usize> {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"NUMBER=(\d+)").unwrap();
    }
    let mut matches = match_lines(filename, &*RE)?;
    return Ok(matches.next().unwrap().parse().unwrap());
}

pub fn get_output<T: FromStr>(filename: &str) -> io::Result<impl Iterator<Item = T>> {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"OUTPUT:(.*)").unwrap();
    }
    get_numbers(filename, &*RE)
}

pub fn get_collection<T: FromStr>(filename: &str, idx: usize) -> io::Result<impl Iterator<Item = T>> {
    let regex: Regex = {
        let r = format!("COLLECTION{}:(.*)", idx);
        Regex::new(&r).unwrap()
    };
    get_numbers(filename, &regex)
}

fn get_numbers<T: FromStr>(filename: &str, regex: &Regex) -> io::Result<impl Iterator<Item = T>> {
    let matches = match_lines(filename, regex)?;
    let to_int = |v: &str| -> Option<T> {
        if let Ok(i) = v.parse::<T>() {
            Some(i)
        } else {
            None
        }
    };
    let values = matches
        .map(move |s| {
            let numbers = s.split(',').filter_map(|v| to_int(&v));
            numbers.collect::<Vec<_>>()
        })
        .flatten();
    Ok(values)
}

fn match_lines(filename: &str, regex: &Regex) -> io::Result<impl Iterator<Item = String>> {
    let read_lines = move || -> io::Result<_> {
        let file = File::open(filename)?;
        Ok(io::BufReader::new(file).lines().map(|line| line.unwrap()))
    };
    let lines = read_lines()?;
    let r = regex.clone(); // TODO
    let matches =
        lines.filter_map(move |line| r.captures(&line).map(|captures| captures[1].to_string()));
    Ok(matches)
}

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

    #[test]
    fn test_number() {
        assert_eq!(get_number("../data/test.txt").unwrap(), 3);
    }

    #[test]
    fn test_output() {
        let output = [1, 1, 2, 2, 3, 4, 4, 6, 7, 9, 9, 20, 21];
        assert_eq!(
            get_output("../data/test.txt").unwrap().collect::<Vec<32>>(),
            output
        );
    }

    #[test]
    fn test_collection() {
        let output = [2, 4, 6, 9, 20];
        assert_eq!(
            get_collection("../data/test.txt", 1)
                .unwrap()
                .collect::<Vec<u32>>(),
            output
        );
    }

    fn merge(filename: &str) -> (impl Iterator<Item = u32>, impl Iterator<Item = u32>) {
        let result = Merge::new(filename, u32::MAX);
        let output = get_output(filename).unwrap();
        (result, output)
    }

    fn assert_iterator<T: PartialOrd>(
        iter1: &mut impl Iterator<Item = T>,
        iter2: &mut impl Iterator<Item = T>,
    ) -> bool {
        loop {
            match (iter1.next(), iter2.next()) {
                (None, None) => return true,
                (Some(v1), Some(v2)) if v1 == v2 => continue,
                _ => return false,
            }
        }
    }

    #[test]
    fn test_merge() {
        let filename = "../data/test.txt";
        let (mut result, mut output) = merge(filename);
        assert!(assert_iterator(&mut result, &mut output));
    }

    #[test]
    #[should_panic]
    fn test_bad_merge() {
        let filename = "../data/bad.txt";
        let (_result, _output) = merge(filename);
    }

    #[test]
    fn test_zero_merge() {
        let filename = "../data/zero.txt";
        let (mut result, mut output) = merge(filename);
        assert!(result.next().is_none());
        assert!(output.next().is_none());
    }

    #[test]
    fn test_err() {
        let filename = "../data/err.txt";
        let (mut result, mut output) = merge(filename);
        assert!(!assert_iterator(&mut result, &mut output));
    }
}
<|endoftext|>


<commit_before>use anyhow::Result;
use std::env::var;
use std::fs;
use std::io::*;
use std::path::*;
use std::process::Command;
use zip::ZipArchive;

fn download_archive_windows(out_dir: &Path) -> Result<()> {
    if out_dir.join("libfftw3.dll").exists() && out_dir.join("libfftw3f.dll").exists() {
        return Ok(());
    }

    let archive = out_dir.join("fftw_windows.zip");
    if !archive.exists() {
        // Download
        let mut conn = ftp::FtpStream::connect("ftp.fftw.org:21")?;
        conn.login("anonymous", "anonymous")?;
        conn.cwd("pub/fftw")?;
        let buf = conn.simple_retr("fftw-3.3.5-dll64.zip")?.into_inner();
        // TODO calc checksum
        let mut f = fs::File::create(&archive)?;
        f.write(&buf)?;
    }
    let f = fs::File::open(&archive)?;
    let mut zip = ZipArchive::new(f)?;
    let target = var("TARGET").unwrap();
    for name in &["fftw3-3", "fftw3f-3"] {
        for ext in &["dll", "def"] {
            let filename = format!("lib{}.{}", name, ext);
            let mut zf = zip.by_name(&filename)?;
            let mut f = fs::File::create(out_dir.join(filename))?;
            copy(&mut zf, &mut f)?;
        }
        run(cc::windows_registry::find_tool(&target, "lib.exe")
            .unwrap()
            .to_command()
            .arg("/MACHINE:X64")
            .arg(format!("/DEF:lib{}.def", name))
            .arg(format!("/OUT:lib{}.lib", name))
            .current_dir(out_dir))
    }
    Ok(())
}

fn build_unix(out_dir: &Path) {
    let root_dir = PathBuf::from(var("CARGO_MANIFEST_DIR").unwrap());
    let archive_dir = root_dir.join("fftw-3.3.8");
    if !out_dir.join("lib/libfftw3.a").exists() {
        build_fftw(&[], &archive_dir, &out_dir);
    }
    if !out_dir.join("lib/libfftw3f.a").exists() {
        build_fftw(&["--enable-single"], &archive_dir, &out_dir);
    }
}

fn build_fftw(flags: &[&str], src_dir: &Path, out_dir: &Path) {
    run(
        Command::new(fs::canonicalize(src_dir.join("configure")).unwrap())
            .arg("--with-pic")
            .arg("--enable-static")
            .arg("--disable-doc")
            .arg(format!("--prefix={}", out_dir.display()))
            .args(flags)
            .current_dir(&src_dir),
    );
    run(Command::new("make")
        .arg(format!("-j{}", var("NUM_JOBS").unwrap()))
        .current_dir(&src_dir));
    run(Command::new("make").arg("install").current_dir(&src_dir));
}

fn run(command: &mut Command) {
    println!("Running: {:?}", command);
    match command.status() {
        Ok(status) => {
            if !status.success() {
                panic!("`{:?}` failed: {}", command, status);
            }
        }
        Err(error) => {
            panic!("failed to execute `{:?}`: {}", command, error);
        }
    }
}

fn main() {
    let out_dir = PathBuf::from(var("OUT_DIR").unwrap());
    if cfg!(target_os = "windows") {
        download_archive_windows(&out_dir).unwrap();
        println!("cargo:rustc-link-search={}", out_dir.display());
        println!("cargo:rustc-link-lib=libfftw3-3");
        println!("cargo:rustc-link-lib=libfftw3f-3");
    } else {
        build_unix(&out_dir);
        println!("cargo:rustc-link-search={}", out_dir.join("lib").display());
        println!("cargo:rustc-link-lib=static=fftw3");
        println!("cargo:rustc-link-lib=static=fftw3f");
    }
}
<commit_msg>fftw-src: Clarify imports<commit_after>use anyhow::Result;
use std::env::var;
use std::fs::{canonicalize, File};
use std::io::{copy, Write};
use std::path::{Path, PathBuf};
use std::process::Command;
use zip::ZipArchive;

fn download_archive_windows(out_dir: &Path) -> Result<()> {
    if out_dir.join("libfftw3.dll").exists() && out_dir.join("libfftw3f.dll").exists() {
        return Ok(());
    }

    let archive = out_dir.join("fftw_windows.zip");
    if !archive.exists() {
        // Download
        let mut conn = ftp::FtpStream::connect("ftp.fftw.org:21")?;
        conn.login("anonymous", "anonymous")?;
        conn.cwd("pub/fftw")?;
        let buf = conn.simple_retr("fftw-3.3.5-dll64.zip")?.into_inner();
        // TODO calc checksum
        let mut f = File::create(&archive)?;
        f.write(&buf)?;
    }
    let f = File::open(&archive)?;
    let mut zip = ZipArchive::new(f)?;
    let target = var("TARGET").unwrap();
    for name in &["fftw3-3", "fftw3f-3"] {
        for ext in &["dll", "def"] {
            let filename = format!("lib{}.{}", name, ext);
            let mut zf = zip.by_name(&filename)?;
            let mut f = File::create(out_dir.join(filename))?;
            copy(&mut zf, &mut f)?;
        }
        run(cc::windows_registry::find_tool(&target, "lib.exe")
            .unwrap()
            .to_command()
            .arg("/MACHINE:X64")
            .arg(format!("/DEF:lib{}.def", name))
            .arg(format!("/OUT:lib{}.lib", name))
            .current_dir(out_dir))
    }
    Ok(())
}

fn build_unix(out_dir: &Path) {
    let root_dir = PathBuf::from(var("CARGO_MANIFEST_DIR").unwrap());
    let archive_dir = root_dir.join("fftw-3.3.8");
    if !out_dir.join("lib/libfftw3.a").exists() {
        build_fftw(&[], &archive_dir, &out_dir);
    }
    if !out_dir.join("lib/libfftw3f.a").exists() {
        build_fftw(&["--enable-single"], &archive_dir, &out_dir);
    }
}

fn build_fftw(flags: &[&str], src_dir: &Path, out_dir: &Path) {
    run(
        Command::new(canonicalize(src_dir.join("configure")).unwrap())
            .arg("--with-pic")
            .arg("--enable-static")
            .arg("--disable-doc")
            .arg(format!("--prefix={}", out_dir.display()))
            .args(flags)
            .current_dir(&src_dir),
    );
    run(Command::new("make")
        .arg(format!("-j{}", var("NUM_JOBS").unwrap()))
        .current_dir(&src_dir));
    run(Command::new("make").arg("install").current_dir(&src_dir));
}

fn run(command: &mut Command) {
    println!("Running: {:?}", command);
    match command.status() {
        Ok(status) => {
            if !status.success() {
                panic!("`{:?}` failed: {}", command, status);
            }
        }
        Err(error) => {
            panic!("failed to execute `{:?}`: {}", command, error);
        }
    }
}

fn main() {
    let out_dir = PathBuf::from(var("OUT_DIR").unwrap());
    if cfg!(target_os = "windows") {
        download_archive_windows(&out_dir).unwrap();
        println!("cargo:rustc-link-search={}", out_dir.display());
        println!("cargo:rustc-link-lib=libfftw3-3");
        println!("cargo:rustc-link-lib=libfftw3f-3");
    } else {
        build_unix(&out_dir);
        println!("cargo:rustc-link-search={}", out_dir.join("lib").display());
        println!("cargo:rustc-link-lib=static=fftw3");
        println!("cargo:rustc-link-lib=static=fftw3f");
    }
}
<|endoftext|>


<commit_before>use actix::actors::signal;
use actix::prelude::*;
use godcoin_p2p::{session::*, NetCmd, Network, Payload};
use tokio::{prelude::*, timer::Delay};
use log::{error, info};
use bytes::BytesMut;
use std::time::{Instant, Duration};

struct Signals;

impl Actor for Signals {
    type Context = Context<Self>;
}

impl Handler<signal::Signal> for Signals {
    type Result = ();

    fn handle(&mut self, msg: signal::Signal, _: &mut Context<Self>) {
        if let signal::SignalType::Int = msg.0 {
            info!("SIGINT received, exiting");
            System::current().stop();
        }
    }
}

struct NetInfo {
    net_id: usize,
}

fn connected(state: &mut NetInfo, ses: SessionInfo) {
    match ses.conn_type {
        ConnectionType::Inbound => {
            info!(
                "[net:{}] Accepted connection -> {}",
                state.net_id, ses.peer_addr
            );
        }
        ConnectionType::Outbound => {
            info!(
                "[net:{}] Connected to node -> {}",
                state.net_id, ses.peer_addr
            );
        }
    }
}

fn disconnected(state: &mut NetInfo, ses: SessionInfo) {
    info!(
        "[net:{}] Connection disconnected -> {}",
        state.net_id, ses.peer_addr
    );
}

fn message(state: &mut NetInfo, id: SessionId, payload: &Payload) -> bool {
    info!(
        "[net:{}] Received message from {} with: {:?}",
        state.net_id, id, payload
    );
    // TODO: ID caching to prevent broadcast loops
    true
}

fn main() {
    let env = env_logger::Env::new()
        .filter_or(env_logger::DEFAULT_FILTER_ENV, "godcoin_simulation=debug");
    env_logger::init_from_env(env);

    let sys = System::new("simulation");

    {
        let sig_addr = Signals.start();
        let addr = signal::ProcessSignals::from_registry();
        addr.do_send(signal::Subscribe(sig_addr.recipient()));
    }

    let nets = {
        let net_count = 3;
        let port = 7777;
        let mut nets = Vec::with_capacity(net_count);
        for net_id in 0..net_count {
            let net = Network::new(NetInfo { net_id }, message)
                .on_connect(connected)
                .on_disconnect(disconnected)
                .start();
            net.do_send(NetCmd::Listen(format!("127.0.0.1:{}", port + net_id).parse().unwrap()));
            info!("[net:{}] Accepting connections on 127.0.0.1:7777", net_id);
            nets.push(net);
        }
        nets
    };

    nets[1].do_send(NetCmd::Connect("127.0.0.1:7777".parse().unwrap()));
    nets[2].do_send(NetCmd::Connect("127.0.0.1:7778".parse().unwrap()));

    let deadline = Instant::now() + Duration::from_secs(1);
    Arbiter::spawn(Delay::new(deadline).and_then(move |_| {
        let payload = Payload {
            id: BytesMut::from(vec![1, 2, 3]),
            msg: BytesMut::from(vec![4, 5, 6])
        };
        info!("[net:2] Broadcasting message: {:?}", &payload);
        nets[2].do_send(NetCmd::Broadcast(payload));
        Ok(())
    }).map_err(|e| {
        error!("Timer failed: {:?}", e);
    }));

    sys.run();
}
<commit_msg>Refactor to NetState<commit_after>use actix::actors::signal;
use actix::prelude::*;
use godcoin_p2p::{session::*, NetCmd, Network, Payload};
use tokio::{prelude::*, timer::Delay};
use log::{error, info};
use bytes::BytesMut;
use std::time::{Instant, Duration};

struct Signals;

impl Actor for Signals {
    type Context = Context<Self>;
}

impl Handler<signal::Signal> for Signals {
    type Result = ();

    fn handle(&mut self, msg: signal::Signal, _: &mut Context<Self>) {
        if let signal::SignalType::Int = msg.0 {
            info!("SIGINT received, exiting");
            System::current().stop();
        }
    }
}

struct NetState {
    net_id: usize,
}

fn connected(state: &mut NetState, ses: SessionInfo) {
    match ses.conn_type {
        ConnectionType::Inbound => {
            info!(
                "[net:{}] Accepted connection -> {}",
                state.net_id, ses.peer_addr
            );
        }
        ConnectionType::Outbound => {
            info!(
                "[net:{}] Connected to node -> {}",
                state.net_id, ses.peer_addr
            );
        }
    }
}

fn disconnected(state: &mut NetState, ses: SessionInfo) {
    info!(
        "[net:{}] Connection disconnected -> {}",
        state.net_id, ses.peer_addr
    );
}

fn message(state: &mut NetState, id: SessionId, payload: &Payload) -> bool {
    info!(
        "[net:{}] Received message from {} with: {:?}",
        state.net_id, id, payload
    );
    // TODO: ID caching to prevent broadcast loops
    true
}

fn main() {
    let env = env_logger::Env::new()
        .filter_or(env_logger::DEFAULT_FILTER_ENV, "godcoin_simulation=debug");
    env_logger::init_from_env(env);

    let sys = System::new("simulation");

    {
        let sig_addr = Signals.start();
        let addr = signal::ProcessSignals::from_registry();
        addr.do_send(signal::Subscribe(sig_addr.recipient()));
    }

    let nets = {
        let net_count = 3;
        let port = 7777;
        let mut nets = Vec::with_capacity(net_count);
        for net_id in 0..net_count {
            let net = Network::new(NetState { net_id }, message)
                .on_connect(connected)
                .on_disconnect(disconnected)
                .start();
            net.do_send(NetCmd::Listen(format!("127.0.0.1:{}", port + net_id).parse().unwrap()));
            info!("[net:{}] Accepting connections on 127.0.0.1:7777", net_id);
            nets.push(net);
        }
        nets
    };

    nets[1].do_send(NetCmd::Connect("127.0.0.1:7777".parse().unwrap()));
    nets[2].do_send(NetCmd::Connect("127.0.0.1:7778".parse().unwrap()));

    let deadline = Instant::now() + Duration::from_secs(1);
    Arbiter::spawn(Delay::new(deadline).and_then(move |_| {
        let payload = Payload {
            id: BytesMut::from(vec![1, 2, 3]),
            msg: BytesMut::from(vec![4, 5, 6])
        };
        info!("[net:2] Broadcasting message: {:?}", &payload);
        nets[2].do_send(NetCmd::Broadcast(payload));
        Ok(())
    }).map_err(|e| {
        error!("Timer failed: {:?}", e);
    }));

    sys.run();
}
<|endoftext|>


<commit_before>use cairo;
use glib_sys;

use cairo::MatrixTrait;
use glib::translate::*;

use float_eq_cairo::ApproxEqCairo;

// Keep this in sync with ../../rsvg-private.h:RsvgBbox
#[repr(C)]
#[derive(Copy, Clone)]
pub struct RsvgBbox {
    pub rect: cairo::Rectangle,
    pub affine: cairo::Matrix,
    virgin: glib_sys::gboolean,
}

impl RsvgBbox {
    pub fn new(affine: &cairo::Matrix) -> RsvgBbox {
        RsvgBbox {
            rect: cairo::Rectangle {
                x: 0.0,
                y: 0.0,
                width: 0.0,
                height: 0.0
            },

            affine: *affine,
            virgin: true.to_glib(),
        }
    }

    pub fn is_virgin(&self) -> bool {
        from_glib(self.virgin)
    }

    pub fn is_empty(&self) -> bool {
        from_glib(self.virgin) || self.rect.width.approx_eq_cairo(&0.0)
            || self.rect.height.approx_eq_cairo(&0.0)
    }

    pub fn insert(&mut self, src: &RsvgBbox) {
        if src.is_virgin() {
            return;
        }

        let (mut xmin, mut ymin, mut xmax, mut ymax) = if !self.is_virgin() {
            (
                self.rect.x,
                self.rect.y,
                (self.rect.x + self.rect.width),
                (self.rect.y + self.rect.height),
            )
        } else {
            (0.0, 0.0, 0.0, 0.0)
        };

        let mut affine = self.affine;

        // this will panic!() if it's not invertible... should we check on our own?
        affine.invert();
        affine = cairo::Matrix::multiply(&src.affine, &affine);

        // This is a trick.  We want to transform each of the corners of
        // the rectangle defined by src.rect with the affine
        // transformation, and get the bounding box of all the four
        // resulting points.  The modulus and division accomplish this by
        // running through all the combinations of adding or not adding
        // the width/height to the first point src.rect.(x, y).
        for i in 0..4 {
            let rx: f64 = src.rect.x + src.rect.width * f64::from(i % 2);
            let ry: f64 = src.rect.y + src.rect.height * f64::from(i / 2);
            let x: f64 = affine.xx * rx + affine.xy * ry + affine.x0;
            let y: f64 = affine.yx * rx + affine.yy * ry + affine.y0;

            if self.is_virgin() {
                xmin = x;
                xmax = x;
                ymin = y;
                ymax = y;
                self.virgin = false.to_glib();
            } else {
                if x < xmin {
                    xmin = x;
                }
                if x > xmax {
                    xmax = x;
                }
                if y < ymin {
                    ymin = y;
                }
                if y > ymax {
                    ymax = y;
                }
            }
        }

        self.rect.x = xmin;
        self.rect.y = ymin;
        self.rect.width = xmax - xmin;
        self.rect.height = ymax - ymin;
    }

    pub fn clip(&mut self, src: &RsvgBbox) {
        if src.is_virgin() {
            return;
        }

        let (mut xmin, mut ymin, mut xmax, mut ymax) = if !self.is_virgin() {
            (
                (self.rect.x + self.rect.width),
                (self.rect.y + self.rect.height),
                self.rect.x,
                self.rect.y,
            )
        } else {
            (0.0, 0.0, 0.0, 0.0)
        };

        let mut affine = self.affine;

        affine.invert();
        affine = cairo::Matrix::multiply(&src.affine, &affine);

        // This is a trick.  See rsvg_bbox_insert() for a description of how it works.
        for i in 0..4 {
            let rx: f64 = src.rect.x + src.rect.width * f64::from(i % 2);
            let ry: f64 = src.rect.y + src.rect.height * f64::from(i / 2);
            let x = affine.xx * rx + affine.xy * ry + affine.x0;
            let y = affine.yx * rx + affine.yy * ry + affine.y0;

            if self.is_virgin() {
                xmin = x;
                xmax = x;
                ymin = y;
                ymax = y;
                self.virgin = false.to_glib();
            } else {
                if x < xmin {
                    xmin = x;
                }
                if x > xmax {
                    xmax = x;
                }
                if y < ymin {
                    ymin = y;
                }
                if y > ymax {
                    ymax = y;
                }
            }
        }

        if xmin < self.rect.x {
            xmin = self.rect.x;
        }
        if ymin < self.rect.y {
            ymin = self.rect.y;
        }

        if xmax > self.rect.x + self.rect.width {
            xmax = self.rect.x + self.rect.width;
        }
        if ymax > self.rect.y + self.rect.height {
            ymax = self.rect.y + self.rect.height;
        }

        self.rect.x = xmin;
        self.rect.width = xmax - xmin;
        self.rect.y = ymin;
        self.rect.height = ymax - ymin;
    }
}

#[no_mangle]
pub extern "C" fn rsvg_bbox_init(raw_bbox: *mut RsvgBbox, raw_matrix: *const cairo::Matrix) {
    assert!(!raw_bbox.is_null());
    assert!(!raw_matrix.is_null());

    let bbox: &mut RsvgBbox = unsafe { &mut (*raw_bbox) };
    let matrix = unsafe { &*raw_matrix };

    *bbox = RsvgBbox::new(matrix);
}

#[no_mangle]
pub extern "C" fn rsvg_bbox_insert(raw_dst: *mut RsvgBbox, raw_src: *const RsvgBbox) {
    assert!(!raw_dst.is_null());
    assert!(!raw_src.is_null());

    let dst: &mut RsvgBbox = unsafe { &mut (*raw_dst) };
    let src: &RsvgBbox = unsafe { &*raw_src };

    dst.insert(src);
}

#[no_mangle]
pub extern "C" fn rsvg_bbox_clip(raw_dst: *mut RsvgBbox, raw_src: *const RsvgBbox) {
    assert!(!raw_dst.is_null());
    assert!(!raw_src.is_null());

    let dst: &mut RsvgBbox = unsafe { &mut (*raw_dst) };
    let src: &RsvgBbox = unsafe { &*raw_src };

    dst.clip(src);
}
<commit_msg>RsvgBbox.set_rect() - new method<commit_after>use cairo;
use glib_sys;

use cairo::MatrixTrait;
use glib::translate::*;

use float_eq_cairo::ApproxEqCairo;

// Keep this in sync with ../../rsvg-private.h:RsvgBbox
#[repr(C)]
#[derive(Copy, Clone)]
pub struct RsvgBbox {
    pub rect: cairo::Rectangle,
    pub affine: cairo::Matrix,
    virgin: glib_sys::gboolean,
}

impl RsvgBbox {
    pub fn new(affine: &cairo::Matrix) -> RsvgBbox {
        RsvgBbox {
            rect: cairo::Rectangle {
                x: 0.0,
                y: 0.0,
                width: 0.0,
                height: 0.0
            },

            affine: *affine,
            virgin: true.to_glib(),
        }
    }

    pub fn is_virgin(&self) -> bool {
        from_glib(self.virgin)
    }

    pub fn is_empty(&self) -> bool {
        from_glib(self.virgin) || self.rect.width.approx_eq_cairo(&0.0)
            || self.rect.height.approx_eq_cairo(&0.0)
    }

    pub fn set_rect(&mut self, r: &cairo::Rectangle) {
        self.rect = *r;
        self.virgin = false.to_glib();
    }

    pub fn insert(&mut self, src: &RsvgBbox) {
        if src.is_virgin() {
            return;
        }

        let (mut xmin, mut ymin, mut xmax, mut ymax) = if !self.is_virgin() {
            (
                self.rect.x,
                self.rect.y,
                (self.rect.x + self.rect.width),
                (self.rect.y + self.rect.height),
            )
        } else {
            (0.0, 0.0, 0.0, 0.0)
        };

        let mut affine = self.affine;

        // this will panic!() if it's not invertible... should we check on our own?
        affine.invert();
        affine = cairo::Matrix::multiply(&src.affine, &affine);

        // This is a trick.  We want to transform each of the corners of
        // the rectangle defined by src.rect with the affine
        // transformation, and get the bounding box of all the four
        // resulting points.  The modulus and division accomplish this by
        // running through all the combinations of adding or not adding
        // the width/height to the first point src.rect.(x, y).
        for i in 0..4 {
            let rx: f64 = src.rect.x + src.rect.width * f64::from(i % 2);
            let ry: f64 = src.rect.y + src.rect.height * f64::from(i / 2);
            let x: f64 = affine.xx * rx + affine.xy * ry + affine.x0;
            let y: f64 = affine.yx * rx + affine.yy * ry + affine.y0;

            if self.is_virgin() {
                xmin = x;
                xmax = x;
                ymin = y;
                ymax = y;
                self.virgin = false.to_glib();
            } else {
                if x < xmin {
                    xmin = x;
                }
                if x > xmax {
                    xmax = x;
                }
                if y < ymin {
                    ymin = y;
                }
                if y > ymax {
                    ymax = y;
                }
            }
        }

        self.rect.x = xmin;
        self.rect.y = ymin;
        self.rect.width = xmax - xmin;
        self.rect.height = ymax - ymin;
    }

    pub fn clip(&mut self, src: &RsvgBbox) {
        if src.is_virgin() {
            return;
        }

        let (mut xmin, mut ymin, mut xmax, mut ymax) = if !self.is_virgin() {
            (
                (self.rect.x + self.rect.width),
                (self.rect.y + self.rect.height),
                self.rect.x,
                self.rect.y,
            )
        } else {
            (0.0, 0.0, 0.0, 0.0)
        };

        let mut affine = self.affine;

        affine.invert();
        affine = cairo::Matrix::multiply(&src.affine, &affine);

        // This is a trick.  See rsvg_bbox_insert() for a description of how it works.
        for i in 0..4 {
            let rx: f64 = src.rect.x + src.rect.width * f64::from(i % 2);
            let ry: f64 = src.rect.y + src.rect.height * f64::from(i / 2);
            let x = affine.xx * rx + affine.xy * ry + affine.x0;
            let y = affine.yx * rx + affine.yy * ry + affine.y0;

            if self.is_virgin() {
                xmin = x;
                xmax = x;
                ymin = y;
                ymax = y;
                self.virgin = false.to_glib();
            } else {
                if x < xmin {
                    xmin = x;
                }
                if x > xmax {
                    xmax = x;
                }
                if y < ymin {
                    ymin = y;
                }
                if y > ymax {
                    ymax = y;
                }
            }
        }

        if xmin < self.rect.x {
            xmin = self.rect.x;
        }
        if ymin < self.rect.y {
            ymin = self.rect.y;
        }

        if xmax > self.rect.x + self.rect.width {
            xmax = self.rect.x + self.rect.width;
        }
        if ymax > self.rect.y + self.rect.height {
            ymax = self.rect.y + self.rect.height;
        }

        self.rect.x = xmin;
        self.rect.width = xmax - xmin;
        self.rect.y = ymin;
        self.rect.height = ymax - ymin;
    }
}

#[no_mangle]
pub extern "C" fn rsvg_bbox_init(raw_bbox: *mut RsvgBbox, raw_matrix: *const cairo::Matrix) {
    assert!(!raw_bbox.is_null());
    assert!(!raw_matrix.is_null());

    let bbox: &mut RsvgBbox = unsafe { &mut (*raw_bbox) };
    let matrix = unsafe { &*raw_matrix };

    *bbox = RsvgBbox::new(matrix);
}

#[no_mangle]
pub extern "C" fn rsvg_bbox_insert(raw_dst: *mut RsvgBbox, raw_src: *const RsvgBbox) {
    assert!(!raw_dst.is_null());
    assert!(!raw_src.is_null());

    let dst: &mut RsvgBbox = unsafe { &mut (*raw_dst) };
    let src: &RsvgBbox = unsafe { &*raw_src };

    dst.insert(src);
}

#[no_mangle]
pub extern "C" fn rsvg_bbox_clip(raw_dst: *mut RsvgBbox, raw_src: *const RsvgBbox) {
    assert!(!raw_dst.is_null());
    assert!(!raw_src.is_null());

    let dst: &mut RsvgBbox = unsafe { &mut (*raw_dst) };
    let src: &RsvgBbox = unsafe { &*raw_src };

    dst.clip(src);
}
<|endoftext|>