<commit_before>use std::io;

use super::{Numeric, SignedNumeric};

pub trait BitWrite {
    fn write<U>(&mut self, bits: u32, value: U) -> Result<(), io::Error>
        where U: Numeric;

    fn write_signed<S>(&mut self, bits: u32, value: S) -> Result<(), io::Error>
        where S: SignedNumeric;

    fn write_bytes(&mut self, buf: &[u8]) -> Result<(), io::Error>;

    fn write_unary0(&mut self, value: u32) -> Result<(), io::Error>;

    fn write_unary1(&mut self, value: u32) -> Result<(), io::Error>;

    fn byte_aligned(&self) -> bool;

    fn byte_align(&mut self) -> Result<(), io::Error>;
}

pub struct BitWriterBE<'a> {
    writer: &'a mut io::Write,
    buffer: [u8; 1],
    bits: usize
}

impl<'a> BitWriterBE<'a> {
    pub fn new(writer: &mut io::Write) -> BitWriterBE {
        BitWriterBE{writer: writer, buffer: [0], bits: 0}
    }

    fn write_bit(&mut self, bit: bool) -> Result<(), io::Error> {
        if bit {
            self.buffer[0] |= 1 << (7 - self.bits);
        }
        self.bits += 1;
        if self.bits == 8 {
            self.writer.write_all(&self.buffer)?;
            self.buffer[0] = 0;
            self.bits = 0;
        }
        Ok(())
    }
}

impl<'a> BitWrite for BitWriterBE<'a> {
    fn write<U>(&mut self, mut bits: u32, value: U) -> Result<(), io::Error>
        where U: Numeric {
        while bits > 0 {
            let mask = U::one() << (bits - 1);
            self.write_bit((value & mask).to_bit())?;
            bits -= 1;
        }
        Ok(())
    }

    fn write_signed<S>(&mut self, bits: u32, value: S) -> Result<(), io::Error>
        where S: SignedNumeric {
        if value.is_negative() {
            self.write(1, 1u8)
                .and_then(|()| self.write(bits - 1, value.as_unsigned(bits)))
        } else {
            self.write(1, 0u8)
                .and_then(|()| self.write(bits - 1, value))
        }
    }

    fn write_bytes(&mut self, buf: &[u8]) -> Result<(), io::Error> {
        if self.byte_aligned() {
            self.writer.write_all(buf)
        } else {
            for b in buf {
                self.write(8, *b)?;
            }
            Ok(())
        }
    }

    fn write_unary0(&mut self, value: u32) -> Result<(), io::Error> {
        /*FIXME - optimize this*/
        for _ in 0..value {
            self.write(1, 1u8)?;
        }
        self.write(1, 0u8)
    }

    fn write_unary1(&mut self, value: u32) -> Result<(), io::Error> {
        /*FIXME - optimize this*/
        for _ in 0..value {
            self.write(1, 0u8)?;
        }
        self.write(1, 1u8)
    }

    fn byte_aligned(&self) -> bool {
        self.bits == 0
    }

    fn byte_align(&mut self) -> Result<(), io::Error> {
        /*FIXME - optimize this*/
        while !self.byte_aligned() {
            self.write(1, 0u8)?;
        }
        Ok(())
    }
}

pub struct BitWriterLE<'a> {
    writer: &'a mut io::Write,
    buffer: [u8; 1],
    bits: usize
}

impl<'a> BitWriterLE<'a> {
    pub fn new(writer: &mut io::Write) -> BitWriterLE {
        BitWriterLE{writer: writer, buffer: [0], bits: 0}
    }

    fn write_bit(&mut self, bit: bool) -> Result<(), io::Error> {
        if bit {
            self.buffer[0] |= 1 << self.bits;
        }
        self.bits += 1;
        if self.bits == 8 {
            self.writer.write_all(&self.buffer)?;
            self.buffer[0] = 0;
            self.bits = 0;
        }
        Ok(())
    }
}

impl<'a> BitWrite for BitWriterLE<'a> {
    fn write<U>(&mut self, mut bits: u32, mut value: U) -> Result<(), io::Error>
        where U: Numeric {
        while bits > 0 {
            self.write_bit((value & U::one()).to_bit())?;
            value >>= U::one();
            bits -= 1;
        }
        Ok(())
    }

    fn write_signed<S>(&mut self, bits: u32, value: S) -> Result<(), io::Error>
        where S: SignedNumeric {
        if value.is_negative() {
            self.write(bits - 1, value.as_unsigned(bits))
                .and_then(|()| self.write(1, 1u8))
        } else {
            self.write(bits - 1, value)
                .and_then(|()| self.write(1, 0u8))
        }
    }

    fn write_bytes(&mut self, buf: &[u8]) -> Result<(), io::Error> {
        if self.byte_aligned() {
            self.writer.write_all(buf)
        } else {
            for b in buf {
                self.write(8, *b)?;
            }
            Ok(())
        }
    }

    fn write_unary0(&mut self, value: u32) -> Result<(), io::Error> {
        /*FIXME - optimize this*/
        for _ in 0..value {
            self.write(1, 1u8)?;
        }
        self.write(1, 0u8)
    }

    fn write_unary1(&mut self, value: u32) -> Result<(), io::Error> {
        /*FIXME - optimize this*/
        for _ in 0..value {
            self.write(1, 0u8)?;
        }
        self.write(1, 1u8)
    }

    fn byte_aligned(&self) -> bool {
        self.bits == 0
    }

    fn byte_align(&mut self) -> Result<(), io::Error> {
        /*FIXME - optimize this*/
        while !self.byte_aligned() {
            self.write(1, 0u8)?;
        }
        Ok(())
    }
}
<commit_msg>Optimize unary writes to output in chunks<commit_after>use std::io;

use super::{Numeric, SignedNumeric};

pub trait BitWrite {
    fn write<U>(&mut self, bits: u32, value: U) -> Result<(), io::Error>
        where U: Numeric;

    fn write_signed<S>(&mut self, bits: u32, value: S) -> Result<(), io::Error>
        where S: SignedNumeric;

    fn write_bytes(&mut self, buf: &[u8]) -> Result<(), io::Error>;

    fn write_unary0(&mut self, value: u32) -> Result<(), io::Error>;

    fn write_unary1(&mut self, value: u32) -> Result<(), io::Error>;

    fn byte_aligned(&self) -> bool;

    fn byte_align(&mut self) -> Result<(), io::Error>;
}

pub struct BitWriterBE<'a> {
    writer: &'a mut io::Write,
    buffer: [u8; 1],
    bits: usize
}

impl<'a> BitWriterBE<'a> {
    pub fn new(writer: &mut io::Write) -> BitWriterBE {
        BitWriterBE{writer: writer, buffer: [0], bits: 0}
    }

    fn write_bit(&mut self, bit: bool) -> Result<(), io::Error> {
        if bit {
            self.buffer[0] |= 1 << (7 - self.bits);
        }
        self.bits += 1;
        if self.bits == 8 {
            self.writer.write_all(&self.buffer)?;
            self.buffer[0] = 0;
            self.bits = 0;
        }
        Ok(())
    }
}

impl<'a> BitWrite for BitWriterBE<'a> {
    fn write<U>(&mut self, mut bits: u32, value: U) -> Result<(), io::Error>
        where U: Numeric {
        while bits > 0 {
            let mask = U::one() << (bits - 1);
            self.write_bit((value & mask).to_bit())?;
            bits -= 1;
        }
        Ok(())
    }

    fn write_signed<S>(&mut self, bits: u32, value: S) -> Result<(), io::Error>
        where S: SignedNumeric {
        if value.is_negative() {
            self.write(1, 1u8)
                .and_then(|()| self.write(bits - 1, value.as_unsigned(bits)))
        } else {
            self.write(1, 0u8)
                .and_then(|()| self.write(bits - 1, value))
        }
    }

    fn write_bytes(&mut self, buf: &[u8]) -> Result<(), io::Error> {
        if self.byte_aligned() {
            self.writer.write_all(buf)
        } else {
            for b in buf {
                self.write(8, *b)?;
            }
            Ok(())
        }
    }

    fn write_unary0(&mut self, mut value: u32) -> Result<(), io::Error> {
        while value > 8 {
            self.write(8, 0xFFu8)?;
            value -= 8;
        }
        if value > 0 {
            self.write(value, (1 << value) - 1)?;
        }
        self.write(1, 0u8)
    }

    fn write_unary1(&mut self, mut value: u32) -> Result<(), io::Error> {
        while value > 8 {
            self.write(8, 0u8)?;
            value -= 8;
        }
        if value > 0 {
            self.write(value, 0)?;
        }
        self.write(1, 1u8)
    }

    fn byte_aligned(&self) -> bool {
        self.bits == 0
    }

    fn byte_align(&mut self) -> Result<(), io::Error> {
        /*FIXME - optimize this*/
        while !self.byte_aligned() {
            self.write(1, 0u8)?;
        }
        Ok(())
    }
}

pub struct BitWriterLE<'a> {
    writer: &'a mut io::Write,
    buffer: [u8; 1],
    bits: usize
}

impl<'a> BitWriterLE<'a> {
    pub fn new(writer: &mut io::Write) -> BitWriterLE {
        BitWriterLE{writer: writer, buffer: [0], bits: 0}
    }

    fn write_bit(&mut self, bit: bool) -> Result<(), io::Error> {
        if bit {
            self.buffer[0] |= 1 << self.bits;
        }
        self.bits += 1;
        if self.bits == 8 {
            self.writer.write_all(&self.buffer)?;
            self.buffer[0] = 0;
            self.bits = 0;
        }
        Ok(())
    }
}

impl<'a> BitWrite for BitWriterLE<'a> {
    fn write<U>(&mut self, mut bits: u32, mut value: U) -> Result<(), io::Error>
        where U: Numeric {
        while bits > 0 {
            self.write_bit((value & U::one()).to_bit())?;
            value >>= U::one();
            bits -= 1;
        }
        Ok(())
    }

    fn write_signed<S>(&mut self, bits: u32, value: S) -> Result<(), io::Error>
        where S: SignedNumeric {
        if value.is_negative() {
            self.write(bits - 1, value.as_unsigned(bits))
                .and_then(|()| self.write(1, 1u8))
        } else {
            self.write(bits - 1, value)
                .and_then(|()| self.write(1, 0u8))
        }
    }

    fn write_bytes(&mut self, buf: &[u8]) -> Result<(), io::Error> {
        if self.byte_aligned() {
            self.writer.write_all(buf)
        } else {
            for b in buf {
                self.write(8, *b)?;
            }
            Ok(())
        }
    }

    fn write_unary0(&mut self, mut value: u32) -> Result<(), io::Error> {
        while value > 8 {
            self.write(8, 0xFFu8)?;
            value -= 8;
        }
        if value > 0 {
            self.write(value, (1 << value) - 1)?;
        }
        self.write(1, 0u8)
    }

