<commit_before>use memory::Memory;
use std::vec::Vec;
use std::sync::atomic::{AtomicIsize, Ordering};

/// Maps multiple `Memory`s into a single address space.
///
/// The `MappedMemory` allows to unify multiple `Memory`s in one address space.
/// A `Memory` is mounted at a certain address and is from now on responsible
/// for all reads and writes between that starting at that address (the “mount
/// point”) and ending where the mounted memory ends.
/// The read and write calls for the responsible `Memory` will be given an
/// address _relative_ to the mount point.
///
/// ```text
///                   Unmapped
///                <-------->
///       mem_a                   mem_b
/// |--------------|            |------|
///                            NullMemory
///                         |--------------
/// |------------- mapped_mem ----------->
/// |              |            |      |
/// 0            0x100        0x200  0x280
/// ```
///
/// For example: `mapped_mem.get(0x208)` would yield the same value as
/// `mem_b.get(0x008)`.
///
/// # Examples
///
/// ```
/// use osciemu::memory::{Memory, SliceMemory, MappedMemory};
///
/// let mut mm = MappedMemory::new();
/// let m1 = mm.mount(0, Box::new(SliceMemory::from_slice(Box::new([1]))));
/// let m2 = mm.mount(2, Box::new(SliceMemory::from_slice(Box::new([2, 2]))));
/// // Now mm =~ [1, _, 2, 2]
/// assert_eq!(mm.get(0), 1);
/// assert_eq!(mm.get(3), 2);
/// ```
///
/// The `MemoryToken`s can be used to access the `Memory` even if it has been
/// mounted. They work like `std::cell::RefCell`.
///
/// ```
/// use osciemu::memory::{Memory, NullMemory, SliceMemory, MappedMemory};
/// use osciemu::memory::mappedmemory::MemoryToken;
///
/// let mut mm = MappedMemory::new();
/// let m1 = mm.mount(0, Box::new(NullMemory::new()));
/// let m2 = mm.mount(0, Box::new(SliceMemory::from_slice(Box::new([1, 2, 3, 4]))));
/// mm.set(0, 99);
/// assert_eq!(mm.get(0), 99);
/// assert_eq!(mm.borrow(&m2).get(0), 99);
/// ```
///
/// The `MemoryToken`s are also used to unmount a mounted `Memory`.
///
/// ```
/// # use osciemu::memory::{Memory, NullMemory, SliceMemory, MappedMemory};
/// # use osciemu::memory::mappedmemory::MemoryToken;
/// # let mut mm = MappedMemory::new();
/// # let m1 = mm.mount(0, Box::new(NullMemory::new()));
/// # let m2 = mm.mount(0, Box::new(SliceMemory::from_slice(Box::new([1, 2, 3, 4]))));
/// # mm.set(0, 99);
/// // ...
/// mm.unmount(&m2);
/// assert_eq!(mm.get(0), 0);
/// assert_eq!(mm.borrow(&m2).get(0), 99);
/// ```
///
/// # Panics
/// `MappedMemory` panics when an unmapped address is read or written.
pub struct MappedMemory {
    mounted_memories: Vec<Entry>,
    unmounted_memories: Vec<Entry>,
}

static id_counter: AtomicIsize = AtomicIsize::new(0);

struct Entry {
    id: isize,
    start_address: usize,
    size: usize,
    memory: Box<Memory>,
}

impl Entry {
    fn contains(&self, addr: usize) -> bool {
        self.start_address <= addr && self.start_address + self.size > addr
    }
}

#[derive(Clone)]
pub struct MemoryToken {
    id: isize,
}

impl MappedMemory {
    pub fn new() -> MappedMemory {
        MappedMemory {
            mounted_memories: Vec::new(),
            unmounted_memories: Vec::new(),
        }
    }

    /// Mounts a `Memory` at the given address.
    pub fn mount(&mut self, start_address: usize, memory: Box<Memory>) -> MemoryToken {
        let size = memory.size();
        let id = id_counter.fetch_add(1, Ordering::Relaxed);
        let new_entry = Entry {
            id,
            start_address,
            size,
            memory,
        };
        self.mounted_memories.push(new_entry);
        MemoryToken{id}
    }

    /// Unmounts the `Memory` references by the `MemoryToken`. After unmounting,
    /// `MappedMemory` does not hold any references to the `Memory`.
    pub fn unmount(&mut self, token: &MemoryToken) {
        let idx = self.mounted_memories
            .iter()
            .enumerate()
            .find(|&(_idx, entry)| entry.id == token.id)
            .map(|(idx, _entry)| {
               idx
            });

        idx
            .map(|idx| self.mounted_memories.remove(idx))
            .map(|entry| self.unmounted_memories.push(entry));
    }

    pub fn borrow(&self, token: &MemoryToken) -> &Box<Memory> {
        &self.entry_for_token(token).memory
    }

    pub fn borrow_mut(&mut self, token: &MemoryToken) -> &mut Box<Memory> {
        &mut self.entry_for_token_mut(token).memory
    }

    fn entry_for_token(&self, token: &MemoryToken) -> &Entry {
        let m = self.mounted_memories
            .iter()
            .find(|ref entry| entry.id == token.id);

        if m.is_some() {
            m.unwrap()
        } else {
            self.unmounted_memories
                .iter()
                .find(|ref entry| entry.id == token.id)
                .unwrap()
        }
    }

    fn entry_for_token_mut(&mut self, token: &MemoryToken) -> &mut Entry {
        let m = self.mounted_memories
            .iter_mut()
            .find(|ref mut entry| entry.id == token.id);

        if m.is_some() {
            m.unwrap()
        } else {
            self.unmounted_memories
                .iter_mut()
                .find(|ref mut entry| entry.id == token.id)
                .unwrap()
        }
    }

    fn entry_at_addr(&self, addr: usize) -> Option<&Entry> {
        self.mounted_memories
            .iter()
            .rev()
            .find(|entry| entry.contains(addr))
    }

    fn entry_at_addr_mut(&mut self, addr: usize) -> Option<&mut Entry> {
        self.mounted_memories
            .iter_mut()
            .rev()
            .find(|entry| entry.contains(addr))
    }
}

impl Memory for MappedMemory {
    fn get(&self, addr: usize) -> u32 {
        self.entry_at_addr(addr)
            .map(|entry| entry.memory.get(addr - entry.start_address))
            .expect("Out of bounds")
    }

    fn set(&mut self, addr: usize, value: u32) {
        self.entry_at_addr_mut(addr)
            .map(|entry| entry.memory.set(addr - entry.start_address, value))
            .expect("Out of bounds")
    }

    fn size(&self) -> usize {
        self.mounted_memories
            .iter()
            .map(|entry| entry.start_address + entry.size)
            .max()
            .unwrap_or(0)
    }
}

#[cfg(test)]
mod tests {
    use memory::{Memory, SliceMemory, NullMemory};

    // #[test]
    // fn overlapping_mounts() {
    //     let m1 = super::MemoryToken::new(NullMemory::new());
    //     let m2 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([2, 2])));
    //     let m3 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([3])));
    //     let mut mm = super::MappedMemory::new();
    //     mm.mount(0, &m1);
    //     mm.mount(1, &m2);
    //     mm.mount(2, &m3);
    //     assert_eq!(mm.get(0), 0);
    //     assert_eq!(mm.get(1), 2);
    //     assert_eq!(mm.get(2), 3);
    //     assert_eq!(mm.get(3), 0);
    // }

    // #[test]
    // fn get_and_set() {
    //     let m1 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([1])));
    //     let m2 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([2, 2])));
    //     let mut mm = super::MappedMemory::new();

    //     mm.mount(0, &m1);
    //     mm.mount(2, &m2);
    //     assert_eq!(mm.get(0), 1);
    //     assert_eq!(mm.get(2), 2);

    //     mm.set(0, 3);
    //     assert_eq!(mm.get(0), 3);

    //     mm.set(3, 0);
    //     assert_eq!(mm.get(3), 0);
    //     assert_eq!(m1.borrow().get(0), 3);
    //     assert_eq!(m2.borrow().get(1), 0);
    // }

    // #[test]
    // fn size() {
    //     let m1 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([1])));
    //     let m2 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([2, 2])));
    //     let mut mm = super::MappedMemory::new();
    //     assert_eq!(mm.size(), 0);

    //     mm.mount(0, &m1);
    //     assert_eq!(mm.size(), 1);

    //     mm.mount(2, &m2);
    //     assert_eq!(mm.size(), 4);
    // }

    // #[test]
    // fn size_with_overlap() {
    //     let m1 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([1, 1, 1, 1, 1])));
    //     let m2 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([2, 2])));
    //     let m3 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([3, 3, 3])));
    //     let mut mm = super::MappedMemory::new();

    //     mm.mount(0, &m1);
    //     mm.mount(2, &m2);
    //     assert_eq!(mm.size(), 5);

    //     mm.mount(6, &m3);
    //     assert_eq!(mm.size(), 9);
    // }

