<commit_before>#![deny(warnings)]
use cases::case::*;
/// Converts a `String` to `Title Case` `String`
///
/// ```
///     use inflector::cases::titlecase::to_title_case;
///     let mock_string: String = "Foo bar".to_string();
///     let expected_string: String = "Foo Bar".to_string();
///     let asserted_string: String = to_title_case(mock_string);
///     assert!(asserted_string == expected_string);
///
/// ```
/// ```
///     use inflector::cases::titlecase::to_title_case;
///     let mock_string: String = "FooBar".to_string();
///     let expected_string: String = "Foo Bar".to_string();
///     let asserted_string: String = to_title_case(mock_string);
///     assert!(asserted_string == expected_string);
///
/// ```
/// ```
///     use inflector::cases::titlecase::to_title_case;
///     let mock_string: String = "fooBar".to_string();
///     let expected_string: String = "Foo Bar".to_string();
///     let asserted_string: String = to_title_case(mock_string);
///     assert!(asserted_string == expected_string);
///
/// ```
/// ```
///     use inflector::cases::titlecase::to_title_case;
///     let mock_string: String = "FOO_BAR".to_string();
///     let expected_string: String = "Foo Bar".to_string();
///     let asserted_string: String = to_title_case(mock_string);
///     assert!(asserted_string == expected_string);
///
/// ```
/// ```
///     use inflector::cases::titlecase::to_title_case;
///     let mock_string: String = "foo_bar".to_string();
///     let expected_string: String = "Foo Bar".to_string();
///     let asserted_string: String = to_title_case(mock_string);
///     assert!(asserted_string == expected_string);
///
/// ```
/// ```
///     use inflector::cases::titlecase::to_title_case;
///     let mock_string: String = "foo-bar".to_string();
///     let expected_string: String = "Foo Bar".to_string();
///     let asserted_string: String = to_title_case(mock_string);
///     assert!(asserted_string == expected_string);
///
/// ```
pub fn to_title_case(non_title_case_string: String) -> String {
    let mut new_word: bool = true;
    let mut first_word: bool = true;
    let mut last_char: char = ' ';
    non_title_case_string
        .chars()
        .fold("".to_string(), |mut result, character|
            if character == '-' || character == '_' || character == ' ' {
                new_word = true;
                result
            } else if character.is_numeric() {
                new_word = true;
                result.push(character);
                result
            } else if new_word || (
                (last_char.is_lowercase() && character.is_uppercase()) &&
                (last_char != ' ')
                ){
                new_word = false;
                if !first_word {
                    result.push(' ');
                }
                first_word = false;
                result.push(character.to_ascii_uppercase());
                result
            } else {
                last_char = character;
                result.push(character.to_ascii_lowercase());
                result
            }
        )
}
/// Determines if a `String` is `Title Case`
///
/// #Examples
/// ```
///     use inflector::cases::titlecase::is_title_case;
///     let mock_string: String = "foo-bar-string-that-is-really-really-long".to_string();
///     let asserted_bool: bool = is_title_case(mock_string);
///     assert!(asserted_bool == false);
///
/// ```
/// ```
///     use inflector::cases::titlecase::is_title_case;
///     let mock_string: String = "FooBarIsAReallyReallyLongString".to_string();
///     let asserted_bool: bool = is_title_case(mock_string);
///     assert!(asserted_bool == false);
///
/// ```
/// ```
///     use inflector::cases::titlecase::is_title_case;
///     let mock_string: String = "fooBarIsAReallyReallyLongString".to_string();
///     let asserted_bool: bool = is_title_case(mock_string);
///     assert!(asserted_bool == false);
///
/// ```
/// ```
///     use inflector::cases::titlecase::is_title_case;
///     let mock_string: String = "FOO_BAR_STRING_THAT_IS_REALLY_REALLY_LONG".to_string();
///     let asserted_bool: bool = is_title_case(mock_string);
///     assert!(asserted_bool == false);
///
/// ```
/// ```
///     use inflector::cases::titlecase::is_title_case;
///     let mock_string: String = "foo_bar_string_that_is_really_really_long".to_string();
///     let asserted_bool: bool = is_title_case(mock_string);
///     assert!(asserted_bool == false);
///
/// ```
/// ```
///     use inflector::cases::titlecase::is_title_case;
///     let mock_string: String = "Foo bar string that is really really long".to_string();
///     let asserted_bool: bool = is_title_case(mock_string);
///     assert!(asserted_bool == false);
///
/// ```
/// ```
///     use inflector::cases::titlecase::is_title_case;
///     let mock_string: String = "foo".to_string();
///     let asserted_bool: bool = is_title_case(mock_string);
///     assert!(asserted_bool == false);
///
/// ```
/// ```
///     use inflector::cases::titlecase::is_title_case;
///     let mock_string: String = "Foo Bar String That Is Really Really Long".to_string();
///     let asserted_bool: bool = is_title_case(mock_string);
///     assert!(asserted_bool == true);
///
/// ```
pub fn is_title_case(test_string: String) -> bool {
    test_string == to_title_case(test_string.clone())
}

#[cfg(all(feature = "unstable", test))]
mod tests {
    extern crate test;
    use self::test::Bencher;

    #[bench]
    fn bench_title(b: &mut Bencher) {
        b.iter(|| super::to_title_case("Foo BAR".to_string()));
    }

    #[bench]
    fn bench_is_title(b: &mut Bencher) {
        b.iter(|| super::is_title_case("Foo bar".to_string()));
    }

    #[bench]
    fn bench_title_from_snake(b: &mut Bencher) {
        b.iter(|| super::to_title_case("foo_bar".to_string()));
    }
}

#[cfg(test)]
mod title_tests{
    use ::cases::titlecase::to_title_case;
    define_tests![
        to_title_case;
        test_camel_case_to_title_case=>             "fooBar"    => "Foo Bar",
        test_class_case_to_title_case =>            "FooBar"    => "Foo Bar",
        test_screaming_snake_case_to_title_case =>  "FOO_BAR"   => "Foo Bar",
        test_kebab_case_to_title_case =>            "foo-bar"   => "Foo Bar",
        test_pascal_case_to_title_case =>           "FooBar"    => "Foo Bar",
        test_sentence_case_to_title_case =>         "Foo bar"   => "Foo Bar",
        test_snake_case_to_title_case =>            "foo_bar"   => "Foo Bar",
        test_title_case_to_title_case =>            "Foo Bar"   => "Foo Bar",
        test_table_case_to_title_case =>            "foo_bars"  => "Foo Bars",
        test_train_case_to_title_case =>            "Foo-Bars"  => "Foo Bars"
    ];
}
<commit_msg>Unified titlecase with the other cases<commit_after>#![deny(warnings)]
use cases::case::*;
/// Converts a `String` to `Title Case` `String`
///
/// ```
///     use inflector::cases::titlecase::to_title_case;
///     let mock_string: String = "Foo bar".to_string();
///     let expected_string: String = "Foo Bar".to_string();
///     let asserted_string: String = to_title_case(mock_string);
///     assert!(asserted_string == expected_string);
///
/// ```
/// ```
///     use inflector::cases::titlecase::to_title_case;
///     let mock_string: String = "FooBar".to_string();
///     let expected_string: String = "Foo Bar".to_string();
///     let asserted_string: String = to_title_case(mock_string);
///     assert!(asserted_string == expected_string);
///
/// ```
/// ```
///     use inflector::cases::titlecase::to_title_case;
///     let mock_string: String = "fooBar".to_string();
///     let expected_string: String = "Foo Bar".to_string();
///     let asserted_string: String = to_title_case(mock_string);
///     assert!(asserted_string == expected_string);
///
/// ```
/// ```
///     use inflector::cases::titlecase::to_title_case;
///     let mock_string: String = "FOO_BAR".to_string();
///     let expected_string: String = "Foo Bar".to_string();
///     let asserted_string: String = to_title_case(mock_string);
///     assert!(asserted_string == expected_string);
///
/// ```
/// ```
///     use inflector::cases::titlecase::to_title_case;
///     let mock_string: String = "foo_bar".to_string();
///     let expected_string: String = "Foo Bar".to_string();
///     let asserted_string: String = to_title_case(mock_string);
///     assert!(asserted_string == expected_string);
///
/// ```
/// ```
///     use inflector::cases::titlecase::to_title_case;
///     let mock_string: String = "foo-bar".to_string();
///     let expected_string: String = "Foo Bar".to_string();
///     let asserted_string: String = to_title_case(mock_string);
///     assert!(asserted_string == expected_string);
///
/// ```
pub fn to_title_case(non_title_case_string: String) -> String {
    let options = CamelOptions {
        new_word: true,
        last_char: ' ',
        first_word: true,
        injectable_char: ' ',
        has_seperator: true
    };
    to_case_camel_like(non_title_case_string, options)
}

/// Determines if a `String` is `Title Case`
///
/// ```
///     use inflector::cases::titlecase::is_title_case;
///     let mock_string: String = "foo-bar-string-that-is-really-really-long".to_string();
///     let asserted_bool: bool = is_title_case(mock_string);
///     assert!(asserted_bool == false);
///
/// ```
/// ```
///     use inflector::cases::titlecase::is_title_case;
///     let mock_string: String = "FooBarIsAReallyReallyLongString".to_string();
///     let asserted_bool: bool = is_title_case(mock_string);
///     assert!(asserted_bool == false);
///
/// ```
/// ```
///     use inflector::cases::titlecase::is_title_case;
///     let mock_string: String = "fooBarIsAReallyReallyLongString".to_string();
///     let asserted_bool: bool = is_title_case(mock_string);
///     assert!(asserted_bool == false);
///
/// ```
/// ```
///     use inflector::cases::titlecase::is_title_case;
///     let mock_string: String = "FOO_BAR_STRING_THAT_IS_REALLY_REALLY_LONG".to_string();
///     let asserted_bool: bool = is_title_case(mock_string);
///     assert!(asserted_bool == false);
///
/// ```
/// ```
///     use inflector::cases::titlecase::is_title_case;
///     let mock_string: String = "foo_bar_string_that_is_really_really_long".to_string();
///     let asserted_bool: bool = is_title_case(mock_string);
///     assert!(asserted_bool == false);
///
/// ```
/// ```
///     use inflector::cases::titlecase::is_title_case;
///     let mock_string: String = "Foo bar string that is really really long".to_string();
///     let asserted_bool: bool = is_title_case(mock_string);
///     assert!(asserted_bool == false);
///
/// ```
/// ```
///     use inflector::cases::titlecase::is_title_case;
///     let mock_string: String = "foo".to_string();
///     let asserted_bool: bool = is_title_case(mock_string);
///     assert!(asserted_bool == false);
///
/// ```
/// ```
///     use inflector::cases::titlecase::is_title_case;
///     let mock_string: String = "Foo Bar String That Is Really Really Long".to_string();
///     let asserted_bool: bool = is_title_case(mock_string);
///     assert!(asserted_bool == true);
///
/// ```
pub fn is_title_case(test_string: String) -> bool {
    test_string == to_title_case(test_string.clone())
}

#[cfg(all(feature = "unstable", test))]
mod tests {
    extern crate test;
    use self::test::Bencher;

    #[bench]
    fn bench_title(b: &mut Bencher) {
        b.iter(|| super::to_title_case("Foo BAR".to_string()));
    }

    #[bench]
    fn bench_is_title(b: &mut Bencher) {
        b.iter(|| super::is_title_case("Foo bar".to_string()));
    }

    #[bench]
    fn bench_title_from_snake(b: &mut Bencher) {
        b.iter(|| super::to_title_case("foo_bar".to_string()));
    }
}

#[cfg(test)]
mod title_tests{
    use ::cases::titlecase::to_title_case;
    define_tests![
        to_title_case;
        test_camel_case_to_title_case=>             "fooBar"    => "Foo Bar",
        test_class_case_to_title_case =>            "FooBar"    => "Foo Bar",
        test_screaming_snake_case_to_title_case =>  "FOO_BAR"   => "Foo Bar",
        test_kebab_case_to_title_case =>            "foo-bar"   => "Foo Bar",
        test_pascal_case_to_title_case =>           "FooBar"    => "Foo Bar",
        test_sentence_case_to_title_case =>         "Foo bar"   => "Foo Bar",
        test_snake_case_to_title_case =>            "foo_bar"   => "Foo Bar",
        test_title_case_to_title_case =>            "Foo Bar"   => "Foo Bar",
        test_table_case_to_title_case =>            "foo_bars"  => "Foo Bars",
        test_train_case_to_title_case =>            "Foo-Bars"  => "Foo Bars"
    ];
}
<|endoftext|>


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

