<commit_before>// Use u64 than usize because it conforms with bittorents network protocol
// (4 byte big endian integers)
#[derive(Serialize, Deserialize, Clone)]
pub struct Bitfield {
    len: u64,
    data: Box<[u8]>,
}

impl Bitfield {
    pub fn new(len: u64) -> Bitfield {
        let mut size = len / 8;
        if len % 8 != 0 {
            size += 1;
        }

        Bitfield {
            len: len,
            data: vec![0; size as usize].into_boxed_slice(),
        }
    }

    pub fn from(b: Box<[u8]>, len: u64) -> Bitfield {
        Bitfield { len: len, data: b }
    }

    pub fn len(&self) -> u64 {
        self.len
    }

    pub fn cap(&mut self, len: u64) {
        self.len = len;
    }

    pub fn bytes(&self) -> usize {
        self.data.len()
    }

    pub fn byte_at(&self, pos: u64) -> u8 {
        self.data[pos as usize]
    }

    pub fn complete(&self) -> bool {
        for i in 0..self.data.len() - 1 {
            if !(self.data[i]) != 0 {
                return false;
            }
        }
        if self.len % 8 == 0 {
            return !self.data.last().unwrap() == 0;
        }
        for i in 0..(self.len % 8) {
            if !self.has_bit(self.len - i - 1) {
                return false;
            }
        }
        true
    }

    pub fn has_bit(&self, pos: u64) -> bool {
        debug_assert!(pos < self.len);
        if pos >= self.len {
            false
        } else {
            let block_pos = pos / 8;
            let index = 7 - (pos % 8);
            let block = self.data[block_pos as usize];
            ((block >> index) & 1) == 1
        }
    }

    pub fn set_bit(&mut self, pos: u64) {
        debug_assert!(pos < self.len);
        if pos < self.len {
            let block_pos = pos / 8;
            let index = 7 - (pos % 8);
            let block = self.data[block_pos as usize];
            self.data[block_pos as usize] = block | (1 << index);
        }
    }

    pub fn unset_bit(&mut self, pos: u64) {
        debug_assert!(pos < self.len);
        if pos < self.len {
            let block_pos = pos / 8;
            let index = 7 - (pos % 8);
            let block = self.data[block_pos as usize];
            self.data[block_pos as usize] = block & !(1 << index);
        }
    }

    pub fn usable(&self, other: &Bitfield) -> bool {
        debug_assert!(self.len <= other.len);
        if self.len <= other.len {
            for i in 0..self.data.len() {
                // If we encounter a 0 for us and a 1 for them, return true.
                // XOR will make sure that 0/0 and 1/1 are invalid, and the & with self ensures
                // that only fields which are set on the other bitfield are the 1 in the 1/0 pair.
                if ((self.data[i] ^ other.data[i]) & other.data[i]) > 0 {
                    return true;
                }
            }
        }
        false
    }

    pub fn iter(&self) -> BitfieldIter {
        BitfieldIter::new(self)
    }
}

impl Default for Bitfield {
    fn default() -> Bitfield {
        Bitfield::new(0)
    }
}

use std::fmt;

impl fmt::Debug for Bitfield {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "Bitfield {{ len: {}, pieces: ", self.len)?;
        for i in 0..self.len {
            if self.has_bit(i) {
                write!(f, "1")?;
            } else {
                write!(f, "0")?;
            }
        }
        write!(f, " }}")?;
        Ok(())
    }
}

pub struct BitfieldIter<'a> {
    pf: &'a Bitfield,
    idx: u64,
}

impl<'a> BitfieldIter<'a> {
    fn new(pf: &'a Bitfield) -> BitfieldIter<'a> {
        BitfieldIter { pf: pf, idx: 0 }
    }
}

impl<'a> Iterator for BitfieldIter<'a> {
    type Item = u64;

    fn next(&mut self) -> Option<u64> {
        while self.idx < self.pf.len() {
            self.idx += 1;
            if self.pf.has_bit(self.idx - 1) {
                return Some(self.idx - 1);
            }
        }
        None
    }
}

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

    #[test]
    fn test_count() {
        let mut pf = Bitfield::new(100);
        for i in 0..100 {
            pf.set_bit(i);
        }
        assert_eq!(pf.iter().count() as u64, pf.len);
    }

    #[test]
    fn test_create() {
        let pf = Bitfield::new(10);
        assert!(pf.len == 10);
        assert!(pf.data.len() == 2)
    }

    #[test]
    fn test_has() {
        let pf = Bitfield::new(10);
        let res = pf.has_bit(9);
        assert!(res == false);
    }

    #[test]
    fn test_set() {
        let mut pf = Bitfield::new(10);

        let res = pf.has_bit(9);
        assert!(res == false);

        pf.set_bit(9);

        let res = pf.has_bit(9);
        assert!(res == true);
    }

    #[test]
    fn test_usable() {
        let mut pf1 = Bitfield::new(10);
        let mut pf2 = Bitfield::new(10);
        assert!(pf1.usable(&pf2) == false);
        pf2.set_bit(9);
        assert!(pf1.usable(&pf2) == true);
        pf1.set_bit(9);
        assert!(pf1.usable(&pf2) == false);
        pf2.set_bit(5);
        assert!(pf1.usable(&pf2) == true);
    }

    #[test]
    fn test_iter() {
        let mut pf = Bitfield::new(10);
        for i in 4..7 {
            pf.set_bit(i as u64);
        }
        pf.iter()
            .map(|r| {
                assert!(r > 3 && r < 7);
            })
            .collect::<Vec<_>>();
    }
}
<commit_msg>Handle magnet conditions more robustly in bitfield<commit_after>// Use u64 than usize because it conforms with bittorents network protocol
// (4 byte big endian integers)
#[derive(Serialize, Deserialize, Clone)]
pub struct Bitfield {
    len: u64,
    data: Box<[u8]>,
}

impl Bitfield {
    pub fn new(len: u64) -> Bitfield {
        let mut size = len / 8;
        if len % 8 != 0 {
            size += 1;
        }

        Bitfield {
            len: len,
            data: vec![0; size as usize].into_boxed_slice(),
        }
    }

    pub fn from(b: Box<[u8]>, len: u64) -> Bitfield {
        Bitfield { len: len, data: b }
    }

    pub fn len(&self) -> u64 {
        self.len
    }

    pub fn cap(&mut self, len: u64) {
        self.len = len;
    }

    pub fn bytes(&self) -> usize {
        self.data.len()
    }

    pub fn byte_at(&self, pos: u64) -> u8 {
        self.data[pos as usize]
    }

    pub fn complete(&self) -> bool {
        // Fail safe for magnets
        if self.data.len() == 0 {
            return false;
        }
        for i in 0..self.data.len() - 1 {
            if !(self.data[i]) != 0 {
                return false;
            }
        }
        if self.len % 8 == 0 {
            return !self.data.last().unwrap() == 0;
        }
        for i in 0..(self.len % 8) {
            if !self.has_bit(self.len - i - 1) {
                return false;
            }
        }
        true
    }

    pub fn has_bit(&self, pos: u64) -> bool {
        debug_assert!(pos < self.len);
        if pos >= self.len {
            false
        } else {
            let block_pos = pos / 8;
            let index = 7 - (pos % 8);
            let block = self.data[block_pos as usize];
            ((block >> index) & 1) == 1
        }
    }

    pub fn set_bit(&mut self, pos: u64) {
        debug_assert!(pos < self.len);
        if pos < self.len {
            let block_pos = pos / 8;
            let index = 7 - (pos % 8);
            let block = self.data[block_pos as usize];
            self.data[block_pos as usize] = block | (1 << index);
        }
    }

    pub fn unset_bit(&mut self, pos: u64) {
        debug_assert!(pos < self.len);
        if pos < self.len {
            let block_pos = pos / 8;
            let index = 7 - (pos % 8);
            let block = self.data[block_pos as usize];
            self.data[block_pos as usize] = block & !(1 << index);
        }
    }

    pub fn usable(&self, other: &Bitfield) -> bool {
        debug_assert!(self.len <= other.len);
        if self.len <= other.len {
            for i in 0..self.data.len() {
                // If we encounter a 0 for us and a 1 for them, return true.
                // XOR will make sure that 0/0 and 1/1 are invalid, and the & with self ensures
                // that only fields which are set on the other bitfield are the 1 in the 1/0 pair.
                if ((self.data[i] ^ other.data[i]) & other.data[i]) > 0 {
                    return true;
                }
            }
        }
        false
    }

    pub fn iter(&self) -> BitfieldIter {
        BitfieldIter::new(self)
    }
}

impl Default for Bitfield {
    fn default() -> Bitfield {
        Bitfield::new(0)
    }
}

use std::fmt;

impl fmt::Debug for Bitfield {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "Bitfield {{ len: {}, pieces: ", self.len)?;
        for i in 0..self.len {
            if self.has_bit(i) {
                write!(f, "1")?;
            } else {
                write!(f, "0")?;
            }
        }
        write!(f, " }}")?;
        Ok(())
    }
}

pub struct BitfieldIter<'a> {
    pf: &'a Bitfield,
    idx: u64,
}

impl<'a> BitfieldIter<'a> {
    fn new(pf: &'a Bitfield) -> BitfieldIter<'a> {
        BitfieldIter { pf: pf, idx: 0 }
    }
}

impl<'a> Iterator for BitfieldIter<'a> {
    type Item = u64;

    fn next(&mut self) -> Option<u64> {
        while self.idx < self.pf.len() {
            self.idx += 1;
            if self.pf.has_bit(self.idx - 1) {
                return Some(self.idx - 1);
            }
        }
        None
    }
}

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

    #[test]
    fn test_count() {
        let mut pf = Bitfield::new(100);
        for i in 0..100 {
            pf.set_bit(i);
        }
        assert_eq!(pf.iter().count() as u64, pf.len);
    }

    #[test]
    fn test_create() {
        let pf = Bitfield::new(10);
        assert!(pf.len == 10);
        assert!(pf.data.len() == 2)
    }

    #[test]
    fn test_has() {
        let pf = Bitfield::new(10);
        let res = pf.has_bit(9);
        assert!(res == false);
    }

    #[test]
    fn test_set() {
        let mut pf = Bitfield::new(10);

        let res = pf.has_bit(9);
        assert!(res == false);

        pf.set_bit(9);

        let res = pf.has_bit(9);
        assert!(res == true);
    }

    #[test]
    fn test_usable() {
        let mut pf1 = Bitfield::new(10);
        let mut pf2 = Bitfield::new(10);
        assert!(pf1.usable(&pf2) == false);
        pf2.set_bit(9);
        assert!(pf1.usable(&pf2) == true);
        pf1.set_bit(9);
        assert!(pf1.usable(&pf2) == false);
        pf2.set_bit(5);
        assert!(pf1.usable(&pf2) == true);
    }

    #[test]
    fn test_iter() {
        let mut pf = Bitfield::new(10);
        for i in 4..7 {
            pf.set_bit(i as u64);
        }
        pf.iter()
            .map(|r| {
                assert!(r > 3 && r < 7);
            })
            .collect::<Vec<_>>();
    }
}
<|endoftext|>


<commit_before>/// An iterator that always continues to yield `None` when exhausted.
///
/// Calling next on a fused iterator that has returned `None` once is guaranteed
/// to return [`None`] again. This trait should be implemented by all iterators
/// that behave this way because it allows optimizing [`Iterator::fuse`].
///
/// Note: In general, you should not use `FusedIterator` in generic bounds if
/// you need a fused iterator. Instead, you should just call [`Iterator::fuse`]
/// on the iterator. If the iterator is already fused, the additional [`Fuse`]
/// wrapper will be a no-op with no performance penalty.
///
/// [`None`]: ../../std/option/enum.Option.html#variant.None
/// [`Iterator::fuse`]: ../../std/iter/trait.Iterator.html#method.fuse
/// [`Fuse`]: ../../std/iter/struct.Fuse.html
#[stable(feature = "fused", since = "1.26.0")]
#[rustc_unsafe_specialization_marker]
pub trait FusedIterator: Iterator {}