    // #[test]
    // fn unmount() {
    //     let m1 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([1, 1, 1, 1, 1])));
    //     let m2 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([2, 2, 2, 2, 2])));
    //     let m3 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([3, 3, 3, 3, 3])));
    //     let mut mm = super::MappedMemory::new();
    //     mm.mount(0, &m1);
    //     mm.mount(0, &m2);
    //     mm.mount(0, &m3);

    //     for i in 0..5 {
    //         assert_eq!(mm.get(i), 3);
    //     }
    //     mm.unmount(&m3);
    //     for i in 0..5 {
    //         assert_eq!(mm.get(i), 2);
    //     }
    //     mm.unmount(&m3);
    //     mm.unmount(&m3);
    //     for i in 0..5 {
    //         assert_eq!(mm.get(i), 2);
    //     }
    //     mm.unmount(&m1);
    //     for i in 0..5 {
    //         assert_eq!(mm.get(i), 2);
    //     }
    // }
}
<commit_msg>refactor(mappedmemory): Re-enable tests<commit_after>use memory::Memory;
use std::vec::Vec;
use std::sync::atomic::{AtomicIsize, Ordering};

/// Maps multiple `Memory`s into a single address space.
///
/// The `MappedMemory` allows to unify multiple `Memory`s in one address space.
/// A `Memory` is mounted at a certain address and is from now on responsible
/// for all reads and writes between that starting at that address (the “mount
/// point”) and ending where the mounted memory ends.
/// The read and write calls for the responsible `Memory` will be given an
/// address _relative_ to the mount point.
///
/// ```text
///                   Unmapped
///                <-------->
///       mem_a                   mem_b
/// |--------------|            |------|
///                            NullMemory
///                         |--------------
/// |------------- mapped_mem ----------->
/// |              |            |      |
/// 0            0x100        0x200  0x280
/// ```
///
/// For example: `mapped_mem.get(0x208)` would yield the same value as
/// `mem_b.get(0x008)`.
///
/// # Examples
///
/// ```
/// use osciemu::memory::{Memory, SliceMemory, MappedMemory};
///
/// let mut mm = MappedMemory::new();
/// let m1 = mm.mount(0, Box::new(SliceMemory::from_slice(Box::new([1]))));
/// let m2 = mm.mount(2, Box::new(SliceMemory::from_slice(Box::new([2, 2]))));
/// // Now mm =~ [1, _, 2, 2]
/// assert_eq!(mm.get(0), 1);
/// assert_eq!(mm.get(3), 2);
/// ```
///
/// The `MemoryToken`s can be used to access the `Memory` even if it has been
/// mounted. They work like `std::cell::RefCell`.
///
/// ```
/// use osciemu::memory::{Memory, NullMemory, SliceMemory, MappedMemory};
/// use osciemu::memory::mappedmemory::MemoryToken;
///
/// let mut mm = MappedMemory::new();
/// let m1 = mm.mount(0, Box::new(NullMemory::new()));
/// let m2 = mm.mount(0, Box::new(SliceMemory::from_slice(Box::new([1, 2, 3, 4]))));
/// mm.set(0, 99);
/// assert_eq!(mm.get(0), 99);
/// assert_eq!(mm.borrow(&m2).get(0), 99);
/// ```
///
/// The `MemoryToken`s are also used to unmount a mounted `Memory`.
///
/// ```
/// # use osciemu::memory::{Memory, NullMemory, SliceMemory, MappedMemory};
/// # use osciemu::memory::mappedmemory::MemoryToken;
/// # let mut mm = MappedMemory::new();
/// # let m1 = mm.mount(0, Box::new(NullMemory::new()));
/// # let m2 = mm.mount(0, Box::new(SliceMemory::from_slice(Box::new([1, 2, 3, 4]))));
/// # mm.set(0, 99);
/// // ...
/// mm.unmount(&m2);
/// assert_eq!(mm.get(0), 0);
/// assert_eq!(mm.borrow(&m2).get(0), 99);
/// ```
///
/// # Panics
/// `MappedMemory` panics when an unmapped address is read or written.
pub struct MappedMemory {
    mounted_memories: Vec<Entry>,
    unmounted_memories: Vec<Entry>,
}

static id_counter: AtomicIsize = AtomicIsize::new(0);

struct Entry {
    id: isize,
    start_address: usize,
    size: usize,
    memory: Box<Memory>,
}

impl Entry {
    fn contains(&self, addr: usize) -> bool {
        self.start_address <= addr && self.start_address + self.size > addr
    }
}

#[derive(Clone)]
pub struct MemoryToken {
    id: isize,
}

impl MappedMemory {
    pub fn new() -> MappedMemory {
        MappedMemory {
            mounted_memories: Vec::new(),
            unmounted_memories: Vec::new(),
        }
    }

    /// Mounts a `Memory` at the given address.
    pub fn mount(&mut self, start_address: usize, memory: Box<Memory>) -> MemoryToken {
        let size = memory.size();
        let id = id_counter.fetch_add(1, Ordering::Relaxed);
        let new_entry = Entry {
            id,
            start_address,
            size,
            memory,
        };
        self.mounted_memories.push(new_entry);
        MemoryToken{id}
    }

    /// Unmounts the `Memory` references by the `MemoryToken`. After unmounting,
    /// `MappedMemory` does not hold any references to the `Memory`.
    pub fn unmount(&mut self, token: &MemoryToken) {
        let idx = self.mounted_memories
            .iter()
            .enumerate()
            .find(|&(_idx, entry)| entry.id == token.id)
            .map(|(idx, _entry)| {
               idx
            });

        idx
            .map(|idx| self.mounted_memories.remove(idx))
            .map(|entry| self.unmounted_memories.push(entry));
    }

    pub fn borrow(&self, token: &MemoryToken) -> &Box<Memory> {
        &self.entry_for_token(token).memory
    }

    pub fn borrow_mut(&mut self, token: &MemoryToken) -> &mut Box<Memory> {
        &mut self.entry_for_token_mut(token).memory
    }

    fn entry_for_token(&self, token: &MemoryToken) -> &Entry {
        let m = self.mounted_memories
            .iter()
            .find(|ref entry| entry.id == token.id);

        if m.is_some() {
            m.unwrap()
        } else {
            self.unmounted_memories
                .iter()
                .find(|ref entry| entry.id == token.id)
                .unwrap()
        }
    }

    fn entry_for_token_mut(&mut self, token: &MemoryToken) -> &mut Entry {
        let m = self.mounted_memories
            .iter_mut()
            .find(|ref mut entry| entry.id == token.id);

        if m.is_some() {
            m.unwrap()
        } else {
            self.unmounted_memories
                .iter_mut()
                .find(|ref mut entry| entry.id == token.id)
                .unwrap()
        }
    }

    fn entry_at_addr(&self, addr: usize) -> Option<&Entry> {
        self.mounted_memories
            .iter()
            .rev()
            .find(|entry| entry.contains(addr))
    }

    fn entry_at_addr_mut(&mut self, addr: usize) -> Option<&mut Entry> {
        self.mounted_memories
            .iter_mut()
            .rev()
            .find(|entry| entry.contains(addr))
    }
}

impl Memory for MappedMemory {
    fn get(&self, addr: usize) -> u32 {
        self.entry_at_addr(addr)
            .map(|entry| entry.memory.get(addr - entry.start_address))
            .expect("Out of bounds")
    }

    fn set(&mut self, addr: usize, value: u32) {
        self.entry_at_addr_mut(addr)
            .map(|entry| entry.memory.set(addr - entry.start_address, value))
            .expect("Out of bounds")
    }

    fn size(&self) -> usize {
        self.mounted_memories
            .iter()
            .map(|entry| entry.start_address + entry.size)
            .max()
            .unwrap_or(0)
    }
}

#[cfg(test)]
mod tests {
    use memory::{Memory, SliceMemory, NullMemory};

    #[test]
    fn overlapping_mounts() {
        let mut mm = super::MappedMemory::new();
        let m1 = mm.mount(0, Box::new(NullMemory::new()));
        let m2 = mm.mount(1, Box::new(SliceMemory::from_slice(Box::new([2, 2]))));
        let m3 = mm.mount(2, Box::new(SliceMemory::from_slice(Box::new([3]))));
        assert_eq!(mm.get(0), 0);
        assert_eq!(mm.get(1), 2);
        assert_eq!(mm.get(2), 3);
        assert_eq!(mm.get(3), 0);
    }

    #[test]
    fn get_and_set() {
        let mut mm = super::MappedMemory::new();
        let m1 = mm.mount(0, Box::new(SliceMemory::from_slice(Box::new([1]))));
        let m2 = mm.mount(2, Box::new(SliceMemory::from_slice(Box::new([2, 2]))));

        assert_eq!(mm.get(0), 1);
        assert_eq!(mm.get(2), 2);

        mm.set(0, 3);
        assert_eq!(mm.get(0), 3);

        mm.set(3, 0);
        assert_eq!(mm.get(3), 0);
        assert_eq!(mm.borrow(&m1).get(0), 3);
        assert_eq!(mm.borrow(&m2).get(1), 0);
    }