    fn write_unary1(&mut self, mut value: u32) -> Result<(), io::Error> {
        while value > 8 {
            self.write(8, 0u8)?;
            value -= 8;
        }
        if value > 0 {
            self.write(value, 0)?;
        }
        self.write(1, 1u8)
    }

    fn byte_aligned(&self) -> bool {
        self.bits == 0
    }

    fn byte_align(&mut self) -> Result<(), io::Error> {
        /*FIXME - optimize this*/
        while !self.byte_aligned() {
            self.write(1, 0u8)?;
        }
        Ok(())
    }
}
<|endoftext|>


<commit_before>#[cfg(feature = "serialization")]
use serde::{Deserialize, Serialize};
use std::fmt;
use std::ops::Range;

use crate::ByteIndex;

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
pub struct Span {
    start: ByteIndex,
    end: ByteIndex,
}

impl Span {
    /// Create a new span from a starting and ending span.
    pub fn new(start: impl Into<ByteIndex>, end: impl Into<ByteIndex>) -> Span {
        let start = start.into();
        let end = end.into();

        assert!(end >= start);

        Span { start, end }
    }

    /// Gives an empty span at the start of a source.
    pub fn initial() -> Span {
        Span::new(0, 0)
    }

    /// Measure the span of a string.
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let span = Span::from_str("hello");
    ///
    /// assert_eq!(span, Span::new(0, 5));
    /// ```
    pub fn from_str(s: &str) -> Span {
        Span::new(0, s.len() as u32)
    }

    /// Combine two spans by taking the start of the first span and the end of
    /// the other span.
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let span1 = Span::new(0, 4);
    /// let span2 = Span::new(10, 16);
    ///
    /// assert_eq!(Span::merge(span1, span2), Span::new(0, 16));
    /// ```
    pub fn merge(self, other: Span) -> Span {
        Span::new(self.start(), other.end())
    }

    /// Get the starting byte index.
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let span = Span::new(0, 4);
    ///
    /// assert_eq!(span.start(), ByteIndex::from(0));
    /// ```
    pub fn start(&self) -> ByteIndex {
        self.start
    }

    /// Get the ending byte index.
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let span = Span::new(0, 4);
    ///
    /// assert_eq!(span.end(), ByteIndex::from(4));
    /// ```
    pub fn end(&self) -> ByteIndex {
        self.end
    }
}

impl Default for Span {
    fn default() -> Span {
        Span::initial()
    }
}

impl fmt::Display for Span {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "[{start}, {end})",
            start = self.start(),
            end = self.end(),
        )
    }
}

impl<I> From<Range<I>> for Span
where
    I: Into<ByteIndex>,
{
    fn from(range: Range<I>) -> Span {
        Span::new(range.start, range.end)
    }
}
<commit_msg>Have `Span` take self by value<commit_after>#[cfg(feature = "serialization")]
use serde::{Deserialize, Serialize};
use std::fmt;
use std::ops::Range;

use crate::ByteIndex;

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serialization", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
pub struct Span {
    start: ByteIndex,
    end: ByteIndex,
}

impl Span {
    /// Create a new span from a starting and ending span.
    pub fn new(start: impl Into<ByteIndex>, end: impl Into<ByteIndex>) -> Span {
        let start = start.into();
        let end = end.into();

        assert!(end >= start);

        Span { start, end }
    }

    /// Gives an empty span at the start of a source.
    pub fn initial() -> Span {
        Span::new(0, 0)
    }

    /// Measure the span of a string.
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let span = Span::from_str("hello");
    ///
    /// assert_eq!(span, Span::new(0, 5));
    /// ```
    pub fn from_str(s: &str) -> Span {
        Span::new(0, s.len() as u32)
    }

    /// Combine two spans by taking the start of the first span and the end of
    /// the other span.
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let span1 = Span::new(0, 4);
    /// let span2 = Span::new(10, 16);
    ///
    /// assert_eq!(Span::merge(span1, span2), Span::new(0, 16));
    /// ```
    pub fn merge(self, other: Span) -> Span {
        Span::new(self.start(), other.end())
    }

    /// Get the starting byte index.
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let span = Span::new(0, 4);
    ///
    /// assert_eq!(span.start(), ByteIndex::from(0));
    /// ```
    pub fn start(self) -> ByteIndex {
        self.start
    }

    /// Get the ending byte index.
    ///
    /// ```rust
    /// use codespan::{ByteIndex, Span};
    ///
    /// let span = Span::new(0, 4);
    ///
    /// assert_eq!(span.end(), ByteIndex::from(4));
    /// ```
    pub fn end(self) -> ByteIndex {
        self.end
    }
}

impl Default for Span {
    fn default() -> Span {
        Span::initial()
    }
}

impl fmt::Display for Span {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "[{start}, {end})",
            start = self.start(),
            end = self.end(),
        )
    }
}

impl<I> From<Range<I>> for Span
where
    I: Into<ByteIndex>,
{
    fn from(range: Range<I>) -> Span {
        Span::new(range.start, range.end)
    }
}
<|endoftext|>


<commit_before>#![allow(dead_code)]
// The constants CRC24_INIT and CRC24_POLY are defined in section 6.1
// of RFC4880 along with the definition of the CRC octet validator.
const CRC24_INIT: usize = 0xB704CE;
const CRC24_POLY: usize = 0x1864CFB;

pub type Crc24 = usize;

// This is an adaption of the CRC-24 algorithm from section 6.1 of TFC4880.
#[allow(unused_variables)]
pub fn crc_octets(octets: &[u8]) -> Crc24 {
    let mut crc: Crc24 = CRC24_INIT;
    for octet in octets {
        crc ^= (*octet as usize) << 16;
        for i in 0..8 {
            crc <<= 1;
            if crc & 0x1000000 != 0 {
                crc ^= CRC24_POLY;
            }
        }
    }
    // Fit crc24 into 24 bits.
    crc & 0xFFFFFF
}

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

    struct TestCase {
        octets: Vec<u8>,
        crc: Crc24
    }

    struct Test {
        data: Vec<TestCase>
    }

    // An empty octet set should compute the crc as the
    // constant CRC24_INIT.
    fn crc_octets_empty_case() -> Test {
        Test {
            data: vec![
                TestCase {
                    octets: vec![],
                    crc: super::CRC24_INIT
                }
            ]
        }
    }

    fn crc_octets_test_cases() -> Test {
        Test {
            data: vec![
                TestCase {
                    octets: vec![0x14, 0xFB, 0x9C, 0x03, 0xD9, 0x7E],
                    crc: 6927321
                },
                TestCase {
                    octets: vec![0x14, 0xFB, 0x9C, 0x03, 0xD9],
                    crc: 8726480
                },
                TestCase {
                    octets: vec![0x14, 0xFB, 0x9C, 0x03],
                    crc: 15804535
                },
                TestCase {
                    octets: vec![0xD5, 0xF0, 0x32, 0x8A, 0xA0, 0xA9,
                                 0x1F, 0xAD, 0x1D, 0xDC, 0x22, 0xB6],
                    crc: 6688197
                }
            ]
        }
    }

    fn run_tests(test: &Test) {
        for test_case in test.data.iter() {
            let crc24 = super::crc_octets(test_case.octets.as_ref());
            assert_eq!(test_case.crc, crc24);
        }
    }

    #[test]
    fn test_crc_octets() {
        run_tests(&crc_octets_test_cases());
    }

    #[test]
    fn test_crc_octets_empty_case() {
        run_tests(&crc_octets_empty_case());
    }
}
<commit_msg>Fix typo in comment.<commit_after>#![allow(dead_code)]
// The constants CRC24_INIT and CRC24_POLY are defined in section 6.1
// of RFC4880 along with the definition of the CRC octet validator.
const CRC24_INIT: usize = 0xB704CE;
const CRC24_POLY: usize = 0x1864CFB;

pub type Crc24 = usize;

// This is an adaption of the CRC-24 algorithm from section 6.1 of RFC4880.
#[allow(unused_variables)]
pub fn crc_octets(octets: &[u8]) -> Crc24 {
    let mut crc: Crc24 = CRC24_INIT;
    for octet in octets {
        crc ^= (*octet as usize) << 16;
        for i in 0..8 {
            crc <<= 1;
            if crc & 0x1000000 != 0 {
                crc ^= CRC24_POLY;
            }
        }
    }
    // Fit crc24 into 24 bits.
    crc & 0xFFFFFF
}

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

    struct TestCase {
        octets: Vec<u8>,
        crc: Crc24
    }

    struct Test {
        data: Vec<TestCase>
    }

    // An empty octet set should compute the crc as the
    // constant CRC24_INIT.
    fn crc_octets_empty_case() -> Test {
        Test {
            data: vec![
                TestCase {
                    octets: vec![],
                    crc: super::CRC24_INIT
                }
            ]
        }
    }

    fn crc_octets_test_cases() -> Test {
        Test {
            data: vec![
                TestCase {
                    octets: vec![0x14, 0xFB, 0x9C, 0x03, 0xD9, 0x7E],
                    crc: 6927321
                },
                TestCase {
                    octets: vec![0x14, 0xFB, 0x9C, 0x03, 0xD9],
                    crc: 8726480
                },
                TestCase {
                    octets: vec![0x14, 0xFB, 0x9C, 0x03],
                    crc: 15804535
                },
                TestCase {
                    octets: vec![0xD5, 0xF0, 0x32, 0x8A, 0xA0, 0xA9,
                                 0x1F, 0xAD, 0x1D, 0xDC, 0x22, 0xB6],
                    crc: 6688197
                }
            ]
        }
    }

    fn run_tests(test: &Test) {
        for test_case in test.data.iter() {
            let crc24 = super::crc_octets(test_case.octets.as_ref());
            assert_eq!(test_case.crc, crc24);
        }
    }

    #[test]
    fn test_crc_octets() {
        run_tests(&crc_octets_test_cases());
    }

    #[test]
    fn test_crc_octets_empty_case() {
        run_tests(&crc_octets_empty_case());
    }
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;

pub fn single_night(file: &str) -> i64 {
    let input = File::open(file).expect("File open fail.");
    let reader = BufReader::new(input);

    let mut nodes = Vec::new();
    let mut edges = Vec::new();
    for line in reader.lines() {
        let line = line.unwrap();
        // println!("{}", s);

        let words: Vec<&str> = line.split_whitespace().collect();
        let from = Node(String::from(words[0]), i64::max_value());
        let to = Node(String::from(words[2]), i64::max_value());
        let distance = words[4]
            .parse::<i64>()
            .expect("parse error");

        nodes.push(from.clone());
        nodes.push(to.clone());
        edges.push((from.clone(), to.clone(), distance));
        edges.push((to, from, distance)); // bi-directed
    }
    // remove duplicate nodes
    nodes.sort_by(|a, b| a.0.cmp(&b.0));
    nodes.dedup();

    println!("nodes");
    for node in nodes.clone() {
        println!("{:?}", node);
    }

    let node_list = nodes.clone();
    let mut results = Vec::new();
    for n in node_list {
        // make n node source
        let mut nodes = nodes.clone();
        if let Ok(n_index) = nodes.binary_search(&n) {
            let mut node = nodes.get_mut(n_index).unwrap();
            *node = Node(n.0.clone(), 0);
        }
        println!("calculating next...");
        results.push(dijkstra(nodes, edges.clone()));
    }

    for result in results.clone() {
        let (route, _) = result;
        for node in route {
            println!("{:?}->", node);
        }
    }
    // sort reversed and pop min
    results.sort_by(|a, b| b.1.cmp(&a.1));
    let (_, min) = results.pop().unwrap();
    min
}