use std::iter::FromIterator;

/// A very simple BitVector type.
#[derive(Clone, Debug, PartialEq)]
pub struct BitVector {
    data: Vec<u64>,
}

impl BitVector {
    pub fn new(num_bits: usize) -> BitVector {
        let num_words = u64s(num_bits);
        BitVector { data: vec![0; num_words] }
    }

    pub fn clear(&mut self) {
        for p in &mut self.data {
            *p = 0;
        }
    }

    pub fn contains(&self, bit: usize) -> bool {
        let (word, mask) = word_mask(bit);
        (self.data[word] & mask) != 0
    }

    /// Returns true if the bit has changed.
    pub fn insert(&mut self, bit: usize) -> bool {
        let (word, mask) = word_mask(bit);
        let data = &mut self.data[word];
        let value = *data;
        let new_value = value | mask;
        *data = new_value;
        new_value != value
    }

    pub fn insert_all(&mut self, all: &BitVector) -> bool {
        assert!(self.data.len() == all.data.len());
        let mut changed = false;
        for (i, j) in self.data.iter_mut().zip(&all.data) {
            let value = *i;
            *i = value | *j;
            if value != *i {
                changed = true;
            }
        }
        changed
    }

    pub fn grow(&mut self, num_bits: usize) {
        let num_words = u64s(num_bits);
        if self.data.len() < num_words {
            self.data.resize(num_words, 0)
        }
    }

    /// Iterates over indexes of set bits in a sorted order
    pub fn iter<'a>(&'a self) -> BitVectorIter<'a> {
        BitVectorIter {
            iter: self.data.iter(),
            current: 0,
            idx: 0,
        }
    }
}

pub struct BitVectorIter<'a> {
    iter: ::std::slice::Iter<'a, u64>,
    current: u64,
    idx: usize,
}

impl<'a> Iterator for BitVectorIter<'a> {
    type Item = usize;
    fn next(&mut self) -> Option<usize> {
        while self.current == 0 {
            self.current = if let Some(&i) = self.iter.next() {
                if i == 0 {
                    self.idx += 64;
                    continue;
                } else {
                    self.idx = u64s(self.idx) * 64;
                    i
                }
            } else {
                return None;
            }
        }
        let offset = self.current.trailing_zeros() as usize;
        self.current >>= offset;
        self.current >>= 1; // shift otherwise overflows for 0b1000_0000_…_0000
        self.idx += offset + 1;
        return Some(self.idx - 1);
    }
}

impl FromIterator<bool> for BitVector {
    fn from_iter<I>(iter: I) -> BitVector where I: IntoIterator<Item=bool> {
        let iter = iter.into_iter();
        let (len, _) = iter.size_hint();
        // Make the minimum length for the bitvector 64 bits since that's
        // the smallest non-zero size anyway.
        let len = if len < 64 { 64 } else { len };
        let mut bv = BitVector::new(len);
        for (idx, val) in iter.enumerate() {
            if idx > len {
                bv.grow(idx);
            }
            if val {
                bv.insert(idx);
            }
        }

        bv
    }
}

/// A "bit matrix" is basically a matrix of booleans represented as
/// one gigantic bitvector. In other words, it is as if you have
/// `rows` bitvectors, each of length `columns`.
#[derive(Clone)]
pub struct BitMatrix {
    columns: usize,
    vector: Vec<u64>,
}

impl BitMatrix {
    // Create a new `rows x columns` matrix, initially empty.
    pub fn new(rows: usize, columns: usize) -> BitMatrix {
        // For every element, we need one bit for every other
        // element. Round up to an even number of u64s.
        let u64s_per_row = u64s(columns);
        BitMatrix {
            columns: columns,
            vector: vec![0; rows * u64s_per_row],
        }
    }

    /// The range of bits for a given row.
    fn range(&self, row: usize) -> (usize, usize) {
        let u64s_per_row = u64s(self.columns);
        let start = row * u64s_per_row;
        (start, start + u64s_per_row)
    }

    pub fn add(&mut self, source: usize, target: usize) -> bool {
        let (start, _) = self.range(source);
        let (word, mask) = word_mask(target);
        let mut vector = &mut self.vector[..];
        let v1 = vector[start + word];
        let v2 = v1 | mask;
        vector[start + word] = v2;
        v1 != v2
    }

    /// Do the bits from `source` contain `target`?
    ///
    /// Put another way, if the matrix represents (transitive)
    /// reachability, can `source` reach `target`?
    pub fn contains(&self, source: usize, target: usize) -> bool {
        let (start, _) = self.range(source);
        let (word, mask) = word_mask(target);
        (self.vector[start + word] & mask) != 0
    }

    /// Returns those indices that are reachable from both `a` and
    /// `b`. This is an O(n) operation where `n` is the number of
    /// elements (somewhat independent from the actual size of the
    /// intersection, in particular).
    pub fn intersection(&self, a: usize, b: usize) -> Vec<usize> {
        let (a_start, a_end) = self.range(a);
        let (b_start, b_end) = self.range(b);
        let mut result = Vec::with_capacity(self.columns);
        for (base, (i, j)) in (a_start..a_end).zip(b_start..b_end).enumerate() {
            let mut v = self.vector[i] & self.vector[j];
            for bit in 0..64 {
                if v == 0 {
                    break;
                }
                if v & 0x1 != 0 {
                    result.push(base * 64 + bit);
                }
                v >>= 1;
            }
        }
        result
    }

    /// Add the bits from `read` to the bits from `write`,
    /// return true if anything changed.
    ///
    /// This is used when computing transitive reachability because if
    /// you have an edge `write -> read`, because in that case
    /// `write` can reach everything that `read` can (and
    /// potentially more).
    pub fn merge(&mut self, read: usize, write: usize) -> bool {
        let (read_start, read_end) = self.range(read);
        let (write_start, write_end) = self.range(write);
        let vector = &mut self.vector[..];
        let mut changed = false;
        for (read_index, write_index) in (read_start..read_end).zip(write_start..write_end) {
            let v1 = vector[write_index];
            let v2 = v1 | vector[read_index];
            vector[write_index] = v2;
            changed = changed | (v1 != v2);
        }
        changed
    }

    pub fn iter<'a>(&'a self, row: usize) -> BitVectorIter<'a> {
        let (start, end) = self.range(row);
        BitVectorIter {
            iter: self.vector[start..end].iter(),
            current: 0,
            idx: 0,
        }
    }
}

fn u64s(elements: usize) -> usize {
    (elements + 63) / 64
}

fn word_mask(index: usize) -> (usize, u64) {
    let word = index / 64;
    let mask = 1 << (index % 64);
    (word, mask)
}

#[test]
fn bitvec_iter_works() {
    let mut bitvec = BitVector::new(100);
    bitvec.insert(1);
    bitvec.insert(10);
    bitvec.insert(19);
    bitvec.insert(62);
    bitvec.insert(63);
    bitvec.insert(64);
    bitvec.insert(65);
    bitvec.insert(66);
    bitvec.insert(99);
    assert_eq!(bitvec.iter().collect::<Vec<_>>(),
               [1, 10, 19, 62, 63, 64, 65, 66, 99]);
}

#[test]
fn bitvec_iter_works_2() {
    let mut bitvec = BitVector::new(319);
    bitvec.insert(0);
    bitvec.insert(127);
    bitvec.insert(191);
    bitvec.insert(255);
    bitvec.insert(319);
    assert_eq!(bitvec.iter().collect::<Vec<_>>(), [0, 127, 191, 255, 319]);
}

#[test]
fn union_two_vecs() {
    let mut vec1 = BitVector::new(65);
    let mut vec2 = BitVector::new(65);
    assert!(vec1.insert(3));
    assert!(!vec1.insert(3));
    assert!(vec2.insert(5));
    assert!(vec2.insert(64));
    assert!(vec1.insert_all(&vec2));
    assert!(!vec1.insert_all(&vec2));
    assert!(vec1.contains(3));
    assert!(!vec1.contains(4));
    assert!(vec1.contains(5));
    assert!(!vec1.contains(63));
    assert!(vec1.contains(64));
}

#[test]
fn grow() {
    let mut vec1 = BitVector::new(65);
    for index in 0 .. 65 {
        assert!(vec1.insert(index));
        assert!(!vec1.insert(index));
    }
    vec1.grow(128);

    // Check if the bits set before growing are still set
    for index in 0 .. 65 {
        assert!(vec1.contains(index));
    }

    // Check if the new bits are all un-set
    for index in 65 .. 128 {
        assert!(!vec1.contains(index));
    }

    // Check that we can set all new bits without running out of bounds
    for index in 65 .. 128 {
        assert!(vec1.insert(index));
        assert!(!vec1.insert(index));
    }
}

#[test]
fn matrix_intersection() {
    let mut vec1 = BitMatrix::new(200, 200);

    // (*) Elements reachable from both 2 and 65.

    vec1.add(2, 3);
    vec1.add(2, 6);
    vec1.add(2, 10); // (*)
    vec1.add(2, 64); // (*)
    vec1.add(2, 65);
    vec1.add(2, 130);
    vec1.add(2, 160); // (*)

    vec1.add(64, 133);

    vec1.add(65, 2);
    vec1.add(65, 8);
    vec1.add(65, 10); // (*)
    vec1.add(65, 64); // (*)
    vec1.add(65, 68);
    vec1.add(65, 133);
    vec1.add(65, 160); // (*)

    let intersection = vec1.intersection(2, 64);
    assert!(intersection.is_empty());

    let intersection = vec1.intersection(2, 65);
    assert_eq!(intersection, &[10, 64, 160]);
}

#[test]
fn matrix_iter() {
    let mut matrix = BitMatrix::new(64, 100);
    matrix.add(3, 22);
    matrix.add(3, 75);
    matrix.add(2, 99);
    matrix.add(4, 0);
    matrix.merge(3, 5);

    let expected = [99];
    let mut iter = expected.iter();
    for i in matrix.iter(2) {
        let j = *iter.next().unwrap();
        assert_eq!(i, j);
    }
    assert!(iter.next().is_none());

    let expected = [22, 75];
    let mut iter = expected.iter();
    for i in matrix.iter(3) {
        let j = *iter.next().unwrap();
        assert_eq!(i, j);
    }
    assert!(iter.next().is_none());

    let expected = [0];
    let mut iter = expected.iter();
    for i in matrix.iter(4) {
        let j = *iter.next().unwrap();
        assert_eq!(i, j);
    }
    assert!(iter.next().is_none());

    let expected = [22, 75];
    let mut iter = expected.iter();
    for i in matrix.iter(5) {
        let j = *iter.next().unwrap();
        assert_eq!(i, j);
    }
    assert!(iter.next().is_none());
}
<commit_msg>Mark some BitVector methods with #[inline]<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::iter::FromIterator;

/// A very simple BitVector type.
#[derive(Clone, Debug, PartialEq)]
pub struct BitVector {
    data: Vec<u64>,
}

impl BitVector {
    #[inline]
    pub fn new(num_bits: usize) -> BitVector {
        let num_words = u64s(num_bits);
        BitVector { data: vec![0; num_words] }
    }

    #[inline]
    pub fn clear(&mut self) {
        for p in &mut self.data {
            *p = 0;
        }
    }

    #[inline]
    pub fn contains(&self, bit: usize) -> bool {
        let (word, mask) = word_mask(bit);
        (self.data[word] & mask) != 0
    }

    /// Returns true if the bit has changed.
    #[inline]
    pub fn insert(&mut self, bit: usize) -> bool {
        let (word, mask) = word_mask(bit);
        let data = &mut self.data[word];
        let value = *data;
        let new_value = value | mask;
        *data = new_value;
        new_value != value
    }

    #[inline]
    pub fn insert_all(&mut self, all: &BitVector) -> bool {
        assert!(self.data.len() == all.data.len());
        let mut changed = false;
        for (i, j) in self.data.iter_mut().zip(&all.data) {
            let value = *i;
            *i = value | *j;
            if value != *i {
                changed = true;
            }
        }
        changed
    }

    #[inline]
    pub fn grow(&mut self, num_bits: usize) {
        let num_words = u64s(num_bits);
        if self.data.len() < num_words {
            self.data.resize(num_words, 0)
        }
    }

    /// Iterates over indexes of set bits in a sorted order
    #[inline]
    pub fn iter<'a>(&'a self) -> BitVectorIter<'a> {
        BitVectorIter {
            iter: self.data.iter(),
            current: 0,
            idx: 0,
        }
    }
}