    #[test]
    fn size() {
        let mut mm = super::MappedMemory::new();
        let m1 = Box::new(SliceMemory::from_slice(Box::new([1])));
        let m2 = Box::new(SliceMemory::from_slice(Box::new([2, 2])));
        assert_eq!(mm.size(), 0);

        mm.mount(0, m1);
        assert_eq!(mm.size(), 1);

        mm.mount(2, m2);
        assert_eq!(mm.size(), 4);
    }

    #[test]
    fn size_with_overlap() {
        let mut mm = super::MappedMemory::new();
        let m1 = Box::new(SliceMemory::from_slice(Box::new([1, 1, 1, 1, 1])));
        let m2 = Box::new(SliceMemory::from_slice(Box::new([2, 2])));
        let m3 = Box::new(SliceMemory::from_slice(Box::new([3, 3, 3])));

        mm.mount(0, m1);
        mm.mount(2, m2);
        assert_eq!(mm.size(), 5);

        mm.mount(6, m3);
        assert_eq!(mm.size(), 9);
    }

    #[test]
    fn unmount() {
        let mut mm = super::MappedMemory::new();
        let m1 = mm.mount(0, Box::new(SliceMemory::from_slice(Box::new([1, 1, 1, 1, 1]))));
        let m2 = mm.mount(0, Box::new(SliceMemory::from_slice(Box::new([2, 2, 2, 2, 2]))));
        let m3 = mm.mount(0, Box::new(SliceMemory::from_slice(Box::new([3, 3, 3, 3, 3]))));

        for i in 0..5 {
            assert_eq!(mm.get(i), 3);
        }
        mm.unmount(&m3);
        for i in 0..5 {
            assert_eq!(mm.get(i), 2);
        }
        mm.unmount(&m3);
        mm.unmount(&m3);
        for i in 0..5 {
            assert_eq!(mm.get(i), 2);
        }
        mm.unmount(&m1);
        for i in 0..5 {
            assert_eq!(mm.get(i), 2);
        }
    }
}
<|endoftext|>


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

use std::cmp::Ordering;

use super::symbol_range::*;
use super::countable::*;

///
/// A symbol map maps from one set of symbol ranges to another
///
pub struct SymbolMap<Symbol: PartialOrd+Clone+Countable> {
    // Ranges in this symbol map
    ranges: Vec<SymbolRange<Symbol>>,
}

impl<Symbol: PartialOrd+Clone+Countable> SymbolMap<Symbol> {
    ///
    /// Creates a new symbol map
    ///
    pub fn new() -> SymbolMap<Symbol> {
        SymbolMap { ranges: vec![] }
    }

    ///
    /// Orders two symbols (makes unordered symbols equal)
    ///
    #[inline]
    fn order_symbols(a: &Symbol, b: &Symbol) -> Ordering {
        if let Some(order) = a.partial_cmp(b) {
            order
        } else {
            Ordering::Equal
        }
    }

    ///
    /// Orders two symbol ranges
    ///
    #[inline]
    fn order_ranges(a: &SymbolRange<Symbol>, b: &SymbolRange<Symbol>) -> Ordering {
        let ordering = SymbolMap::order_symbols(&a.lowest, &b.lowest);

        if ordering == Ordering::Equal {
            SymbolMap::order_symbols(&b.highest, &a.highest)
        } else {
            ordering
        }
    }

    ///
    /// Adds a range to those that are known about by this object
    ///
    pub fn add_range(&mut self, range: &SymbolRange<Symbol>) {
        let existing = self.ranges.binary_search_by(|test_range| { SymbolMap::order_ranges(test_range, range) });

        // Insert the range if it is not already in the map
        if let Err(insertion_pos) = existing {
            self.ranges.insert(insertion_pos, range.clone());
        }
    }

    ///
    /// Finds the ranges in this map that overlap the target ranges
    ///
    pub fn find_overlapping_ranges(&self, range: &SymbolRange<Symbol>) -> Vec<&SymbolRange<Symbol>> {
        let mut result = vec![];

        // Find the first range that matches (or the insertion position, which should be the first range wit a lowest value higher than the target range)
        let existing = self.ranges.binary_search_by(|test_range| { SymbolMap::order_ranges(test_range, range) });

        // Start returning values from here
        let mut pos = match existing {
            Ok(found_position) => found_position,
            Err(insert_position) => insert_position
        };

        // Move backwards if the previous position overlaps this one
        if pos > 0 && self.ranges[pos-1].highest >= range.lowest {
            pos -= 1;
        }

        // TODO: can we construct a set of ranges such that one is missed here? Think maybe we can
        while pos < self.ranges.len() && self.ranges[pos].lowest <= range.highest {
            result.push(&self.ranges[pos]);
            pos += 1;
        }

        result
    }

    ///
    /// Creates a non-overlapping range from an overlapping one
    ///
    pub fn to_non_overlapping_map(&self) -> SymbolMap<Symbol> {
        // Stack, popping the lowest ordered ranges first
        let mut to_process = self.ranges.clone();
        to_process.reverse();

        let mut result = vec![];

        while let Some(might_overlap) = to_process.pop() {
            if let Some(overlap_with) = to_process.pop() {
                // Stack has two ranges on top. They might overlap
                if !might_overlap.overlaps(&overlap_with) {
                    // Doesn't overlap: can just push might_overlap and continue
                    result.push(might_overlap);
                    to_process.push(overlap_with);
                } else {
                    // Got an overlap
                    if might_overlap == overlap_with {
                        // Ranges are the same, just discard one
                        to_process.push(overlap_with);
                    } else if might_overlap.lowest == overlap_with.lowest {
                        // Ranges start at the same location. We need to divide them in case more than two ranges are overlapping
                        let (smaller_range, larger_range) = (overlap_with, might_overlap);      // Because of the sort order

                        // Chop out the smaller range from the larger range, then insert into the stack in order
                        let larger_range_without_smaller_range = SymbolRange::new(smaller_range.highest.next(), larger_range.highest.clone());

                        to_process.push(smaller_range);

                        if let Err(insertion_pos) = to_process.binary_search_by(|test_range| { SymbolMap::order_ranges(&larger_range_without_smaller_range, test_range) }) {
                            to_process.insert(insertion_pos, larger_range_without_smaller_range);
                        }
                    } else {
                        // There's a range from the lowest of the first range to the lowest of the second ranges
                        result.push(SymbolRange::new(might_overlap.lowest.clone(), overlap_with.lowest.prev()));

                        // Chop out the bit we just pushed from might_overlap and push back both ranges
                        to_process.push(overlap_with.clone());
                        to_process.push(SymbolRange::new(overlap_with.lowest, might_overlap.highest));
                    }
                }
            } else {
                // Last range should never overlap
                result.push(might_overlap);
            }
        }

        // Ranges should already be sorted as we worked from left to right
        SymbolMap { ranges: result }
    }
}

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

    #[test]
    fn can_lookup_overlapping_ranges() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 4));
        map.add_range(&SymbolRange::new(2, 5));
        map.add_range(&SymbolRange::new(3, 6));

        let bottom = map.find_overlapping_ranges(&SymbolRange::new(0, 1));
        let all    = map.find_overlapping_ranges(&SymbolRange::new(1, 3));
        let top    = map.find_overlapping_ranges(&SymbolRange::new(6, 6));

        assert!(bottom == vec![&SymbolRange::new(0, 4)]);
        assert!(all == vec![&SymbolRange::new(0, 4), &SymbolRange::new(2, 5), &SymbolRange::new(3, 6)]);
        assert!(top == vec![&SymbolRange::new(3, 6)]);
    }

    #[test]
    fn can_lookup_mid_range() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 4));
        map.add_range(&SymbolRange::new(5, 10));
        map.add_range(&SymbolRange::new(11, 15));

        let mid = map.find_overlapping_ranges(&SymbolRange::new(1, 3));

        assert!(mid == vec![&SymbolRange::new(0, 4)]);
    }

    #[test]
    fn works_with_duplicate_lower_values() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 2));
        map.add_range(&SymbolRange::new(0, 3));

        let all    = map.find_overlapping_ranges(&SymbolRange::new(0, 1));

        assert!(all == vec![&SymbolRange::new(0, 2), &SymbolRange::new(0, 3)]);
    }

    #[test]
    fn can_get_non_overlapping_map() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 4));
        map.add_range(&SymbolRange::new(2, 5));
        map.add_range(&SymbolRange::new(3, 6));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 6));

        assert!(all == vec![&SymbolRange::new(0, 1), &SymbolRange::new(2, 2), &SymbolRange::new(3, 4), &SymbolRange::new(5, 5), &SymbolRange::new(6, 6)]);
    }

    #[test]
    fn can_get_non_overlapping_map_with_single_symbols() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 5));
        map.add_range(&SymbolRange::new(2, 2));
        map.add_range(&SymbolRange::new(3, 6));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 6));

        assert!(all == vec![&SymbolRange::new(0, 1), &SymbolRange::new(2, 2), &SymbolRange::new(3, 5), &SymbolRange::new(6, 6)]);
    }

    #[test]
    fn generate_correctly_for_single_symbol() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 0));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 10));

        assert!(all == vec![&SymbolRange::new(0, 0)]);
    }

    #[test]
    fn generate_correctly_for_two_single_symbols() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 0));
        map.add_range(&SymbolRange::new(1, 1));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 10));

        assert!(all == vec![&SymbolRange::new(0, 0), &SymbolRange::new(1, 1)]);
    }

    #[test]
    fn generate_correctly_for_non_overlapping_ranges() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 1));
        map.add_range(&SymbolRange::new(2, 4));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 10));

        assert!(all == vec![&SymbolRange::new(0, 1), &SymbolRange::new(2, 4)]);
    }

    #[test]
    fn generate_correctly_for_single_overlap() {
        let mut map = SymbolMap::new();

        // Here the symbol '5' is in both ranges, so we should generate it as a seperate range in the non-overlapping version
        map.add_range(&SymbolRange::new(0, 5));
        map.add_range(&SymbolRange::new(5, 10));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 10));
        println!("{:?}", all);

        assert!(all == vec![&SymbolRange::new(0, 4), &SymbolRange::new(5,5), &SymbolRange::new(6, 10)]);
    }

    #[test]
    fn can_get_non_overlapping_map_with_single_symbols_at_start() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 0));
        map.add_range(&SymbolRange::new(0, 1));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 6));

        assert!(all == vec![&SymbolRange::new(0, 0), &SymbolRange::new(1, 1)]);
    }

    #[test]
    fn can_get_non_overlapping_map_with_single_symbols_at_start_and_gap() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 0));
        map.add_range(&SymbolRange::new(0, 1));
        map.add_range(&SymbolRange::new(3, 6));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 6));

        assert!(all == vec![&SymbolRange::new(0, 0), &SymbolRange::new(1, 1), &SymbolRange::new(3, 6)]);
    }
}
<commit_msg>Fix ordering algorithm<commit_after>//
//   Copyright 2016 Andrew Hunter
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//