fn dijkstra(mut nodes: Vec<Node>, edges: Vec<(Node, Node, i64)>) -> (Vec<Node>, i64) {
    let mut out: Vec<Node> = Vec::new();
    loop {
        if nodes.is_empty() {
            let mut sum = 0;
            for node in out.clone() {
                sum += node.1;
                println!("{:?}", node);
            }
            return (out, sum);
        }
        println!("\nsorted nodes");
        // sort by value
        nodes.sort_by(|a, b| b.1.cmp(&a.1));
        for node in nodes.clone() {
            println!("{:?}", node);
        }

        let node = nodes.pop().unwrap();
        println!("pop min {:?}", node);

        // sort by name
        nodes.sort_by(|a, b| a.0.cmp(&b.0));

        // for each neighbor of n
        for edge in edges.clone().iter() {
            let (ref from, ref to, ref dist) = *edge;
            if from == &node {
                if let Ok(neighbor_index) = nodes.binary_search_by(|n| n.0.cmp(&to.0)) {
                    println!("edge {:?} {:?} {:?}", from.0, to.0, dist);
                    let mut neighbor = nodes.get_mut(neighbor_index).unwrap();
                    let alt = node.1 + *dist;
                    // assign new weight to neighbor
                    if alt < neighbor.1 {
                        println!("{:?} <- {:?}", neighbor.0, alt);
                        *neighbor = Node(to.0.clone(), alt);
                    } else {
                        println!("{:?} - {:?}", neighbor.0, neighbor.1);
                    }
                }
            }
        }
        out.push(node);
        print!("Out: ");
        for node in out.clone() {
            print!("{:?},", node);
        }
    }
}

#[derive(Debug, Eq, Ord, PartialOrd)]
struct Node(String, i64);

impl PartialEq for Node {
    fn eq(&self, other: &Node) -> bool {
        self.0.eq(&other.0)
    }
    fn ne(&self, other: &Node) -> bool {
        !self.0.eq(&other.0)
    }
}

impl Clone for Node {
    fn clone(&self) -> Self {
        Node(self.0.clone(), self.1)
    }
}

<commit_msg>Simplify result processing.<commit_after>use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;

pub fn single_night(file: &str) -> i64 {
    let input = File::open(file).expect("File open fail.");
    let reader = BufReader::new(input);

    let mut nodes = Vec::new();
    let mut edges = Vec::new();
    for line in reader.lines() {
        let line = line.unwrap();
        // println!("{}", s);

        let words: Vec<&str> = line.split_whitespace().collect();
        let from = Node(String::from(words[0]), i64::max_value());
        let to = Node(String::from(words[2]), i64::max_value());
        let distance = words[4]
            .parse::<i64>()
            .expect("parse error");

        nodes.push(from.clone());
        nodes.push(to.clone());
        edges.push((from.clone(), to.clone(), distance));
        edges.push((to, from, distance)); // bi-directed
    }
    // remove duplicate nodes
    nodes.sort_by(|a, b| a.0.cmp(&b.0));
    nodes.dedup();

    println!("nodes");
    for node in nodes.clone() {
        println!("{:?}", node);
    }

    let node_list = nodes.clone();
    let mut results = Vec::new();
    for n in node_list {
        // make n node source
        let mut nodes = nodes.clone();
        if let Ok(n_index) = nodes.binary_search(&n) {
            let mut node = nodes.get_mut(n_index).unwrap();
            *node = Node(n.0.clone(), 0);
        }
        println!("calculating next...");
        results.push(dijkstra(nodes, edges.clone()));
    }

    println!("results");
    for result in results.clone() {
        println!("{}", result);
    }
    results.iter().cloned().min().unwrap()
}

fn dijkstra(mut nodes: Vec<Node>, edges: Vec<(Node, Node, i64)>) -> i64 {
    let mut out: Vec<Node> = Vec::new();
    loop {
        if nodes.is_empty() {
            break;
        }
        println!("\nsorted nodes");
        // sort by value decreasing
        nodes.sort_by(|a, b| b.1.cmp(&a.1));

        let node = nodes.pop().unwrap();
        println!("pop min {:?}", node);

        // sort by name
        nodes.sort_by(|a, b| a.0.cmp(&b.0));

        // for each neighbor of n
        for edge in edges.clone().iter() {
            let (ref from, ref to, ref dist) = *edge;
            if from == &node {
                if let Ok(neighbor_index) = nodes.binary_search_by(|n| n.0.cmp(&to.0)) {
                    println!("edge {:?} {:?} {:?}", from.0, to.0, dist);
                    let mut neighbor = nodes.get_mut(neighbor_index).unwrap();
                    println!("neighbor {:?}", &neighbor);
                    let alt = node.1 + *dist;
                    // assign new weight to neighbor
                    if alt < neighbor.1 {
                        println!("{:?} <- {:?}", neighbor.0, alt);
                        *neighbor = Node(to.0.clone(), alt);
                    } else {
                        println!("{:?} - {:?}", neighbor.0, neighbor.1);
                    }
                }
            }
        }
        out.push(node.clone());
    }
    print!("Out: ");
    for node in out.clone() {
        print!("{:?},", node);
    }
    out.iter().fold(0, |acc, ref n| acc + n.1)
}

#[derive(Debug, Eq, Ord, PartialOrd)]
struct Node(String, i64);

impl PartialEq for Node {
    fn eq(&self, other: &Node) -> bool {
        self.0.eq(&other.0)
    }
    fn ne(&self, other: &Node) -> bool {
        !self.0.eq(&other.0)
    }
}

impl Clone for Node {
    fn clone(&self) -> Self {
        Node(self.0.clone(), self.1)
    }
}

<|endoftext|>


<commit_before>extern crate zeromq;

use zeromq::{Context, Msg, SocketType};

fn main() {
    println!("24 days of Rust - zeromq (day 20)");
    let args = std::os::args();
    if args.len() < 2 {
        println!("Usage: {} (client|server)", args[0]);
        return;
    }
    let ctx = Context::new();
    let addr = "tcp://127.0.0.1:25933";
    if args[1] == "client" {
        println!("ZeroMQ client connecting to {}", addr);
        let mut sock = ctx.socket(SocketType::REQ);
        let _ = sock.connect(addr);
        let payload = "Hello world!".to_string();
        let mut msg = box Msg::new(payload.len());
        msg.data = payload.into_bytes();
        let _ = sock.msg_send(msg);
    }
    else {
        println!("ZeroMQ server listening on {}", addr);
        let mut sock = ctx.socket(SocketType::REP);
        let _ = sock.bind(addr);
        loop {
            if let Ok(msg) = sock.msg_recv() {
                let contents = String::from_utf8(msg.data).ok().expect("Not a UTF-8 string");
                println!("{}", contents);
                let reply = "Why yes, hello!".to_string();
                let mut msg = box Msg::new(reply.len());
                msg.data = reply.into_bytes();
                let _ = sock.msg_send(msg);
            }
        }
    }
}
<commit_msg>Echo server.<commit_after>extern crate zeromq;

use zeromq::{Context, Msg, SocketType};

fn main() {
    println!("24 days of Rust - zeromq (day 20)");
    let args = std::os::args();
    if args.len() < 2 {
        println!("Usage: {} (client|server)", args[0]);
        return;
    }
    let ctx = Context::new();
    let addr = "tcp://127.0.0.1:25933";
    if args[1] == "client" {
        println!("ZeroMQ client connecting to {}", addr);
        let mut sock = ctx.socket(SocketType::REQ);
        let _ = sock.connect(addr);
        let payload = "Hello world!".to_string();
        println!("-> {}", payload);
        let mut msg = box Msg::new(payload.len());
        msg.data = payload.into_bytes();
        let _ = sock.msg_send(msg);
        if let Ok(msg) = sock.msg_recv() {
            let contents = String::from_utf8(msg.data).ok().expect("Not a UTF-8 string");
            println!("<- {}", contents);
        }
    }
    else {
        println!("ZeroMQ server listening on {}", addr);
        let mut sock = ctx.socket(SocketType::REP);
        let _ = sock.bind(addr);
        loop {
            if let Ok(msg) = sock.msg_recv() {
                let mut reply = box Msg::new(msg.data.len());
                reply.data = msg.data;
                let _ = sock.msg_send(reply);
            }
        }
    }
}
<|endoftext|>


<commit_before>/// Utilities for writing messages to the Janus log.
extern crate chrono;
extern crate colored;

use self::chrono::{DateTime, Local};
use self::colored::{Color, Colorize};
use super::ffi;
use std::ffi::CString;
use std::fmt::Write;

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
/// A Janus log level. Lower is more severe.
pub enum LogLevel {
    Fatal = 1,
    Err = 2,
    Warn = 3,
    Info = 4,
    Verb = 5,
    Huge = 6,
    Dbg = 7,
}

impl LogLevel {
    /// The color associated with each log level's label (if colors are enabled.)
    fn color(&self) -> Option<Color> {
        match *self {
            LogLevel::Fatal => Some(Color::Magenta),
            LogLevel::Err => Some(Color::Red),
            LogLevel::Warn => Some(Color::Yellow),
            _ => None,
        }
    }
}

#[derive(Debug, Clone)]
pub struct LogParameters {
    pub max_log_level: i32,
    pub log_timestamps: bool,
    pub log_colors: bool,
    pub clock: fn() -> DateTime<Local>,
}

impl Default for LogParameters {
    fn default() -> Self {
        unsafe {
            Self {
                max_log_level: ffi::janus_log_level,
                log_timestamps: ffi::janus_log_timestamps == 1,
                log_colors: ffi::janus_log_colors == 1,
                clock: Local::now,
            }
        }
    }
}

/// Writes a message at the given log level to the Janus log, using the provided parameters to control
/// how the log message is formatted.
pub fn write_log(level: LogLevel, message: &str, params: LogParameters) {
    if level as i32 <= params.max_log_level {
        let output = CString::new(print_log(level, message, params)).expect("Null character in log message :(");
        unsafe { ffi::janus_vprintf(output.as_ptr()) }
    }
}

/// Prints a message at the given log level into an owned string, using the provided parameters to control
/// how the log message is formatted.
pub fn print_log(level: LogLevel, message: &str, params: LogParameters) -> String {
    let mut output = String::with_capacity(message.len() + 40);
    if params.log_timestamps {
        write!(output, "{} ", (params.clock)().format("[%a %b %e %T %Y]")).unwrap();
    }
    if level <= LogLevel::Warn {
        let prefix = format!("[{:?}] ", level).to_uppercase();
        let prefix = match level.color() {
            Some(c) if params.log_colors => format!("{}", prefix.color(c)),
            _ => prefix,
        };
        write!(output, "{}", prefix).unwrap();
    }
    write!(output, "{}\n", message).unwrap();
    output
}