#[stable(feature = "fused", since = "1.26.0")]
impl<I: FusedIterator + ?Sized> FusedIterator for &mut I {}

/// An iterator that reports an accurate length using size_hint.
///
/// The iterator reports a size hint where it is either exact
/// (lower bound is equal to upper bound), or the upper bound is [`None`].
/// The upper bound must only be [`None`] if the actual iterator length is
/// larger than [`usize::MAX`]. In that case, the lower bound must be
/// [`usize::MAX`], resulting in a [`.size_hint`] of `(usize::MAX, None)`.
///
/// The iterator must produce exactly the number of elements it reported
/// or diverge before reaching the end.
///
/// # Safety
///
/// This trait must only be implemented when the contract is upheld.
/// Consumers of this trait must inspect [`.size_hint`]’s upper bound.
///
/// [`None`]: ../../std/option/enum.Option.html#variant.None
/// [`usize::MAX`]: ../../std/usize/constant.MAX.html
/// [`.size_hint`]: ../../std/iter/trait.Iterator.html#method.size_hint
#[unstable(feature = "trusted_len", issue = "37572")]
#[rustc_unsafe_specialization_marker]
pub unsafe trait TrustedLen: Iterator {}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<I: TrustedLen + ?Sized> TrustedLen for &mut I {}
<commit_msg>Intra doc for iter marker traits<commit_after>/// An iterator that always continues to yield `None` when exhausted.
///
/// Calling next on a fused iterator that has returned `None` once is guaranteed
/// to return [`None`] again. This trait should be implemented by all iterators
/// that behave this way because it allows optimizing [`Iterator::fuse`].
///
/// Note: In general, you should not use `FusedIterator` in generic bounds if
/// you need a fused iterator. Instead, you should just call [`Iterator::fuse`]
/// on the iterator. If the iterator is already fused, the additional [`Fuse`]
/// wrapper will be a no-op with no performance penalty.
///
/// [`Iterator::fuse`]: crate::iter::Iterator::fuse
/// [`Fuse`]: crate::iter::Fuse
#[stable(feature = "fused", since = "1.26.0")]
#[rustc_unsafe_specialization_marker]
pub trait FusedIterator: Iterator {}

#[stable(feature = "fused", since = "1.26.0")]
impl<I: FusedIterator + ?Sized> FusedIterator for &mut I {}

/// An iterator that reports an accurate length using size_hint.
///
/// The iterator reports a size hint where it is either exact
/// (lower bound is equal to upper bound), or the upper bound is [`None`].
/// The upper bound must only be [`None`] if the actual iterator length is
/// larger than [`usize::MAX`]. In that case, the lower bound must be
/// [`usize::MAX`], resulting in a [`.size_hint`] of `(usize::MAX, None)`.
///
/// The iterator must produce exactly the number of elements it reported
/// or diverge before reaching the end.
///
/// # Safety
///
/// This trait must only be implemented when the contract is upheld.
/// Consumers of this trait must inspect [`.size_hint`]’s upper bound.
///
/// [`usize::MAX`]: crate::usize::MAX
/// [`.size_hint`]: crate::iter::Iterator::size_hint
#[unstable(feature = "trusted_len", issue = "37572")]
#[rustc_unsafe_specialization_marker]
pub unsafe trait TrustedLen: Iterator {}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<I: TrustedLen + ?Sized> TrustedLen for &mut I {}
<|endoftext|>


<commit_before>// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use super::Value;

impl PartialEq<str> for Value {
    fn eq(&self, other: &str) -> bool {
        self.as_str().map_or(false, |s| s == other)
    }
}

impl<'a> PartialEq<&'a str> for Value {
    fn eq(&self, other: &&str) -> bool {
        self.as_str().map_or(false, |s| s == *other)
    }
}

impl PartialEq<Value> for str {
    fn eq(&self, other: &Value) -> bool {
        other.as_str().map_or(false, |s| s == self)
    }
}

impl<'a> PartialEq<Value> for &'a str {
    fn eq(&self, other: &Value) -> bool {
        other.as_str().map_or(false, |s| s == *self)
    }
}

impl PartialEq<String> for Value {
    fn eq(&self, other: &String) -> bool {
        self.as_str().map_or(false, |s| s == other)
    }
}

impl PartialEq<Value> for String {
    fn eq(&self, other: &Value) -> bool {
        other.as_str().map_or(false, |s| s == self)
    }
}

macro_rules! partialeq_numeric {
    ($([$($ty:ty)*], $conversion:ident, $base:ty)*) => {
        $($(
            impl PartialEq<$ty> for Value {
                fn eq(&self, other: &$ty) -> bool {
                    self.$conversion().map_or(false, |i| i == (*other as $base))
                }
            }

            impl PartialEq<Value> for $ty {
                fn eq(&self, other: &Value) -> bool {
                    other.$conversion().map_or(false, |i| i == (*self as $base))
                }
            }

            impl<'a> PartialEq<$ty> for &'a Value {
                fn eq(&self, other: &$ty) -> bool {
                    self.$conversion().map_or(false, |i| i == (*other as $base))
                }
            }

            impl<'a> PartialEq<$ty> for &'a mut Value {
                fn eq(&self, other: &$ty) -> bool {
                    self.$conversion().map_or(false, |i| i == (*other as $base))
                }
            }
        )*)*
    }
}

partialeq_numeric! {
    [i8 i16 i32 i64 isize], as_i64, i64
    [u8 u16 u32 u64 usize], as_u64, u64
    [f32 f64], as_f64, f64
    [bool], as_bool, bool
}
<commit_msg>Fewer instantiations of Option::map_or<commit_after>// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use super::Value;

fn eq_i64(value: &Value, other: i64) -> bool {
    value.as_i64().map_or(false, |i| i == other)
}

fn eq_u64(value: &Value, other: u64) -> bool {
    value.as_u64().map_or(false, |i| i == other)
}

fn eq_f64(value: &Value, other: f64) -> bool {
    value.as_f64().map_or(false, |i| i == other)
}

fn eq_bool(value: &Value, other: bool) -> bool {
    value.as_bool().map_or(false, |i| i == other)
}

fn eq_str(value: &Value, other: &str) -> bool {
    value.as_str().map_or(false, |i| i == other)
}

impl PartialEq<str> for Value {
    fn eq(&self, other: &str) -> bool {
        eq_str(self, other)
    }
}

impl<'a> PartialEq<&'a str> for Value {
    fn eq(&self, other: &&str) -> bool {
        eq_str(self, *other)
    }
}

impl PartialEq<Value> for str {
    fn eq(&self, other: &Value) -> bool {
        eq_str(other, self)
    }
}

impl<'a> PartialEq<Value> for &'a str {
    fn eq(&self, other: &Value) -> bool {
        eq_str(other, *self)
    }
}

impl PartialEq<String> for Value {
    fn eq(&self, other: &String) -> bool {
        eq_str(self, other.as_str())
    }
}

impl PartialEq<Value> for String {
    fn eq(&self, other: &Value) -> bool {
        eq_str(other, self.as_str())
    }
}

macro_rules! partialeq_numeric {
    ($($eq:ident [$($ty:ty)*])*) => {
        $($(
            impl PartialEq<$ty> for Value {
                fn eq(&self, other: &$ty) -> bool {
                    $eq(self, *other as _)
                }
            }

            impl PartialEq<Value> for $ty {
                fn eq(&self, other: &Value) -> bool {
                    $eq(other, *self as _)
                }
            }

            impl<'a> PartialEq<$ty> for &'a Value {
                fn eq(&self, other: &$ty) -> bool {
                    $eq(*self, *other as _)
                }
            }

            impl<'a> PartialEq<$ty> for &'a mut Value {
                fn eq(&self, other: &$ty) -> bool {
                    $eq(*self, *other as _)
                }
            }
        )*)*
    }
}

partialeq_numeric! {
    eq_i64[i8 i16 i32 i64 isize]
    eq_u64[u8 u16 u32 u64 usize]
    eq_f64[f32 f64]
    eq_bool[bool]
}
<|endoftext|>


<commit_before>/*

----------------------------------------
Grammatik:

LL(1)
----------------------------------------|
S -> Passage S2                         |
S2 -> S                                 |
S2 -> ɛ                                 |
Passage -> PassageName PassageContent   |
PassageContent -> TextPassage B         |
PassageContent -> Formatting B          |
PassageContent -> Newline B             |
B -> PassageContent                     |
B -> ɛ                                  |
----------------------------------------|

Hello World im LL(1)-Parser:
token: [TokPassageName("Start"), TokText("Hello World\n")]

input                   | stack                         | output                              |
------------------------+-------------------------------+-------------------------------------+---------------------------------------------------
PassageName TextPassage | S                             | S->Passage S'                       | passage and s' as child of S
        --||--          | Passage S2                    | Passage->PassageName PassageContent | passageName and passagecontent as child of passage
        --||--          | PassageName PassageContent S2 |                                     | gehe bei den token 1 weiter
TextPassage             | PassageContent S2             | PassageContent->TextPassage B       | textpassage and b as child of PassageContent
        --||--          | TextPassage B S'              |                                     | gehe bei den token 1 weiter
empty                   | B S'                          | B->ɛ                                |
empty                   | S'                            | S' -> ɛ                             |
empty                   | empty                         | ACCEPT                              |
------------------------+-------------------------------+-------------------------------------|---------------------------------------------------

*/

pub use super::frontend::lexer::Token;

//==============================
// grammar

#[derive(Debug)]
enum NonTerminalType {
    S,
    S2,
    Passage,
    PassageContent,
    B
}

//==============================

struct SyntaxTree {
    root: NodeType
}

//#[derive(Debug)]
enum NodeType {
    NonTerminal (NodeNonTerminal),
    Terminal (NodeTerminal)
}

// ================================
// node types

struct NodeNonTerminal {
    category: NonTerminalType,
    childs: Vec<NodeType>
}

struct NodeTerminal {
    category: Token
}

impl NodeType {

    pub fn new_terminal(terminal: Token) -> NodeType {
        NodeType::Terminal(NodeTerminal  { category: terminal })
    }

    pub fn new_non_terminal(non_terminal: NonTerminalType) -> NodeType {
        NodeType::NonTerminal(NodeNonTerminal { category: non_terminal, childs: Vec::new() })
    }

    // prints a node
    pub fn print(&self, indent: usize) {
        let mut spaces = "".to_string();
        for _ in 0..indent {
            spaces.push_str(" ");
        }

        match self {
            &NodeType::NonTerminal(ref t) => {
                debug!("{}|- Node: {:?}", spaces, t.category);

                for child in &t.childs {
                    child.print(indent+2);
                }
            }
            &NodeType::Terminal(ref t) => {
                debug!("{}|- Terminal: {:?}", spaces, t.category);
            }
        }
    }

    // returns a non_terminal of the path
    pub fn get_non_terminal(&self, path: Vec<usize>) -> &NonTerminalType {
        match self {
            &NodeType::NonTerminal(ref node) => {
                if let Some(index) = path.first() {
                    let mut new_path: Vec<usize> = path.to_vec();
                    new_path.remove(0);
                    return node.childs[*index].get_non_terminal(new_path);
                } else {
                    return &node.category;
                }
            },
            _ => panic!("error")
        }
    }

    // adds a node to the childs in path
    pub fn add_child_at(&mut self, path: &[usize], child: NodeType) {
        match self {

            &mut NodeType::NonTerminal (ref mut node) => {
                if let Some(index) = path.first() {
                    let mut new_path: Vec<usize> = path.to_vec();
                    new_path.remove(0);
                    node.childs[*index].add_child_at(&new_path, child);
                } else {
                    node.childs.push(child);
                }
            },
            _ => panic!("error")
        }
    }