pub struct BitVectorIter<'a> {
    iter: ::std::slice::Iter<'a, u64>,
    current: u64,
    idx: usize,
}

impl<'a> Iterator for BitVectorIter<'a> {
    type Item = usize;
    fn next(&mut self) -> Option<usize> {
        while self.current == 0 {
            self.current = if let Some(&i) = self.iter.next() {
                if i == 0 {
                    self.idx += 64;
                    continue;
                } else {
                    self.idx = u64s(self.idx) * 64;
                    i
                }
            } else {
                return None;
            }
        }
        let offset = self.current.trailing_zeros() as usize;
        self.current >>= offset;
        self.current >>= 1; // shift otherwise overflows for 0b1000_0000_…_0000
        self.idx += offset + 1;
        return Some(self.idx - 1);
    }
}

impl FromIterator<bool> for BitVector {
    fn from_iter<I>(iter: I) -> BitVector where I: IntoIterator<Item=bool> {
        let iter = iter.into_iter();
        let (len, _) = iter.size_hint();
        // Make the minimum length for the bitvector 64 bits since that's
        // the smallest non-zero size anyway.
        let len = if len < 64 { 64 } else { len };
        let mut bv = BitVector::new(len);
        for (idx, val) in iter.enumerate() {
            if idx > len {
                bv.grow(idx);
            }
            if val {
                bv.insert(idx);
            }
        }

        bv
    }
}

/// A "bit matrix" is basically a matrix of booleans represented as
/// one gigantic bitvector. In other words, it is as if you have
/// `rows` bitvectors, each of length `columns`.
#[derive(Clone)]
pub struct BitMatrix {
    columns: usize,
    vector: Vec<u64>,
}

impl BitMatrix {
    // Create a new `rows x columns` matrix, initially empty.
    pub fn new(rows: usize, columns: usize) -> BitMatrix {
        // For every element, we need one bit for every other
        // element. Round up to an even number of u64s.
        let u64s_per_row = u64s(columns);
        BitMatrix {
            columns: columns,
            vector: vec![0; rows * u64s_per_row],
        }
    }

    /// The range of bits for a given row.
    fn range(&self, row: usize) -> (usize, usize) {
        let u64s_per_row = u64s(self.columns);
        let start = row * u64s_per_row;
        (start, start + u64s_per_row)
    }

    pub fn add(&mut self, source: usize, target: usize) -> bool {
        let (start, _) = self.range(source);
        let (word, mask) = word_mask(target);
        let mut vector = &mut self.vector[..];
        let v1 = vector[start + word];
        let v2 = v1 | mask;
        vector[start + word] = v2;
        v1 != v2
    }

    /// Do the bits from `source` contain `target`?
    ///
    /// Put another way, if the matrix represents (transitive)
    /// reachability, can `source` reach `target`?
    pub fn contains(&self, source: usize, target: usize) -> bool {
        let (start, _) = self.range(source);
        let (word, mask) = word_mask(target);
        (self.vector[start + word] & mask) != 0
    }

    /// Returns those indices that are reachable from both `a` and
    /// `b`. This is an O(n) operation where `n` is the number of
    /// elements (somewhat independent from the actual size of the
    /// intersection, in particular).
    pub fn intersection(&self, a: usize, b: usize) -> Vec<usize> {
        let (a_start, a_end) = self.range(a);
        let (b_start, b_end) = self.range(b);
        let mut result = Vec::with_capacity(self.columns);
        for (base, (i, j)) in (a_start..a_end).zip(b_start..b_end).enumerate() {
            let mut v = self.vector[i] & self.vector[j];
            for bit in 0..64 {
                if v == 0 {
                    break;
                }
                if v & 0x1 != 0 {
                    result.push(base * 64 + bit);
                }
                v >>= 1;
            }
        }
        result
    }

    /// Add the bits from `read` to the bits from `write`,
    /// return true if anything changed.
    ///
    /// This is used when computing transitive reachability because if
    /// you have an edge `write -> read`, because in that case
    /// `write` can reach everything that `read` can (and
    /// potentially more).
    pub fn merge(&mut self, read: usize, write: usize) -> bool {
        let (read_start, read_end) = self.range(read);
        let (write_start, write_end) = self.range(write);
        let vector = &mut self.vector[..];
        let mut changed = false;
        for (read_index, write_index) in (read_start..read_end).zip(write_start..write_end) {
            let v1 = vector[write_index];
            let v2 = v1 | vector[read_index];
            vector[write_index] = v2;
            changed = changed | (v1 != v2);
        }
        changed
    }

    pub fn iter<'a>(&'a self, row: usize) -> BitVectorIter<'a> {
        let (start, end) = self.range(row);
        BitVectorIter {
            iter: self.vector[start..end].iter(),
            current: 0,
            idx: 0,
        }
    }
}

#[inline]
fn u64s(elements: usize) -> usize {
    (elements + 63) / 64
}

#[inline]
fn word_mask(index: usize) -> (usize, u64) {
    let word = index / 64;
    let mask = 1 << (index % 64);
    (word, mask)
}

#[test]
fn bitvec_iter_works() {
    let mut bitvec = BitVector::new(100);
    bitvec.insert(1);
    bitvec.insert(10);
    bitvec.insert(19);
    bitvec.insert(62);
    bitvec.insert(63);
    bitvec.insert(64);
    bitvec.insert(65);
    bitvec.insert(66);
    bitvec.insert(99);
    assert_eq!(bitvec.iter().collect::<Vec<_>>(),
               [1, 10, 19, 62, 63, 64, 65, 66, 99]);
}

#[test]
fn bitvec_iter_works_2() {
    let mut bitvec = BitVector::new(319);
    bitvec.insert(0);
    bitvec.insert(127);
    bitvec.insert(191);
    bitvec.insert(255);
    bitvec.insert(319);
    assert_eq!(bitvec.iter().collect::<Vec<_>>(), [0, 127, 191, 255, 319]);
}

#[test]
fn union_two_vecs() {
    let mut vec1 = BitVector::new(65);
    let mut vec2 = BitVector::new(65);
    assert!(vec1.insert(3));
    assert!(!vec1.insert(3));
    assert!(vec2.insert(5));
    assert!(vec2.insert(64));
    assert!(vec1.insert_all(&vec2));
    assert!(!vec1.insert_all(&vec2));
    assert!(vec1.contains(3));
    assert!(!vec1.contains(4));
    assert!(vec1.contains(5));
    assert!(!vec1.contains(63));
    assert!(vec1.contains(64));
}

#[test]
fn grow() {
    let mut vec1 = BitVector::new(65);
    for index in 0 .. 65 {
        assert!(vec1.insert(index));
        assert!(!vec1.insert(index));
    }
    vec1.grow(128);

    // Check if the bits set before growing are still set
    for index in 0 .. 65 {
        assert!(vec1.contains(index));
    }

    // Check if the new bits are all un-set
    for index in 65 .. 128 {
        assert!(!vec1.contains(index));
    }

    // Check that we can set all new bits without running out of bounds
    for index in 65 .. 128 {
        assert!(vec1.insert(index));
        assert!(!vec1.insert(index));
    }
}

#[test]
fn matrix_intersection() {
    let mut vec1 = BitMatrix::new(200, 200);

    // (*) Elements reachable from both 2 and 65.

    vec1.add(2, 3);
    vec1.add(2, 6);
    vec1.add(2, 10); // (*)
    vec1.add(2, 64); // (*)
    vec1.add(2, 65);
    vec1.add(2, 130);
    vec1.add(2, 160); // (*)

    vec1.add(64, 133);

    vec1.add(65, 2);
    vec1.add(65, 8);
    vec1.add(65, 10); // (*)
    vec1.add(65, 64); // (*)
    vec1.add(65, 68);
    vec1.add(65, 133);
    vec1.add(65, 160); // (*)

    let intersection = vec1.intersection(2, 64);
    assert!(intersection.is_empty());

    let intersection = vec1.intersection(2, 65);
    assert_eq!(intersection, &[10, 64, 160]);
}

#[test]
fn matrix_iter() {
    let mut matrix = BitMatrix::new(64, 100);
    matrix.add(3, 22);
    matrix.add(3, 75);
    matrix.add(2, 99);
    matrix.add(4, 0);
    matrix.merge(3, 5);

    let expected = [99];
    let mut iter = expected.iter();
    for i in matrix.iter(2) {
        let j = *iter.next().unwrap();
        assert_eq!(i, j);
    }
    assert!(iter.next().is_none());

    let expected = [22, 75];
    let mut iter = expected.iter();
    for i in matrix.iter(3) {
        let j = *iter.next().unwrap();
        assert_eq!(i, j);
    }
    assert!(iter.next().is_none());

    let expected = [0];
    let mut iter = expected.iter();
    for i in matrix.iter(4) {
        let j = *iter.next().unwrap();
        assert_eq!(i, j);
    }
    assert!(iter.next().is_none());

    let expected = [22, 75];
    let mut iter = expected.iter();
    for i in matrix.iter(5) {
        let j = *iter.next().unwrap();
        assert_eq!(i, j);
    }
    assert!(iter.next().is_none());
}
<|endoftext|>


<commit_before>use std::collections::HashSet;
use super::bls::{
    AggregateSignature,
    AggregatePublicKey,
};
use super::db::ClientDB;
use super::db::stores::{
    ValidatorStore,
    ValidatorStoreError,
};
use super::utils::types::Bitfield;

#[derive(Debug, PartialEq)]
pub enum SignatureVerificationError {
    BadValidatorIndex,
    PublicKeyCorrupt,
    NoPublicKeyForValidator,
    DBError(String),
}

/// Verify an aggregate signature across the supplied message.
///
/// The public keys used for verification are collected by mapping
/// each true bitfield bit to canonical ValidatorRecord index through
/// the attestation_indicies map.
///
/// Each public key is loaded from the store on-demand.
pub fn verify_aggregate_signature_for_indices<T>(
    message: &[u8],
    agg_sig: &AggregateSignature,
    attestation_indices: &[usize],
    bitfield: &Bitfield,
    validator_store: &ValidatorStore<T>)
    -> Result<Option<HashSet<usize>>, SignatureVerificationError>
    where T: ClientDB + Sized
{
    let mut voters = HashSet::new();
    let mut agg_pub_key = AggregatePublicKey::new();

    for i in 0..attestation_indices.len() {
        let voted = bitfield.get_bit(i);
        if voted {
            /*
             * De-reference the attestation index into a canonical ValidatorRecord index.
             */
            let validator = *attestation_indices.get(i)
                .ok_or(SignatureVerificationError::BadValidatorIndex)?;
            /*
             * Load the validators public key from our store.
             */
            let pub_key = validator_store.get_public_key_by_index(i)?
                .ok_or(SignatureVerificationError::NoPublicKeyForValidator)?;
            /*
             * Add the validators public key to the aggregate public key.
             */
            agg_pub_key.add(&pub_key);
            /*
             * Add to the validator to the set of voters for this attestation record.
             */
            voters.insert(validator);
        }
    }
    /*
     * Verify the aggregate public key against the aggregate signature.
     *
     * This verification will only succeed if the exact set of public keys
     * were added to the aggregate public key as those that signed the aggregate signature.
     */
    if agg_sig.verify(&message, &agg_pub_key) {
        Ok(Some(voters))
    } else {
        Ok(None)
    }
}