/// Writes a message at the given log level to the Janus log.
pub fn log(level: LogLevel, message: &str) {
    write_log(level, message, LogParameters::default());
}

#[cfg(test)]
mod tests {

    use super::*;
    use super::chrono::TimeZone;

    fn fixed_clock(year: i32, month: u32, day: u32, hour: u32, min: u32, sec: u32) -> DateTime<Local> {
        Local.ymd(year, month, day).and_hms(hour, min, sec)
    }

    #[test]
    fn log_format_correctness() {
        assert_eq!(
            "[Tue Oct 10 01:37:46 2017] [WARN] Test message.\n",
            print_log(
                LogLevel::Warn,
                "Test message.",
                LogParameters {
                    max_log_level: 6,
                    log_timestamps: true,
                    log_colors: false,
                    clock: || fixed_clock(2017, 10, 10, 1, 37, 46),
                }
            )
        )
    }
}
<commit_msg>Add tests for log colored output<commit_after>/// Utilities for writing messages to the Janus log.
extern crate chrono;
extern crate colored;

use self::chrono::{DateTime, Local};
use self::colored::{Color, Colorize};
use super::ffi;
use std::ffi::CString;
use std::fmt::Write;

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
/// A Janus log level. Lower is more severe.
pub enum LogLevel {
    Fatal = 1,
    Err = 2,
    Warn = 3,
    Info = 4,
    Verb = 5,
    Huge = 6,
    Dbg = 7,
}

impl LogLevel {
    /// The color associated with each log level's label (if colors are enabled.)
    fn color(&self) -> Option<Color> {
        match *self {
            LogLevel::Fatal => Some(Color::Magenta),
            LogLevel::Err => Some(Color::Red),
            LogLevel::Warn => Some(Color::Yellow),
            _ => None,
        }
    }
}

#[derive(Debug, Clone)]
pub struct LogParameters {
    pub max_log_level: i32,
    pub log_timestamps: bool,
    pub log_colors: bool,
    pub clock: fn() -> DateTime<Local>,
}

impl Default for LogParameters {
    fn default() -> Self {
        unsafe {
            Self {
                max_log_level: ffi::janus_log_level,
                log_timestamps: ffi::janus_log_timestamps == 1,
                log_colors: ffi::janus_log_colors == 1,
                clock: Local::now,
            }
        }
    }
}

/// Writes a message at the given log level to the Janus log, using the provided parameters to control
/// how the log message is formatted.
pub fn write_log(level: LogLevel, message: &str, params: LogParameters) {
    if level as i32 <= params.max_log_level {
        let output = CString::new(print_log(level, message, params)).expect("Null character in log message :(");
        unsafe { ffi::janus_vprintf(output.as_ptr()) }
    }
}

/// Prints a message at the given log level into an owned string, using the provided parameters to control
/// how the log message is formatted.
pub fn print_log(level: LogLevel, message: &str, params: LogParameters) -> String {
    let mut output = String::with_capacity(message.len() + 40);
    if params.log_timestamps {
        write!(output, "{} ", (params.clock)().format("[%a %b %e %T %Y]")).unwrap();
    }
    if level <= LogLevel::Warn {
        let prefix = format!("[{:?}] ", level).to_uppercase();
        let prefix = match level.color() {
            Some(c) if params.log_colors => format!("{}", prefix.color(c)),
            _ => prefix,
        };
        write!(output, "{}", prefix).unwrap();
    }
    write!(output, "{}\n", message).unwrap();
    output
}

/// Writes a message at the given log level to the Janus log.
pub fn log(level: LogLevel, message: &str) {
    write_log(level, message, LogParameters::default());
}

#[cfg(test)]
mod tests {

    use super::*;
    use super::chrono::TimeZone;

    fn fixed_clock(year: i32, month: u32, day: u32, hour: u32, min: u32, sec: u32) -> DateTime<Local> {
        Local.ymd(year, month, day).and_hms(hour, min, sec)
    }

    #[test]
    fn log_format_correctness() {
        assert_eq!(
            "[Tue Oct 10 01:37:46 2017] [WARN] Test message.\n",
            print_log(
                LogLevel::Warn,
                "Test message.",
                LogParameters {
                    log_timestamps: true,
                    ..default_log_parameters()
                }
            )
        )
    }

    #[test]
    fn log_colored_output() {
        assert_eq!(
            "\u{1b}[35m[FATAL] \u{1b}[0mCrash!\n",
            print_log(
                LogLevel::Fatal,
                "Crash!",
                LogParameters {
                    log_colors: true,
                    ..default_log_parameters()
                }
            )
        );

        assert_eq!(
            "\u{1b}[31m[ERR] \u{1b}[0mAn error occurred!\n",
            print_log(
                LogLevel::Err,
                "An error occurred!",
                LogParameters {
                    log_colors: true,
                    ..default_log_parameters()
                }
            )
        );

        assert_eq!(
            "\u{1b}[33m[WARN] \u{1b}[0mAttention!\n",
            print_log(
                LogLevel::Warn,
                "Attention!",
                LogParameters {
                    log_colors: true,
                    ..default_log_parameters()
                }
            )
        );

        assert_eq!(
            "Just a message.\n",
            print_log(
                LogLevel::Info,
                "Just a message.",
                LogParameters {
                    log_colors: true,
                    ..default_log_parameters()
                }
            )
        );
    }

    fn default_log_parameters() -> LogParameters {
        LogParameters {
            max_log_level: 6,
            log_timestamps: false,
            log_colors: false,
            clock: || fixed_clock(2017, 10, 10, 1, 37, 46),
        }
    }
}
<|endoftext|>


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

use cssparser::ToCss;
use dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::{self, CSSStyleDeclarationMethods};
use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::global::GlobalRef;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, Root};
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::str::DOMString;
use dom::element::{Element, StylePriority};
use dom::node::{Node, NodeDamage, window_from_node};
use dom::window::Window;
use std::ascii::AsciiExt;
use std::cell::Ref;
use std::slice;
use string_cache::Atom;
use style::parser::ParserContextExtraData;
use style::properties::{PropertyDeclaration, Shorthand};
use style::properties::{is_supported_property, parse_one_declaration, parse_style_attribute};
use style::selector_impl::PseudoElement;

// http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
#[dom_struct]
pub struct CSSStyleDeclaration {
    reflector_: Reflector,
    owner: JS<Element>,
    readonly: bool,
    pseudo: Option<PseudoElement>,
}

#[derive(PartialEq, HeapSizeOf)]
pub enum CSSModificationAccess {
    ReadWrite,
    Readonly,
}

macro_rules! css_properties(
    ( $([$getter:ident, $setter:ident, $cssprop:expr]),* ) => (
        $(
            fn $getter(&self) -> DOMString {
                self.GetPropertyValue(DOMString::from($cssprop))
            }
            fn $setter(&self, value: DOMString) -> ErrorResult {
                self.SetPropertyValue(DOMString::from($cssprop), value)
            }
        )*
    );
);

impl CSSStyleDeclaration {
    pub fn new_inherited(owner: &Element,
                         pseudo: Option<PseudoElement>,
                         modification_access: CSSModificationAccess)
                         -> CSSStyleDeclaration {
        CSSStyleDeclaration {
            reflector_: Reflector::new(),
            owner: JS::from_ref(owner),
            readonly: modification_access == CSSModificationAccess::Readonly,
            pseudo: pseudo,
        }
    }

    pub fn new(global: &Window,
               owner: &Element,
               pseudo: Option<PseudoElement>,
               modification_access: CSSModificationAccess)
               -> Root<CSSStyleDeclaration> {
        reflect_dom_object(box CSSStyleDeclaration::new_inherited(owner,
                                                                  pseudo,
                                                                  modification_access),
                           GlobalRef::Window(global),
                           CSSStyleDeclarationBinding::Wrap)
    }

    fn get_computed_style(&self, property: &Atom) -> Option<DOMString> {
        let node = self.owner.upcast::<Node>();
        if !node.is_in_doc() {
            // TODO: Node should be matched against the style rules of this window.
            // Firefox is currently the only browser to implement this.
            return None;
        }
        let addr = node.to_trusted_node_address();
        window_from_node(&*self.owner).resolved_style_query(addr, self.pseudo.clone(), property)
    }
}

impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
    // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-length
    fn Length(&self) -> u32 {
        let elem = self.owner.upcast::<Element>();
        let len = match *elem.style_attribute().borrow() {
            Some(ref declarations) => declarations.normal.len() + declarations.important.len(),
            None => 0,
        };
        len as u32
    }

    // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-item
    fn Item(&self, index: u32) -> DOMString {
        let index = index as usize;
        let elem = self.owner.upcast::<Element>();
        let style_attribute = elem.style_attribute().borrow();
        let result = style_attribute.as_ref().and_then(|declarations| {
            if index > declarations.normal.len() {
                declarations.important
                            .get(index - declarations.normal.len())
                            .map(|decl| format!("{:?} !important", decl))
            } else {
                declarations.normal
                            .get(index)
                            .map(|decl| format!("{:?}", decl))
            }
        });

        result.map_or(DOMString::new(), DOMString::from)
    }

    // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue
    fn GetPropertyValue(&self, mut property: DOMString) -> DOMString {
        let owner = &self.owner;

        // Step 1
        property.make_ascii_lowercase();
        let property = Atom::from(property);

        if self.readonly {
            // Readonly style declarations are used for getComputedStyle.
            return self.get_computed_style(&property).unwrap_or(DOMString::new());
        }

        // Step 2
        if let Some(shorthand) = Shorthand::from_name(&property) {
            // Step 2.1
            let mut list = vec![];

            // Step 2.2
            for longhand in shorthand.longhands() {
                // Step 2.2.1
                let declaration = owner.get_inline_style_declaration(&Atom::from(*longhand));

                // Step 2.2.2 & 2.2.3
                match declaration {
                    Some(declaration) => list.push(declaration),
                    None => return DOMString::new(),
                }
            }

            // Step 2.3
            // Work around closures not being Clone
            #[derive(Clone)]
            struct Map<'a, 'b: 'a>(slice::Iter<'a, Ref<'b, PropertyDeclaration>>);
            impl<'a, 'b> Iterator for Map<'a, 'b> {
                type Item = &'a PropertyDeclaration;
                fn next(&mut self) -> Option<Self::Item> {
                    self.0.next().map(|r| &**r)
                }
            }

            // TODO: important is hardcoded to false because method does not implement it yet
            let serialized_value = shorthand.serialize_shorthand_value_to_string(Map(list.iter()), false);
            return DOMString::from(serialized_value);
        }

        // Step 3 & 4
        match owner.get_inline_style_declaration(&property) {
            Some(declaration) => DOMString::from(declaration.value()),
            None => DOMString::new(),
        }
    }

    // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority
    fn GetPropertyPriority(&self, mut property: DOMString) -> DOMString {
        // Step 1
        property.make_ascii_lowercase();
        let property = Atom::from(property);

        // Step 2
        if let Some(shorthand) = Shorthand::from_name(&property) {
            // Step 2.1 & 2.2 & 2.3
            if shorthand.longhands().iter()
                                    .map(|&longhand| self.GetPropertyPriority(DOMString::from(longhand)))
                                    .all(|priority| priority == "important") {
                return DOMString::from("important");
            }
        // Step 3
        } else {
            if self.owner.get_important_inline_style_declaration(&property).is_some() {
                return DOMString::from("important");
            }
        }

        // Step 4
        DOMString::new()
    }

    // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-setproperty
    fn SetProperty(&self,
                   mut property: DOMString,
                   value: DOMString,
                   priority: DOMString)
                   -> ErrorResult {
        // Step 1
        if self.readonly {
            return Err(Error::NoModificationAllowed);
        }

        // Step 2
        property.make_ascii_lowercase();

        // Step 3
        if !is_supported_property(&property) {
            return Ok(());
        }

        // Step 4
        if value.is_empty() {
            return self.RemoveProperty(property).map(|_| ());
        }

        // Step 5
        let priority = match &*priority {
            "" => StylePriority::Normal,
            p if p.eq_ignore_ascii_case("important") => StylePriority::Important,
            _ => return Ok(()),
        };

        // Step 6
        let window = window_from_node(&*self.owner);
        let declarations =
            parse_one_declaration(&property, &value, &window.get_url(), window.css_error_reporter(),
                                  ParserContextExtraData::default());

        // Step 7
        let declarations = if let Ok(declarations) = declarations {
            declarations
        } else {
            return Ok(());
        };

        let element = self.owner.upcast::<Element>();

        // Step 8
        // Step 9
        element.update_inline_style(declarations, priority);

        let node = element.upcast::<Node>();
        node.dirty(NodeDamage::NodeStyleDamaged);
        Ok(())
    }

    // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-setpropertypriority
    fn SetPropertyPriority(&self, property: DOMString, priority: DOMString) -> ErrorResult {
        // Step 1
        if self.readonly {
            return Err(Error::NoModificationAllowed);
        }

        // Step 2 & 3
        if !is_supported_property(&property) {
            return Ok(());
        }

        // Step 4
        let priority = match &*priority {
            "" => StylePriority::Normal,
            p if p.eq_ignore_ascii_case("important") => StylePriority::Important,
            _ => return Ok(()),
        };

        let element = self.owner.upcast::<Element>();

        // Step 5 & 6
        match Shorthand::from_name(&property) {
            Some(shorthand) => {
                element.set_inline_style_property_priority(shorthand.longhands(), priority)
            }
            None => element.set_inline_style_property_priority(&[&*property], priority),
        }

        let node = element.upcast::<Node>();
        node.dirty(NodeDamage::NodeStyleDamaged);
        Ok(())
    }

    // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-setpropertyvalue
    fn SetPropertyValue(&self, property: DOMString, value: DOMString) -> ErrorResult {
        self.SetProperty(property, value, DOMString::new())
    }

    // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-removeproperty
    fn RemoveProperty(&self, mut property: DOMString) -> Fallible<DOMString> {
        // Step 1
        if self.readonly {
            return Err(Error::NoModificationAllowed);
        }

        // Step 2
        property.make_ascii_lowercase();

        // Step 3
        let value = self.GetPropertyValue(property.clone());

        let element = self.owner.upcast::<Element>();

        match Shorthand::from_name(&property) {
            // Step 4
            Some(shorthand) => {
                for longhand in shorthand.longhands() {
                    element.remove_inline_style_property(longhand)
                }
            }
            // Step 5
            None => element.remove_inline_style_property(&property),
        }

        let node = element.upcast::<Node>();
        node.dirty(NodeDamage::NodeStyleDamaged);

        // Step 6
        Ok(value)
    }

    // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-cssfloat
    fn CssFloat(&self) -> DOMString {
        self.GetPropertyValue(DOMString::from("float"))
    }

    // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-cssfloat
    fn SetCssFloat(&self, value: DOMString) -> ErrorResult {
        self.SetPropertyValue(DOMString::from("float"), value)
    }

    // https://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
    fn IndexedGetter(&self, index: u32, found: &mut bool) -> DOMString {
        let rval = self.Item(index);
        *found = index < self.Length();
        rval
    }

    // https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-csstext
    fn CssText(&self) -> DOMString {
        let elem = self.owner.upcast::<Element>();
        let style_attribute = elem.style_attribute().borrow();

        if let Some(declarations) = style_attribute.as_ref() {
            DOMString::from(declarations.to_css_string())
        } else {
            DOMString::new()
        }
    }

    // https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-csstext
    fn SetCssText(&self, value: DOMString) -> ErrorResult {
        let window = window_from_node(self.owner.upcast::<Node>());
        let element = self.owner.upcast::<Element>();

        // Step 1
        if self.readonly {
            return Err(Error::NoModificationAllowed);
        }

        // Step 3
        let decl_block = parse_style_attribute(&value, &window.get_url(), window.css_error_reporter(),
                                               ParserContextExtraData::default());
        *element.style_attribute().borrow_mut() = if decl_block.normal.is_empty() && decl_block.important.is_empty() {
            None // Step 2
        } else {
            Some(decl_block)
        };
        element.sync_property_with_attrs_style();
        let node = element.upcast::<Node>();
        node.dirty(NodeDamage::NodeStyleDamaged);
        Ok(())
    }

    // https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-_camel_cased_attribute
    css_properties_accessors!(css_properties);
}
<commit_msg>Simplify CSSStyleDeclaration::GetPropertyValue<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use cssparser::ToCss;
use dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::{self, CSSStyleDeclarationMethods};
use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::global::GlobalRef;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, Root};
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::str::DOMString;
use dom::element::{Element, StylePriority};
use dom::node::{Node, NodeDamage, window_from_node};
use dom::window::Window;
use std::ascii::AsciiExt;
use std::ops::Deref;
use string_cache::Atom;
use style::parser::ParserContextExtraData;
use style::properties::{Shorthand, is_supported_property};
use style::properties::{parse_one_declaration, parse_style_attribute};
use style::selector_impl::PseudoElement;

// http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
#[dom_struct]
pub struct CSSStyleDeclaration {
    reflector_: Reflector,
    owner: JS<Element>,
    readonly: bool,
    pseudo: Option<PseudoElement>,
}

#[derive(PartialEq, HeapSizeOf)]
pub enum CSSModificationAccess {
    ReadWrite,
    Readonly,
}

macro_rules! css_properties(
    ( $([$getter:ident, $setter:ident, $cssprop:expr]),* ) => (
        $(
            fn $getter(&self) -> DOMString {
                self.GetPropertyValue(DOMString::from($cssprop))
            }
            fn $setter(&self, value: DOMString) -> ErrorResult {
                self.SetPropertyValue(DOMString::from($cssprop), value)
            }
        )*
    );
);

impl CSSStyleDeclaration {
    pub fn new_inherited(owner: &Element,
                         pseudo: Option<PseudoElement>,
                         modification_access: CSSModificationAccess)
                         -> CSSStyleDeclaration {
        CSSStyleDeclaration {
            reflector_: Reflector::new(),
            owner: JS::from_ref(owner),
            readonly: modification_access == CSSModificationAccess::Readonly,
            pseudo: pseudo,
        }
    }

    pub fn new(global: &Window,
               owner: &Element,
               pseudo: Option<PseudoElement>,
               modification_access: CSSModificationAccess)
               -> Root<CSSStyleDeclaration> {
        reflect_dom_object(box CSSStyleDeclaration::new_inherited(owner,
                                                                  pseudo,
                                                                  modification_access),
                           GlobalRef::Window(global),
                           CSSStyleDeclarationBinding::Wrap)
    }

    fn get_computed_style(&self, property: &Atom) -> Option<DOMString> {
        let node = self.owner.upcast::<Node>();
        if !node.is_in_doc() {
            // TODO: Node should be matched against the style rules of this window.
            // Firefox is currently the only browser to implement this.
            return None;
        }
        let addr = node.to_trusted_node_address();
        window_from_node(&*self.owner).resolved_style_query(addr, self.pseudo.clone(), property)
    }
}

impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
    // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-length
    fn Length(&self) -> u32 {
        let elem = self.owner.upcast::<Element>();
        let len = match *elem.style_attribute().borrow() {
            Some(ref declarations) => declarations.normal.len() + declarations.important.len(),
            None => 0,
        };
        len as u32
    }

    // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-item
    fn Item(&self, index: u32) -> DOMString {
        let index = index as usize;
        let elem = self.owner.upcast::<Element>();
        let style_attribute = elem.style_attribute().borrow();
        let result = style_attribute.as_ref().and_then(|declarations| {
            if index > declarations.normal.len() {
                declarations.important
                            .get(index - declarations.normal.len())
                            .map(|decl| format!("{:?} !important", decl))
            } else {
                declarations.normal
                            .get(index)
                            .map(|decl| format!("{:?}", decl))
            }
        });

        result.map_or(DOMString::new(), DOMString::from)
    }

    // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertyvalue
    fn GetPropertyValue(&self, mut property: DOMString) -> DOMString {
        let owner = &self.owner;

        // Step 1
        property.make_ascii_lowercase();
        let property = Atom::from(property);

        if self.readonly {
            // Readonly style declarations are used for getComputedStyle.
            return self.get_computed_style(&property).unwrap_or(DOMString::new());
        }

        // Step 2
        if let Some(shorthand) = Shorthand::from_name(&property) {
            // Step 2.1
            let mut list = vec![];

            // Step 2.2
            for longhand in shorthand.longhands() {
                // Step 2.2.1
                let declaration = owner.get_inline_style_declaration(&Atom::from(*longhand));

                // Step 2.2.2 & 2.2.3
                match declaration {
                    Some(declaration) => list.push(declaration),
                    None => return DOMString::new(),
                }
            }

            // TODO: important is hardcoded to false because method does not implement it yet
            let serialized_value = shorthand.serialize_shorthand_value_to_string(
                list.iter().map(Deref::deref as fn(_) -> _), false);
            return DOMString::from(serialized_value);
        }

        // Step 3 & 4
        match owner.get_inline_style_declaration(&property) {
            Some(declaration) => DOMString::from(declaration.value()),
            None => DOMString::new(),
        }
    }

    // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-getpropertypriority
    fn GetPropertyPriority(&self, mut property: DOMString) -> DOMString {
        // Step 1
        property.make_ascii_lowercase();
        let property = Atom::from(property);

        // Step 2
        if let Some(shorthand) = Shorthand::from_name(&property) {
            // Step 2.1 & 2.2 & 2.3
            if shorthand.longhands().iter()
                                    .map(|&longhand| self.GetPropertyPriority(DOMString::from(longhand)))
                                    .all(|priority| priority == "important") {
                return DOMString::from("important");
            }
        // Step 3
        } else {
            if self.owner.get_important_inline_style_declaration(&property).is_some() {
                return DOMString::from("important");
            }
        }

        // Step 4
        DOMString::new()
    }

    // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-setproperty
    fn SetProperty(&self,
                   mut property: DOMString,
                   value: DOMString,
                   priority: DOMString)
                   -> ErrorResult {
        // Step 1
        if self.readonly {
            return Err(Error::NoModificationAllowed);
        }

        // Step 2
        property.make_ascii_lowercase();

        // Step 3
        if !is_supported_property(&property) {
            return Ok(());
        }

        // Step 4
        if value.is_empty() {
            return self.RemoveProperty(property).map(|_| ());
        }

        // Step 5
        let priority = match &*priority {
            "" => StylePriority::Normal,
            p if p.eq_ignore_ascii_case("important") => StylePriority::Important,
            _ => return Ok(()),
        };

        // Step 6
        let window = window_from_node(&*self.owner);
        let declarations =
            parse_one_declaration(&property, &value, &window.get_url(), window.css_error_reporter(),
                                  ParserContextExtraData::default());

        // Step 7
        let declarations = if let Ok(declarations) = declarations {
            declarations
        } else {
            return Ok(());
        };

        let element = self.owner.upcast::<Element>();

        // Step 8
        // Step 9
        element.update_inline_style(declarations, priority);

        let node = element.upcast::<Node>();
        node.dirty(NodeDamage::NodeStyleDamaged);
        Ok(())
    }

    // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-setpropertypriority
    fn SetPropertyPriority(&self, property: DOMString, priority: DOMString) -> ErrorResult {
        // Step 1
        if self.readonly {
            return Err(Error::NoModificationAllowed);
        }

        // Step 2 & 3
        if !is_supported_property(&property) {
            return Ok(());
        }

        // Step 4
        let priority = match &*priority {
            "" => StylePriority::Normal,
            p if p.eq_ignore_ascii_case("important") => StylePriority::Important,
            _ => return Ok(()),
        };

        let element = self.owner.upcast::<Element>();

        // Step 5 & 6
        match Shorthand::from_name(&property) {
            Some(shorthand) => {
                element.set_inline_style_property_priority(shorthand.longhands(), priority)
            }
            None => element.set_inline_style_property_priority(&[&*property], priority),
        }

        let node = element.upcast::<Node>();
        node.dirty(NodeDamage::NodeStyleDamaged);
        Ok(())
    }

    // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-setpropertyvalue
    fn SetPropertyValue(&self, property: DOMString, value: DOMString) -> ErrorResult {
        self.SetProperty(property, value, DOMString::new())
    }

    // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-removeproperty
    fn RemoveProperty(&self, mut property: DOMString) -> Fallible<DOMString> {
        // Step 1
        if self.readonly {
            return Err(Error::NoModificationAllowed);
        }

        // Step 2
        property.make_ascii_lowercase();

        // Step 3
        let value = self.GetPropertyValue(property.clone());

        let element = self.owner.upcast::<Element>();

        match Shorthand::from_name(&property) {
            // Step 4
            Some(shorthand) => {
                for longhand in shorthand.longhands() {
                    element.remove_inline_style_property(longhand)
                }
            }
            // Step 5
            None => element.remove_inline_style_property(&property),
        }

        let node = element.upcast::<Node>();
        node.dirty(NodeDamage::NodeStyleDamaged);

        // Step 6
        Ok(value)
    }

    // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-cssfloat
    fn CssFloat(&self) -> DOMString {
        self.GetPropertyValue(DOMString::from("float"))
    }

    // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-cssfloat
    fn SetCssFloat(&self, value: DOMString) -> ErrorResult {
        self.SetPropertyValue(DOMString::from("float"), value)
    }

    // https://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
    fn IndexedGetter(&self, index: u32, found: &mut bool) -> DOMString {
        let rval = self.Item(index);
        *found = index < self.Length();
        rval
    }

    // https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-csstext
    fn CssText(&self) -> DOMString {
        let elem = self.owner.upcast::<Element>();
        let style_attribute = elem.style_attribute().borrow();

        if let Some(declarations) = style_attribute.as_ref() {
            DOMString::from(declarations.to_css_string())
        } else {
            DOMString::new()
        }
    }

    // https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-csstext
    fn SetCssText(&self, value: DOMString) -> ErrorResult {
        let window = window_from_node(self.owner.upcast::<Node>());
        let element = self.owner.upcast::<Element>();

        // Step 1
        if self.readonly {
            return Err(Error::NoModificationAllowed);
        }

        // Step 3
        let decl_block = parse_style_attribute(&value, &window.get_url(), window.css_error_reporter(),
                                               ParserContextExtraData::default());
        *element.style_attribute().borrow_mut() = if decl_block.normal.is_empty() && decl_block.important.is_empty() {
            None // Step 2
        } else {
            Some(decl_block)
        };
        element.sync_property_with_attrs_style();
        let node = element.upcast::<Node>();
        node.dirty(NodeDamage::NodeStyleDamaged);
        Ok(())
    }

    // https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-_camel_cased_attribute
    css_properties_accessors!(css_properties);
}
<|endoftext|>


<commit_before>//! C API extensions to experiment with eager execution of kernels.
//!
//! WARNING: The underlying C-API for the eager execution is not guaranteed to be
//! stable and can be changed without notice, which could result in breaking.

mod context;
pub use context::*;

mod tensor_handle;
pub use tensor_handle::*;

mod op;

pub use op::raw_ops;

use crate::{Result, Tensor, TensorType};

#[cfg(feature = "ndarray")]
use ndarray::{ArrayBase, Data, Dimension};

/// Simple helper trait to convert a Tensor into a TensorHandle for use in eager
/// execution.
pub trait ToTensorHandle<'a> {
    /// Convert the Tensor or TensorHandle into a new TensorHandle.
    ///
    /// _Warning_ : This function may create multiple handles to the same
    /// underlying tensor. Users should be careful not to modify the tensor
    /// after converting it to a handle. Also, users should be careful not
    /// to modify the tensor obtained via the TensorHandle's `resolve` method.
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>>;
}

impl<'a, T> ToTensorHandle<'a> for Tensor<T>
where
    T: TensorType,
{
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        TensorHandle::new(ctx, self)
    }
}

impl<'a> ToTensorHandle<'a> for TensorHandle<'a> {
    fn to_handle(&self, _: &'a Context) -> Result<TensorHandle<'a>> {
        self.copy_sharing_tensor()
    }
}

impl<'a, T: TensorType> ToTensorHandle<'a> for T {
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        let mut tensor = Tensor::<T>::new(&[]);
        tensor[0] = self.clone();
        TensorHandle::new(ctx, &tensor)
    }
}

impl<'a, T: TensorType> ToTensorHandle<'a> for [T] {
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        let mut tensor = Tensor::<T>::new(&[self.len() as u64]);
        for (e, v) in tensor.iter_mut().zip(self) {
            e.clone_from(v);
        }
        TensorHandle::new(ctx, &tensor)
    }
}

#[cfg(feature = "ndarray")]
/// Convert any ndarray::ArrayBase type into a TensorHandle
impl<'a, T, S, D> ToTensorHandle<'a> for ArrayBase<S, D>
where
    T: TensorType,
    S: Data<Elem = T>,
    D: Dimension,
{
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        let dims: Vec<u64> = self.shape().iter().map(|x| *x as u64).collect();
        let mut tensor: Tensor<T> = Tensor::new(&dims);
        for (e, v) in tensor.iter_mut().zip(self.iter()) {
            e.clone_from(v);
        }
        TensorHandle::new(ctx, &tensor)
    }
}
#[cfg(test)]
mod tests {
    use super::*;
    use crate::eager::{Context, ContextOptions};
    use crate::Tensor;

    #[cfg(feature = "ndarray")]
    use ndarray::array;

    #[test]
    fn tensor_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]);
        let handle = tensor.to_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);

        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]);
        let handle = &tensor.to_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);
    }

    #[test]
    fn handle_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]);
        let handle = tensor.to_handle(&ctx).unwrap();
        let handle2 = handle.to_handle(&ctx).unwrap();
        let tensor2: Tensor<i32> = handle2.resolve().unwrap();
        assert_eq!(&tensor[..], &tensor2[..]);
    }

    #[test]
    fn tensortype_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let v = 1i32;
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<i32> = handle.resolve().unwrap();
        assert_eq!(&[v], &tensor[..]);

        let v = 1i64;
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<i64> = handle.resolve().unwrap();
        assert_eq!(&[v], &tensor[..]);

        let v = 1f32;
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<f32> = handle.resolve().unwrap();
        assert_eq!(&[v], &tensor[..]);

        let v = 1f64;
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<f64> = handle.resolve().unwrap();
        assert_eq!(&[v], &tensor[..]);
    }

    #[test]
    fn tarray_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let v = [1i32, 2, 3, 4];
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<i32> = handle.resolve().unwrap();
        assert_eq!(&v, &tensor[..]);

        let v = [1i64, 2, 3, 4];
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<i64> = handle.resolve().unwrap();
        assert_eq!(&v, &tensor[..]);

        let v = [1f32, 2.0, 3.0, 4.0];
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<f32> = handle.resolve().unwrap();
        assert_eq!(&v, &tensor[..]);

        let v = [1f64, 2.0, 3.0, 4.0];
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<f64> = handle.resolve().unwrap();
        assert_eq!(&v, &tensor[..]);
    }

    #[cfg(feature = "ndarray")]
    #[test]
    fn ndarray_to_handle() {
        let a = array![[1i32, 2], [3, 4]];

        let ctx = Context::new(ContextOptions::new()).unwrap();
        let handle = a.to_handle(&ctx).unwrap();
        let tensor: Tensor<i32> = handle.resolve().unwrap();
        assert_eq!(a.as_slice().unwrap(), &tensor[..]);

        let at = Tensor::from(a);
        assert_eq!(at, tensor);
    }
}
<commit_msg>implement trait for generic sized array<commit_after>//! C API extensions to experiment with eager execution of kernels.
//!
//! WARNING: The underlying C-API for the eager execution is not guaranteed to be
//! stable and can be changed without notice, which could result in breaking.

mod context;
pub use context::*;

mod tensor_handle;
pub use tensor_handle::*;

mod op;

pub use op::raw_ops;

use crate::{Result, Tensor, TensorType};

#[cfg(feature = "ndarray")]
use ndarray::{ArrayBase, Data, Dimension};

/// Simple helper trait to convert a Tensor into a TensorHandle for use in eager
/// execution.
pub trait ToTensorHandle<'a> {
    /// Convert the Tensor or TensorHandle into a new TensorHandle.
    ///
    /// _Warning_ : This function may create multiple handles to the same
    /// underlying tensor. Users should be careful not to modify the tensor
    /// after converting it to a handle. Also, users should be careful not
    /// to modify the tensor obtained via the TensorHandle's `resolve` method.
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>>;
}