    // checks if the node of the path is a terminal or not
    pub fn is_terminal(&self, path: Vec<usize>) -> bool {
        match self {
            &NodeType::NonTerminal(ref node) => {
                if let Some(index) = path.first() {
                    let mut new_path: Vec<usize> = path.to_vec();
                    new_path.remove(0);
                    return node.childs[*index].is_terminal(new_path);
                }

                return false
            },
            &NodeType::Terminal(_) => return true
        }

        false
    }
}

impl SyntaxTree {
    pub fn new() -> SyntaxTree {
        SyntaxTree {
            root: NodeType::new_non_terminal(NonTerminalType::S)
        }
    }
}

pub fn temp_create_parse_tree(tokens: Vec<Token>) {
    debug!("temp_create_syntax_tree");

    let mut tree: SyntaxTree = SyntaxTree::new();
    let mut stack: Vec<Vec<usize>> = Vec::new();

    stack.push(vec![]);
    let mut token_index = 0;

    // stack parser...
    while !stack.is_empty() {
        //println!("stack loop");
        let mut is_terminal;
        let top_path;

        if let Some(top) = stack.last() {
            is_terminal = tree.root.is_terminal( top.to_vec() );
            top_path = top.to_vec();
        } else {
            panic!("error")
        }

        stack.pop();

        if is_terminal {
            token_index = token_index + 1;

        } else {
            // parse table in code
            let to_add_path: Vec<usize> = top_path.to_vec();
            match tree.root.get_non_terminal(top_path) {
                &NonTerminalType::S => {
                    let child1 = NodeType::new_non_terminal(NonTerminalType::Passage);
                    let child2 = NodeType::new_non_terminal(NonTerminalType::S2);
                    tree.root.add_child_at(&to_add_path, child1);
                    tree.root.add_child_at(&to_add_path, child2);

                    add_two_to_stack(&mut stack, to_add_path);

                },
                &NonTerminalType::S2 => {
                    // check follow...
                    if let Some(token) = tokens.get(token_index) {
                        match token {
                            &Token::TokPassageName (_) => {
                                let child = NodeType::new_non_terminal(NonTerminalType::S);
                                tree.root.add_child_at(&to_add_path, child);
                                add_one_to_stack(&mut stack, to_add_path);
                            },
                            _ => { }
                        }
                    }
                },
                &NonTerminalType::Passage => {
                    if let Some(token) = tokens.get(token_index) {
                        match token {
                            &Token::TokPassageName (ref name) => {
                                let new_token: Token = Token::TokPassageName(name.clone());
                                let child1 = NodeType::new_terminal(new_token);
                                tree.root.add_child_at(&to_add_path, child1);

                            },
                            _ => { }
                        }
                    }
                    let child2 = NodeType::new_non_terminal(NonTerminalType::PassageContent);
                    tree.root.add_child_at(&to_add_path, child2);

                    add_two_to_stack(&mut stack, to_add_path);
                },
                &NonTerminalType::PassageContent => {
                     if let Some(token) = tokens.get(token_index) {
                        match token {
                            &Token::TokText (ref text) => {
                                let new_token: Token = Token::TokText(text.clone());
                                let child1 = NodeType::new_terminal(new_token);
                                tree.root.add_child_at(&to_add_path, child1);
                            },
                            _ => { }
                        }
                    }
                    let child2 = NodeType::new_non_terminal(NonTerminalType::B);
                    tree.root.add_child_at(&to_add_path, child2);

                    add_two_to_stack(&mut stack, to_add_path);
                },
                &NonTerminalType::B => {
                    /*
                    debug!("B: {}", token_index);

                    don't supportet at the moment
                    // check follow...
                    if let Some(token) = tokens.get(token_index) {
                        match token {
                            &Token::TokText (_) | &Token::TokFormatBold => {
                                let child = NodeType::new_non_terminal(NonTerminalType::PassageContent);
                                tree.root.add_child_at(&to_add_path, child);
                                add_one_to_stack(&mut stack, to_add_path);
                            },
                            _ => { }
                        }
                    }*/
                }
            }
        }
    }

    tree.root.print(0);
}

// save the path to the node in the tree in the stack
// todo: add_child_at should return the path
// the right part of the production
// should be on the stack in reverse order
fn add_two_to_stack(stack: &mut Vec<Vec<usize>>, to_add_path: Vec<usize>) {
    let mut path1: Vec<usize> = to_add_path.to_vec();
    let mut path2: Vec<usize> = to_add_path.to_vec();

    path1.push(1);
    path2.push(0);

    stack.push(path1);
    stack.push(path2);
}

fn add_one_to_stack(stack: &mut Vec<Vec<usize>>, to_add_path: Vec<usize>) {
    let mut path1: Vec<usize> = to_add_path.to_vec();
    path1.push(0);
    stack.push(path1);
}

#[test]
fn it_works() {
}
<commit_msg>small changes<commit_after>/*

----------------------------------------
Grammatik:

LL(1)
----------------------------------------|
S -> Passage S2                         |
S2 -> S                                 |
S2 -> ɛ                                 |
Passage -> PassageName PassageContent   |
PassageContent -> TextPassage B         |
PassageContent -> Formatting B          |
PassageContent -> Newline B             |
B -> PassageContent                     |
B -> ɛ                                  |
----------------------------------------|

Hello World im LL(1)-Parser:
token: [TokPassageName("Start"), TokText("Hello World\n")]

input                   | stack                         | output                              |
------------------------+-------------------------------+-------------------------------------+---------------------------------------------------
PassageName TextPassage | S                             | S->Passage S'                       | passage and s' as child of S
        --||--          | Passage S2                    | Passage->PassageName PassageContent | passageName and passagecontent as child of passage
        --||--          | PassageName PassageContent S2 |                                     | gehe bei den token 1 weiter
TextPassage             | PassageContent S2             | PassageContent->TextPassage B       | textpassage and b as child of PassageContent
        --||--          | TextPassage B S'              |                                     | gehe bei den token 1 weiter
empty                   | B S'                          | B->ɛ                                |
empty                   | S'                            | S' -> ɛ                             |
empty                   | empty                         | ACCEPT                              |
------------------------+-------------------------------+-------------------------------------|---------------------------------------------------

*/

pub use super::frontend::lexer::Token;

//==============================
// grammar

#[derive(Debug)]
enum NonTerminalType {
    S,
    S2,
    Passage,
    PassageContent,
    B
}

//==============================

struct SyntaxTree {
    root: NodeType
}

//#[derive(Debug)]
enum NodeType {
    NonTerminal (NodeNonTerminal),
    Terminal (NodeTerminal)
}

// ================================
// node types

struct NodeNonTerminal {
    category: NonTerminalType,
    childs: Vec<NodeType>
}

struct NodeTerminal {
    category: Token
}

impl NodeType {

    pub fn new_terminal(terminal: Token) -> NodeType {
        NodeType::Terminal(NodeTerminal  { category: terminal })
    }

    pub fn new_non_terminal(non_terminal: NonTerminalType) -> NodeType {
        NodeType::NonTerminal(NodeNonTerminal { category: non_terminal, childs: Vec::new() })
    }

    // prints a node
    pub fn print(&self, indent: usize) {
        let mut spaces = "".to_string();
        for _ in 0..indent {
            spaces.push_str(" ");
        }

        match self {
            &NodeType::NonTerminal(ref t) => {
                debug!("{}|- Node: {:?}", spaces, t.category);

                for child in &t.childs {
                    child.print(indent+2);
                }
            }
            &NodeType::Terminal(ref t) => {
                debug!("{}|- Terminal: {:?}", spaces, t.category);
            }
        }
    }

    // returns a non_terminal of the path
    pub fn get_non_terminal(&self, path: Vec<usize>) -> &NonTerminalType {
        match self {
            &NodeType::NonTerminal(ref node) => {
                if let Some(index) = path.first() {
                    let mut new_path: Vec<usize> = path.to_vec();
                    new_path.remove(0);
                    return node.childs[*index].get_non_terminal(new_path);
                } else {
                    return &node.category;
                }
            },
            _ => panic!("error")
        }
    }

    // adds a node to the childs in path
    pub fn add_child_at(&mut self, path: &[usize], child: NodeType) {
        match self {
            &mut NodeType::NonTerminal (ref mut node) => {
                if let Some(index) = path.first() {
                    let mut new_path: Vec<usize> = path.to_vec();
                    new_path.remove(0);
                    node.childs[*index].add_child_at(&new_path, child);
                } else {
                    node.childs.push(child);
                }
            },
            _ => panic!("error")
        }
    }

    // checks if the node of the path is a terminal or not
    pub fn is_terminal(&self, path: Vec<usize>) -> bool {
        match self {
            &NodeType::NonTerminal(ref node) => {
                if let Some(index) = path.first() {
                    let mut new_path: Vec<usize> = path.to_vec();
                    new_path.remove(0);
                    return node.childs[*index].is_terminal(new_path);
                }

                return false
            },
            &NodeType::Terminal(_) => return true
        }

        false
    }
}

impl SyntaxTree {
    pub fn new() -> SyntaxTree {
        SyntaxTree {
            root: NodeType::new_non_terminal(NonTerminalType::S)
        }
    }

    // adds one nodes to childs at the path
    pub fn add_one_node(&mut self, child: NodeType, to_add_path: &Vec<usize>) {
        self.root.add_child_at(&to_add_path, child);
    }

    // adds two nodes to childs at the path
    pub fn add_two_nodes(&mut self, child1: NodeType, child2: NodeType, to_add_path: &Vec<usize>) {
        self.root.add_child_at(&to_add_path, child1);
        self.root.add_child_at(&to_add_path, child2);
    }
}

pub fn temp_create_parse_tree(tokens: Vec<Token>) {
    let mut tree: SyntaxTree = SyntaxTree::new();
    let mut stack: Vec<Vec<usize>> = Vec::new();

    stack.push(vec![]);
    let mut token_index = 0;

    // stack parser...
    while !stack.is_empty() {
        //println!("stack loop");
        let mut is_terminal;
        let top_path;

        if let Some(top) = stack.last() {
            is_terminal = tree.root.is_terminal( top.to_vec() );
            top_path = top.to_vec();
        } else {
            panic!("error")
        }

        stack.pop();

        if is_terminal {
            token_index = token_index + 1;

        } else {
            // parse table in code
            let to_add_path: Vec<usize> = top_path.to_vec();
            match tree.root.get_non_terminal(top_path) {
                &NonTerminalType::S => {
                    tree.add_two_nodes(NodeType::new_non_terminal(NonTerminalType::Passage), NodeType::new_non_terminal(NonTerminalType::S2), &to_add_path);
                    add_two_to_stack(&mut stack, to_add_path);

                },
                &NonTerminalType::S2 => {
                    // check follow...
                    if let Some(token) = tokens.get(token_index) {
                        match token {
                            &Token::TokPassageName (_) => {
                                tree.add_one_node(NodeType::new_non_terminal(NonTerminalType::S), &to_add_path);
                                add_one_to_stack(&mut stack, to_add_path);
                            },
                            _ => { }
                        }
                    }
                },
                &NonTerminalType::Passage => {
                    if let Some(token) = tokens.get(token_index) {
                        match token {
                            &Token::TokPassageName (ref name) => {
                                let new_token: Token = Token::TokPassageName(name.clone());
                                tree.add_two_nodes(NodeType::new_terminal(new_token), NodeType::new_non_terminal(NonTerminalType::PassageContent), &to_add_path);
                                add_two_to_stack(&mut stack, to_add_path);
                            },
                            _ => { }
                        }
                    }

                },
                &NonTerminalType::PassageContent => {
                     if let Some(token) = tokens.get(token_index) {
                        match token {
                            &Token::TokText (ref text) => {
                                let new_token: Token = Token::TokText(text.clone());
                                tree.add_two_nodes(NodeType::new_terminal(new_token), NodeType::new_non_terminal(NonTerminalType::B), &to_add_path);
                                add_two_to_stack(&mut stack, to_add_path);
                            },
                            _ => { }
                        }
                    }
                },
                &NonTerminalType::B => {
                    /*
                    debug!("B: {}", token_index);

                    don't supportet at the moment
                    // check follow...
                    if let Some(token) = tokens.get(token_index) {
                        match token {
                            &Token::TokText (_) | &Token::TokFormatBold => {
                                let child = NodeType::new_non_terminal(NonTerminalType::PassageContent);
                                tree.root.add_child_at(&to_add_path, child);
                                add_one_to_stack(&mut stack, to_add_path);
                            },
                            _ => { }
                        }
                    }*/
                }
            }
        }
    }

    debug!("Parse Tree");
    tree.root.print(0);
}