use std::cmp::Ordering;

use super::symbol_range::*;
use super::countable::*;

///
/// A symbol map maps from one set of symbol ranges to another
///
pub struct SymbolMap<Symbol: PartialOrd+Clone+Countable> {
    // Ranges in this symbol map
    ranges: Vec<SymbolRange<Symbol>>,
}

impl<Symbol: PartialOrd+Clone+Countable> SymbolMap<Symbol> {
    ///
    /// Creates a new symbol map
    ///
    pub fn new() -> SymbolMap<Symbol> {
        SymbolMap { ranges: vec![] }
    }

    ///
    /// Orders two symbols (makes unordered symbols equal)
    ///
    #[inline]
    fn order_symbols(a: &Symbol, b: &Symbol) -> Ordering {
        if let Some(order) = a.partial_cmp(b) {
            order
        } else {
            Ordering::Equal
        }
    }

    ///
    /// Orders two symbol ranges
    ///
    #[inline]
    fn order_ranges(a: &SymbolRange<Symbol>, b: &SymbolRange<Symbol>) -> Ordering {
        let ordering = SymbolMap::order_symbols(&a.lowest, &b.lowest);

        if ordering == Ordering::Equal {
            SymbolMap::order_symbols(&a.highest, &b.highest)
        } else {
            ordering
        }
    }

    ///
    /// Adds a range to those that are known about by this object
    ///
    pub fn add_range(&mut self, range: &SymbolRange<Symbol>) {
        let existing = self.ranges.binary_search_by(|test_range| { SymbolMap::order_ranges(test_range, range) });

        // Insert the range if it is not already in the map
        if let Err(insertion_pos) = existing {
            self.ranges.insert(insertion_pos, range.clone());
        }
    }

    ///
    /// Finds the ranges in this map that overlap the target ranges
    ///
    pub fn find_overlapping_ranges(&self, range: &SymbolRange<Symbol>) -> Vec<&SymbolRange<Symbol>> {
        let mut result = vec![];

        // Find the first range that matches (or the insertion position, which should be the first range wit a lowest value higher than the target range)
        let existing = self.ranges.binary_search_by(|test_range| { SymbolMap::order_ranges(test_range, range) });

        // Start returning values from here
        let mut pos = match existing {
            Ok(found_position) => found_position,
            Err(insert_position) => insert_position
        };

        // Move backwards if the previous position overlaps this one
        if pos > 0 && self.ranges[pos-1].highest >= range.lowest {
            pos -= 1;
        }

        // TODO: can we construct a set of ranges such that one is missed here? Think maybe we can
        while pos < self.ranges.len() && self.ranges[pos].lowest <= range.highest {
            result.push(&self.ranges[pos]);
            pos += 1;
        }

        result
    }

    ///
    /// Creates a non-overlapping range from an overlapping one
    ///
    pub fn to_non_overlapping_map(&self) -> SymbolMap<Symbol> {
        // Stack, popping the lowest ordered ranges first
        let mut to_process = self.ranges.clone();
        to_process.reverse();

        let mut result = vec![];

        while let Some(might_overlap) = to_process.pop() {
            if let Some(overlap_with) = to_process.pop() {
                // Stack has two ranges on top. They might overlap
                if !might_overlap.overlaps(&overlap_with) {
                    // Doesn't overlap: can just push might_overlap and continue
                    result.push(might_overlap);
                    to_process.push(overlap_with);
                } else {
                    // Got an overlap
                    if might_overlap == overlap_with {
                        // Ranges are the same, just discard one
                        to_process.push(overlap_with);
                    } else if might_overlap.lowest == overlap_with.lowest {
                        // Ranges start at the same location. We need to divide them in case more than two ranges are overlapping
                        let (smaller_range, larger_range) = (might_overlap, overlap_with);      // Because of the sort order

                        // Chop out the smaller range from the larger range, then insert into the stack in order
                        let larger_range_without_smaller_range = SymbolRange::new(smaller_range.highest.next(), larger_range.highest.clone());

                        if let Err(insertion_pos) = to_process.binary_search_by(|test_range| { SymbolMap::order_ranges(&larger_range_without_smaller_range, test_range) }) {
                            to_process.insert(insertion_pos, larger_range_without_smaller_range);
                        }

                        to_process.push(smaller_range);
                    } else {
                        // There's a range from the lowest of the first range to the lowest of the second ranges
                        result.push(SymbolRange::new(might_overlap.lowest.clone(), overlap_with.lowest.prev()));

                        // Chop out the bit we just pushed from might_overlap and push back both ranges
                        to_process.push(overlap_with.clone());
                        to_process.push(SymbolRange::new(overlap_with.lowest, might_overlap.highest));
                    }
                }
            } else {
                // Last range should never overlap
                result.push(might_overlap);
            }
        }

        // Ranges should already be sorted as we worked from left to right
        SymbolMap { ranges: result }
    }
}

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

    #[test]
    fn can_lookup_overlapping_ranges() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 4));
        map.add_range(&SymbolRange::new(2, 5));
        map.add_range(&SymbolRange::new(3, 6));

        let bottom = map.find_overlapping_ranges(&SymbolRange::new(0, 1));
        let all    = map.find_overlapping_ranges(&SymbolRange::new(1, 3));
        let top    = map.find_overlapping_ranges(&SymbolRange::new(6, 6));

        assert!(bottom == vec![&SymbolRange::new(0, 4)]);
        assert!(all == vec![&SymbolRange::new(0, 4), &SymbolRange::new(2, 5), &SymbolRange::new(3, 6)]);
        assert!(top == vec![&SymbolRange::new(3, 6)]);
    }

    #[test]
    fn can_lookup_mid_range() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 4));
        map.add_range(&SymbolRange::new(5, 10));
        map.add_range(&SymbolRange::new(11, 15));

        let mid = map.find_overlapping_ranges(&SymbolRange::new(1, 3));

        assert!(mid == vec![&SymbolRange::new(0, 4)]);
    }

    #[test]
    fn works_with_duplicate_lower_values() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 2));
        map.add_range(&SymbolRange::new(0, 3));

        let all    = map.find_overlapping_ranges(&SymbolRange::new(0, 1));

        assert!(all == vec![&SymbolRange::new(0, 2), &SymbolRange::new(0, 3)]);
    }

    #[test]
    fn can_get_non_overlapping_map() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 4));
        map.add_range(&SymbolRange::new(2, 5));
        map.add_range(&SymbolRange::new(3, 6));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 6));

        assert!(all == vec![&SymbolRange::new(0, 1), &SymbolRange::new(2, 2), &SymbolRange::new(3, 4), &SymbolRange::new(5, 5), &SymbolRange::new(6, 6)]);
    }

    #[test]
    fn can_get_non_overlapping_map_with_single_symbols() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 5));
        map.add_range(&SymbolRange::new(2, 2));
        map.add_range(&SymbolRange::new(3, 6));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 6));

        assert!(all == vec![&SymbolRange::new(0, 1), &SymbolRange::new(2, 2), &SymbolRange::new(3, 5), &SymbolRange::new(6, 6)]);
    }

    #[test]
    fn generate_correctly_for_single_symbol() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 0));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 10));

        assert!(all == vec![&SymbolRange::new(0, 0)]);
    }

    #[test]
    fn generate_correctly_for_two_single_symbols() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 0));
        map.add_range(&SymbolRange::new(1, 1));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 10));

        assert!(all == vec![&SymbolRange::new(0, 0), &SymbolRange::new(1, 1)]);
    }

    #[test]
    fn generate_correctly_for_non_overlapping_ranges() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 1));
        map.add_range(&SymbolRange::new(2, 4));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 10));

        assert!(all == vec![&SymbolRange::new(0, 1), &SymbolRange::new(2, 4)]);
    }

    #[test]
    fn generate_correctly_for_single_overlap() {
        let mut map = SymbolMap::new();

        // Here the symbol '5' is in both ranges, so we should generate it as a seperate range in the non-overlapping version
        map.add_range(&SymbolRange::new(0, 5));
        map.add_range(&SymbolRange::new(5, 10));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 10));
        println!("{:?}", all);

        assert!(all == vec![&SymbolRange::new(0, 4), &SymbolRange::new(5,5), &SymbolRange::new(6, 10)]);
    }

    #[test]
    fn can_get_non_overlapping_map_with_single_symbols_at_start() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 0));
        map.add_range(&SymbolRange::new(0, 1));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 6));

        assert!(all == vec![&SymbolRange::new(0, 0), &SymbolRange::new(1, 1)]);
    }

    #[test]
    fn can_get_non_overlapping_map_with_single_symbols_at_start_and_gap() {
        let mut map = SymbolMap::new();

        map.add_range(&SymbolRange::new(0, 0));
        map.add_range(&SymbolRange::new(0, 1));
        map.add_range(&SymbolRange::new(3, 6));

        let non_overlapping = map.to_non_overlapping_map();

        let all = non_overlapping.find_overlapping_ranges(&SymbolRange::new(0, 6));

        assert!(all == vec![&SymbolRange::new(0, 0), &SymbolRange::new(1, 1), &SymbolRange::new(3, 6)]);
    }
}
<|endoftext|>