impl From<ValidatorStoreError> for SignatureVerificationError {
    fn from(error: ValidatorStoreError) -> Self {
        match error {
            ValidatorStoreError::DBError(s) =>
                SignatureVerificationError::DBError(s),
            ValidatorStoreError::DecodeError =>
                SignatureVerificationError::PublicKeyCorrupt,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use super::super::bls::{
        Keypair,
        Signature,
    };
    use super::super::db::MemoryDB;
    use std::sync::Arc;

    /*
     * Cases that still need testing:
     *
     * - No signatures.
     * - Database failure.
     * - Unknown validator index.
     * - Extra validator on signature.
     */

    #[test]
    fn test_signature_verification() {
        let message = "cats".as_bytes();
        let signing_keypairs = vec![
            Keypair::random(),
            Keypair::random(),
            Keypair::random(),
            Keypair::random(),
            Keypair::random(),
            Keypair::random(),
        ];
        let non_signing_keypairs = vec![
            Keypair::random(),
            Keypair::random(),
            Keypair::random(),
            Keypair::random(),
            Keypair::random(),
            Keypair::random(),
        ];
        /*
         * Signing keypairs first, then non-signing
         */
        let mut all_keypairs = signing_keypairs.clone();
        all_keypairs.append(&mut non_signing_keypairs.clone());

        let attestation_indices: Vec<usize> = (0..all_keypairs.len())
            .collect();
        let mut bitfield = Bitfield::new();
        for i in 0..signing_keypairs.len() {
            bitfield.set_bit(i, true);
        }

        let db = Arc::new(MemoryDB::open());
        let store = ValidatorStore::new(db);

        for (i, keypair) in all_keypairs.iter().enumerate() {
            store.put_public_key_by_index(i, &keypair.pk).unwrap();
        }

        let mut agg_sig = AggregateSignature::new();
        for keypair in &signing_keypairs {
            let sig = Signature::new(&message, &keypair.sk);
            agg_sig.add(&sig);
        }

        /*
         * Test using all valid parameters.
         */
        let voters = verify_aggregate_signature_for_indices(
            &message,
            &agg_sig,
            &attestation_indices,
            &bitfield,
            &store).unwrap();

        let voters = voters.unwrap();
        (0..signing_keypairs.len())
            .for_each(|i| assert!(voters.contains(&i)));
        (signing_keypairs.len()..non_signing_keypairs.len())
            .for_each(|i| assert!(!voters.contains(&i)));

        /*
         * Add another validator to the bitfield, run validation will all other
         * parameters the same and assert that it fails.
         */
        bitfield.set_bit(signing_keypairs.len() + 1, true);
        let voters = verify_aggregate_signature_for_indices(
            &message,
            &agg_sig,
            &attestation_indices,
            &bitfield,
            &store).unwrap();

        assert_eq!(voters, None);
    }
}
<commit_msg>Fix pub key getting in signature verification<commit_after>use std::collections::HashSet;
use super::bls::{
    AggregateSignature,
    AggregatePublicKey,
};
use super::db::ClientDB;
use super::db::stores::{
    ValidatorStore,
    ValidatorStoreError,
};
use super::utils::types::Bitfield;

#[derive(Debug, PartialEq)]
pub enum SignatureVerificationError {
    BadValidatorIndex,
    PublicKeyCorrupt,
    NoPublicKeyForValidator,
    DBError(String),
}

/// Verify an aggregate signature across the supplied message.
///
/// The public keys used for verification are collected by mapping
/// each true bitfield bit to canonical ValidatorRecord index through
/// the attestation_indicies map.
///
/// Each public key is loaded from the store on-demand.
pub fn verify_aggregate_signature_for_indices<T>(
    message: &[u8],
    agg_sig: &AggregateSignature,
    attestation_indices: &[usize],
    bitfield: &Bitfield,
    validator_store: &ValidatorStore<T>)
    -> Result<Option<HashSet<usize>>, SignatureVerificationError>
    where T: ClientDB + Sized
{
    let mut voters = HashSet::new();
    let mut agg_pub_key = AggregatePublicKey::new();

    for i in 0..attestation_indices.len() {
        let voted = bitfield.get_bit(i);
        if voted {
            /*
             * De-reference the attestation index into a canonical ValidatorRecord index.
             */
            let validator = *attestation_indices.get(i)
                .ok_or(SignatureVerificationError::BadValidatorIndex)?;
            /*
             * Load the validators public key from our store.
             */
            let pub_key = validator_store
                .get_public_key_by_index(validator)?
                .ok_or(SignatureVerificationError::NoPublicKeyForValidator)?;
            /*
             * Add the validators public key to the aggregate public key.
             */
            agg_pub_key.add(&pub_key);
            /*
             * Add to the validator to the set of voters for this attestation record.
             */
            voters.insert(validator);
        }
    }
    /*
     * Verify the aggregate public key against the aggregate signature.
     *
     * This verification will only succeed if the exact set of public keys
     * were added to the aggregate public key as those that signed the aggregate signature.
     */
    if agg_sig.verify(&message, &agg_pub_key) {
        Ok(Some(voters))
    } else {
        Ok(None)
    }
}

impl From<ValidatorStoreError> for SignatureVerificationError {
    fn from(error: ValidatorStoreError) -> Self {
        match error {
            ValidatorStoreError::DBError(s) =>
                SignatureVerificationError::DBError(s),
            ValidatorStoreError::DecodeError =>
                SignatureVerificationError::PublicKeyCorrupt,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use super::super::bls::{
        Keypair,
        Signature,
    };
    use super::super::db::MemoryDB;
    use std::sync::Arc;

    /*
     * Cases that still need testing:
     *
     * - No signatures.
     * - Database failure.
     * - Unknown validator index.
     * - Extra validator on signature.
     */

    #[test]
    fn test_signature_verification() {
        let message = "cats".as_bytes();
        let signing_keypairs = vec![
            Keypair::random(),
            Keypair::random(),
            Keypair::random(),
            Keypair::random(),
            Keypair::random(),
            Keypair::random(),
        ];
        let non_signing_keypairs = vec![
            Keypair::random(),
            Keypair::random(),
            Keypair::random(),
            Keypair::random(),
            Keypair::random(),
            Keypair::random(),
        ];
        /*
         * Signing keypairs first, then non-signing
         */
        let mut all_keypairs = signing_keypairs.clone();
        all_keypairs.append(&mut non_signing_keypairs.clone());

        let attestation_indices: Vec<usize> = (0..all_keypairs.len())
            .collect();
        let mut bitfield = Bitfield::new();
        for i in 0..signing_keypairs.len() {
            bitfield.set_bit(i, true);
        }

        let db = Arc::new(MemoryDB::open());
        let store = ValidatorStore::new(db);

        for (i, keypair) in all_keypairs.iter().enumerate() {
            store.put_public_key_by_index(i, &keypair.pk).unwrap();
        }

        let mut agg_sig = AggregateSignature::new();
        for keypair in &signing_keypairs {
            let sig = Signature::new(&message, &keypair.sk);
            agg_sig.add(&sig);
        }

        /*
         * Test using all valid parameters.
         */
        let voters = verify_aggregate_signature_for_indices(
            &message,
            &agg_sig,
            &attestation_indices,
            &bitfield,
            &store).unwrap();

        let voters = voters.unwrap();
        (0..signing_keypairs.len())
            .for_each(|i| assert!(voters.contains(&i)));
        (signing_keypairs.len()..non_signing_keypairs.len())
            .for_each(|i| assert!(!voters.contains(&i)));

        /*
         * Add another validator to the bitfield, run validation will all other
         * parameters the same and assert that it fails.
         */
        bitfield.set_bit(signing_keypairs.len() + 1, true);
        let voters = verify_aggregate_signature_for_indices(
            &message,
            &agg_sig,
            &attestation_indices,
            &bitfield,
            &store).unwrap();

        assert_eq!(voters, None);
    }
}
<|endoftext|>


<commit_before>include!("header.rs");
use ndarray_linalg::vector::outer;

#[test]
fn outer_() {
    let dist = RealNormal::<f64>::new(0.0, 1.0);
    let m = 2;
    let n = 3;
    let a = Array::random(m, dist);
    let b = Array::random(n, dist);
    println!("a = \n{:?}", &a);
    println!("b = \n{:?}", &b);
    let ab = outer(&a, &b);
    println!("ab = \n{:?}", &ab);
    for i in 0..m {
        for j in 0..n {
            ab[(i, j)].assert_close(a[i] * b[j], 1e-7);
        }
    }
}
<commit_msg>Add test<commit_after>include!("header.rs");
use ndarray_linalg::vector::outer;

#[test]
fn outer_3x4() {
    let dist = RealNormal::<f64>::new(0.0, 1.0);
    let m = 3;
    let n = 4;
    let a = Array::random(m, dist);
    let b = Array::random(n, dist);
    println!("a = \n{:?}", &a);
    println!("b = \n{:?}", &b);
    let ab = outer(&a, &b);
    println!("ab = \n{:?}", &ab);
    for i in 0..m {
        for j in 0..n {
            ab[(i, j)].assert_close(a[i] * b[j], 1e-7);
        }
    }
}

#[test]
fn outer_4x3() {
    let dist = RealNormal::<f64>::new(0.0, 1.0);
    let m = 4;
    let n = 3;
    let a = Array::random(m, dist);
    let b = Array::random(n, dist);
    println!("a = \n{:?}", &a);
    println!("b = \n{:?}", &b);
    let ab = outer(&a, &b);
    println!("ab = \n{:?}", &ab);
    for i in 0..m {
        for j in 0..n {
            ab[(i, j)].assert_close(a[i] * b[j], 1e-7);
        }
    }
}
<|endoftext|>


<commit_before>// TODO: Doc the rest

use core::{cmp, intrinsics, mem};
use core::ops::{Index, IndexMut};
use core::{ptr, slice};

use super::paging::{Page, PAGE_END};

pub const CLUSTER_ADDRESS: usize = PAGE_END;
pub const CLUSTER_COUNT: usize = 1024 * 1024; // 4 GiB
pub const CLUSTER_SIZE: usize = 4096; // Of 4 K chunks

use system::error::{Result, Error, ENOMEM};

/// A wrapper around raw pointers
pub struct Memory<T> {
    ptr: *mut T,
    length: usize,
}

impl<T> Memory<T> {
    /// Allocate memory
    pub fn new(length: usize) -> Result<Self> {
        let alloc = unsafe { alloc(length * mem::size_of::<T>()) };
        if alloc > 0 {
            Ok(Memory {
                ptr: alloc as *mut T,
                length: length,
            })
        } else {
            Err(Error::new(ENOMEM))
        }
    }

    /// Allocate memory, aligned
    pub fn new_aligned(length: usize, align: usize) -> Result<Self> {
        let alloc = unsafe { alloc_aligned(length * mem::size_of::<T>(), align) };
        if alloc > 0 {
            Ok(Memory {
                ptr: alloc as *mut T,
                length: length,
            })
        } else {
            Err(Error::new(ENOMEM))
        }
    }

    /// Reallocate the memory
    pub fn renew(mut self, length: usize) -> Result<Self> {
        let alloc = unsafe { realloc(self.ptr as usize, length * mem::size_of::<T>()) };
        self.ptr = 0 as *mut T;
        if alloc > 0 {
            Ok(Memory {
                ptr: alloc as *mut T,
                length: length,
            })
        } else {
            Err(Error::new(ENOMEM))
        }
    }

    /// Reallocate the memory, aligned
    pub fn renew_aligned(mut self, length: usize, align: usize) -> Result<Self> {
        let alloc = unsafe { realloc_aligned(self.ptr as usize, length * mem::size_of::<T>(), align) };
        self.ptr = 0 as *mut T;
        if alloc > 0 {
            Ok(Memory {
                ptr: alloc as *mut T,
                length: length,
            })
        } else {
            Err(Error::new(ENOMEM))
        }
    }

    /// Get the length in T elements
    pub fn len(&self) -> usize {
        self.length
    }

    #[inline(always)]
    fn check_index(&self, i: usize) {
        if i >= self.length {
            panic!("Memory: {} >= {}", i, self.length);
        }
    }

    /// Read the memory
    pub fn read(&self, i: usize) -> T {
        self.check_index(i);
        unsafe { ptr::read(self.ptr.offset(i as isize)) }
    }

    /// Load the memory
    pub fn load(&self, i: usize) -> T {
        self.check_index(i);
        unsafe {
            intrinsics::atomic_singlethreadfence();
            ptr::read(self.ptr.offset(i as isize))
        }
    }

    /// Overwrite the memory
    pub fn write(&mut self, i: usize, value: T) {
        self.check_index(i);
        unsafe { ptr::write(self.ptr.offset(i as isize), value) };
    }

    /// Store the memory
    pub fn store(&mut self, i: usize, value: T) {
        self.check_index(i);
        unsafe {
            intrinsics::atomic_singlethreadfence();
            ptr::write(self.ptr.offset(i as isize), value)
        }
    }

    /// Get the address
    pub fn address(&self) -> usize {
        self.ptr as usize
    }

    /// Borrow as a slice
    pub fn as_slice(&self) -> &[T] {
        unsafe { slice::from_raw_parts(self.ptr, self.length) }
    }

    /// Borrow as a mutable slice
    pub fn as_mut_slice(&mut self) -> &mut [T] {
        unsafe { slice::from_raw_parts_mut(self.ptr, self.length) }
    }

    /// Borrow as a raw pointer
    pub unsafe fn as_ptr(&self) -> *const T {
        self.ptr as *const T
    }

    /// Borrow as a mutable raw pointer
    pub unsafe fn as_mut_ptr(&mut self) -> *mut T {
        self.ptr as *mut T
    }

    /// Convert into a raw pointer
    pub unsafe fn into_raw(mut self) -> *mut T {
        let ptr = self.ptr;
        self.ptr = 0 as *mut T;
        ptr
    }
}

impl<T> Drop for Memory<T> {
    fn drop(&mut self) {
        if self.ptr as usize > 0 {
            unsafe { unalloc(self.ptr as usize) };
        }
    }
}

impl<T> Index<usize> for Memory<T> {
    type Output = T;

    fn index<'a>(&'a self, i: usize) -> &'a T {
        self.check_index(i);
        unsafe { &*self.ptr.offset(i as isize) }
    }
}

impl<T> IndexMut<usize> for Memory<T> {
    fn index_mut<'a>(&'a mut self, i: usize) -> &'a mut T {
        self.check_index(i);
        unsafe { &mut *self.ptr.offset(i as isize) }
    }
}