// save the path to the node in the tree in the stack
// todo: add_child_at should return the path
// the right part of the production
// should be on the stack in reverse order
fn add_two_to_stack(stack: &mut Vec<Vec<usize>>, to_add_path: Vec<usize>) {
    let mut path1: Vec<usize> = to_add_path.to_vec();
    let mut path2: Vec<usize> = to_add_path.to_vec();

    path1.push(1);
    path2.push(0);

    stack.push(path1);
    stack.push(path2);
}

fn add_one_to_stack(stack: &mut Vec<Vec<usize>>, to_add_path: Vec<usize>) {
    let mut path1: Vec<usize> = to_add_path.to_vec();
    path1.push(0);
    stack.push(path1);
}

#[test]
fn it_works() {
}
<|endoftext|>


<commit_before>use error::Error;
use client::Client;
use resources::{Discount, Plan};
use params::{List, Metadata, Timestamp};

#[derive(Default, Serialize)]
pub struct CancelParams {
    #[serde(skip_serializing_if = "Option::is_none")] pub at_period_end: Option<bool>,
}

#[derive(Serialize, Debug)]
pub struct ItemParams<'a> {
    pub plan: &'a str,
    #[serde(skip_serializing_if = "Option::is_none")] pub quantity: Option<u64>,
}

/// The set of parameters that can be used when creating or updating a subscription.
///
/// For more details see https://stripe.com/docs/api#create_subscription and https://stripe.com/docs/api#update_subscription.
#[derive(Default, Serialize, Debug)]
pub struct SubscriptionParams<'a> {
    #[serde(skip_serializing_if = "Option::is_none")] pub customer: Option<&'a str>,
    #[serde(skip_serializing_if = "Option::is_none")] pub application_fee_percent: Option<f64>,
    #[serde(skip_serializing_if = "Option::is_none")] pub coupon: Option<&'a str>,
    #[serde(skip_serializing_if = "Option::is_none")] pub items: Option<Vec<ItemParams<'a>>>,
    #[serde(skip_serializing_if = "Option::is_none")] pub metadata: Option<Metadata>,
    #[serde(skip_serializing_if = "Option::is_none")] pub plan: Option<&'a str>,
    #[serde(skip_serializing_if = "Option::is_none")] pub prorate: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")] pub proration_date: Option<Timestamp>,
    #[serde(skip_serializing_if = "Option::is_none")] pub quantity: Option<u64>,
    #[serde(skip_serializing_if = "Option::is_none")] pub source: Option<&'a str>,
    #[serde(skip_serializing_if = "Option::is_none")] pub tax_percent: Option<f64>,
    #[serde(skip_serializing_if = "Option::is_none")] pub trial_end: Option<Timestamp>,
    #[serde(skip_serializing_if = "Option::is_none")] pub trial_period_days: Option<u64>,
}

/// The resource representing a Stripe subscription item.
///
/// For more details see https://stripe.com/docs/api#subscription_items.
#[derive(Debug, Deserialize)]
pub struct SubscriptionItem {
    pub id: String,
    pub created: Timestamp,
    pub plan: Plan,
    pub quantity: u64,
}

/// The resource representing a Stripe subscription.
///
/// For more details see https://stripe.com/docs/api#subscriptions.
#[derive(Debug, Deserialize)]
pub struct Subscription {
    pub id: String,
    pub application_fee_percent: Option<f64>,
    pub cancel_at_period_end: bool,
    pub canceled_at: Option<Timestamp>,
    pub created: Option<Timestamp>,
    pub current_period_start: Timestamp,
    pub current_period_end: Timestamp,
    pub customer: String,
    pub discount: Option<Discount>,
    pub ended_at: Option<Timestamp>,
    pub items: List<SubscriptionItem>,
    pub livemode: bool,
    pub metadata: Metadata,
    pub plan: Plan,
    pub quantity: u64,
    pub start: Timestamp,
    pub status: String, // (trialing, active, past_due, canceled, unpaid)
    pub tax_percent: Option<f64>,
    pub trial_start: Option<Timestamp>,
    pub trial_end: Option<Timestamp>,
}

impl Subscription {
    /// Creates a new subscription for a customer.
    ///
    /// For more details see https://stripe.com/docs/api#create_subscription.
    pub fn create(client: &Client, params: SubscriptionParams) -> Result<Subscription, Error> {
        client.post("/subscriptions", params)
    }

    /// Retrieves the details of a subscription.
    ///
    /// For more details see https://stripe.com/docs/api#retrieve_subscription.
    pub fn retrieve(client: &Client, subscription_id: &str) -> Result<Subscription, Error> {
        client.get(&format!("/subscriptions/{}", subscription_id))
    }

    /// Updates a subscription's properties.
    /// For more details see https://stripe.com/docs/api#update_subscription.
    pub fn update(client: &Client, subscription_id: &str, params: SubscriptionParams) -> Result<Subscription, Error> {
        client.post(&format!("/subscriptions/{}", subscription_id), params)
    }

    /// Cancels a subscription.
    ///
    /// For more details see https://stripe.com/docs/api#cancel_subscription.
    pub fn cancel(client: &Client, subscription_id: &str, params: CancelParams) -> Result<Subscription, Error> {
        client.post(&format!("/subscriptions/{}/cancel", subscription_id), params)
    }
}
<commit_msg>Add delete subscription params<commit_after>use error::Error;
use client::Client;
use resources::{Discount, Plan};
use params::{List, Metadata, Timestamp};
use serde_qs as query;

#[derive(Default, Serialize)]
pub struct CancelParams {
    #[serde(skip_serializing_if = "Option::is_none")] pub at_period_end: Option<bool>,
}

#[derive(Serialize, Debug)]
pub struct ItemParams<'a> {
    pub plan: &'a str,
    #[serde(skip_serializing_if = "Option::is_none")] pub quantity: Option<u64>,
}

/// The set of parameters that can be used when creating or updating a subscription.
///
/// For more details see https://stripe.com/docs/api#create_subscription and https://stripe.com/docs/api#update_subscription.
#[derive(Default, Serialize, Debug)]
pub struct SubscriptionParams<'a> {
    #[serde(skip_serializing_if = "Option::is_none")] pub customer: Option<&'a str>,
    #[serde(skip_serializing_if = "Option::is_none")] pub application_fee_percent: Option<f64>,
    #[serde(skip_serializing_if = "Option::is_none")] pub coupon: Option<&'a str>,
    #[serde(skip_serializing_if = "Option::is_none")] pub items: Option<Vec<ItemParams<'a>>>,
    #[serde(skip_serializing_if = "Option::is_none")] pub metadata: Option<Metadata>,
    #[serde(skip_serializing_if = "Option::is_none")] pub plan: Option<&'a str>,
    #[serde(skip_serializing_if = "Option::is_none")] pub prorate: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")] pub proration_date: Option<Timestamp>,
    #[serde(skip_serializing_if = "Option::is_none")] pub quantity: Option<u64>,
    #[serde(skip_serializing_if = "Option::is_none")] pub source: Option<&'a str>,
    #[serde(skip_serializing_if = "Option::is_none")] pub tax_percent: Option<f64>,
    #[serde(skip_serializing_if = "Option::is_none")] pub trial_end: Option<Timestamp>,
    #[serde(skip_serializing_if = "Option::is_none")] pub trial_period_days: Option<u64>,
}

/// The resource representing a Stripe subscription item.
///
/// For more details see https://stripe.com/docs/api#subscription_items.
#[derive(Debug, Deserialize)]
pub struct SubscriptionItem {
    pub id: String,
    pub created: Timestamp,
    pub plan: Plan,
    pub quantity: u64,
}

/// The resource representing a Stripe subscription.
///
/// For more details see https://stripe.com/docs/api#subscriptions.
#[derive(Debug, Deserialize)]
pub struct Subscription {
    pub id: String,
    pub application_fee_percent: Option<f64>,
    pub cancel_at_period_end: bool,
    pub canceled_at: Option<Timestamp>,
    pub created: Option<Timestamp>,
    pub current_period_start: Timestamp,
    pub current_period_end: Timestamp,
    pub customer: String,
    pub discount: Option<Discount>,
    pub ended_at: Option<Timestamp>,
    pub items: List<SubscriptionItem>,
    pub livemode: bool,
    pub metadata: Metadata,
    pub plan: Plan,
    pub quantity: u64,
    pub start: Timestamp,
    pub status: String, // (trialing, active, past_due, canceled, unpaid)
    pub tax_percent: Option<f64>,
    pub trial_start: Option<Timestamp>,
    pub trial_end: Option<Timestamp>,
}

impl Subscription {
    /// Creates a new subscription for a customer.
    ///
    /// For more details see https://stripe.com/docs/api#create_subscription.
    pub fn create(client: &Client, params: SubscriptionParams) -> Result<Subscription, Error> {
        client.post("/subscriptions", params)
    }

    /// Retrieves the details of a subscription.
    ///
    /// For more details see https://stripe.com/docs/api#retrieve_subscription.
    pub fn retrieve(client: &Client, subscription_id: &str) -> Result<Subscription, Error> {
        client.get(&format!("/subscriptions/{}", subscription_id))
    }

    /// Updates a subscription's properties.
    /// For more details see https://stripe.com/docs/api#update_subscription.
    pub fn update(client: &Client, subscription_id: &str, params: SubscriptionParams) -> Result<Subscription, Error> {
        client.post(&format!("/subscriptions/{}", subscription_id), params)
    }

    /// Cancels a subscription.
    ///
    /// For more details see https://stripe.com/docs/api#cancel_subscription.
    pub fn cancel(client: &Client, subscription_id: &str, params: CancelParams) -> Result<Subscription, Error> {
        client.delete(&format!("/subscriptions/{}?{}", subscription_id, query::to_string(&params)?))
    }
}
<|endoftext|>


<commit_before>extern crate gauc;

use gauc::client::*;
use std::{thread, time};

fn main() {
    let mut client = Client::new("couchbase://localhost/default");

//     println!("{:?}", client.get_sync("foo"));

    // Store some data
    client.upsert("foo", "{\"msg\": \"This is test!\"}", |res| {
        if let Ok(response) = res {
            println!("Created new document, CAS: {}", response.cas)
        }
    });

    // Get data
    client.get("foo", |res| {
        if let Ok(response) = res {
            println!("{} - {}", response.key.unwrap(), response.value.unwrap())
        }
    });

    // Store some data
    client.upsert("foo", "{\"msg\": \"This is test!\"}", |res| {
        if let Ok(response) = res {
            println!("Created new document, CAS: {}", response.cas)
        }
    });

    // Get data
    client.get("foo", |res| {
        if let Ok(response) = res {
            println!("{} - {}", response.key.unwrap(), response.value.unwrap())
        }
    });

    let sleep_interval = time::Duration::from_millis(1000);
    thread::sleep(sleep_interval);
}

<commit_msg>USe korczis.com<commit_after>extern crate gauc;
extern crate env_logger;

use gauc::client::*;
use std::{thread, time};