impl<'a, T> ToTensorHandle<'a> for Tensor<T>
where
    T: TensorType,
{
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        TensorHandle::new(ctx, self)
    }
}

impl<'a> ToTensorHandle<'a> for TensorHandle<'a> {
    fn to_handle(&self, _: &'a Context) -> Result<TensorHandle<'a>> {
        self.copy_sharing_tensor()
    }
}

impl<'a, T: TensorType> ToTensorHandle<'a> for T {
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        let mut tensor = Tensor::<T>::new(&[]);
        tensor[0] = self.clone();
        TensorHandle::new(ctx, &tensor)
    }
}

impl<'a, T: TensorType> ToTensorHandle<'a> for [T] {
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        let mut tensor = Tensor::<T>::new(&[self.len() as u64]);
        for (e, v) in tensor.iter_mut().zip(self) {
            e.clone_from(v);
        }
        TensorHandle::new(ctx, &tensor)
    }
}

impl<'a, T: TensorType, const N: usize> ToTensorHandle<'a> for [T; N] {
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        let tensor = Tensor::from(&self[..]);
        TensorHandle::new(ctx, &tensor)
    }
}

#[cfg(feature = "ndarray")]
/// Convert any ndarray::ArrayBase type into a TensorHandle
impl<'a, T, S, D> ToTensorHandle<'a> for ArrayBase<S, D>
where
    T: TensorType,
    S: Data<Elem = T>,
    D: Dimension,
{
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        let dims: Vec<u64> = self.shape().iter().map(|x| *x as u64).collect();
        let mut tensor: Tensor<T> = Tensor::new(&dims);
        for (e, v) in tensor.iter_mut().zip(self.iter()) {
            e.clone_from(v);
        }
        TensorHandle::new(ctx, &tensor)
    }
}
#[cfg(test)]
mod tests {
    use super::*;
    use crate::eager::{Context, ContextOptions};
    use crate::Tensor;

    #[cfg(feature = "ndarray")]
    use ndarray::array;

    #[test]
    fn tensor_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]);
        let handle = tensor.to_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);

        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]);
        let handle = &tensor.to_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);
    }

    #[test]
    fn handle_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]);
        let handle = tensor.to_handle(&ctx).unwrap();
        let handle2 = handle.to_handle(&ctx).unwrap();
        let tensor2: Tensor<i32> = handle2.resolve().unwrap();
        assert_eq!(&tensor[..], &tensor2[..]);
    }

    #[test]
    fn tensortype_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let v = 1i32;
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<i32> = handle.resolve().unwrap();
        assert_eq!(&[v], &tensor[..]);

        let v = 1i64;
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<i64> = handle.resolve().unwrap();
        assert_eq!(&[v], &tensor[..]);

        let v = 1f32;
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<f32> = handle.resolve().unwrap();
        assert_eq!(&[v], &tensor[..]);

        let v = 1f64;
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<f64> = handle.resolve().unwrap();
        assert_eq!(&[v], &tensor[..]);
    }

    #[test]
    fn tarray_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let v = [1i32, 2, 3, 4];
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<i32> = handle.resolve().unwrap();
        assert_eq!(&v, &tensor[..]);

        let v = [1i64, 2, 3, 4];
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<i64> = handle.resolve().unwrap();
        assert_eq!(&v, &tensor[..]);

        let v = [1f32, 2.0, 3.0, 4.0];
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<f32> = handle.resolve().unwrap();
        assert_eq!(&v, &tensor[..]);

        let v = [1f64, 2.0, 3.0, 4.0];
        let handle = v.to_handle(&ctx).unwrap();
        let tensor: Tensor<f64> = handle.resolve().unwrap();
        assert_eq!(&v, &tensor[..]);
    }

    #[cfg(feature = "ndarray")]
    #[test]
    fn ndarray_to_handle() {
        let a = array![[1i32, 2], [3, 4]];

        let ctx = Context::new(ContextOptions::new()).unwrap();
        let handle = a.to_handle(&ctx).unwrap();
        let tensor: Tensor<i32> = handle.resolve().unwrap();
        assert_eq!(a.as_slice().unwrap(), &tensor[..]);

        let at = Tensor::from(a);
        assert_eq!(at, tensor);
    }
}
<|endoftext|>


<commit_before>use graphics::*;

// Local crate.
use Vector2d = vector2d::Vector2d;

static EPSILON: f64 = 0.0000000001;

pub fn area(contour: &[Vector2d]) -> f64 {
    let n = contour.len();
    let mut A = 0.0_f64;

    for i in range(0, n) {
        let q = i;
        let p = (i + n - 1) % n;
        A += contour.get(p).unwrap().get_x() * contour.get(q).unwrap().get_y()
            - contour.get(q).unwrap().get_x() * contour.get(p).unwrap().get_y();
    }

    A * 0.5_f64
}

/// InsideTriangle decides if a point P is Inside of the triangle
/// defined by A, B, C.
pub fn inside_triangle(
    Ax: f64, Ay: f64,
    Bx: f64, By: f64,
    Cx: f64, Cy: f64,
    Px: f64, Py: f64
) -> bool {

    let ax = Cx - Bx;
    let ay = Cy - By;
    let bx = Ax - Cx;
    let by = Ay - Cy;
    let cx = Bx - Ax;
    let cy = By - Ay;
    let apx = Px - Ax;
    let apy = Py - Ay;
    let bpx = Px - Bx;
    let bpy = Py - By;
    let cpx = Px - Cx;
    let cpy = Py - Cy;

    let aCROSSbp = ax*bpy - ay*bpx;
    let cCROSSap = cx*apy - cy*apx;
    let bCROSScp = bx*cpy - by*cpx;

    (
        (aCROSSbp >= 0.0_f64)
        && (bCROSScp >= 0.0_f64)
        && (cCROSSap >= 0.0_f64)
    )
}

pub fn snip(
    contour: &[Vector2d],
    triangle: [uint, ..3],
    n: uint,
    V: &mut Vec<uint>
) -> bool {
    let u = triangle[0];
    let v = triangle[1];
    let w = triangle[2];

    let Ax = contour.get(*V.get(u)).unwrap().get_x();
    let Ay = contour.get(*V.get(u)).unwrap().get_y();

    let Bx = contour.get(*V.get(v)).unwrap().get_x();
    let By = contour.get(*V.get(v)).unwrap().get_y();

    let Cx = contour.get(*V.get(w)).unwrap().get_x();
    let Cy = contour.get(*V.get(w)).unwrap().get_y();

    if EPSILON > (((Bx-Ax)*(Cy-Ay)) - ((By-Ay)*(Cx-Ax))) {
        return false;
    }

    for p in range(0, n) {
        if (p == u) || (p == v) || (p == w) { continue; }

        let Px = contour.get(*V.get(p)).unwrap().get_x();
        let Py = contour.get(*V.get(p)).unwrap().get_y();

        if inside_triangle(Ax,Ay,Bx,By,Cx,Cy,Px,Py) { return false; }
    }

    return true;
}

pub fn process(
    contour: &[Vector2d]
) -> Option<Vec<Vector2d>> {
    /* allocate and initialize list of Vertices in polygon */

    let n = contour.len();
    if n < 3 { return None; }

    let mut result: Vec<Vector2d> = Vec::new();
    let mut vertex_indices: Vec<uint> = Vec::with_capacity(n);

    /* we want a counter-clockwise polygon in V */

    // Computes the area which has opposite signs
    // whether the polygon is clock-wise or counter-clockwise.
    if 0.0_f64 < area(contour) {
        for v in range(0, n) { vertex_indices.push(v); }
    } else {
        for v in range(0, n) { vertex_indices.push((n-1)-v); }
    }

    let mut number_of_vertices = n;

    /*  remove nv-2 Vertices, creating 1 triangle every time */
    let mut count = 2 * number_of_vertices;   /* error detection */

    let mut v = number_of_vertices - 1;
    while number_of_vertices > 2 {
        /* if we loop, it is probably a non-simple polygon */
        if count <= 0 {
            //** Triangulate: ERROR - probable bad polygon!
            return None;
        }

        count -= 1;

        /* three consecutive vertices in current polygon, <u,v,w> */
        let triangle = [
            v,
            vecmath::modular_offset_index(number_of_vertices, v, 1),
            vecmath::modular_offset_index(number_of_vertices, v, 2)
        ];
        v = triangle[1];

        if snip(contour, triangle, number_of_vertices, &mut vertex_indices) {
            for &i in triangle.iter() {
                result.push(*contour.get(*vertex_indices.get(i)).unwrap());
            }

            /* remove v from remaining polygon */
            for i in range(0, number_of_vertices - 3) {
                let s = v + i;
                let t = v + i + 1;

                *vertex_indices.get_mut(s) = *vertex_indices.get(t);
            }

            // "Removed" a vertex.
            number_of_vertices -= 1;

            /* resest error detection counter */
            count = 2 * number_of_vertices;
        }
    }

    Some(result)
}

<commit_msg>Added comment<commit_after>use graphics::*;

// Local crate.
use Vector2d = vector2d::Vector2d;

static EPSILON: f64 = 0.0000000001;

pub fn area(contour: &[Vector2d]) -> f64 {
    let n = contour.len();
    let mut A = 0.0_f64;

    for i in range(0, n) {
        let q = i;
        let p = (i + n - 1) % n;
        A += contour.get(p).unwrap().get_x() * contour.get(q).unwrap().get_y()
            - contour.get(q).unwrap().get_x() * contour.get(p).unwrap().get_y();
    }

    A * 0.5_f64
}

/// InsideTriangle decides if a point P is Inside of the triangle
/// defined by A, B, C.
pub fn inside_triangle(
    Ax: f64, Ay: f64,
    Bx: f64, By: f64,
    Cx: f64, Cy: f64,
    Px: f64, Py: f64
) -> bool {

    let ax = Cx - Bx;
    let ay = Cy - By;
    let bx = Ax - Cx;
    let by = Ay - Cy;
    let cx = Bx - Ax;
    let cy = By - Ay;
    let apx = Px - Ax;
    let apy = Py - Ay;
    let bpx = Px - Bx;
    let bpy = Py - By;
    let cpx = Px - Cx;
    let cpy = Py - Cy;

    let aCROSSbp = ax*bpy - ay*bpx;
    let cCROSSap = cx*apy - cy*apx;
    let bCROSScp = bx*cpy - by*cpx;

    (
        (aCROSSbp >= 0.0_f64)
        && (bCROSScp >= 0.0_f64)
        && (cCROSSap >= 0.0_f64)
    )
}