<commit_before>//! Implements static board evaluation.

use std::hash::{Hasher, SipHasher};
use basetypes::*;
use bitsets::*;
use position::board::Board;

/// Statically evaluates the board.
///
/// This method considers only static material and positional
/// properties of the position. If the position is dynamic, with
/// pending tactical threats, this function will return a grossly
/// incorrect evaluation. Therefore, it should be relied upon only
/// for reasonably "quiet" positions.
///
/// The returned value will always be between -19999 and 19999.
#[inline]
pub fn evaluate_board(board: &Board) -> Value {
    // TODO: Implement a real evaluation.

    const PIECE_VALUES: [Value; 8] = [10000, 975, 500, 325, 325, 100, 0, 0];

    let piece_type = board.piece_type();
    let color = board.color();
    let us = board.to_move();
    let them = 1 ^ us;
    let mut result = 0;
    for piece in QUEEN..NO_PIECE {
        result += PIECE_VALUES[piece] *
                  (pop_count(piece_type[piece] & color[us]) as i16 -
                   pop_count(piece_type[piece] & color[them]) as i16);
    }
    let mut hasher = SipHasher::new();
    hasher.write_u64(board.occupied());
    result + (hasher.finish() >> 59) as i16
}

// use rand;
// use rand::distributions::{Sample, Range};
// let mut rng = rand::thread_rng();
// let mut between = Range::new(0, 10);
// let x = between.sample(&mut rng);

<commit_msg>be incorrect in evaluations under check<commit_after>//! Implements static board evaluation.

use std::hash::{Hasher, SipHasher};
use basetypes::*;
use bitsets::*;
use position::board::Board;

/// Statically evaluates the board.
///
/// This method considers only static material and positional
/// properties of the position. If the position is dynamic, with
/// pending tactical threats, this function will return a grossly
/// incorrect evaluation. Therefore, it should be relied upon only
/// for reasonably "quiet" positions.
///
/// The returned value will always be between -19999 and 19999.
#[inline]
pub fn evaluate_board(board: &Board) -> Value {
    // TODO: Implement a real evaluation.

    const PIECE_VALUES: [Value; 8] = [10000, 975, 500, 325, 325, 100, 0, 0];

    if board.checkers() != 0 {
        // In positions under check we can be vastly incorrect with no
        // negative consequences.
        return -19999;
    }

    let piece_type = board.piece_type();
    let color = board.color();
    let us = board.to_move();
    let them = 1 ^ us;
    let mut result = 0;
    for piece in QUEEN..NO_PIECE {
        result += PIECE_VALUES[piece] *
                  (pop_count(piece_type[piece] & color[us]) as i16 -
                   pop_count(piece_type[piece] & color[them]) as i16);
    }
    let mut hasher = SipHasher::new();
    hasher.write_u64(board.occupied());
    result + (hasher.finish() >> 59) as i16
}

// use rand;
// use rand::distributions::{Sample, Range};
// let mut rng = rand::thread_rng();
// let mut between = Range::new(0, 10);
// let x = between.sample(&mut rng);

<|endoftext|>


<commit_before>use std::sync::Arc;

use serde::{Serialize, Deserialize};
use parking_lot::RwLock;

use super::state::{TurtleState, DrawingState};
use super::renderer::display_list::PrimHandle;

/// The unique ID of a particular turtle
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct TurtleId(usize);

#[derive(Default, Debug)]
pub struct TurtleDrawings {
    /// The current state of this turtle: position, heading, etc.
    pub state: TurtleState,

    /// The drawings in the display list that have been created by this turtle
    pub drawings: Vec<PrimHandle>,

    /// If the turtle is currently filling, this is the handle to the fill polygon that new points
    /// should be appended to
    ///
    /// This handle will already be present in `drawings`, so it does not need to be added after
    /// the fill has begun.
    pub current_fill_polygon: Option<PrimHandle>,
}

/// The entire state of the application, shared between threads in the server
#[derive(Default, Debug)]
pub struct App {
    /// The current state of the drawing
    drawing: DrawingState,
    /// Each `TurtleId` indexes into this field
    ///
    /// Need to be very careful deleting from this field because the `TurtleId` returned from
    /// `add_turtle()` must remain unique and thus can never be repeated.
    turtles: Vec<TurtleDrawings>,
}

impl App {
    /// Adds a new turtle to the application state, returning its `TurtleId`
    pub fn add_turtle(&mut self) -> TurtleId {
        let id = TurtleId(self.turtles.len());
        self.turtles.push(Default::default());
        id
    }

    /// Returns a read-only handle to the drawing state
    pub fn drawing(&self) -> &DrawingState {
        &self.drawing
    }

    /// Returns a mutable handle to the drawing state
    pub fn drawing_mut(&mut self) -> &mut DrawingState {
        &mut self.drawing
    }

    /// Returns a read-only handle to the given turtle
    pub fn turtle(&self, id: TurtleId) -> &TurtleDrawings {
        let TurtleId(index) = id;
        &self.turtles[index]
    }

    /// Returns a mutable handle to the given turtle
    pub fn turtle_mut(&mut self, id: TurtleId) -> &mut TurtleDrawings {
        let TurtleId(index) = id;
        &mut self.turtles[index]
    }

    /// Returns an iterator over all of the turtles
    pub fn turtles(&self) -> impl Iterator<Item=(TurtleId, &TurtleDrawings)> {
        (0..).zip(self.turtles.iter()).map(|(id, turtle)| (TurtleId(id), turtle))
    }

    /// Returns an iterator over all of the turtles
    pub fn turtles_mut(&mut self) -> impl Iterator<Item=(TurtleId, &mut TurtleDrawings)> {
        (0..).zip(self.turtles.iter_mut()).map(|(id, turtle)| (TurtleId(id), turtle))
    }
}

// Using `RwLock` so that requests that only need to read from the state can run concurrently with
// rendering.
pub type SharedApp = Arc<RwLock<App>>;
<commit_msg>Allowing dead code for method not used in tests<commit_after>use std::sync::Arc;

use serde::{Serialize, Deserialize};
use parking_lot::RwLock;

use super::state::{TurtleState, DrawingState};
use super::renderer::display_list::PrimHandle;

/// The unique ID of a particular turtle
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct TurtleId(usize);

#[derive(Default, Debug)]
pub struct TurtleDrawings {
    /// The current state of this turtle: position, heading, etc.
    pub state: TurtleState,

    /// The drawings in the display list that have been created by this turtle
    pub drawings: Vec<PrimHandle>,