fn main() {
    env_logger::init().unwrap();

    let mut client = Client::new("couchbase://korczis.com/default");

//     println!("{:?}", client.get_sync("foo"));

    // Store some data
    client.upsert("foo", "{\"msg\": \"This is test!\"}", |res| {
        if let Ok(response) = res {
            println!("Created new document, CAS: {}", response.cas)
        }
    });

    // Get data
    client.get("foo", |res| {
        if let Ok(response) = res {
            println!("{} - {}", response.key.unwrap(), response.value.unwrap())
        }
    });

    // Store some data
    client.upsert("foo", "{\"msg\": \"This is test!\"}", |res| {
        if let Ok(response) = res {
            println!("Created new document, CAS: {}", response.cas)
        }
    });

    // Get data
    client.get("foo", |res| {
        if let Ok(response) = res {
            println!("{} - {}", response.key.unwrap(), response.value.unwrap())
        }
    });

    let sleep_interval = time::Duration::from_millis(1000);
    thread::sleep(sleep_interval);
}

<|endoftext|>


<commit_before>use crate::airport_data::{Airport, AirportType, Position, Runway};
use rand::seq::SliceRandom;
use rocket::State;
use rocket_contrib::json::{Json, JsonValue};
use serde_derive::{Deserialize, Serialize};
use smallvec::{smallvec, SmallVec};
use std::fmt;
use std::ptr;

const MAX_AIRPORTS_TO_GET: usize = 2000;
const MAX_AIRPORTS_TO_RETURN: usize = 100;

#[post("/search_routes", format = "json", data = "<filters>")]
pub fn search_routes<'a>(filters: Json<Filters>, airports: State<'a, Vec<Airport>>) -> JsonValue {
    let departures = filters
        .departure
        .as_ref()
        .map(|filters| filters.matching_airports(&airports))
        .unwrap_or_else(|| random_airport_set(&airports));

    let arrivals = filters
        .arrival
        .as_ref()
        .map(|filters| filters.matching_airports(&airports))
        .unwrap_or_else(|| random_airport_set(&airports));

    let mut routes = Vec::with_capacity(MAX_AIRPORTS_TO_RETURN / 2);

    for departure in departures {
        for arrival in &arrivals {
            if ptr::eq(departure, *arrival) {
                continue;
            }

            let route = Route::new(departure, arrival, filters.speed);

            match &filters.time_or_dist {
                Some(TimeOrDistance::Time(time_range)) => {
                    if !time_range.within(&route.time) {
                        continue;
                    }
                }
                Some(TimeOrDistance::Distance(dist_range)) => {
                    if !dist_range.within(&route.distance) {
                        continue;
                    }
                }
                None => (),
            }

            routes.push(route);
        }
    }

    let mut routes = routes.as_mut_slice();

    if routes.len() > 1 {
        let (shuffled, _) = routes.partial_shuffle(&mut rand::thread_rng(), MAX_AIRPORTS_TO_RETURN);
        routes = shuffled;
    }

    json!({ "routes": routes })
}

#[inline(always)]
fn random_airport_set(airports: &[Airport]) -> AirportList {
    airports
        .choose_multiple(&mut rand::thread_rng(), MAX_AIRPORTS_TO_GET)
        .collect()
}

#[derive(Debug, Serialize)]
struct Route<'a> {
    from: &'a Airport,
    to: &'a Airport,
    distance: f32,
    time: Time,
}

impl<'a> Route<'a> {
    #[inline(always)]
    fn new(from: &'a Airport, to: &'a Airport, speed: Speed) -> Self {
        let distance = Self::calculate_distance(from.position, to.position);
        let time = Time::from_distance(distance, speed);

        Self {
            from,
            to,
            distance,
            time,
        }
    }

    /// Get the distance in nautical miles between two longitude and latitude points
    /// using the Haversine formula.
    fn calculate_distance(from: Position, to: Position) -> f32 {
        // Radius of Earth in nautical miles
        const RADIUS_NM: f32 = 3440.0;

        let from_lat = from.latitude_deg.to_radians();
        let to_lat = to.latitude_deg.to_radians();
        let lat = to_lat - from_lat;

        let lon = (to.longitude_deg - from.longitude_deg).to_radians();

        let a =
            (lat / 2.0).sin().powi(2) + from_lat.cos() * to_lat.cos() * (lon / 2.0).sin().powi(2);
        let c = 2.0 * a.sqrt().atan2((1.0 - a).sqrt());

        RADIUS_NM * c
    }
}

#[derive(Copy, Clone, Debug, Default, Deserialize, Serialize, PartialEq, PartialOrd)]
pub struct Time {
    pub hour: u8,
    pub minutes: u8,
}

impl Time {
    fn from_distance(distance: f32, speed: Speed) -> Self {
        let total_hours = distance / speed.as_knots();

        let hour = total_hours.floor().min(99.0);
        let minutes = ((total_hours - hour) * 60.0).floor().min(59.0);

        Self {
            hour: hour as u8,
            minutes: minutes as u8,
        }
    }
}

#[derive(Copy, Clone, Debug, Deserialize)]
#[serde(rename_all = "lowercase")]
#[serde(tag = "type", content = "value")]
pub enum Speed {
    Mach(f32),
    Knots(f32),
}

impl Speed {
    #[inline(always)]
    fn as_knots(self) -> f32 {
        const KNOTS_PER_MACH: f32 = 666.739;

        match self {
            Self::Mach(mach) => mach * KNOTS_PER_MACH,
            Self::Knots(knots) => knots,
        }
    }
}

#[derive(Debug, Deserialize)]
pub struct Filters {
    pub speed: Speed,
    pub departure: Option<AirportFilters>,
    pub arrival: Option<AirportFilters>,
    #[serde(rename = "timeDist", default)]
    pub time_or_dist: Option<TimeOrDistance>,
}

type AirportList<'a> = SmallVec<[&'a Airport; 1]>;

#[derive(Debug, Deserialize)]
pub struct AirportFilters {
    pub icao: Option<String>,
    #[serde(rename = "airportType", default)]
    pub airport_type: AirportType,
    #[serde(rename = "runwayLength")]
    pub runway_length: Option<RunwayLength>,
    #[serde(default)]
    pub countries: Vec<String>,
}

impl AirportFilters {
    pub fn matching_airports<'a>(&self, airports: &'a [Airport]) -> AirportList<'a> {
        if let Some(icao) = &self.icao {
            let index = airports
                .binary_search_by(|arpt| arpt.icao.as_str().cmp(icao.as_str()))
                .ok();

            let index = match index {
                Some(index) => index,
                None => return SmallVec::new(),
            };

            return smallvec![&airports[index]];
        }

        // TODO: convert to macro
        match (
            self.airport_type,
            &self.runway_length,
            self.countries.as_slice(),
        ) {
            (AirportType::Unknown, None, []) => Self::airport_matches(|_| true, airports),
            (arpt_type, None, []) => {
                Self::airport_matches(|arpt| arpt.class == arpt_type, airports)
            }
            (AirportType::Unknown, Some(len), []) => {
                Self::airport_matches(|arpt| len.fits_any(&arpt.runways), airports)
            }
            (arpt_type, Some(len), []) => Self::airport_matches(
                |arpt| arpt.class == arpt_type && len.fits_any(&arpt.runways),
                airports,
            ),
            (AirportType::Unknown, Some(len), countries) => Self::airport_matches(
                |arpt| {
                    len.fits_any(&arpt.runways) && Self::list_has_any(&arpt.country_name, countries)
                },
                airports,
            ),
            (arpt_type, Some(len), countries) => Self::airport_matches(
                |arpt| {
                    arpt.class == arpt_type
                        && len.fits_any(&arpt.runways)
                        && Self::list_has_any(&arpt.country_name, countries)
                },
                airports,
            ),
            (AirportType::Unknown, None, countries) => Self::airport_matches(
                |arpt| Self::list_has_any(&arpt.country_name, countries),
                airports,
            ),
            (arpt_type, None, countries) => Self::airport_matches(
                |arpt| arpt.class == arpt_type && Self::list_has_any(&arpt.country_name, countries),
                airports,
            ),
        }
    }

    fn airport_matches<F>(matcher: F, airports: &[Airport]) -> AirportList
    where
        F: Fn(&Airport) -> bool,
    {
        let mut results = SmallVec::new();

        for airport in airports {
            if !matcher(airport) {
                continue;
            }

            results.push(airport);

            if results.len() >= MAX_AIRPORTS_TO_GET {
                break;
            }
        }

        results
    }

    #[inline(always)]
    fn list_has_any(name: &str, list: &[String]) -> bool {
        list.iter().any(|x| x.eq_ignore_ascii_case(name))
    }
}

#[derive(Copy, Clone, Debug, Deserialize)]
#[serde(tag = "selector", content = "length")]
pub enum RunwayLength {
    #[serde(rename = "eq")]
    Equal(u32),
    #[serde(rename = "gt")]
    GreaterThan(u32),
    #[serde(rename = "lt")]
    LessThan(u32),
}

impl RunwayLength {
    #[inline(always)]
    pub fn fits(self, length: u32) -> bool {
        match self {
            Self::Equal(len) => len == length,
            Self::GreaterThan(len) => length > len,
            Self::LessThan(len) => length < len,
        }
    }

    #[inline(always)]
    pub fn fits_any(self, runways: &[Runway]) -> bool {
        runways.iter().any(|runway| match runway.length_ft {
            Some(len) => self.fits(len),
            None => false,
        })
    }
}

#[derive(Debug, Default, Deserialize)]
pub struct Range<T>
where
    T: fmt::Debug + Default + PartialOrd,
{
    pub min: Option<T>,
    pub max: Option<T>,
}

impl<T> Range<T>
where
    T: fmt::Debug + Default + PartialOrd,
{
    fn within(&self, value: &T) -> bool {
        if let Some(min) = &self.min {
            if value < min {
                return false;
            }
        }

        if let Some(max) = &self.max {
            if value > max {
                return false;
            }
        }

        true
    }
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "lowercase")]
#[serde(tag = "type", content = "value")]
pub enum TimeOrDistance {
    #[serde(rename = "timeRange")]
    Time(Range<Time>),
    Distance(Range<f32>),
}
<commit_msg>backend: Shorten field names for time and distance filter<commit_after>use crate::airport_data::{Airport, AirportType, Position, Runway};
use rand::seq::SliceRandom;
use rocket::State;
use rocket_contrib::json::{Json, JsonValue};
use serde_derive::{Deserialize, Serialize};
use smallvec::{smallvec, SmallVec};
use std::fmt;
use std::ptr;

const MAX_AIRPORTS_TO_GET: usize = 2000;
const MAX_AIRPORTS_TO_RETURN: usize = 100;

#[post("/search_routes", format = "json", data = "<filters>")]
pub fn search_routes<'a>(filters: Json<Filters>, airports: State<'a, Vec<Airport>>) -> JsonValue {
    let departures = filters
        .departure
        .as_ref()
        .map(|filters| filters.matching_airports(&airports))
        .unwrap_or_else(|| random_airport_set(&airports));

    let arrivals = filters
        .arrival
        .as_ref()
        .map(|filters| filters.matching_airports(&airports))
        .unwrap_or_else(|| random_airport_set(&airports));

    let mut routes = Vec::with_capacity(MAX_AIRPORTS_TO_RETURN / 2);

    for departure in departures {
        for arrival in &arrivals {
            if ptr::eq(departure, *arrival) {
                continue;
            }

            let route = Route::new(departure, arrival, filters.speed);

            match &filters.time_or_dist {
                Some(TimeOrDistance::Time(time_range)) => {
                    if !time_range.within(&route.time) {
                        continue;
                    }
                }
                Some(TimeOrDistance::Distance(dist_range)) => {
                    if !dist_range.within(&route.distance) {
                        continue;
                    }
                }
                None => (),
            }

            routes.push(route);
        }
    }

    let mut routes = routes.as_mut_slice();

    if routes.len() > 1 {
        let (shuffled, _) = routes.partial_shuffle(&mut rand::thread_rng(), MAX_AIRPORTS_TO_RETURN);
        routes = shuffled;
    }

    json!({ "routes": routes })
}