pub fn snip(
    contour: &[Vector2d],
    triangle: [uint, ..3],
    n: uint,
    V: &mut Vec<uint>
) -> bool {
    let u = triangle[0];
    let v = triangle[1];
    let w = triangle[2];

    let Ax = contour.get(*V.get(u)).unwrap().get_x();
    let Ay = contour.get(*V.get(u)).unwrap().get_y();

    let Bx = contour.get(*V.get(v)).unwrap().get_x();
    let By = contour.get(*V.get(v)).unwrap().get_y();

    let Cx = contour.get(*V.get(w)).unwrap().get_x();
    let Cy = contour.get(*V.get(w)).unwrap().get_y();

    if EPSILON > (((Bx-Ax)*(Cy-Ay)) - ((By-Ay)*(Cx-Ax))) {
        return false;
    }

    for p in range(0, n) {
        if (p == u) || (p == v) || (p == w) { continue; }

        let Px = contour.get(*V.get(p)).unwrap().get_x();
        let Py = contour.get(*V.get(p)).unwrap().get_y();

        if inside_triangle(Ax,Ay,Bx,By,Cx,Cy,Px,Py) { return false; }
    }

    return true;
}

pub fn process(
    contour: &[Vector2d]
) -> Option<Vec<Vector2d>> {
    /* allocate and initialize list of Vertices in polygon */

    let n = contour.len();
    if n < 3 { return None; }

    let mut result: Vec<Vector2d> = Vec::new();
    let mut vertex_indices: Vec<uint> = Vec::with_capacity(n);

    /* we want a counter-clockwise polygon in V */

    // Computes the area which has opposite signs
    // whether the polygon is clock-wise or counter-clockwise.
    if 0.0_f64 < area(contour) {
        for v in range(0, n) { vertex_indices.push(v); }
    } else {
        for v in range(0, n) { vertex_indices.push((n-1)-v); }
    }

    let mut number_of_vertices = n;

    /*  remove nv-2 Vertices, creating 1 triangle every time */

    // Used for error detection.
    let mut count = 2 * number_of_vertices;

    let mut v = number_of_vertices - 1;
    while number_of_vertices > 2 {
        /* if we loop, it is probably a non-simple polygon */
        if count <= 0 {
            //** Triangulate: ERROR - probable bad polygon!
            return None;
        }

        count -= 1;

        /* three consecutive vertices in current polygon, <u,v,w> */
        let triangle = [
            v,
            vecmath::modular_offset_index(number_of_vertices, v, 1),
            vecmath::modular_offset_index(number_of_vertices, v, 2)
        ];
        v = triangle[1];

        if snip(contour, triangle, number_of_vertices, &mut vertex_indices) {
            for &i in triangle.iter() {
                result.push(*contour.get(*vertex_indices.get(i)).unwrap());
            }

            /* remove v from remaining polygon */
            for i in range(0, number_of_vertices - 3) {
                let s = v + i;
                let t = v + i + 1;

                *vertex_indices.get_mut(s) = *vertex_indices.get(t);
            }

            // "Removed" a vertex.
            number_of_vertices -= 1;

            /* resest error detection counter */
            count = 2 * number_of_vertices;
        }
    }

    Some(result)
}

<|endoftext|>


<commit_before>use std::fmt;
use std::error;
use nom::{Err, Needed};

#[derive(PartialEq, Debug, Clone)]
pub enum Error {
    ParseError(String),
    ParseIncomplete(String),
    GenerateError(String),
    RecursionLimit(String),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::ParseError(ref s) => write!(f, "{}", s),
            Error::ParseIncomplete(ref s) => write!(f, "{}", s),
            Error::GenerateError(ref s) => write!(f, "{}", s),
            Error::RecursionLimit(ref s) => write!(f, "{}", s),
        }
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        "BNF error"
    }
}

impl<'a> From<Err<&'a [u8]>> for Error {
    fn from(err: Err<&[u8]>) -> Self {
        let string = match err {
            Err::Code(_) => String::from("Parsing error: Unknown origin"),
            Err::Node(_, n) => {
                n.iter().fold(
                    String::from("Parsing error: Unknown origin."),
                    |s, e| s + &format!(" {}", e),
                )
            }
            Err::Position(_, p) => {
                format!(
                    "Parsing error: When input is {}",
                    String::from_utf8_lossy(p)
                )
            }
            Err::NodePosition(_, p, n) => {
                n.iter().fold(
                    format!(
                        "Parsing error: When input is {}.",
                        String::from_utf8_lossy(p)
                    ),
                    |s, e| s + &format!(" {}", e),
                )
            }
        };

        Error::ParseError(string)
    }
}

impl From<Needed> for Error {
    fn from(needed: Needed) -> Self {
        let string = match needed {
            Needed::Unknown => format!("Data error: insufficient size, expectation unknown"),
            Needed::Size(s) => format!("Data error: insufficient size, expected {} bytes", s),
        };

        Error::ParseIncomplete(string)
    }
}

#[cfg(test)]
mod tests {
    use nom::IResult;
    use error::Error;

    named!(
        give_error_kind,
        do_parse!(
            tag!("1234") >>
            res: tag!("5678") >>
            (res)
        )
    );

    #[test]
    fn gets_error_error() {
        let nom_result = give_error_kind("12340".as_bytes());
        let nom_error;
        match nom_result {
            IResult::Error(e) => nom_error = e,
            _ => panic!("gets_error_error should result in IResult::Error"),
        }

        let bnf_error: Result<String, Error> = Err(Error::from(nom_error));

        assert!(
            bnf_error.is_err(),
            "production result should be error {:?}",
            bnf_error
        );

        match bnf_error.unwrap_err() {
            Error::ParseError(_) => (),
            e => panic!("production error should be error parsing: {:?}", e),
        }
    }

    #[test]
    fn gets_error_incomplete() {
        let nom_result = give_error_kind("".as_bytes());
        let nom_error;
        match nom_result {
            IResult::Incomplete(e) => nom_error = e,
            _ => panic!("gets_error_error should result in IResult::Error"),
        }

        let bnf_error: Result<String, Error> = Err(Error::from(nom_error));

        assert!(
            bnf_error.is_err(),
            "production result should be error {:?}",
            bnf_error
        );
        match bnf_error.unwrap_err() {
            Error::ParseIncomplete(_) => (),
            e => panic!("production error should be incomplete: {:?}", e),
        }
    }

    #[test]
    fn uses_error_recursion_limit() {
        let bnf_error = Error::RecursionLimit(String::from("reucrsion limit reached!"));
        match bnf_error {
            Error::RecursionLimit(_) => (),
            e => panic!("should match on reursion limit: {:?}", e),
        }
    }

    #[test]
    fn uses_error_generate() {
        let bnf_error = Error::GenerateError(String::from("error generating!"));
        match bnf_error {
            Error::GenerateError(_) => (),
            e => panic!("should match on generate error: {:?}", e),
        }
    }
}
<commit_msg>filling in tests on uncovered LOC<commit_after>use std::fmt;
use std::error;
use nom::{Err, Needed};

#[derive(PartialEq, Debug, Clone)]
pub enum Error {
    ParseError(String),
    ParseIncomplete(String),
    GenerateError(String),
    RecursionLimit(String),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::ParseError(ref s) => write!(f, "{}", s),
            Error::ParseIncomplete(ref s) => write!(f, "{}", s),
            Error::GenerateError(ref s) => write!(f, "{}", s),
            Error::RecursionLimit(ref s) => write!(f, "{}", s),
        }
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        "BNF error"
    }
}

impl<'a> From<Err<&'a [u8]>> for Error {
    fn from(err: Err<&[u8]>) -> Self {
        let string = match err {
            Err::Code(_) => String::from("Parsing error: Unknown origin"),
            Err::Node(_, n) => {
                n.iter().fold(
                    String::from("Parsing error: Unknown origin."),
                    |s, e| s + &format!(" {}", e),
                )
            }
            Err::Position(_, p) => {
                format!(
                    "Parsing error: When input is {}",
                    String::from_utf8_lossy(p)
                )
            }
            Err::NodePosition(_, p, n) => {
                n.iter().fold(
                    format!(
                        "Parsing error: When input is {}.",
                        String::from_utf8_lossy(p)
                    ),
                    |s, e| s + &format!(" {}", e),
                )
            }
        };

        Error::ParseError(string)
    }
}

impl From<Needed> for Error {
    fn from(needed: Needed) -> Self {
        let string = match needed {
            Needed::Unknown => format!("Data error: insufficient size, expectation unknown"),
            Needed::Size(s) => format!("Data error: insufficient size, expected {} bytes", s),
        };

        Error::ParseIncomplete(string)
    }
}

#[cfg(test)]
mod tests {
    use nom::IResult;
    use error::Error;

    named!(
        give_error_kind,
        do_parse!(
            tag!("1234") >>
            res: tag!("5678") >>
            (res)
        )
    );

    #[test]
    fn gets_error_error() {
        let nom_result = give_error_kind("12340".as_bytes());
        let nom_error;
        match nom_result {
            IResult::Error(e) => nom_error = e,
            _ => panic!("gets_error_error should result in IResult::Error"),
        }

        let bnf_error: Result<String, Error> = Err(Error::from(nom_error));

        assert!(
            bnf_error.is_err(),
            "production result should be error {:?}",
            bnf_error
        );

        match bnf_error.unwrap_err() {
            Error::ParseError(_) => (),
            e => panic!("production error should be error parsing: {:?}", e),
        }
    }

    #[test]
    fn gets_error_incomplete() {
        let nom_result = give_error_kind("".as_bytes());
        let nom_error;
        match nom_result {
            IResult::Incomplete(e) => nom_error = e,
            _ => panic!("gets_error_error should result in IResult::Error"),
        }

        let bnf_error: Result<String, Error> = Err(Error::from(nom_error));

        assert!(
            bnf_error.is_err(),
            "production result should be error {:?}",
            bnf_error
        );
        match bnf_error.unwrap_err() {
            Error::ParseIncomplete(_) => (),
            e => panic!("production error should be incomplete: {:?}", e),
        }
    }

    #[test]
    fn uses_error_recursion_limit() {
        let bnf_error = Error::RecursionLimit(String::from("reucrsion limit reached!"));
        match bnf_error {
            Error::RecursionLimit(_) => (),
            e => panic!("should match on reursion limit: {:?}", e),
        }
    }

    #[test]
    fn uses_error_generate() {
        let bnf_error = Error::GenerateError(String::from("error generating!"));
        match bnf_error {
            Error::GenerateError(_) => (),
            e => panic!("should match on generate error: {:?}", e),
        }
    }

    #[test]
    fn test_error_display() {
        let parse_error = Error::ParseError(String::from("syntax error!"));
        let incomplete_error = Error::ParseIncomplete(String::from("incomplete data size!"));
        let generate_error = Error::GenerateError(String::from("error generating!"));
        let recursion_error = Error::RecursionLimit(String::from("recursion limit reached!"));

        assert_eq!(parse_error.to_string(), String::from("syntax error!"));
        assert_eq!(
            incomplete_error.to_string(),
            String::from("incomplete data size!")
        );
        assert_eq!(
            generate_error.to_string(),
            String::from("error generating!")
        );
        assert_eq!(
            recursion_error.to_string(),
            String::from("recursion limit reached!")
        );

    }

}
<|endoftext|>