/// A memory map entry
#[repr(packed)]
struct MemoryMapEntry {
    base: u64,
    len: u64,
    class: u32,
    acpi: u32,
}

const MEMORY_MAP: *const MemoryMapEntry = 0x500 as *const MemoryMapEntry;

/// Get the data (address) of a given cluster
pub unsafe fn cluster(number: usize) -> usize {
    if number < CLUSTER_COUNT {
        ptr::read((CLUSTER_ADDRESS + number * mem::size_of::<usize>()) as *const usize)
    } else {
        0
    }
}

/// Set the address of a cluster
pub unsafe fn set_cluster(number: usize, address: usize) {
    if number < CLUSTER_COUNT {
        ptr::write((CLUSTER_ADDRESS + number * mem::size_of::<usize>()) as *mut usize,
                   address);
    }
}

/// Convert an adress to the cluster number
pub unsafe fn address_to_cluster(address: usize) -> usize {
    if address >= CLUSTER_ADDRESS + CLUSTER_COUNT * mem::size_of::<usize>() {
        (address - CLUSTER_ADDRESS - CLUSTER_COUNT * mem::size_of::<usize>()) / CLUSTER_SIZE
    } else {
        0
    }
}

pub unsafe fn cluster_to_address(number: usize) -> usize {
    CLUSTER_ADDRESS + CLUSTER_COUNT * mem::size_of::<usize>() + number * CLUSTER_SIZE
}

/// Initialize clusters
pub unsafe fn cluster_init() {
    // First, set all clusters to the not present value
    for cluster in 0..CLUSTER_COUNT {
        set_cluster(cluster, 0xFFFFFFFF);
    }

    // Next, set all valid clusters to the free value
    // TODO: Optimize this function
    for i in 0..((0x5000 - 0x500) / mem::size_of::<MemoryMapEntry>()) {
        let entry = &*MEMORY_MAP.offset(i as isize);
        if entry.len > 0 && entry.class == 1 {
            for cluster in 0..CLUSTER_COUNT {
                let address = cluster_to_address(cluster);
                if address as u64 >= entry.base &&
                   (address as u64 + CLUSTER_SIZE as u64) <= (entry.base + entry.len) {
                    set_cluster(cluster, 0);
                }
            }
        }
    }
}

/// Allocate memory
pub unsafe fn alloc(size: usize) -> usize {
    alloc_aligned(size, 1)
}

/// Allocate memory, aligned
pub unsafe fn alloc_aligned(size: usize, align: usize) -> usize {
    if size > 0 {
        let mut number = 0;
        let mut count = 0;

        for i in 0..CLUSTER_COUNT {
            if cluster(i) == 0 && (count > 0 || cluster_to_address(i) % align == 0) {
                if count == 0 {
                    number = i;
                }

                count += 1;

                if count * CLUSTER_SIZE >= size {
                    break;
                }
            } else {
                count = 0;
            }
        }

        if count * CLUSTER_SIZE >= size {
            let address = cluster_to_address(number);

            for i in number..number + count {
                set_cluster(i, address);

                let cluster_address = cluster_to_address(i);

                let mut page = Page::new(cluster_address);
                let old = page.entry_data();
                page.map_kernel_write(address);

                ::memset(cluster_address as *mut u8, 0, CLUSTER_SIZE);

                page.set_entry_data(old);
                page.flush();
            }

            return address;
        }
    }

    0
}

/// Allocate a type
pub unsafe fn alloc_type<T>() -> *mut T {
    alloc(mem::size_of::<T>()) as *mut T
}

pub unsafe fn alloc_size(ptr: usize) -> usize {
    let mut size = 0;

    if ptr > 0 {
        for i in address_to_cluster(ptr)..CLUSTER_COUNT {
            if cluster(i) == ptr {
                size += CLUSTER_SIZE;
            } else {
                break;
            }
        }
    }

    size
}

pub unsafe fn unalloc(ptr: usize) {
    if ptr > 0 {
        for i in address_to_cluster(ptr)..CLUSTER_COUNT {
            if cluster(i) == ptr {
                set_cluster(i, 0);
            } else {
                break;
            }
        }
    }
}

pub unsafe fn unalloc_type<T>(ptr: *mut T) {
    unalloc(ptr as usize);
}

pub unsafe fn realloc(ptr: usize, size: usize) -> usize {
    realloc_aligned(ptr, size, 1)
}

pub unsafe fn realloc_aligned(ptr: usize, size: usize, align: usize) -> usize {
    let mut ret = 0;

    if size == 0 {
        if ptr > 0 {
            unalloc(ptr);
        }
    } else {
        let old_size = alloc_size(ptr);
        if size <= old_size {
            ret = ptr;
        } else {
            ret = alloc_aligned(size, align);
            if ptr > 0 {
                if ret > 0 {
                    let copy_size = cmp::min(old_size, size);

                    let read_cluster = address_to_cluster(ptr);
                    let write_cluster = address_to_cluster(ret);

                    for i in 0..(copy_size + CLUSTER_SIZE - 1)/CLUSTER_SIZE {
                        let read_address = cluster_to_address(read_cluster + i);
                        let write_address = cluster_to_address(write_cluster + i);

                        let mut read_page = Page::new(read_address);
                        let read_old = read_page.entry_data();
                        read_page.map_kernel_read(read_address);

                        let mut write_page = Page::new(write_address);
                        let write_old = write_page.entry_data();
                        write_page.map_kernel_write(write_address);

                        ::memmove(write_address as *mut u8, read_address as *const u8, CLUSTER_SIZE);

                        write_page.set_entry_data(write_old);
                        write_page.flush();

                        read_page.set_entry_data(read_old);
                        read_page.flush();
                    }
                }
                unalloc(ptr);
            }
        }
    }

    ret
}

pub unsafe fn realloc_inplace(ptr: usize, size: usize) -> usize {
    let old_size = alloc_size(ptr);
    if size <= old_size {
        size
    } else {
        old_size
    }
}

pub fn memory_used() -> usize {
    let mut ret = 0;

    unsafe {
        for i in 0..CLUSTER_COUNT {
            if cluster(i) != 0 && cluster(i) != 0xFFFFFFFF {
                ret += CLUSTER_SIZE;
            }
        }
    }

    ret
}

pub fn memory_free() -> usize {
    let mut ret = 0;

    unsafe {
        for i in 0..CLUSTER_COUNT {
            if cluster(i) == 0 {
                ret += CLUSTER_SIZE;
            }
        }
    }

    ret
}
<commit_msg>Fix mapping issue in alloc<commit_after>// TODO: Doc the rest

use core::{cmp, intrinsics, mem};
use core::ops::{Index, IndexMut};
use core::{ptr, slice};

use super::paging::{Page, PAGE_END};

pub const CLUSTER_ADDRESS: usize = PAGE_END;
pub const CLUSTER_COUNT: usize = 1024 * 1024; // 4 GiB
pub const CLUSTER_SIZE: usize = 4096; // Of 4 K chunks

use system::error::{Result, Error, ENOMEM};

/// A wrapper around raw pointers
pub struct Memory<T> {
    ptr: *mut T,
    length: usize,
}

impl<T> Memory<T> {
    /// Allocate memory
    pub fn new(length: usize) -> Result<Self> {
        let alloc = unsafe { alloc(length * mem::size_of::<T>()) };
        if alloc > 0 {
            Ok(Memory {
                ptr: alloc as *mut T,
                length: length,
            })
        } else {
            Err(Error::new(ENOMEM))
        }
    }

    /// Allocate memory, aligned
    pub fn new_aligned(length: usize, align: usize) -> Result<Self> {
        let alloc = unsafe { alloc_aligned(length * mem::size_of::<T>(), align) };
        if alloc > 0 {
            Ok(Memory {
                ptr: alloc as *mut T,
                length: length,
            })
        } else {
            Err(Error::new(ENOMEM))
        }
    }

    /// Reallocate the memory
    pub fn renew(mut self, length: usize) -> Result<Self> {
        let alloc = unsafe { realloc(self.ptr as usize, length * mem::size_of::<T>()) };
        self.ptr = 0 as *mut T;
        if alloc > 0 {
            Ok(Memory {
                ptr: alloc as *mut T,
                length: length,
            })
        } else {
            Err(Error::new(ENOMEM))
        }
    }

    /// Reallocate the memory, aligned
    pub fn renew_aligned(mut self, length: usize, align: usize) -> Result<Self> {
        let alloc = unsafe { realloc_aligned(self.ptr as usize, length * mem::size_of::<T>(), align) };
        self.ptr = 0 as *mut T;
        if alloc > 0 {
            Ok(Memory {
                ptr: alloc as *mut T,
                length: length,
            })
        } else {
            Err(Error::new(ENOMEM))
        }
    }

    /// Get the length in T elements
    pub fn len(&self) -> usize {
        self.length
    }

    #[inline(always)]
    fn check_index(&self, i: usize) {
        if i >= self.length {
            panic!("Memory: {} >= {}", i, self.length);
        }
    }

    /// Read the memory
    pub fn read(&self, i: usize) -> T {
        self.check_index(i);
        unsafe { ptr::read(self.ptr.offset(i as isize)) }
    }

    /// Load the memory
    pub fn load(&self, i: usize) -> T {
        self.check_index(i);
        unsafe {
            intrinsics::atomic_singlethreadfence();
            ptr::read(self.ptr.offset(i as isize))
        }
    }

    /// Overwrite the memory
    pub fn write(&mut self, i: usize, value: T) {
        self.check_index(i);
        unsafe { ptr::write(self.ptr.offset(i as isize), value) };
    }

    /// Store the memory
    pub fn store(&mut self, i: usize, value: T) {
        self.check_index(i);
        unsafe {
            intrinsics::atomic_singlethreadfence();
            ptr::write(self.ptr.offset(i as isize), value)
        }
    }

    /// Get the address
    pub fn address(&self) -> usize {
        self.ptr as usize
    }

    /// Borrow as a slice
    pub fn as_slice(&self) -> &[T] {
        unsafe { slice::from_raw_parts(self.ptr, self.length) }
    }

    /// Borrow as a mutable slice
    pub fn as_mut_slice(&mut self) -> &mut [T] {
        unsafe { slice::from_raw_parts_mut(self.ptr, self.length) }
    }

    /// Borrow as a raw pointer
    pub unsafe fn as_ptr(&self) -> *const T {
        self.ptr as *const T
    }

    /// Borrow as a mutable raw pointer
    pub unsafe fn as_mut_ptr(&mut self) -> *mut T {
        self.ptr as *mut T
    }

    /// Convert into a raw pointer
    pub unsafe fn into_raw(mut self) -> *mut T {
        let ptr = self.ptr;
        self.ptr = 0 as *mut T;
        ptr
    }
}

impl<T> Drop for Memory<T> {
    fn drop(&mut self) {
        if self.ptr as usize > 0 {
            unsafe { unalloc(self.ptr as usize) };
        }
    }
}

impl<T> Index<usize> for Memory<T> {
    type Output = T;

    fn index<'a>(&'a self, i: usize) -> &'a T {
        self.check_index(i);
        unsafe { &*self.ptr.offset(i as isize) }
    }
}

impl<T> IndexMut<usize> for Memory<T> {
    fn index_mut<'a>(&'a mut self, i: usize) -> &'a mut T {
        self.check_index(i);
        unsafe { &mut *self.ptr.offset(i as isize) }
    }
}

/// A memory map entry
#[repr(packed)]
struct MemoryMapEntry {
    base: u64,
    len: u64,
    class: u32,
    acpi: u32,
}

const MEMORY_MAP: *const MemoryMapEntry = 0x500 as *const MemoryMapEntry;