#[inline(always)]
fn random_airport_set(airports: &[Airport]) -> AirportList {
    airports
        .choose_multiple(&mut rand::thread_rng(), MAX_AIRPORTS_TO_GET)
        .collect()
}

#[derive(Debug, Serialize)]
struct Route<'a> {
    from: &'a Airport,
    to: &'a Airport,
    distance: f32,
    time: Time,
}

impl<'a> Route<'a> {
    #[inline(always)]
    fn new(from: &'a Airport, to: &'a Airport, speed: Speed) -> Self {
        let distance = Self::calculate_distance(from.position, to.position);
        let time = Time::from_distance(distance, speed);

        Self {
            from,
            to,
            distance,
            time,
        }
    }

    /// Get the distance in nautical miles between two longitude and latitude points
    /// using the Haversine formula.
    fn calculate_distance(from: Position, to: Position) -> f32 {
        // Radius of Earth in nautical miles
        const RADIUS_NM: f32 = 3440.0;

        let from_lat = from.latitude_deg.to_radians();
        let to_lat = to.latitude_deg.to_radians();
        let lat = to_lat - from_lat;

        let lon = (to.longitude_deg - from.longitude_deg).to_radians();

        let a =
            (lat / 2.0).sin().powi(2) + from_lat.cos() * to_lat.cos() * (lon / 2.0).sin().powi(2);
        let c = 2.0 * a.sqrt().atan2((1.0 - a).sqrt());

        RADIUS_NM * c
    }
}

#[derive(Copy, Clone, Debug, Default, Deserialize, Serialize, PartialEq, PartialOrd)]
pub struct Time {
    pub hour: u8,
    pub minutes: u8,
}

impl Time {
    fn from_distance(distance: f32, speed: Speed) -> Self {
        let total_hours = distance / speed.as_knots();

        let hour = total_hours.floor().min(99.0);
        let minutes = ((total_hours - hour) * 60.0).floor().min(59.0);

        Self {
            hour: hour as u8,
            minutes: minutes as u8,
        }
    }
}

#[derive(Copy, Clone, Debug, Deserialize)]
#[serde(rename_all = "lowercase")]
#[serde(tag = "type", content = "value")]
pub enum Speed {
    Mach(f32),
    Knots(f32),
}

impl Speed {
    #[inline(always)]
    fn as_knots(self) -> f32 {
        const KNOTS_PER_MACH: f32 = 666.739;

        match self {
            Self::Mach(mach) => mach * KNOTS_PER_MACH,
            Self::Knots(knots) => knots,
        }
    }
}

#[derive(Debug, Deserialize)]
pub struct Filters {
    pub speed: Speed,
    pub departure: Option<AirportFilters>,
    pub arrival: Option<AirportFilters>,
    #[serde(rename = "timeDist", default)]
    pub time_or_dist: Option<TimeOrDistance>,
}

type AirportList<'a> = SmallVec<[&'a Airport; 1]>;

#[derive(Debug, Deserialize)]
pub struct AirportFilters {
    pub icao: Option<String>,
    #[serde(rename = "airportType", default)]
    pub airport_type: AirportType,
    #[serde(rename = "runwayLength")]
    pub runway_length: Option<RunwayLength>,
    #[serde(default)]
    pub countries: Vec<String>,
}

impl AirportFilters {
    pub fn matching_airports<'a>(&self, airports: &'a [Airport]) -> AirportList<'a> {
        if let Some(icao) = &self.icao {
            let index = airports
                .binary_search_by(|arpt| arpt.icao.as_str().cmp(icao.as_str()))
                .ok();

            let index = match index {
                Some(index) => index,
                None => return SmallVec::new(),
            };

            return smallvec![&airports[index]];
        }

        // TODO: convert to macro
        match (
            self.airport_type,
            &self.runway_length,
            self.countries.as_slice(),
        ) {
            (AirportType::Unknown, None, []) => Self::airport_matches(|_| true, airports),
            (arpt_type, None, []) => {
                Self::airport_matches(|arpt| arpt.class == arpt_type, airports)
            }
            (AirportType::Unknown, Some(len), []) => {
                Self::airport_matches(|arpt| len.fits_any(&arpt.runways), airports)
            }
            (arpt_type, Some(len), []) => Self::airport_matches(
                |arpt| arpt.class == arpt_type && len.fits_any(&arpt.runways),
                airports,
            ),
            (AirportType::Unknown, Some(len), countries) => Self::airport_matches(
                |arpt| {
                    len.fits_any(&arpt.runways) && Self::list_has_any(&arpt.country_name, countries)
                },
                airports,
            ),
            (arpt_type, Some(len), countries) => Self::airport_matches(
                |arpt| {
                    arpt.class == arpt_type
                        && len.fits_any(&arpt.runways)
                        && Self::list_has_any(&arpt.country_name, countries)
                },
                airports,
            ),
            (AirportType::Unknown, None, countries) => Self::airport_matches(
                |arpt| Self::list_has_any(&arpt.country_name, countries),
                airports,
            ),
            (arpt_type, None, countries) => Self::airport_matches(
                |arpt| arpt.class == arpt_type && Self::list_has_any(&arpt.country_name, countries),
                airports,
            ),
        }
    }

    fn airport_matches<F>(matcher: F, airports: &[Airport]) -> AirportList
    where
        F: Fn(&Airport) -> bool,
    {
        let mut results = SmallVec::new();

        for airport in airports {
            if !matcher(airport) {
                continue;
            }

            results.push(airport);

            if results.len() >= MAX_AIRPORTS_TO_GET {
                break;
            }
        }

        results
    }

    #[inline(always)]
    fn list_has_any(name: &str, list: &[String]) -> bool {
        list.iter().any(|x| x.eq_ignore_ascii_case(name))
    }
}

#[derive(Copy, Clone, Debug, Deserialize)]
#[serde(tag = "selector", content = "length")]
pub enum RunwayLength {
    #[serde(rename = "eq")]
    Equal(u32),
    #[serde(rename = "gt")]
    GreaterThan(u32),
    #[serde(rename = "lt")]
    LessThan(u32),
}

impl RunwayLength {
    #[inline(always)]
    pub fn fits(self, length: u32) -> bool {
        match self {
            Self::Equal(len) => len == length,
            Self::GreaterThan(len) => length > len,
            Self::LessThan(len) => length < len,
        }
    }

    #[inline(always)]
    pub fn fits_any(self, runways: &[Runway]) -> bool {
        runways.iter().any(|runway| match runway.length_ft {
            Some(len) => self.fits(len),
            None => false,
        })
    }
}

#[derive(Debug, Default, Deserialize)]
pub struct Range<T>
where
    T: fmt::Debug + Default + PartialOrd,
{
    pub min: Option<T>,
    pub max: Option<T>,
}

impl<T> Range<T>
where
    T: fmt::Debug + Default + PartialOrd,
{
    fn within(&self, value: &T) -> bool {
        if let Some(min) = &self.min {
            if value < min {
                return false;
            }
        }

        if let Some(max) = &self.max {
            if value > max {
                return false;
            }
        }

        true
    }
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "lowercase")]
#[serde(tag = "type", content = "value")]
pub enum TimeOrDistance {
    #[serde(rename = "time")]
    Time(Range<Time>),
    #[serde(rename = "dist")]
    Distance(Range<f32>),
}
<|endoftext|>


<commit_before>// Copyright (c) 2019 DDN. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

use bytes::Buf;
use futures::{channel::mpsc, Future, Stream, StreamExt, TryStreamExt};
use std::{collections::HashMap, path::PathBuf, pin::Pin};
use tokio::{fs::OpenOptions, io::AsyncWriteExt};
use warp::{body::BodyStream, filters::BoxedFilter, reject, Filter};

#[derive(Debug)]
pub enum Errors {
    IoError(std::io::Error),
    TrySendError(mpsc::TrySendError<String>),
}

impl reject::Reject for Errors {}

pub trait LineStream: Stream<Item = Result<String, warp::Rejection>> {}
impl<T: Stream<Item = Result<String, warp::Rejection>>> LineStream for T {}

fn streamer(s: BodyStream) -> Pin<Box<dyn Stream<Item = Result<String, warp::Rejection>> + Send>> {
    let s = s.map_ok(|mut x| x.to_bytes());

    iml_fs::read_lines(s)
        .map_err(Errors::IoError)
        .map_err(reject::custom)
        .boxed()
}

/// Warp Filter that streams a newline delimited body
pub fn line_stream(
) -> BoxedFilter<(Pin<Box<dyn Stream<Item = Result<String, warp::Rejection>> + Send>>,)> {
    warp::body::stream().map(streamer).boxed()
}

/// Holds all active streams that are currently writing to an address.
pub struct MailboxSenders(HashMap<PathBuf, mpsc::UnboundedSender<String>>);

impl Default for MailboxSenders {
    fn default() -> Self {
        MailboxSenders(HashMap::new())
    }
}

impl MailboxSenders {
    /// Adds a new address and tx handle to write lines with
    pub fn insert(&mut self, address: PathBuf, tx: mpsc::UnboundedSender<String>) {
        self.0.insert(address, tx);
    }
    /// Removes an address.
    ///
    /// Usually called when the associated rx stream has finished.
    pub fn remove(&mut self, address: &PathBuf) {
        self.0.remove(address);
    }
    /// Returns a cloned reference to a tx handle matching the provided address, if one exists.
    pub fn get(&mut self, address: &PathBuf) -> Option<mpsc::UnboundedSender<String>> {
        self.0.get(address).cloned()
    }
    /// Creates a new sender entry.
    ///
    /// Returns a pair of tx handle and a future that will write to a file.
    /// The returned future must be used, and should be spawned as a new task
    /// so it won't block the current task.
    pub fn create(
        &mut self,
        address: PathBuf,
    ) -> (
        mpsc::UnboundedSender<String>,
        impl Future<Output = Result<(), std::io::Error>>,
    ) {
        let (tx, rx) = mpsc::unbounded();

        self.insert(address.clone(), tx.clone());

        (tx, ingest_data(address, rx))
    }
}