    /// If the turtle is currently filling, this is the handle to the fill polygon that new points
    /// should be appended to
    ///
    /// This handle will already be present in `drawings`, so it does not need to be added after
    /// the fill has begun.
    pub current_fill_polygon: Option<PrimHandle>,
}

/// The entire state of the application, shared between threads in the server
#[derive(Default, Debug)]
pub struct App {
    /// The current state of the drawing
    drawing: DrawingState,
    /// Each `TurtleId` indexes into this field
    ///
    /// Need to be very careful deleting from this field because the `TurtleId` returned from
    /// `add_turtle()` must remain unique and thus can never be repeated.
    turtles: Vec<TurtleDrawings>,
}

impl App {
    /// Adds a new turtle to the application state, returning its `TurtleId`
    pub fn add_turtle(&mut self) -> TurtleId {
        let id = TurtleId(self.turtles.len());
        self.turtles.push(Default::default());
        id
    }

    /// Returns a read-only handle to the drawing state
    pub fn drawing(&self) -> &DrawingState {
        &self.drawing
    }

    /// Returns a mutable handle to the drawing state
    pub fn drawing_mut(&mut self) -> &mut DrawingState {
        &mut self.drawing
    }

    /// Returns a read-only handle to the given turtle
    pub fn turtle(&self, id: TurtleId) -> &TurtleDrawings {
        let TurtleId(index) = id;
        &self.turtles[index]
    }

    /// Returns a mutable handle to the given turtle
    pub fn turtle_mut(&mut self, id: TurtleId) -> &mut TurtleDrawings {
        let TurtleId(index) = id;
        &mut self.turtles[index]
    }

    /// Returns an iterator over all of the turtles
    #[cfg_attr(feature = "test", allow(dead_code))] // Used in renderer, but not for tests
    pub fn turtles(&self) -> impl Iterator<Item=(TurtleId, &TurtleDrawings)> {
        (0..).zip(self.turtles.iter()).map(|(id, turtle)| (TurtleId(id), turtle))
    }

    /// Returns an iterator over all of the turtles
    pub fn turtles_mut(&mut self) -> impl Iterator<Item=(TurtleId, &mut TurtleDrawings)> {
        (0..).zip(self.turtles.iter_mut()).map(|(id, turtle)| (TurtleId(id), turtle))
    }
}

// Using `RwLock` so that requests that only need to read from the state can run concurrently with
// rendering.
pub type SharedApp = Arc<RwLock<App>>;
<|endoftext|>


<commit_before>//! Windows-specific types for signal handling.
//!
//! This module is only defined on Windows and contains the primary `Event` type
//! for receiving notifications of events. These events are listened for via the
//! `SetConsoleCtrlHandler` function which receives events of the type
//! `CTRL_C_EVENT` and `CTRL_BREAK_EVENT`

#![cfg(windows)]

use crate::signal::registry::{globals, EventId, EventInfo, Init, Storage};
use crate::sync::mpsc::{channel, Receiver};

use std::convert::TryFrom;
use std::io;
use std::sync::Once;
use std::task::{Context, Poll};
use winapi::shared::minwindef::{BOOL, DWORD, FALSE, TRUE};
use winapi::um::consoleapi::SetConsoleCtrlHandler;
use winapi::um::wincon::{CTRL_BREAK_EVENT, CTRL_C_EVENT};

#[derive(Debug)]
pub(crate) struct OsStorage {
    ctrl_c: EventInfo,
    ctrl_break: EventInfo,
}

impl Init for OsStorage {
    fn init() -> Self {
        Self {
            ctrl_c: EventInfo::default(),
            ctrl_break: EventInfo::default(),
        }
    }
}

impl Storage for OsStorage {
    fn event_info(&self, id: EventId) -> Option<&EventInfo> {
        match DWORD::try_from(id) {
            Ok(CTRL_C_EVENT) => Some(&self.ctrl_c),
            Ok(CTRL_BREAK_EVENT) => Some(&self.ctrl_break),
            _ => None,
        }
    }

    fn for_each<'a, F>(&'a self, mut f: F)
    where
        F: FnMut(&'a EventInfo),
    {
        f(&self.ctrl_c);
        f(&self.ctrl_break);
    }
}

#[derive(Debug)]
pub(crate) struct OsExtraData {}

impl Init for OsExtraData {
    fn init() -> Self {
        Self {}
    }
}

/// Stream of events discovered via `SetConsoleCtrlHandler`.
///
/// This structure can be used to listen for events of the type `CTRL_C_EVENT`
/// and `CTRL_BREAK_EVENT`. The `Stream` trait is implemented for this struct
/// and will resolve for each notification received by the process. Note that
/// there are few limitations with this as well:
///
/// * A notification to this process notifies *all* `Event` streams for that
///   event type.
/// * Notifications to an `Event` stream **are coalesced** if they aren't
///   processed quickly enough. This means that if two notifications are
///   received back-to-back, then the stream may only receive one item about the
///   two notifications.
#[must_use = "streams do nothing unless polled"]
#[derive(Debug)]
pub(crate) struct Event {
    rx: Receiver<()>,
}

pub(crate) fn ctrl_c() -> io::Result<Event> {
    Event::new(CTRL_C_EVENT)
}

impl Event {
    fn new(signum: DWORD) -> io::Result<Self> {
        global_init()?;

        let (tx, rx) = channel(1);
        globals().register_listener(signum as EventId, tx);

        Ok(Event { rx })
    }

    pub(crate) async fn recv(&mut self) -> Option<()> {
        use crate::future::poll_fn;
        poll_fn(|cx| self.rx.poll_recv(cx)).await
    }
}

fn global_init() -> io::Result<()> {
    static INIT: Once = Once::new();

    let mut init = None;

    INIT.call_once(|| unsafe {
        let rc = SetConsoleCtrlHandler(Some(handler), TRUE);
        let ret = if rc == 0 {
            Err(io::Error::last_os_error())
        } else {
            Ok(())
        };

        init = Some(ret);
    });

    init.unwrap_or_else(|| Ok(()))
}

unsafe extern "system" fn handler(ty: DWORD) -> BOOL {
    let globals = globals();
    globals.record_event(ty as EventId);

    // According to https://docs.microsoft.com/en-us/windows/console/handlerroutine
    // the handler routine is always invoked in a new thread, thus we don't
    // have the same restrictions as in Unix signal handlers, meaning we can
    // go ahead and perform the broadcast here.
    if globals.broadcast() {
        TRUE
    } else {
        // No one is listening for this notification any more
        // let the OS fire the next (possibly the default) handler.
        FALSE
    }
}

/// Represents a stream which receives "ctrl-break" notifications sent to the process
/// via `SetConsoleCtrlHandler`.
///
/// A notification to this process notifies *all* streams listening for
/// this event. Moreover, the notifications **are coalesced** if they aren't processed
/// quickly enough. This means that if two notifications are received back-to-back,
/// then the stream may only receive one item about the two notifications.
#[must_use = "streams do nothing unless polled"]
#[derive(Debug)]
pub struct CtrlBreak {
    inner: Event,
}

impl CtrlBreak {
    /// Receives the next signal notification event.
    ///
    /// `None` is returned if no more events can be received by this stream.
    ///
    /// # Examples
    ///
    /// ```rust,no_run
    /// use tokio::signal::windows::ctrl_break;
    ///
    /// #[tokio::main]
    /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
    ///     // An infinite stream of CTRL-BREAK events.
    ///     let mut stream = ctrl_break()?;
    ///
    ///     // Print whenever a CTRL-BREAK event is received
    ///     loop {
    ///         stream.recv().await;
    ///         println!("got signal CTRL-BREAK");
    ///     }
    /// }
    /// ```
    pub async fn recv(&mut self) -> Option<()> {
        use crate::future::poll_fn;
        poll_fn(|cx| self.poll_recv(cx)).await
    }

    /// Polls to receive the next signal notification event, outside of an
    /// `async` context.
    ///
    /// `None` is returned if no more events can be received by this stream.
    ///
    /// # Examples
    ///
    /// Polling from a manually implemented future
    ///
    /// ```rust,no_run
    /// use std::pin::Pin;
    /// use std::future::Future;
    /// use std::task::{Context, Poll};
    /// use tokio::signal::windows::CtrlBreak;
    ///
    /// struct MyFuture {
    ///     ctrl_break: CtrlBreak,
    /// }
    ///
    /// impl Future for MyFuture {
    ///     type Output = Option<()>;
    ///
    ///     fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
    ///         println!("polling MyFuture");
    ///         self.ctrl_break.poll_recv(cx)
    ///     }
    /// }
    /// ```
    pub fn poll_recv(&mut self, cx: &mut Context<'_>) -> Poll<Option<()>> {
        self.inner.rx.poll_recv(cx)
    }
}