/// Get the data (address) of a given cluster
pub unsafe fn cluster(number: usize) -> usize {
    if number < CLUSTER_COUNT {
        ptr::read((CLUSTER_ADDRESS + number * mem::size_of::<usize>()) as *const usize)
    } else {
        0
    }
}

/// Set the address of a cluster
pub unsafe fn set_cluster(number: usize, address: usize) {
    if number < CLUSTER_COUNT {
        ptr::write((CLUSTER_ADDRESS + number * mem::size_of::<usize>()) as *mut usize,
                   address);
    }
}

/// Convert an adress to the cluster number
pub unsafe fn address_to_cluster(address: usize) -> usize {
    if address >= CLUSTER_ADDRESS + CLUSTER_COUNT * mem::size_of::<usize>() {
        (address - CLUSTER_ADDRESS - CLUSTER_COUNT * mem::size_of::<usize>()) / CLUSTER_SIZE
    } else {
        0
    }
}

pub unsafe fn cluster_to_address(number: usize) -> usize {
    CLUSTER_ADDRESS + CLUSTER_COUNT * mem::size_of::<usize>() + number * CLUSTER_SIZE
}

/// Initialize clusters
pub unsafe fn cluster_init() {
    // First, set all clusters to the not present value
    for cluster in 0..CLUSTER_COUNT {
        set_cluster(cluster, 0xFFFFFFFF);
    }

    // Next, set all valid clusters to the free value
    // TODO: Optimize this function
    for i in 0..((0x5000 - 0x500) / mem::size_of::<MemoryMapEntry>()) {
        let entry = &*MEMORY_MAP.offset(i as isize);
        if entry.len > 0 && entry.class == 1 {
            for cluster in 0..CLUSTER_COUNT {
                let address = cluster_to_address(cluster);
                if address as u64 >= entry.base &&
                   (address as u64 + CLUSTER_SIZE as u64) <= (entry.base + entry.len) {
                    set_cluster(cluster, 0);
                }
            }
        }
    }
}

/// Allocate memory
pub unsafe fn alloc(size: usize) -> usize {
    alloc_aligned(size, 1)
}

/// Allocate memory, aligned
pub unsafe fn alloc_aligned(size: usize, align: usize) -> usize {
    if size > 0 {
        let mut number = 0;
        let mut count = 0;

        for i in 0..CLUSTER_COUNT {
            if cluster(i) == 0 && (count > 0 || cluster_to_address(i) % align == 0) {
                if count == 0 {
                    number = i;
                }

                count += 1;

                if count * CLUSTER_SIZE >= size {
                    break;
                }
            } else {
                count = 0;
            }
        }

        if count * CLUSTER_SIZE >= size {
            let address = cluster_to_address(number);

            for i in number..number + count {
                set_cluster(i, address);

                let cluster_address = cluster_to_address(i);

                let mut page = Page::new(cluster_address);
                let old = page.entry_data();
                page.map_kernel_write(cluster_address);

                ::memset(cluster_address as *mut u8, 0, CLUSTER_SIZE);

                page.set_entry_data(old);
                page.flush();
            }

            return address;
        }
    }

    0
}

/// Allocate a type
pub unsafe fn alloc_type<T>() -> *mut T {
    alloc(mem::size_of::<T>()) as *mut T
}

pub unsafe fn alloc_size(ptr: usize) -> usize {
    let mut size = 0;

    if ptr > 0 {
        for i in address_to_cluster(ptr)..CLUSTER_COUNT {
            if cluster(i) == ptr {
                size += CLUSTER_SIZE;
            } else {
                break;
            }
        }
    }

    size
}

pub unsafe fn unalloc(ptr: usize) {
    if ptr > 0 {
        for i in address_to_cluster(ptr)..CLUSTER_COUNT {
            if cluster(i) == ptr {
                set_cluster(i, 0);
            } else {
                break;
            }
        }
    }
}

pub unsafe fn unalloc_type<T>(ptr: *mut T) {
    unalloc(ptr as usize);
}

pub unsafe fn realloc(ptr: usize, size: usize) -> usize {
    realloc_aligned(ptr, size, 1)
}

pub unsafe fn realloc_aligned(ptr: usize, size: usize, align: usize) -> usize {
    let mut ret = 0;

    if size == 0 {
        if ptr > 0 {
            unalloc(ptr);
        }
    } else {
        let old_size = alloc_size(ptr);
        if size <= old_size {
            ret = ptr;
        } else {
            ret = alloc_aligned(size, align);
            if ptr > 0 {
                if ret > 0 {
                    let copy_size = cmp::min(old_size, size);

                    let read_cluster = address_to_cluster(ptr);
                    let write_cluster = address_to_cluster(ret);

                    for i in 0..(copy_size + CLUSTER_SIZE - 1)/CLUSTER_SIZE {
                        let read_address = cluster_to_address(read_cluster + i);
                        let write_address = cluster_to_address(write_cluster + i);

                        let mut read_page = Page::new(read_address);
                        let read_old = read_page.entry_data();
                        read_page.map_kernel_read(read_address);

                        let mut write_page = Page::new(write_address);
                        let write_old = write_page.entry_data();
                        write_page.map_kernel_write(write_address);

                        ::memmove(write_address as *mut u8, read_address as *const u8, CLUSTER_SIZE);

                        write_page.set_entry_data(write_old);
                        write_page.flush();

                        read_page.set_entry_data(read_old);
                        read_page.flush();
                    }
                }
                unalloc(ptr);
            }
        }
    }

    ret
}

pub unsafe fn realloc_inplace(ptr: usize, size: usize) -> usize {
    let old_size = alloc_size(ptr);
    if size <= old_size {
        size
    } else {
        old_size
    }
}

pub fn memory_used() -> usize {
    let mut ret = 0;

    unsafe {
        for i in 0..CLUSTER_COUNT {
            if cluster(i) != 0 && cluster(i) != 0xFFFFFFFF {
                ret += CLUSTER_SIZE;
            }
        }
    }

    ret
}

pub fn memory_free() -> usize {
    let mut ret = 0;

    unsafe {
        for i in 0..CLUSTER_COUNT {
            if cluster(i) == 0 {
                ret += CLUSTER_SIZE;
            }
        }
    }

    ret
}
<|endoftext|>


<commit_before>use super::*;

use dpi::{LogicalPosition, LogicalSize};
use event::{DeviceEvent, DeviceId as RootDI, ElementState, Event, KeyboardInput, ModifiersState, MouseButton, ScanCode, StartCause, VirtualKeyCode, WindowEvent};
use event_loop::{ControlFlow, EventLoopWindowTarget as RootELW, EventLoopClosed};
use icon::Icon;
use window::{MouseCursor, WindowId as RootWI};
use stdweb::{
    JsSerialize,
    traits::*,
    unstable::TryInto,
    web::{
        document,
        event::*,
        html_element::CanvasElement,
    },
};
use std::cell::{RefCell, RefMut};
use std::collections::VecDeque;
use std::collections::vec_deque::IntoIter as VecDequeIter;
use std::marker::PhantomData;
use std::rc::Rc;

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct DeviceId(i32);

impl DeviceId {
    pub unsafe fn dummy() -> Self {
        DeviceId(0)
    }
}

pub struct EventLoop<T: 'static> {
    elw: RootELW<T>,
}

pub struct EventLoopWindowTarget<T: 'static> {
    pub(crate) runner: EventLoopRunnerShared<T>,
}

impl<T> EventLoopWindowTarget<T> {
    fn new() -> Self {
        EventLoopWindowTarget {
            runner: Rc::new(ELRShared {
                runner: RefCell::new(None),
                events: RefCell::new(VecDeque::new())
            })
        }
    }
}

#[derive(Clone)]
pub struct EventLoopProxy<T> {
    runner: EventLoopRunnerShared<T>
}

impl<T> EventLoopProxy<T> {
    pub fn send_event(&self, event: T) -> Result<(), EventLoopClosed> {
        self.runner.send_event(Event::UserEvent(event));
        Ok(())
    }
}

pub type EventLoopRunnerShared<T> = Rc<ELRShared<T>>;

pub struct ELRShared<T> {
    runner: RefCell<Option<EventLoopRunner<T>>>,
    events: RefCell<VecDeque<Event<T>>>, // TODO: this may not be necessary?
}

struct EventLoopRunner<T> {
    control: ControlFlow,
    event_handler: Box<dyn FnMut(Event<T>, &mut ControlFlow)>,
}

impl<T> EventLoop<T> {
    pub fn new() -> Self {
        EventLoop {
            elw: RootELW {
                p: EventLoopWindowTarget::new(),
                _marker: PhantomData
            },
        }
    }

    pub fn get_available_monitors(&self) -> VecDequeIter<MonitorHandle> {
        VecDeque::new().into_iter()
    }

    pub fn get_primary_monitor(&self) -> MonitorHandle {
        MonitorHandle
    }

    pub fn run<F>(mut self, mut event_handler: F) -> !
        where F: 'static + FnMut(Event<T>, &RootELW<T>, &mut ControlFlow)
    {
        // TODO: how to handle request redraw?
        // TODO: onclose (stdweb PR)
        // TODO: file dropping, PathBuf isn't useful for web
        let runner = self.elw.p.runner;

        let relw = RootELW {
            p: EventLoopWindowTarget::new(),
            _marker: PhantomData
        };
        runner.set_listener(Box::new(move |evt, ctrl| event_handler(evt, &relw, ctrl)));

        let document = &document();
        add_event(&runner, document, |_, _: BlurEvent| {
        });
        add_event(&runner, document, |_, _: FocusEvent| {

        });
        add_event(&runner, document, |elrs, event: KeyDownEvent| {
            let key = event.key();
            let mut characters = key.chars();
            let first = characters.next();
            let second = characters.next();
            if let (Some(key), None) = (first, second) {
                elrs.send_event(Event::WindowEvent {
                    window_id: RootWI(WindowId),
                    event: WindowEvent::ReceivedCharacter(key)
                });
            }
            elrs.send_event(Event::WindowEvent {
                window_id: RootWI(WindowId),
                event: WindowEvent::KeyboardInput {
                    // TODO: is there a way to get keyboard device?
                    device_id: RootDI(unsafe { DeviceId::dummy() }),
                    input: KeyboardInput {
                        scancode: scancode(&event),
                        state: ElementState::Pressed,
                        virtual_keycode: button_mapping(&event),
                        modifiers: keyboard_modifiers_state(&event),
                    }
                }
            });
        });
        add_event(&runner, document, |elrs, event: KeyUpEvent| {
            elrs.send_event(Event::WindowEvent {
                window_id: RootWI(WindowId),
                event: WindowEvent::KeyboardInput {
                    // TODO: is there a way to get keyboard device?
                    device_id: RootDI(unsafe { DeviceId::dummy() }),
                    input: KeyboardInput {
                        scancode: scancode(&event),
                        state: ElementState::Released,
                        virtual_keycode: button_mapping(&event),
                        modifiers: keyboard_modifiers_state(&event),
                    }
                }
            });
        });
        stdweb::event_loop(); // TODO: this is only necessary for stdweb emscripten, should it be here?

        // Throw an exception to break out of Rust exceution and use unreachable to tell the
        // compiler this function won't return, giving it a return type of '!'
        js! {
            throw "Using exceptions for control flow, don't mind me";
        }
        unreachable!();
    }

    pub fn create_proxy(&self) -> EventLoopProxy<T> {
        EventLoopProxy {
            runner: self.elw.p.runner.clone()
        }
    }

    pub fn window_target(&self) -> &RootELW<T> {
        &self.elw
    }
}