/// Given an address and `mpsc::UnboundedReceiver` handle,
/// this fn will create or open an existing file in append mode.
///
/// It will then write any incoming lines from the passed `mpsc::UnboundedReceiver`
/// to that file.
pub async fn ingest_data(
    address: PathBuf,
    mut rx: mpsc::UnboundedReceiver<String>,
) -> Result<(), std::io::Error> {
    tracing::debug!("Starting ingest for {:?}", address);

    let mut file = OpenOptions::new()
        .append(true)
        .create(true)
        .open(address)
        .await?;

    while let Some(mut line) = rx.next().await {
        if !line.ends_with('\n') {
            line.extend(['\n'].iter());
        }

        tracing::debug!("handling line {:?}", line);

        file.write_all(line.as_bytes()).await?;
    }

    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::fs;
    use tempdir::TempDir;

    #[tokio::test]
    async fn test_mailbox_senders() -> Result<(), Box<dyn std::error::Error>> {
        let tmp_dir = TempDir::new("test_mailbox")?;
        let address = tmp_dir.path().join("test_message_1");

        let mut mailbox_sender = MailboxSenders::default();

        let (tx, fut) = mailbox_sender.create(address.clone());

        tx.unbounded_send("foo\n".into())?;

        mailbox_sender
            .get(&address)
            .unwrap()
            .unbounded_send("bar".into())?;

        tx.unbounded_send("baz\n".into())?;

        mailbox_sender.remove(&address);

        drop(tx);

        fut.await?;

        let contents = fs::read_to_string(&address).unwrap();

        assert_eq!(contents, "foo\nbar\nbaz\n");

        Ok(())
    }
}
<commit_msg>Flush after write-all in mailbox (#1424)<commit_after>// Copyright (c) 2019 DDN. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

use bytes::Buf;
use futures::{channel::mpsc, Future, Stream, StreamExt, TryStreamExt};
use std::{collections::HashMap, path::PathBuf, pin::Pin};
use tokio::{fs::OpenOptions, io::AsyncWriteExt};
use warp::{body::BodyStream, filters::BoxedFilter, reject, Filter};

#[derive(Debug)]
pub enum Errors {
    IoError(std::io::Error),
    TrySendError(mpsc::TrySendError<String>),
}

impl reject::Reject for Errors {}

pub trait LineStream: Stream<Item = Result<String, warp::Rejection>> {}
impl<T: Stream<Item = Result<String, warp::Rejection>>> LineStream for T {}

fn streamer(s: BodyStream) -> Pin<Box<dyn Stream<Item = Result<String, warp::Rejection>> + Send>> {
    let s = s.map_ok(|mut x| x.to_bytes());

    iml_fs::read_lines(s)
        .map_err(Errors::IoError)
        .map_err(reject::custom)
        .boxed()
}

/// Warp Filter that streams a newline delimited body
pub fn line_stream(
) -> BoxedFilter<(Pin<Box<dyn Stream<Item = Result<String, warp::Rejection>> + Send>>,)> {
    warp::body::stream().map(streamer).boxed()
}

/// Holds all active streams that are currently writing to an address.
pub struct MailboxSenders(HashMap<PathBuf, mpsc::UnboundedSender<String>>);

impl Default for MailboxSenders {
    fn default() -> Self {
        MailboxSenders(HashMap::new())
    }
}

impl MailboxSenders {
    /// Adds a new address and tx handle to write lines with
    pub fn insert(&mut self, address: PathBuf, tx: mpsc::UnboundedSender<String>) {
        self.0.insert(address, tx);
    }
    /// Removes an address.
    ///
    /// Usually called when the associated rx stream has finished.
    pub fn remove(&mut self, address: &PathBuf) {
        self.0.remove(address);
    }
    /// Returns a cloned reference to a tx handle matching the provided address, if one exists.
    pub fn get(&mut self, address: &PathBuf) -> Option<mpsc::UnboundedSender<String>> {
        self.0.get(address).cloned()
    }
    /// Creates a new sender entry.
    ///
    /// Returns a pair of tx handle and a future that will write to a file.
    /// The returned future must be used, and should be spawned as a new task
    /// so it won't block the current task.
    pub fn create(
        &mut self,
        address: PathBuf,
    ) -> (
        mpsc::UnboundedSender<String>,
        impl Future<Output = Result<(), std::io::Error>>,
    ) {
        let (tx, rx) = mpsc::unbounded();

        self.insert(address.clone(), tx.clone());

        (tx, ingest_data(address, rx))
    }
}

/// Given an address and `mpsc::UnboundedReceiver` handle,
/// this fn will create or open an existing file in append mode.
///
/// It will then write any incoming lines from the passed `mpsc::UnboundedReceiver`
/// to that file.
pub async fn ingest_data(
    address: PathBuf,
    mut rx: mpsc::UnboundedReceiver<String>,
) -> Result<(), std::io::Error> {
    tracing::debug!("Starting ingest for {:?}", address);

    let mut file = OpenOptions::new()
        .append(true)
        .create(true)
        .open(address)
        .await?;

    while let Some(mut line) = rx.next().await {
        if !line.ends_with('\n') {
            line.extend(['\n'].iter());
        }

        tracing::debug!("handling line {:?}", line);

        file.write_all(line.as_bytes()).await?;
    }

    file.flush().await?;

    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::fs;
    use tempdir::TempDir;

    #[tokio::test]
    async fn test_mailbox_senders() -> Result<(), Box<dyn std::error::Error>> {
        let tmp_dir = TempDir::new("test_mailbox")?;
        let address = tmp_dir.path().join("test_message_1");

        let mut mailbox_sender = MailboxSenders::default();

        let (tx, fut) = mailbox_sender.create(address.clone());

        tx.unbounded_send("foo\n".into())?;

        mailbox_sender
            .get(&address)
            .unwrap()
            .unbounded_send("bar".into())?;

        tx.unbounded_send("baz\n".into())?;

        mailbox_sender.remove(&address);

        drop(tx);

        fut.await?;

        let contents = fs::read_to_string(&address).unwrap();

        assert_eq!(contents, "foo\nbar\nbaz\n");

        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::any::TypeId;
use std::cell::RefCell;
use std::collections::HashMap;
#[cfg(test)]
use std::ffi::CString;
use std::rc::Rc;

use pg::{Pg, PgQueryBuilder};
use query_builder::{QueryFragment, QueryId};
use result::QueryResult;
use result::Error::QueryBuilderError;
use super::{Query, RawConnection};

pub struct StatementCache {
    cache: RefCell<HashMap<StatementCacheKey, Rc<Query>>>,
}

#[derive(Hash, PartialEq, Eq)]
enum StatementCacheKey {
    Type(TypeId),
    Query {
        sql: String,
        bind_types: Vec<u32>,
    }
}

impl StatementCacheKey {
    fn sql(&self) -> Option<&str> {
        match self {
            &StatementCacheKey::Query { ref sql, .. } => Some(&*sql),
            _ => None
        }
    }

    fn bind_types(&self) -> Option<&Vec<u32>> {
        match self {
            &StatementCacheKey::Query { ref bind_types, .. } => Some(bind_types),
            _ => None
        }
    }
}

impl StatementCache {
    pub fn new() -> Self {
        StatementCache {
            cache: RefCell::new(HashMap::new()),
        }
    }

    pub fn cached_query<T: QueryFragment<Pg> + QueryId>(
        &self,
        conn: &Rc<RawConnection>,
        source: &T,
        bind_types: Vec<u32>,
    ) -> QueryResult<Rc<Query>> {
        use std::borrow::Cow;

        let mut cache = self.cache.borrow_mut();
        let (cache_key, maybe_binds) = try!(cache_key(conn, source, bind_types));
        // FIXME: This can be cleaned up once https://github.com/rust-lang/rust/issues/32281
        // is stable
        if cache.contains_key(&cache_key) {
            Ok(cache[&cache_key].clone())
        } else {
            let name = format!("__diesel_stmt_{}", cache.len() + 1);
            let statement = {
                let sql = match cache_key.sql() {
                    Some(sql) => Cow::Borrowed(sql),
                    None => Cow::Owned(try!(to_sql(conn, source))),
                };
                let bind_types = cache_key.bind_types()
                    .or(maybe_binds.as_ref()).unwrap();

                Rc::new(try!(Query::prepare(
                    conn,
                    &sql,
                    &name,
                    &bind_types,
                )))
            };
            let entry = cache.entry(cache_key);
            Ok(entry.or_insert(statement).clone())
        }
    }

    #[cfg(test)]
    pub fn len(&self) -> usize {
        self.cache.borrow().len()
    }

    #[cfg(test)]
    pub fn statement_names(&self) -> Vec<CString> {
        let mut statement_names = self.cache.borrow().iter()
            .map(|(_, v)| match **v {
                Query::Prepared { ref name, .. } => name.clone(),
                _ => unreachable!(),
            }).collect::<Vec<_>>();
        statement_names.dedup();
        statement_names
    }
}

fn to_sql<T: QueryFragment<Pg>>(conn: &Rc<RawConnection>, source: &T)
    -> QueryResult<String>
{
    let mut query_builder = PgQueryBuilder::new(conn);
    try!(source.to_sql(&mut query_builder).map_err(QueryBuilderError));
    Ok(query_builder.sql)
}

fn cache_key<T: QueryFragment<Pg> + QueryId>(
    conn: &Rc<RawConnection>,
    source: &T,
    bind_types: Vec<u32>,
) -> QueryResult<(StatementCacheKey, Option<Vec<u32>>)> {
    match T::query_id() {
        Some(id) => Ok((StatementCacheKey::Type(id), Some(bind_types))),
        None => Ok((
            StatementCacheKey::Query {
                sql: try!(to_sql(conn, source)),
                bind_types: bind_types
            },
            None,
        )),
    }
}
<commit_msg>cleanup prepared statement caching #388<commit_after>use std::any::TypeId;
use std::cell::RefCell;
use std::collections::HashMap;
#[cfg(test)]
use std::ffi::CString;
use std::rc::Rc;

use pg::{Pg, PgQueryBuilder};
use query_builder::{QueryFragment, QueryId};
use result::QueryResult;
use result::Error::QueryBuilderError;
use super::{Query, RawConnection};

pub struct StatementCache {
    cache: RefCell<HashMap<StatementCacheKey, Rc<Query>>>,
}

#[derive(Hash, PartialEq, Eq)]
enum StatementCacheKey {
    Type(TypeId),
    Query {
        sql: String,
        bind_types: Vec<u32>,
    }
}

impl StatementCacheKey {
    fn sql(&self) -> Option<&str> {
        match self {
            &StatementCacheKey::Query { ref sql, .. } => Some(&*sql),
            _ => None
        }
    }

    fn bind_types(&self) -> Option<&Vec<u32>> {
        match self {
            &StatementCacheKey::Query { ref bind_types, .. } => Some(bind_types),
            _ => None
        }
    }
}

impl StatementCache {
    pub fn new() -> Self {
        StatementCache {
            cache: RefCell::new(HashMap::new()),
        }
    }

    pub fn cached_query<T: QueryFragment<Pg> + QueryId>(
        &self,
        conn: &Rc<RawConnection>,
        source: &T,
        bind_types: Vec<u32>,
    ) -> QueryResult<Rc<Query>> {
        use std::borrow::Cow;
        use std::collections::hash_map::Entry::{Occupied, Vacant};

        let cache_suffix = self.cache.borrow().len() + 1;
        let mut cache = self.cache.borrow_mut();
        let (cache_key, maybe_binds) = try!(cache_key(conn, source, bind_types));

        match cache.entry(cache_key) {
            Occupied(entry) => Ok(entry.get().clone()),
            Vacant(entry) => {
                let statement = {
                    let sql = match entry.key().sql() {
                        Some(sql) => Cow::Borrowed(sql),
                        None => Cow::Owned(try!(to_sql(conn, source))),
                    };

                    let name = format!("__diesel_stmt_{}", cache_suffix);

                    let bind_types = entry.key().bind_types()
                        .or(maybe_binds.as_ref()).unwrap();

                    Rc::new(try!(Query::prepare(
                        conn,
                        &sql,
                        &name,
                        &bind_types,
                    )))
                };

                Ok(entry.insert(statement).clone())
            }
        }
    }

    #[cfg(test)]
    pub fn len(&self) -> usize {
        self.cache.borrow().len()
    }

    #[cfg(test)]
    pub fn statement_names(&self) -> Vec<CString> {
        let mut statement_names = self.cache.borrow().iter()
            .map(|(_, v)| match **v {
                Query::Prepared { ref name, .. } => name.clone(),
                _ => unreachable!(),
            }).collect::<Vec<_>>();
        statement_names.dedup();
        statement_names
    }
}

fn to_sql<T: QueryFragment<Pg>>(conn: &Rc<RawConnection>, source: &T)
    -> QueryResult<String>
{
    let mut query_builder = PgQueryBuilder::new(conn);
    try!(source.to_sql(&mut query_builder).map_err(QueryBuilderError));
    Ok(query_builder.sql)
}

fn cache_key<T: QueryFragment<Pg> + QueryId>(
    conn: &Rc<RawConnection>,
    source: &T,
    bind_types: Vec<u32>,
) -> QueryResult<(StatementCacheKey, Option<Vec<u32>>)> {
    match T::query_id() {
        Some(id) => Ok((StatementCacheKey::Type(id), Some(bind_types))),
        None => Ok((
            StatementCacheKey::Query {
                sql: try!(to_sql(conn, source)),
                bind_types: bind_types
            },
            None,
        )),
    }
}
<|endoftext|>


<commit_before>// Copyright 2013 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.

//! Implementation of running at_exit routines
//!
//! Documentation can be found on the `rt::at_exit` function.

use core::prelude::*;

use alloc::owned::Box;
use collections::vec::Vec;
use core::atomics;
use core::mem;

use exclusive::Exclusive;

type Queue = Exclusive<Vec<proc():Send>>;

static mut QUEUE: atomics::AtomicUint = atomics::INIT_ATOMIC_UINT;
static mut RUNNING: atomics::AtomicBool = atomics::INIT_ATOMIC_BOOL;

pub fn init() {
    let state: Box<Queue> = box Exclusive::new(Vec::new());
    unsafe {
        rtassert!(!RUNNING.load(atomics::SeqCst));
        rtassert!(QUEUE.swap(mem::transmute(state), atomics::SeqCst) == 0);
    }
}

pub fn push(f: proc():Send) {
    unsafe {
        // Note that the check against 0 for the queue pointer is not atomic at
        // all with respect to `run`, meaning that this could theoretically be a
        // use-after-free. There's not much we can do to protect against that,
        // however. Let's just assume a well-behaved runtime and go from there!
        rtassert!(!RUNNING.load(atomics::SeqCst));
        let queue = QUEUE.load(atomics::SeqCst);
        rtassert!(queue != 0);
        (*(queue as *Queue)).lock().push(f);
    }
}

pub fn run() {
    let cur = unsafe {
        rtassert!(!RUNNING.load(atomics::SeqCst));
        let queue = QUEUE.swap(0, atomics::SeqCst);
        rtassert!(queue != 0);

        let queue: Box<Queue> = mem::transmute(queue);
        mem::replace(&mut *queue.lock(), Vec::new())
    };

    for to_run in cur.move_iter() {
        to_run();
    }
}
<commit_msg>auto merge of #14787 : alexcrichton/rust/issue-14784, r=pcwalton<commit_after>// Copyright 2013 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.

//! Implementation of running at_exit routines
//!
//! Documentation can be found on the `rt::at_exit` function.

use core::prelude::*;

use alloc::owned::Box;
use collections::vec::Vec;
use core::atomics;
use core::mem;

use exclusive::Exclusive;

type Queue = Exclusive<Vec<proc():Send>>;

static mut QUEUE: atomics::AtomicUint = atomics::INIT_ATOMIC_UINT;
static mut RUNNING: atomics::AtomicBool = atomics::INIT_ATOMIC_BOOL;

pub fn init() {
    let state: Box<Queue> = box Exclusive::new(Vec::new());
    unsafe {
        rtassert!(!RUNNING.load(atomics::SeqCst));
        rtassert!(QUEUE.swap(mem::transmute(state), atomics::SeqCst) == 0);
    }
}

pub fn push(f: proc():Send) {
    unsafe {
        // Note that the check against 0 for the queue pointer is not atomic at
        // all with respect to `run`, meaning that this could theoretically be a
        // use-after-free. There's not much we can do to protect against that,
        // however. Let's just assume a well-behaved runtime and go from there!
        rtassert!(!RUNNING.load(atomics::SeqCst));
        let queue = QUEUE.load(atomics::SeqCst);
        rtassert!(queue != 0);
        (*(queue as *Queue)).lock().push(f);
    }
}

pub fn run() {
    let cur = unsafe {
        rtassert!(!RUNNING.load(atomics::SeqCst));
        let queue = QUEUE.swap(0, atomics::SeqCst);
        rtassert!(queue != 0);

        let queue: Box<Queue> = mem::transmute(queue);
        let v = mem::replace(&mut *queue.lock(), Vec::new());
        v
    };

    for to_run in cur.move_iter() {
        to_run();
    }
}
<|endoftext|>


<commit_before>use std::net::ToSocketAddrs;
use std::sync::Arc;
use std::sync::Mutex;
use std::thread;

use futures::channel::oneshot;
use futures::future;
use futures::future::FutureExt;
use futures::future::TryFutureExt;

use httpbis;
use httpbis::for_test::*;
use httpbis::*;

use super::BIND_HOST;
use crate::assert_types::assert_send_future;
use std::thread::JoinHandle;
use tokio::runtime::Runtime;

/// Single connection HTTP/server.
/// Accepts only one connection.
pub struct ServerOneConn {
    from_loop: FromLoop,
    join_handle: Option<thread::JoinHandle<()>>,
    shutdown_tx: Option<oneshot::Sender<()>>,
    conn: Arc<Mutex<Option<ServerConn>>>,
}

struct FromLoop {
    port: u16,
}

impl ServerOneConn {
    pub fn new_fn<S>(port: u16, service: S) -> Self
    where
        S: Fn(ServerHandlerContext, ServerRequest, ServerResponse) -> httpbis::Result<()>
            + Send
            + Sync
            + 'static,
    {
        ServerOneConn::new_fn_impl(port, service)
    }

    #[allow(dead_code)]
    fn new_fn_impl<S>(port: u16, service: S) -> Self
    where
        S: Fn(ServerHandlerContext, ServerRequest, ServerResponse) -> httpbis::Result<()>
            + Send
            + Sync
            + 'static,
    {
        let (from_loop_tx, from_loop_rx) = std::sync::mpsc::channel();
        let (shutdown_tx, shutdown_rx) = oneshot::channel::<()>();

        let conn: Arc<Mutex<Option<ServerConn>>> = Default::default();

        let conn_for_thread = conn.clone();

        let join_handle: JoinHandle<()> = thread::Builder::new()
            .name("server_one_conn".to_owned())
            .spawn(move || {
                let mut lp = Runtime::new().unwrap();

                let mut listener = lp
                    .block_on(tokio::net::TcpListener::bind(
                        &(BIND_HOST, port).to_socket_addrs().unwrap().next().unwrap(),
                    ))
                    .unwrap();

                let actual_port = listener.local_addr().unwrap().port();
                from_loop_tx
                    .send(FromLoop { port: actual_port })
                    .ok()
                    .unwrap();

                let handle = lp.handle().clone();

                let conn = listener.accept().map_err(httpbis::Error::from);

                let future = conn.and_then(move |(conn, peer_addr)| {
                    drop(listener);

                    let (conn, future) = ServerConn::new_plain_single_thread_fn(
                        &handle,
                        conn,
                        peer_addr,
                        Default::default(),
                        service,
                    );
                    *conn_for_thread.lock().unwrap() = Some(conn);
                    future
                });

                let shutdown_rx = shutdown_rx.then(|_| future::ready(()));
                let future = future.then(|_| future::ready(()));

                let shutdown_rx = assert_send_future::<(), _>(shutdown_rx);
                let future = assert_send_future::<(), _>(future);

                let shutdown_rx = Box::pin(shutdown_rx);
                let future = Box::pin(future);

                lp.block_on(future::select(shutdown_rx, future));
            })
            .expect("spawn");

        ServerOneConn {
            from_loop: from_loop_rx.recv().unwrap(),
            join_handle: Some(join_handle),
            shutdown_tx: Some(shutdown_tx),
            conn,
        }
    }
}

#[allow(dead_code)]
impl ServerOneConn {
    pub fn port(&self) -> u16 {
        self.from_loop.port
    }

    pub fn dump_state(&self) -> ConnStateSnapshot {
        let g = self.conn.lock().expect("lock");
        let conn = g.as_ref().expect("conn");
        Runtime::new()
            .unwrap()
            .block_on(conn.dump_state())
            .expect("dump_status")
    }
}

impl Drop for ServerOneConn {
    fn drop(&mut self) {
        drop(self.shutdown_tx.take().unwrap().send(()));
        self.join_handle.take().unwrap().join().ok();
    }
}
<commit_msg>Revert "Remove TODO"<commit_after>use std::net::ToSocketAddrs;
use std::sync::Arc;
use std::sync::Mutex;
use std::thread;

use futures::channel::oneshot;
use futures::future;
use futures::future::FutureExt;
use futures::future::TryFutureExt;

use httpbis;
use httpbis::for_test::*;
use httpbis::*;

use super::BIND_HOST;
use crate::assert_types::assert_send_future;
use std::thread::JoinHandle;
use tokio::runtime::Runtime;

/// Single connection HTTP/server.
/// Accepts only one connection.
pub struct ServerOneConn {
    from_loop: FromLoop,
    join_handle: Option<thread::JoinHandle<()>>,
    shutdown_tx: Option<oneshot::Sender<()>>,
    conn: Arc<Mutex<Option<ServerConn>>>,
}

struct FromLoop {
    port: u16,
}

impl ServerOneConn {
    pub fn new_fn<S>(port: u16, service: S) -> Self
    where
        S: Fn(ServerHandlerContext, ServerRequest, ServerResponse) -> httpbis::Result<()>
            + Send
            + Sync
            + 'static,
    {
        ServerOneConn::new_fn_impl(port, service)
    }

    #[allow(dead_code)]
    fn new_fn_impl<S>(port: u16, service: S) -> Self
    where
        S: Fn(ServerHandlerContext, ServerRequest, ServerResponse) -> httpbis::Result<()>
            + Send
            + Sync
            + 'static,
    {
        let (from_loop_tx, from_loop_rx) = std::sync::mpsc::channel();
        let (shutdown_tx, shutdown_rx) = oneshot::channel::<()>();

        let conn: Arc<Mutex<Option<ServerConn>>> = Default::default();

        let conn_for_thread = conn.clone();

        let join_handle: JoinHandle<()> = thread::Builder::new()
            .name("server_one_conn".to_owned())
            .spawn(move || {
                let mut lp = Runtime::new().unwrap();

                let mut listener = lp
                    .block_on(tokio::net::TcpListener::bind(
                        &(BIND_HOST, port).to_socket_addrs().unwrap().next().unwrap(),
                    ))
                    .unwrap();

                let actual_port = listener.local_addr().unwrap().port();
                from_loop_tx
                    .send(FromLoop { port: actual_port })
                    .ok()
                    .unwrap();

                let handle = lp.handle().clone();

                let conn = listener.accept().map_err(httpbis::Error::from);

                // TODO: close listening port
                //drop(listener);

                let future = conn.and_then(move |(conn, peer_addr)| {
                    let (conn, future) = ServerConn::new_plain_single_thread_fn(
                        &handle,
                        conn,
                        peer_addr,
                        Default::default(),
                        service,
                    );
                    *conn_for_thread.lock().unwrap() = Some(conn);
                    future
                });

                let shutdown_rx = shutdown_rx.then(|_| future::ready(()));
                let future = future.then(|_| future::ready(()));

                let shutdown_rx = assert_send_future::<(), _>(shutdown_rx);
                let future = assert_send_future::<(), _>(future);

                let shutdown_rx = Box::pin(shutdown_rx);
                let future = Box::pin(future);

                lp.block_on(future::select(shutdown_rx, future));
            })
            .expect("spawn");

        ServerOneConn {
            from_loop: from_loop_rx.recv().unwrap(),
            join_handle: Some(join_handle),
            shutdown_tx: Some(shutdown_tx),
            conn,
        }
    }
}

#[allow(dead_code)]
impl ServerOneConn {
    pub fn port(&self) -> u16 {
        self.from_loop.port
    }

    pub fn dump_state(&self) -> ConnStateSnapshot {
        let g = self.conn.lock().expect("lock");
        let conn = g.as_ref().expect("conn");
        Runtime::new()
            .unwrap()
            .block_on(conn.dump_state())
            .expect("dump_status")
    }
}

impl Drop for ServerOneConn {
    fn drop(&mut self) {
        drop(self.shutdown_tx.take().unwrap().send(()));
        self.join_handle.take().unwrap().join().ok();
    }
}
<|endoftext|>