cfg_stream! {
    impl crate::stream::Stream for CtrlBreak {
        type Item = ();

        fn poll_next(mut self: std::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<()>> {
            self.poll_recv(cx)
        }
    }
}

/// Creates a new stream which receives "ctrl-break" notifications sent to the
/// process.
///
/// # Examples
///
/// ```rust,no_run
/// use tokio::signal::windows::ctrl_break;
///
/// #[tokio::main]
/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
///     // An infinite stream of CTRL-BREAK events.
///     let mut stream = ctrl_break()?;
///
///     // Print whenever a CTRL-BREAK event is received
///     loop {
///         stream.recv().await;
///         println!("got signal CTRL-BREAK");
///     }
/// }
/// ```
pub fn ctrl_break() -> io::Result<CtrlBreak> {
    Event::new(CTRL_BREAK_EVENT).map(|inner| CtrlBreak { inner })
}

#[cfg(all(test, not(loom)))]
mod tests {
    use super::*;
    use crate::runtime::Runtime;
    use crate::stream::StreamExt;

    use tokio_test::{assert_ok, assert_pending, assert_ready_ok, task};

    #[test]
    fn ctrl_c() {
        let rt = rt();
        let _enter = rt.enter();

        let mut ctrl_c = task::spawn(crate::signal::ctrl_c());

        assert_pending!(ctrl_c.poll());

        // Windows doesn't have a good programmatic way of sending events
        // like sending signals on Unix, so we'll stub out the actual OS
        // integration and test that our handling works.
        unsafe {
            super::handler(CTRL_C_EVENT);
        }

        assert_ready_ok!(ctrl_c.poll());
    }

    #[test]
    fn ctrl_break() {
        let rt = rt();

        rt.block_on(async {
            let mut ctrl_break = assert_ok!(super::ctrl_break());

            // Windows doesn't have a good programmatic way of sending events
            // like sending signals on Unix, so we'll stub out the actual OS
            // integration and test that our handling works.
            unsafe {
                super::handler(CTRL_BREAK_EVENT);
            }

            ctrl_break.next().await.unwrap();
        });
    }

    fn rt() -> Runtime {
        crate::runtime::Builder::new_current_thread()
            .build()
            .unwrap()
    }
}
<commit_msg>signal: expose CtrlC stream on windows (#3186)<commit_after>//! Windows-specific types for signal handling.
//!
//! This module is only defined on Windows and allows receiving "ctrl-c"
//! and "ctrl-break" notifications. These events are listened for via the
//! `SetConsoleCtrlHandler` function which receives events of the type
//! `CTRL_C_EVENT` and `CTRL_BREAK_EVENT`.

#![cfg(windows)]

use crate::signal::registry::{globals, EventId, EventInfo, Init, Storage};
use crate::sync::mpsc::{channel, Receiver};

use std::convert::TryFrom;
use std::io;
use std::sync::Once;
use std::task::{Context, Poll};
use winapi::shared::minwindef::{BOOL, DWORD, FALSE, TRUE};
use winapi::um::consoleapi::SetConsoleCtrlHandler;
use winapi::um::wincon::{CTRL_BREAK_EVENT, CTRL_C_EVENT};

#[derive(Debug)]
pub(crate) struct OsStorage {
    ctrl_c: EventInfo,
    ctrl_break: EventInfo,
}

impl Init for OsStorage {
    fn init() -> Self {
        Self {
            ctrl_c: EventInfo::default(),
            ctrl_break: EventInfo::default(),
        }
    }
}

impl Storage for OsStorage {
    fn event_info(&self, id: EventId) -> Option<&EventInfo> {
        match DWORD::try_from(id) {
            Ok(CTRL_C_EVENT) => Some(&self.ctrl_c),
            Ok(CTRL_BREAK_EVENT) => Some(&self.ctrl_break),
            _ => None,
        }
    }

    fn for_each<'a, F>(&'a self, mut f: F)
    where
        F: FnMut(&'a EventInfo),
    {
        f(&self.ctrl_c);
        f(&self.ctrl_break);
    }
}

#[derive(Debug)]
pub(crate) struct OsExtraData {}

impl Init for OsExtraData {
    fn init() -> Self {
        Self {}
    }
}

/// Stream of events discovered via `SetConsoleCtrlHandler`.
///
/// This structure can be used to listen for events of the type `CTRL_C_EVENT`
/// and `CTRL_BREAK_EVENT`. The `Stream` trait is implemented for this struct
/// and will resolve for each notification received by the process. Note that
/// there are few limitations with this as well:
///
/// * A notification to this process notifies *all* `Event` streams for that
///   event type.
/// * Notifications to an `Event` stream **are coalesced** if they aren't
///   processed quickly enough. This means that if two notifications are
///   received back-to-back, then the stream may only receive one item about the
///   two notifications.
#[must_use = "streams do nothing unless polled"]
#[derive(Debug)]
pub(crate) struct Event {
    rx: Receiver<()>,
}

impl Event {
    fn new(signum: DWORD) -> io::Result<Self> {
        global_init()?;

        let (tx, rx) = channel(1);
        globals().register_listener(signum as EventId, tx);

        Ok(Event { rx })
    }

    pub(crate) async fn recv(&mut self) -> Option<()> {
        use crate::future::poll_fn;
        poll_fn(|cx| self.rx.poll_recv(cx)).await
    }
}

fn global_init() -> io::Result<()> {
    static INIT: Once = Once::new();

    let mut init = None;

    INIT.call_once(|| unsafe {
        let rc = SetConsoleCtrlHandler(Some(handler), TRUE);
        let ret = if rc == 0 {
            Err(io::Error::last_os_error())
        } else {
            Ok(())
        };

        init = Some(ret);
    });

    init.unwrap_or_else(|| Ok(()))
}

unsafe extern "system" fn handler(ty: DWORD) -> BOOL {
    let globals = globals();
    globals.record_event(ty as EventId);

    // According to https://docs.microsoft.com/en-us/windows/console/handlerroutine
    // the handler routine is always invoked in a new thread, thus we don't
    // have the same restrictions as in Unix signal handlers, meaning we can
    // go ahead and perform the broadcast here.
    if globals.broadcast() {
        TRUE
    } else {
        // No one is listening for this notification any more
        // let the OS fire the next (possibly the default) handler.
        FALSE
    }
}

/// Creates a new stream which receives "ctrl-c" notifications sent to the
/// process.
///
/// # Examples
///
/// ```rust,no_run
/// use tokio::signal::windows::ctrl_c;
///
/// #[tokio::main]
/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
///     // An infinite stream of CTRL-C events.
///     let mut stream = ctrl_c()?;
///
///     // Print whenever a CTRL-C event is received.
///     for countdown in (0..3).rev() {
///         stream.recv().await;
///         println!("got CTRL-C. {} more to exit", countdown);
///     }
///
///     Ok(())
/// }
/// ```
pub fn ctrl_c() -> io::Result<CtrlC> {
    Event::new(CTRL_C_EVENT).map(|inner| CtrlC { inner })
}

/// Represents a stream which receives "ctrl-c" notifications sent to the process
/// via `SetConsoleCtrlHandler`.
///
/// A notification to this process notifies *all* streams listening for
/// this event. Moreover, the notifications **are coalesced** if they aren't processed
/// quickly enough. This means that if two notifications are received back-to-back,
/// then the stream may only receive one item about the two notifications.
#[must_use = "streams do nothing unless polled"]
#[derive(Debug)]
pub struct CtrlC {
    inner: Event,
}

impl CtrlC {
    /// Receives the next signal notification event.
    ///
    /// `None` is returned if no more events can be received by this stream.
    ///
    /// # Examples
    ///
    /// ```rust,no_run
    /// use tokio::signal::windows::ctrl_c;
    ///
    /// #[tokio::main]
    /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
    ///     // An infinite stream of CTRL-C events.
    ///     let mut stream = ctrl_c()?;
    ///
    ///     // Print whenever a CTRL-C event is received.
    ///     for countdown in (0..3).rev() {
    ///         stream.recv().await;
    ///         println!("got CTRL-C. {} more to exit", countdown);
    ///     }
    ///
    ///     Ok(())
    /// }
    /// ```
    pub async fn recv(&mut self) -> Option<()> {
        self.inner.recv().await
    }

    /// Polls to receive the next signal notification event, outside of an
    /// `async` context.
    ///
    /// `None` is returned if no more events can be received by this stream.
    ///
    /// # Examples
    ///
    /// Polling from a manually implemented future
    ///
    /// ```rust,no_run
    /// use std::pin::Pin;
    /// use std::future::Future;
    /// use std::task::{Context, Poll};
    /// use tokio::signal::windows::CtrlC;
    ///
    /// struct MyFuture {
    ///     ctrl_c: CtrlC,
    /// }
    ///
    /// impl Future for MyFuture {
    ///     type Output = Option<()>;
    ///
    ///     fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
    ///         println!("polling MyFuture");
    ///         self.ctrl_c.poll_recv(cx)
    ///     }
    /// }
    /// ```
    pub fn poll_recv(&mut self, cx: &mut Context<'_>) -> Poll<Option<()>> {
        self.inner.rx.poll_recv(cx)
    }
}

cfg_stream! {
    impl crate::stream::Stream for CtrlC {
        type Item = ();

        fn poll_next(mut self: std::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<()>> {
            self.poll_recv(cx)
        }
    }
}

/// Represents a stream which receives "ctrl-break" notifications sent to the process
/// via `SetConsoleCtrlHandler`.
///
/// A notification to this process notifies *all* streams listening for
/// this event. Moreover, the notifications **are coalesced** if they aren't processed
/// quickly enough. This means that if two notifications are received back-to-back,
/// then the stream may only receive one item about the two notifications.
#[must_use = "streams do nothing unless polled"]
#[derive(Debug)]
pub struct CtrlBreak {
    inner: Event,
}

impl CtrlBreak {
    /// Receives the next signal notification event.
    ///
    /// `None` is returned if no more events can be received by this stream.
    ///
    /// # Examples
    ///
    /// ```rust,no_run
    /// use tokio::signal::windows::ctrl_break;
    ///
    /// #[tokio::main]
    /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
    ///     // An infinite stream of CTRL-BREAK events.
    ///     let mut stream = ctrl_break()?;
    ///
    ///     // Print whenever a CTRL-BREAK event is received.
    ///     loop {
    ///         stream.recv().await;
    ///         println!("got signal CTRL-BREAK");
    ///     }
    /// }
    /// ```
    pub async fn recv(&mut self) -> Option<()> {
        self.inner.recv().await
    }

    /// Polls to receive the next signal notification event, outside of an
    /// `async` context.
    ///
    /// `None` is returned if no more events can be received by this stream.
    ///
    /// # Examples
    ///
    /// Polling from a manually implemented future
    ///
    /// ```rust,no_run
    /// use std::pin::Pin;
    /// use std::future::Future;
    /// use std::task::{Context, Poll};
    /// use tokio::signal::windows::CtrlBreak;
    ///
    /// struct MyFuture {
    ///     ctrl_break: CtrlBreak,
    /// }
    ///
    /// impl Future for MyFuture {
    ///     type Output = Option<()>;
    ///
    ///     fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
    ///         println!("polling MyFuture");
    ///         self.ctrl_break.poll_recv(cx)
    ///     }
    /// }
    /// ```
    pub fn poll_recv(&mut self, cx: &mut Context<'_>) -> Poll<Option<()>> {
        self.inner.rx.poll_recv(cx)
    }
}

cfg_stream! {
    impl crate::stream::Stream for CtrlBreak {
        type Item = ();

        fn poll_next(mut self: std::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<()>> {
            self.poll_recv(cx)
        }
    }
}

/// Creates a new stream which receives "ctrl-break" notifications sent to the
/// process.
///
/// # Examples
///
/// ```rust,no_run
/// use tokio::signal::windows::ctrl_break;
///
/// #[tokio::main]
/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
///     // An infinite stream of CTRL-BREAK events.
///     let mut stream = ctrl_break()?;
///
///     // Print whenever a CTRL-BREAK event is received.
///     loop {
///         stream.recv().await;
///         println!("got signal CTRL-BREAK");
///     }
/// }
/// ```
pub fn ctrl_break() -> io::Result<CtrlBreak> {
    Event::new(CTRL_BREAK_EVENT).map(|inner| CtrlBreak { inner })
}

#[cfg(all(test, not(loom)))]
mod tests {
    use super::*;
    use crate::runtime::Runtime;
    use crate::stream::StreamExt;

    use tokio_test::{assert_ok, assert_pending, assert_ready_ok, task};

    #[test]
    fn ctrl_c() {
        let rt = rt();
        let _enter = rt.enter();

        let mut ctrl_c = task::spawn(crate::signal::ctrl_c());

        assert_pending!(ctrl_c.poll());

        // Windows doesn't have a good programmatic way of sending events
        // like sending signals on Unix, so we'll stub out the actual OS
        // integration and test that our handling works.
        unsafe {
            super::handler(CTRL_C_EVENT);
        }

        assert_ready_ok!(ctrl_c.poll());
    }

    #[test]
    fn ctrl_break() {
        let rt = rt();

        rt.block_on(async {
            let mut ctrl_break = assert_ok!(super::ctrl_break());

            // Windows doesn't have a good programmatic way of sending events
            // like sending signals on Unix, so we'll stub out the actual OS
            // integration and test that our handling works.
            unsafe {
                super::handler(CTRL_BREAK_EVENT);
            }

            ctrl_break.next().await.unwrap();
        });
    }

    fn rt() -> Runtime {
        crate::runtime::Builder::new_current_thread()
            .build()
            .unwrap()
    }
}
<|endoftext|>


<commit_before>use std::default;
use universal;
use structure;

use super::{ASNTag, Tag};
use common::TagClass;

#[derive(Clone, Debug, PartialEq)]
pub struct Sequence {
    pub id: u64,
    pub class: TagClass,
    pub inner: Vec<Tag>,
}

impl ASNTag for Sequence {
    fn into_structure(self) -> structure::StructureTag {
        structure::StructureTag {
            id: self.id,
            class: self.class,
            payload: structure::PL::C(self.inner.into_iter().map(|x| x.into_structure()).collect()),
        }
    }
}

impl default::Default for Sequence {
    fn default() -> Self {
        Sequence {
            id: universal::Types::Sequence as u64,
            class: TagClass::Universal,
            inner: Vec::new(),
        }
    }
}

#[derive(Clone, Debug)]
pub struct SequenceOf<T> {
    pub id: u64,
    pub class: TagClass,
    pub inner: Vec<T>,
}

impl<T: ASNTag + Sized> SequenceOf<T> {
    fn into_structure(self) -> structure::StructureTag {
        structure::StructureTag {
            id: self.id,
            class: self.class,
            payload: structure::PL::C(self.inner.into_iter().map(|x| x.into_structure()).collect()),
        }
    }
}

impl<T: ASNTag + Sized> default::Default for SequenceOf<T> {
    fn default() -> Self {
        SequenceOf::<T> {
            id: universal::Types::Sequence as u64,
            class: TagClass::Universal,
            inner: Vec::new(),
        }
    }
}

#[derive(Clone, Debug)]
pub struct SetOf<T> {
    pub id: u64,
    pub class: TagClass,
    pub inner: Vec<T>,
}

impl<T: ASNTag + Sized> ASNTag for SetOf<T> {
    fn into_structure(self) -> structure::StructureTag {
        structure::StructureTag {
            id: self.id,
            class: self.class,
            payload: structure::PL::C(self.inner.into_iter().map(|x| x.into_structure()).collect()),
        }
    }
}

impl<T: ASNTag + Sized> default::Default for SetOf<T> {
    fn default() -> Self {
        SetOf {
            id: universal::Types::Set as u64,
            class: TagClass::Universal,
            inner: Vec::new(),
        }
    }
}
<commit_msg>Derive PartialEq<commit_after>use std::default;
use universal;
use structure;

use super::{ASNTag, Tag};
use common::TagClass;

#[derive(Clone, Debug, PartialEq)]
pub struct Sequence {
    pub id: u64,
    pub class: TagClass,
    pub inner: Vec<Tag>,
}

impl ASNTag for Sequence {
    fn into_structure(self) -> structure::StructureTag {
        structure::StructureTag {
            id: self.id,
            class: self.class,
            payload: structure::PL::C(self.inner.into_iter().map(|x| x.into_structure()).collect()),
        }
    }
}

impl default::Default for Sequence {
    fn default() -> Self {
        Sequence {
            id: universal::Types::Sequence as u64,
            class: TagClass::Universal,
            inner: Vec::new(),
        }
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct SequenceOf<T> {
    pub id: u64,
    pub class: TagClass,
    pub inner: Vec<T>,
}

impl<T: ASNTag + Sized> SequenceOf<T> {
    fn into_structure(self) -> structure::StructureTag {
        structure::StructureTag {
            id: self.id,
            class: self.class,
            payload: structure::PL::C(self.inner.into_iter().map(|x| x.into_structure()).collect()),
        }
    }
}

impl<T: ASNTag + Sized> default::Default for SequenceOf<T> {
    fn default() -> Self {
        SequenceOf::<T> {
            id: universal::Types::Sequence as u64,
            class: TagClass::Universal,
            inner: Vec::new(),
        }
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct SetOf<T> {
    pub id: u64,
    pub class: TagClass,
    pub inner: Vec<T>,
}

impl<T: ASNTag + Sized> ASNTag for SetOf<T> {
    fn into_structure(self) -> structure::StructureTag {
        structure::StructureTag {
            id: self.id,
            class: self.class,
            payload: structure::PL::C(self.inner.into_iter().map(|x| x.into_structure()).collect()),
        }
    }
}

impl<T: ASNTag + Sized> default::Default for SetOf<T> {
    fn default() -> Self {
        SetOf {
            id: universal::Types::Set as u64,
            class: TagClass::Universal,
            inner: Vec::new(),
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Cargo fmt<commit_after><|endoftext|>