pub fn register<T: 'static>(elrs: &EventLoopRunnerShared<T>, canvas: &CanvasElement) {
    add_event(elrs, canvas, |elrs, event: PointerOutEvent| {
        elrs.send_event(Event::WindowEvent {
            window_id: RootWI(WindowId),
            event: WindowEvent::CursorLeft {
                device_id: RootDI(DeviceId(event.pointer_id()))
            }
        });
    });
    add_event(elrs, canvas, |elrs, event: PointerOverEvent| {
        elrs.send_event(Event::WindowEvent {
            window_id: RootWI(WindowId),
            event: WindowEvent::CursorEntered {
                device_id: RootDI(DeviceId(event.pointer_id()))
            }
        });
    });
    add_event(elrs, canvas, |elrs, event: PointerMoveEvent| {
        elrs.send_event(Event::WindowEvent {
            window_id: RootWI(WindowId),
            event: WindowEvent::CursorMoved {
                device_id: RootDI(DeviceId(event.pointer_id())),
                position: LogicalPosition {
                    x: event.offset_x(),
                    y: event.offset_y()
                },
                modifiers: mouse_modifiers_state(&event)
            }
        });
    });
    add_event(elrs, canvas, |elrs, event: PointerUpEvent| {
        elrs.send_event(Event::WindowEvent {
            window_id: RootWI(WindowId),
            event: WindowEvent::MouseInput {
                device_id: RootDI(DeviceId(event.pointer_id())),
                state: ElementState::Pressed,
                button: mouse_button(&event),
                modifiers: mouse_modifiers_state(&event)
            }
        });
    });
    add_event(elrs, canvas, |elrs, event: PointerDownEvent| {
        elrs.send_event(Event::WindowEvent {
            window_id: RootWI(WindowId),
            event: WindowEvent::MouseInput {
                device_id: RootDI(DeviceId(event.pointer_id())),
                state: ElementState::Released,
                button: mouse_button(&event),
                modifiers: mouse_modifiers_state(&event)
            }
        });
    });
}

fn add_event<T: 'static, E, F>(elrs: &EventLoopRunnerShared<T>, target: &impl IEventTarget, mut handler: F)
        where E: ConcreteEvent, F: FnMut(&EventLoopRunnerShared<T>, E) + 'static {
    let elrs = elrs.clone();

    target.add_event_listener(move |event: E| {
        event.prevent_default();
        event.stop_propagation();
        event.cancel_bubble();

        handler(&elrs, event);
    });
}

impl<T> ELRShared<T> {
    fn blank() -> ELRShared<T> {
        ELRShared {
            runner: RefCell::new(None),
            events: RefCell::new(VecDeque::new())
        }
    }

    fn set_listener(&self, event_handler: Box<dyn FnMut(Event<T>, &mut ControlFlow)>) {
        *self.runner.borrow_mut() = Some(EventLoopRunner {
            control: ControlFlow::Poll,
            event_handler
        });
    }

    // TODO: handle event loop closures
    // TODO: handle event buffer
    pub fn send_event(&self, event: Event<T>) {
        match *self.runner.borrow_mut() {
            Some(ref mut runner) =>  {
                // TODO: bracket this in control flow events?
                (runner.event_handler)(event, &mut runner.control);
            }
            None => ()
        }
    }

}

<commit_msg>Implement focus event<commit_after>use super::*;

use dpi::{LogicalPosition, LogicalSize};
use event::{DeviceEvent, DeviceId as RootDI, ElementState, Event, KeyboardInput, ModifiersState, MouseButton, ScanCode, StartCause, VirtualKeyCode, WindowEvent};
use event_loop::{ControlFlow, EventLoopWindowTarget as RootELW, EventLoopClosed};
use icon::Icon;
use window::{MouseCursor, WindowId as RootWI};
use stdweb::{
    JsSerialize,
    traits::*,
    unstable::TryInto,
    web::{
        document,
        event::*,
        html_element::CanvasElement,
    },
};
use std::cell::{RefCell, RefMut};
use std::collections::VecDeque;
use std::collections::vec_deque::IntoIter as VecDequeIter;
use std::marker::PhantomData;
use std::rc::Rc;

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct DeviceId(i32);

impl DeviceId {
    pub unsafe fn dummy() -> Self {
        DeviceId(0)
    }
}

pub struct EventLoop<T: 'static> {
    elw: RootELW<T>,
}

pub struct EventLoopWindowTarget<T: 'static> {
    pub(crate) runner: EventLoopRunnerShared<T>,
}

impl<T> EventLoopWindowTarget<T> {
    fn new() -> Self {
        EventLoopWindowTarget {
            runner: Rc::new(ELRShared {
                runner: RefCell::new(None),
                events: RefCell::new(VecDeque::new())
            })
        }
    }
}

#[derive(Clone)]
pub struct EventLoopProxy<T> {
    runner: EventLoopRunnerShared<T>
}

impl<T> EventLoopProxy<T> {
    pub fn send_event(&self, event: T) -> Result<(), EventLoopClosed> {
        self.runner.send_event(Event::UserEvent(event));
        Ok(())
    }
}

pub type EventLoopRunnerShared<T> = Rc<ELRShared<T>>;

pub struct ELRShared<T> {
    runner: RefCell<Option<EventLoopRunner<T>>>,
    events: RefCell<VecDeque<Event<T>>>, // TODO: this may not be necessary?
}

struct EventLoopRunner<T> {
    control: ControlFlow,
    event_handler: Box<dyn FnMut(Event<T>, &mut ControlFlow)>,
}

impl<T> EventLoop<T> {
    pub fn new() -> Self {
        EventLoop {
            elw: RootELW {
                p: EventLoopWindowTarget::new(),
                _marker: PhantomData
            },
        }
    }

    pub fn get_available_monitors(&self) -> VecDequeIter<MonitorHandle> {
        VecDeque::new().into_iter()
    }

    pub fn get_primary_monitor(&self) -> MonitorHandle {
        MonitorHandle
    }

    pub fn run<F>(mut self, mut event_handler: F) -> !
        where F: 'static + FnMut(Event<T>, &RootELW<T>, &mut ControlFlow)
    {
        // TODO: how to handle request redraw?
        // TODO: onclose (stdweb PR)
        // TODO: file dropping, PathBuf isn't useful for web
        let runner = self.elw.p.runner;

        let relw = RootELW {
            p: EventLoopWindowTarget::new(),
            _marker: PhantomData
        };
        runner.set_listener(Box::new(move |evt, ctrl| event_handler(evt, &relw, ctrl)));

        let document = &document();
        add_event(&runner, document, |elrs, _: BlurEvent| {
            elrs.send_event(Event::WindowEvent {
                window_id: RootWI(WindowId),
                event: WindowEvent::Focused(false)
            });
        });
        add_event(&runner, document, |elrs, _: FocusEvent| {
            elrs.send_event(Event::WindowEvent {
                window_id: RootWI(WindowId),
                event: WindowEvent::Focused(true)
            });

        });
        add_event(&runner, document, |elrs, event: KeyDownEvent| {
            let key = event.key();
            let mut characters = key.chars();
            let first = characters.next();
            let second = characters.next();
            if let (Some(key), None) = (first, second) {
                elrs.send_event(Event::WindowEvent {
                    window_id: RootWI(WindowId),
                    event: WindowEvent::ReceivedCharacter(key)
                });
            }
            elrs.send_event(Event::WindowEvent {
                window_id: RootWI(WindowId),
                event: WindowEvent::KeyboardInput {
                    // TODO: is there a way to get keyboard device?
                    device_id: RootDI(unsafe { DeviceId::dummy() }),
                    input: KeyboardInput {
                        scancode: scancode(&event),
                        state: ElementState::Pressed,
                        virtual_keycode: button_mapping(&event),
                        modifiers: keyboard_modifiers_state(&event),
                    }
                }
            });
        });
        add_event(&runner, document, |elrs, event: KeyUpEvent| {
            elrs.send_event(Event::WindowEvent {
                window_id: RootWI(WindowId),
                event: WindowEvent::KeyboardInput {
                    // TODO: is there a way to get keyboard device?
                    device_id: RootDI(unsafe { DeviceId::dummy() }),
                    input: KeyboardInput {
                        scancode: scancode(&event),
                        state: ElementState::Released,
                        virtual_keycode: button_mapping(&event),
                        modifiers: keyboard_modifiers_state(&event),
                    }
                }
            });
        });
        stdweb::event_loop(); // TODO: this is only necessary for stdweb emscripten, should it be here?

        // Throw an exception to break out of Rust exceution and use unreachable to tell the
        // compiler this function won't return, giving it a return type of '!'
        js! {
            throw "Using exceptions for control flow, don't mind me";
        }
        unreachable!();
    }

    pub fn create_proxy(&self) -> EventLoopProxy<T> {
        EventLoopProxy {
            runner: self.elw.p.runner.clone()
        }
    }

    pub fn window_target(&self) -> &RootELW<T> {
        &self.elw
    }
}

pub fn register<T: 'static>(elrs: &EventLoopRunnerShared<T>, canvas: &CanvasElement) {
    add_event(elrs, canvas, |elrs, event: PointerOutEvent| {
        elrs.send_event(Event::WindowEvent {
            window_id: RootWI(WindowId),
            event: WindowEvent::CursorLeft {
                device_id: RootDI(DeviceId(event.pointer_id()))
            }
        });
    });
    add_event(elrs, canvas, |elrs, event: PointerOverEvent| {
        elrs.send_event(Event::WindowEvent {
            window_id: RootWI(WindowId),
            event: WindowEvent::CursorEntered {
                device_id: RootDI(DeviceId(event.pointer_id()))
            }
        });
    });
    add_event(elrs, canvas, |elrs, event: PointerMoveEvent| {
        elrs.send_event(Event::WindowEvent {
            window_id: RootWI(WindowId),
            event: WindowEvent::CursorMoved {
                device_id: RootDI(DeviceId(event.pointer_id())),
                position: LogicalPosition {
                    x: event.offset_x(),
                    y: event.offset_y()
                },
                modifiers: mouse_modifiers_state(&event)
            }
        });
    });
    add_event(elrs, canvas, |elrs, event: PointerUpEvent| {
        elrs.send_event(Event::WindowEvent {
            window_id: RootWI(WindowId),
            event: WindowEvent::MouseInput {
                device_id: RootDI(DeviceId(event.pointer_id())),
                state: ElementState::Pressed,
                button: mouse_button(&event),
                modifiers: mouse_modifiers_state(&event)
            }
        });
    });
    add_event(elrs, canvas, |elrs, event: PointerDownEvent| {
        elrs.send_event(Event::WindowEvent {
            window_id: RootWI(WindowId),
            event: WindowEvent::MouseInput {
                device_id: RootDI(DeviceId(event.pointer_id())),
                state: ElementState::Released,
                button: mouse_button(&event),
                modifiers: mouse_modifiers_state(&event)
            }
        });
    });
}

fn add_event<T: 'static, E, F>(elrs: &EventLoopRunnerShared<T>, target: &impl IEventTarget, mut handler: F)
        where E: ConcreteEvent, F: FnMut(&EventLoopRunnerShared<T>, E) + 'static {
    let elrs = elrs.clone();

    target.add_event_listener(move |event: E| {
        event.prevent_default();
        event.stop_propagation();
        event.cancel_bubble();

        handler(&elrs, event);
    });
}

impl<T> ELRShared<T> {
    fn blank() -> ELRShared<T> {
        ELRShared {
            runner: RefCell::new(None),
            events: RefCell::new(VecDeque::new())
        }
    }

    fn set_listener(&self, event_handler: Box<dyn FnMut(Event<T>, &mut ControlFlow)>) {
        *self.runner.borrow_mut() = Some(EventLoopRunner {
            control: ControlFlow::Poll,
            event_handler
        });
    }

    // TODO: handle event loop closures
    // TODO: handle event buffer
    pub fn send_event(&self, event: Event<T>) {
        match *self.runner.borrow_mut() {
            Some(ref mut runner) =>  {
                // TODO: bracket this in control flow events?
                (runner.event_handler)(event, &mut runner.control);
            }
            None => ()
        }
    }

}

<|endoftext|>


<commit_before>use std::fs::File;
use std::{io, io::prelude::*};
use std::hash::Hash;
use std::fmt::Debug;
use std::collections::HashMap;

type Recipe<T> = HashMap<T, u64>;
type RecipeBook<T> = HashMap<T, (Recipe<T>, u64)>;

fn get_input() -> io::Result<String> {
  let mut file = File::open("14.txt")?;
  let mut contents = String::new();
  file.read_to_string(&mut contents)?;

  Ok(contents)
}

fn parse_input(input: &str) -> RecipeBook<&str> {
  fn parse_ingredient(input: &str) -> Option<(&str, u64)> {
    let mut tokens = input.trim().split(" ");

    match (tokens.next(), tokens.next()) {
      (Some(amount), Some(id)) => {
        amount.parse::<u64>().ok()
        .map(|amount| (id, amount))
      },
      _ => None
    }
  }

  input.lines()
  .map(|line| line.split(" => "))
  .filter_map(|mut tokens| match (tokens.next(), tokens.next()) {
    (Some(ingredients), Some(outcome)) => {
      Some((ingredients.split(", "), outcome))
    },
    _ => None
  })
  .map(|(ingredients, outcome)| (ingredients.filter_map(parse_ingredient), parse_ingredient(outcome)))
  .filter_map(|(ingredients, outcome)| outcome.and_then(|outcome| {
    let ingredients = ingredients.collect::<Recipe<_>>();

    if ingredients.len() == 0 {
      return None;
    }

    Some((outcome.0, (ingredients, outcome.1)))
  }))
  .collect()
}

fn get_base_ingredient_amount<T>(recipes: &RecipeBook<T>, ingredient: T, amount: u64, residues: &mut Recipe<T>) -> u64
where T: Eq + Clone + Copy + Debug + Hash {
  let mut amount = amount;

  if let Some(residue) = residues.get_mut(&ingredient) {
    if *residue >= amount {
      *residue -= amount;
      amount = 0;
    } else {
      amount -= *residue;
      *residue = 0;
    }
  }

  if amount == 0 {
    return 0;
  }

  match recipes.get(&ingredient) {
    None => amount,
    Some((subrecipe, yield_amount)) => {
      let times = (amount as f64 / *yield_amount as f64).ceil() as u64;
      let result = subrecipe.iter()
        .map(|(&ingredient, &amount)| {
          get_base_ingredient_amount(recipes, ingredient, amount * times, residues)
        })
        .sum();

      let new_residue = residues.get(&ingredient).cloned().unwrap_or(0) + *yield_amount * times - amount;
      residues.insert(ingredient, new_residue);

      result
    }
  }
}

fn main() {
  let input = get_input().unwrap();
  let recipes = parse_input(&input);

  let ore = get_base_ingredient_amount(&recipes, "FUEL", 1, &mut Recipe::new());
  println!("Part 1: {}", ore);
}
<commit_msg>Add day 14 part 2 solution<commit_after>use std::fs::File;
use std::{io, io::prelude::*};
use std::hash::Hash;
use std::fmt::Debug;
use std::collections::HashMap;

type Recipe<T> = HashMap<T, u64>;
type RecipeBook<T> = HashMap<T, (Recipe<T>, u64)>;

fn get_input() -> io::Result<String> {
  let mut file = File::open("14.txt")?;
  let mut contents = String::new();
  file.read_to_string(&mut contents)?;

  Ok(contents)
}

fn parse_input(input: &str) -> RecipeBook<&str> {
  fn parse_ingredient(input: &str) -> Option<(&str, u64)> {
    let mut tokens = input.trim().split(" ");

    match (tokens.next(), tokens.next()) {
      (Some(amount), Some(id)) => {
        amount.parse::<u64>().ok()
        .map(|amount| (id, amount))
      },
      _ => None
    }
  }

  input.lines()
  .map(|line| line.split(" => "))
  .filter_map(|mut tokens| match (tokens.next(), tokens.next()) {
    (Some(ingredients), Some(outcome)) => {
      Some((ingredients.split(", "), outcome))
    },
    _ => None
  })
  .map(|(ingredients, outcome)| (ingredients.filter_map(parse_ingredient), parse_ingredient(outcome)))
  .filter_map(|(ingredients, outcome)| outcome.and_then(|outcome| {
    let ingredients = ingredients.collect::<Recipe<_>>();

    if ingredients.len() == 0 {
      return None;
    }

    Some((outcome.0, (ingredients, outcome.1)))
  }))
  .collect()
}

fn get_base_ingredient_amount<T>(recipes: &RecipeBook<T>, ingredient: T, amount: u64, residues: &mut Recipe<T>) -> u64
where T: Eq + Clone + Copy + Debug + Hash {
  let mut amount = amount;

  if let Some(residue) = residues.get_mut(&ingredient) {
    if *residue >= amount {
      *residue -= amount;
      amount = 0;
    } else {
      amount -= *residue;
      *residue = 0;
    }
  }

  if amount == 0 {
    return 0;
  }

  match recipes.get(&ingredient) {
    None => amount,
    Some((subrecipe, yield_amount)) => {
      let times = (amount as f64 / *yield_amount as f64).ceil() as u64;
      let result = subrecipe.iter()
        .map(|(&ingredient, &amount)| {
          get_base_ingredient_amount(recipes, ingredient, amount * times, residues)
        })
        .sum();

      let new_residue = residues.get(&ingredient).cloned().unwrap_or(0) + *yield_amount * times - amount;
      residues.insert(ingredient, new_residue);

      result
    }
  }
}

fn main() {
  let input = get_input().unwrap();
  let recipes = parse_input(&input);

  let one_fuel_ore = get_base_ingredient_amount(&recipes, "FUEL", 1, &mut Recipe::new());
  println!("Part 1: {}", one_fuel_ore);

  let max_ore = 1000000000000u64;
  let mut max_fuel_approx = max_ore / one_fuel_ore;
  let mut cooldown = false;

  loop {
    let ore = get_base_ingredient_amount(&recipes, "FUEL", max_fuel_approx, &mut Recipe::new());

    if ore < max_ore {
      if cooldown {
        break;
      }

      max_fuel_approx += (max_ore - ore) / one_fuel_ore + 1;
    } else {
      cooldown = true;
      max_fuel_approx -= 1;
    }
  }

  println!("Part 2: {}", max_fuel_approx);
}
<|endoftext|>


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

mod intcode;
use intcode::*;

#[derive(Debug, Clone)]
struct NetworkPackage {
  from: usize,
  to: usize,
  x: i64,
  y: i64
}

#[derive(Debug)]
enum NetworkEvent {
  OnPackage(NetworkPackage),
  OnTick
}

struct Network {
  nics: Vec<ProgramState>,
  queues: Vec<VecDeque<NetworkPackage>>,
  started: Vec<bool>,
  idle: Vec<bool>,
  event_queue: VecDeque<NetworkEvent>
}

impl Network {
  fn new(program: &[i64], count: usize) -> Network {
    let nics = (0..count)
      .map(|_| ProgramState::new(program.to_vec()))
      .collect::<Vec<_>>();
    let queues = nics.iter()
      .map(|_| VecDeque::<NetworkPackage>::new())
      .collect::<Vec<_>>();
    let started = nics.iter()
      .map(|_| false)
      .collect::<Vec<_>>();
    let idle = nics.iter()
      .map(|_| true)
      .collect::<Vec<_>>();

    Network {
      nics, queues, started, idle,
      event_queue: VecDeque::new()
    }
  }
}

impl Iterator for Network {
  type Item = NetworkEvent;

  fn next(&mut self) -> Option<NetworkEvent> {
    if let Some(event) = self.event_queue.pop_front() {
      return Some(event);
    }

    let count = self.nics.len();

    for id in 0..count {
      let (inputs, has_incoming_package) = {
        let mut inputs = if !self.started[id] {
          self.started[id] = true;
          vec![id as i64]
        } else {
          vec![]
        };

        let has_incoming_package = self.queues[id].len() > 0;

        inputs.append(
          &mut self.queues[id].pop_front()
          .map(|package| vec![package.x, package.y])
          .unwrap_or_else(|| vec![-1])
        );

        (inputs, has_incoming_package)
      };

      let (outputs, _) = run_program_with_inputs(&mut self.nics[id], inputs.into_iter());
      let mut outputs = outputs.into_iter();
      let mut has_outgoing_package = false;

      while let (Some(to), Some(x), Some(y)) = (outputs.next(), outputs.next(), outputs.next()) {
        has_outgoing_package = true;

        let package = NetworkPackage {
          from: id,
          to: to as usize,
          x, y
        };

        self.event_queue.push_back(NetworkEvent::OnPackage(package.clone()));

        if let Some(queue) = self.queues.get_mut(to as usize) {
          queue.push_back(package);
        }
      }

      self.idle[id] = !has_incoming_package && !has_outgoing_package;
      self.event_queue.push_back(NetworkEvent::OnTick);
    }

    self.event_queue.pop_front()
  }
}

fn get_input() -> std::io::Result<String> {
  let mut file = File::open("23.txt")?;
  let mut contents = String::new();
  file.read_to_string(&mut contents)?;

  Ok(contents)
}

fn main() {
  let input = get_input().unwrap();
  let program = input.split(',')
    .filter_map(|x| x.trim().parse::<i64>().ok())
    .collect::<Vec<_>>();

  let mut print_part1 = true;
  let mut nat = None;
  let network = Network::new(&program, 50);

  for event in network {
    match event {
      NetworkEvent::OnPackage(package) => {
        println!("{:?}", package);
        if package.to == 255 {
          if print_part1 {
            println!("Part 1: {}", package.y);
            print_part1 = false;
          }

          nat = Some((package.x, package.y));
        }
      },
      NetworkEvent::OnTick => {}
    }
  }
}
<commit_msg>Add day 23 part 2 solution<commit_after>use std::fs::File;
use std::io::prelude::*;
use std::collections::VecDeque;

mod intcode;
use intcode::*;

#[derive(Debug, Clone)]
struct NetworkPackage {
  from: usize,
  to: usize,
  x: i64,
  y: i64
}

#[derive(Debug)]
enum NetworkEvent {
  OnPackage(NetworkPackage),
  OnTick
}

struct Network {
  nics: Vec<ProgramState>,
  queues: Vec<VecDeque<NetworkPackage>>,
  started: Vec<bool>,
  idle: Vec<bool>,
  event_queue: VecDeque<NetworkEvent>
}

impl Network {
  fn new(program: &[i64], count: usize) -> Network {
    let nics = (0..count)
      .map(|_| ProgramState::new(program.to_vec()))
      .collect::<Vec<_>>();
    let queues = nics.iter()
      .map(|_| VecDeque::<NetworkPackage>::new())
      .collect::<Vec<_>>();
    let started = nics.iter()
      .map(|_| false)
      .collect::<Vec<_>>();
    let idle = nics.iter()
      .map(|_| true)
      .collect::<Vec<_>>();

    Network {
      nics, queues, started, idle,
      event_queue: VecDeque::new()
    }
  }
}

impl Iterator for Network {
  type Item = NetworkEvent;

  fn next(&mut self) -> Option<NetworkEvent> {
    if let Some(event) = self.event_queue.pop_front() {
      return Some(event);
    }

    let count = self.nics.len();

    for id in 0..count {
      let (inputs, has_incoming_package) = {
        let mut inputs = if !self.started[id] {
          self.started[id] = true;
          vec![id as i64]
        } else {
          vec![]
        };

        let has_incoming_package = self.queues[id].len() > 0;

        inputs.append(
          &mut self.queues[id].pop_front()
          .map(|package| vec![package.x, package.y])
          .unwrap_or_else(|| vec![-1])
        );

        (inputs, has_incoming_package)
      };

      let (outputs, _) = run_program_with_inputs(&mut self.nics[id], inputs.into_iter());
      let mut outputs = outputs.into_iter();
      let mut has_outgoing_package = false;

      while let (Some(to), Some(x), Some(y)) = (outputs.next(), outputs.next(), outputs.next()) {
        has_outgoing_package = true;

        let package = NetworkPackage {
          from: id,
          to: to as usize,
          x, y
        };

        self.event_queue.push_back(NetworkEvent::OnPackage(package.clone()));

        if let Some(queue) = self.queues.get_mut(to as usize) {
          queue.push_back(package);
        }
      }

      self.idle[id] = !has_incoming_package && !has_outgoing_package;
      self.event_queue.push_back(NetworkEvent::OnTick);
    }

    self.event_queue.pop_front()
  }
}

fn get_input() -> std::io::Result<String> {
  let mut file = File::open("23.txt")?;
  let mut contents = String::new();
  file.read_to_string(&mut contents)?;

  Ok(contents)
}

fn main() {
  let input = get_input().unwrap();
  let program = input.split(',')
    .filter_map(|x| x.trim().parse::<i64>().ok())
    .collect::<Vec<_>>();

  let mut print_part1 = true;
  let mut nat = None;
  let mut last_nat = None;
  let mut network = Network::new(&program, 50);

  while let Some(event) = network.next() {
    match event {
      NetworkEvent::OnPackage(package) => {
        if package.to == 255 {
          if print_part1 {
            println!("Part 1: {}", package.y);
            print_part1 = false;
          }

          nat = Some((package.x, package.y));
        }
      },
      NetworkEvent::OnTick => {
        if network.idle.iter().all(|&x| x) {
          if let Some((x, y)) = nat {
            match last_nat {
              Some((_, last_y)) if last_y == y => {
                println!("Part 2: {}", y);
                return;
              },
              _ => {}
            }

            network.queues[0].push_back(NetworkPackage {
              from: 255,
              to: 0,
              x, y
            });

            last_nat = nat;
            nat = None;
          }
        }
      }
    }
  }
}
<|endoftext|>