<commit_before>#![feature(nll)]

use std::collections::hash_map;
use std::collections::hash_map::DefaultHasher;
use std::collections::{HashMap, HashSet};
use std::ffi::OsStr;
use std::hash::{Hash, Hasher};
use std::slice;
use build::Arg;
// ! rustdoc

#[derive(Default, PartialEq, Debug)]
pub struct MKeyMap<'a, 'b>
where
    'a: 'b,
{
    keys: HashMap<KeyType<'a>, usize>,
    value_index: Vec<Arg<'a, 'b>>,
    values: HashMap<u64, HashSet<usize>>,
}

#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub enum KeyType<'a> {
    Short(char),
    Long(&'a OsStr),
    Position(usize),
}

impl<'a, 'b> MKeyMap<'a, 'b> {
    pub fn new() -> Self {
        MKeyMap::default()
    }
    //TODO ::from(x), ::with_capacity(n) etc
    //? set theory ops?

    pub fn insert(&mut self, key: KeyType<'a>, value: Arg<'a, 'b>) -> usize {
        let index = self.push(value);
        self.keys.insert(key, index);
        index
    }

    pub fn push(&mut self, value: Arg<'a, 'b>) -> usize {
        let index;
        let mut hasher = DefaultHasher::new();

        value.hash(&mut hasher);

        let hash = hasher.finish();

        if let Some((idx, _)) = self.values.get(&hash).and_then(|ids| {
            ids.iter()
                .map(|&x| (x, &self.value_index[x]))
                .find(|(_i, x)| x == &&value)
        }) {
            index = idx;
        } else {
            self.value_index.push(value);
            index = self.value_index.len() - 1;
            self.values
                .entry(hash)
                .and_modify(|x| {
                    x.insert(index);
                })
                .or_insert({
                    let mut set = HashSet::new();
                    set.insert(index);
                    set
                });
        }
    }
    //TODO ::push_many([x, y])

    pub fn insert_key(&mut self, key: KeyType<'a>, index: usize) {
        if index >= self.values.len() {
            panic!("Index out of bounds");
        }

        self.keys.insert(key, index);
    }
    //TODO ::insert_keyset([Long, Key2])

    pub fn insert_key_by_name(&mut self, key: KeyType<'a>, name: &str) {
        let index = self
            .value_index
            .iter()
            .position(|x| x.name == name)
            .expect("No such name found");

        self.keys.insert(key, index);
    }

    pub fn get(&self, key: KeyType<'a>) -> &Arg<'a, 'b> {
        self.keys
            .get(&key)
            .and_then(|&idx| self.value_index.get(idx))
            .expect(&format!("No entry for the key: {:?}", key))
    }
    //TODO ::get_first([KeyA, KeyB])

    pub fn get_mut(&mut self, key: KeyType<'a>) -> &mut Arg<'a, 'b> {
        let idx = *self
            .keys
            .get(&key)
            .expect(&format!("No entry for the key: {:?}", key));

        self.value_index.get_mut(idx).unwrap()
    }

    pub fn is_empty(&self) -> bool {
        self.keys.is_empty() && self.values.is_empty()
    }

    pub fn remove(&mut self, key: KeyType) -> Option<Arg> {
        unimplemented!()
    }
    //TODO ::remove_many([KeyA, KeyB])
    //? probably shouldn't add a possibility for removal?
    //? or remove by replacement by some dummy object, so the order is preserved

    pub fn remove_key(&mut self, key: KeyType) {
        unimplemented!()
    }
    //TODO ::remove_keys([KeyA, KeyB])

    pub fn keys(&'a self) -> Keys<'a, usize> {
        Keys {
            iter: self.keys.keys(),
        }
    }

    pub fn values(&'a self) -> Values<'a, Arg> {
        Values {
            iter: self.value_index.iter(),
        }
    }

    pub fn values_mut(&'a mut self) -> ValuesMut<'a, Arg> {
        ValuesMut {
            iter: self.value_index.iter_mut(),
        }
    }
}

pub struct Keys<'a, V: 'a> {
    iter: hash_map::Keys<'a, KeyType<'a>, V>,
}

impl<'a, V> Iterator for Keys<'a, V> {
    type Item = &'a KeyType<'a>;

    fn next(&mut self) -> Option<Self::Item> {
        self.iter.next()
    }
}

pub struct Values<'a, V: 'a> {
    iter: slice::Iter<'a, V>,
}

impl<'a, V> Iterator for Values<'a, V> {
    type Item = &'a V;

    fn next(&mut self) -> Option<Self::Item> {
        self.iter.next()
    }
}

pub struct ValuesMut<'a, V: 'a> {
    iter: slice::IterMut<'a, V>,
}

impl<'a, V> Iterator for ValuesMut<'a, V> {
    type Item = &'a V;

    fn next(&mut self) -> Option<Self::Item> {
        self.iter.next()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::ffi::OsStr;
    use self::KeyType::*;

    #[test]
    fn get_some_value() {
        let mut map: MKeyMap = MKeyMap::new();

        {
            map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));
        }

        assert_eq!(
            map.get(Long(&OsStr::new("One"))),
            &Arg::with_name("Value1")
        );
    }

    #[test]
    #[should_panic]
    fn get_none_value() {
        let mut map: MKeyMap = MKeyMap::new();

        map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));
        map.get(Long(&OsStr::new("Two")));
    }

    //    #[test]
    //    fn insert_delete_value() {
    //        let mut map = MKeyMap::new();
    //        map.insert("One", clap::Arg::with_name("Value1"));
    //        assert_eq!(map.remove("One"), Some(clap::Arg::with_name("Value1")));
    //        assert!(map.is_empty());
    //    }

    #[test]
    fn insert_duplicate_key() {
        let mut map: MKeyMap = MKeyMap::new();

        map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));

        assert_eq!(
            map.insert(Long(&OsStr::new("One")), Arg::with_name("Value2")),
            1
        );
    }

    #[test]
    fn insert_duplicate_value() {
        let mut map: MKeyMap = MKeyMap::new();

        map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));

        let orig_len = map.values.len();

        map.insert(Long(&OsStr::new("Two")), Arg::with_name("Value1"));

        assert_eq!(map.values.len(), orig_len);
        assert_eq!(
            map.get(Long(&OsStr::new("One"))),
            map.get(Long(&OsStr::new("Two")))
        );
    }

    //    #[test]
    //    fn insert_delete_none() {
    //        let mut map = MKeyMap::new();
    //        map.insert("One", clap::Arg::with_name("Value1"));
    //        assert_eq!(map.remove("Two"), None);
    //        assert!(!map.is_empty());
    //        assert_eq!(map.get("One"), Some(clap::Arg::with_name("Value1")));
    //    }

    #[test]
    fn insert_multiple_keys() {
        let mut map: MKeyMap = MKeyMap::new();
        let index = map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));

        map.insert_key(Long(&OsStr::new("Two")), index);

        assert_eq!(
            map.get(Long(&OsStr::new("One"))),
            map.get(Long(&OsStr::new("Two")))
        );
        assert_eq!(map.values.len(), 1);
    }

    #[test]
    fn insert_by_name() {
        let mut map: MKeyMap = MKeyMap::new();
        let index = map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));

        map.insert_key_by_name(Long(&OsStr::new("Two")), "Value1");

        assert_eq!(
            map.get(Long(&OsStr::new("One"))),
            map.get(Long(&OsStr::new("Two")))
        );
        assert_eq!(map.values.len(), 1);
    }

    #[test]
    fn get_mutable(){
        let mut map: MKeyMap = MKeyMap::new();

        map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));

        assert_eq!(
            map.get_mut(Long(&OsStr::new("One"))),
            &mut Arg::with_name("Value1")
        );
    }

    #[test]
    fn remove_key() {
        let mut map: MKeyMap = MKeyMap::new();
        let index = map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));

        map.insert_key(Long(&OsStr::new("Two")), index);
        map.remove_key(Long(&OsStr::new("One")));

        assert_eq!(map.keys.len(), 1);
        assert_eq!(map.values.len(), 1);
    }

    #[test]
    fn iter_keys() {
        let mut map: MKeyMap = MKeyMap::new();

        map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));
        map.insert(Long(&OsStr::new("Two")), Arg::with_name("Value2"));
        map.insert(Position(1), Arg::with_name("Value1"));

        let iter = map.keys().cloned();
        let mut ground_truth = HashSet::new();

        ground_truth.insert(Long(&OsStr::new("One")));
        ground_truth.insert(Long(&OsStr::new("Two")));
        ground_truth.insert(Position(1));

        assert_eq!(
            ground_truth.symmetric_difference(&iter.collect()).count(),
            0
        );
    }
}
<commit_msg>MkeyMap API changes<commit_after>#![feature(nll)]

use build::Arg;
use std::collections::hash_map;
use std::collections::hash_map::DefaultHasher;
use std::collections::{HashMap, HashSet};
use std::ffi::OsStr;
use std::hash::{Hash, Hasher};
use std::slice;
// ! rustdoc

#[derive(Default, PartialEq, Debug)]
pub struct MKeyMap<'a, 'b>
where
    'a: 'b,
{
    keys: HashMap<KeyType<'a>, usize>,
    value_index: Vec<Arg<'a, 'b>>,
    values: HashMap<u64, HashSet<usize>>,
}

#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub enum KeyType<'a> {
    Short(char),
    Long(&'a OsStr),
    Position(usize),
}

impl<'a, 'b> MKeyMap<'a, 'b> {
    pub fn new() -> Self { MKeyMap::default() }
    //TODO ::from(x), ::with_capacity(n) etc
    //? set theory ops?

    pub fn insert(&mut self, key: KeyType<'a>, value: Arg<'a, 'b>) -> usize {
        let index = self.push(value);
        self.keys.insert(key, index);
        index
    }

    pub fn push(&mut self, value: Arg<'a, 'b>) -> usize {
        let index;
        let mut hasher = DefaultHasher::new();

        value.hash(&mut hasher);

        let hash = hasher.finish();

        if let Some((idx, _)) = self.values.get(&hash).and_then(|ids| {
            ids.iter()
                .map(|&x| (x, &self.value_index[x]))
                .find(|(_i, x)| x == &&value)
        }) {
            index = idx;
        } else {
            self.value_index.push(value);
            index = self.value_index.len() - 1;
            self.values
                .entry(hash)
                .and_modify(|x| {
                    x.insert(index);
                })
                .or_insert({
                    let mut set = HashSet::new();
                    set.insert(index);
                    set
                });
        }

        index
    }
    //TODO ::push_many([x, y])

    pub fn insert_key(&mut self, key: KeyType<'a>, index: usize) {
        if index >= self.values.len() {
            panic!("Index out of bounds");
        }

        self.keys.insert(key, index);
    }
    //TODO ::insert_keyset([Long, Key2])

    pub fn insert_key_by_name(&mut self, key: KeyType<'a>, name: &str) {
        let index = self
            .value_index
            .iter()
            .position(|x| x.name == name)
            .expect("No such name found");

        self.keys.insert(key, index);
    }

    pub fn get(&self, key: KeyType<'a>) -> Option<&Arg<'a, 'b>> {
        self.keys
            .get(&key)
            .and_then(|&idx| self.value_index.get(idx))
    }
    //TODO ::get_first([KeyA, KeyB])

    pub fn get_mut(&mut self, key: KeyType<'a>) -> Option<&mut Arg<'a, 'b>> {
        if let Some(&idx) = self
            .keys
            .get(&key) {
                self.value_index.get_mut(idx)
            } else {
                None
            }
    }

    pub fn is_empty(&self) -> bool { self.keys.is_empty() && self.values.is_empty() }

    pub fn remove(&mut self, key: KeyType) -> Option<Arg> { unimplemented!() }
    //TODO ::remove_many([KeyA, KeyB])
    //? probably shouldn't add a possibility for removal?
    //? or remove by replacement by some dummy object, so the order is preserved

    pub fn remove_key(&mut self, key: KeyType) { unimplemented!() }
    //TODO ::remove_keys([KeyA, KeyB])

    pub fn keys(&'a self) -> Keys<'a, usize> {
        Keys {
            iter: self.keys.keys(),
        }
    }

    pub fn values(&'a self) -> Values<'a, Arg> {
        Values {
            iter: self.value_index.iter(),
        }
    }

    pub fn values_mut(&'a mut self) -> ValuesMut<'a, Arg> {
        ValuesMut {
            iter: self.value_index.iter_mut(),
        }
    }

    pub fn iter(&self) -> Iter {
        Iter {
            map: self,
            keys: self.keys(),
        }
    }
}

//TODO remove generics
pub struct Keys<'a, V: 'a> {
    iter: hash_map::Keys<'a, KeyType<'a>, V>,
}

impl<'a, V> Iterator for Keys<'a, V> {
    type Item = &'a KeyType<'a>;

    fn next(&mut self) -> Option<Self::Item> { self.iter.next() }
}

pub struct Values<'a, V: 'a> {
    iter: slice::Iter<'a, V>,
}

impl<'a, V> Iterator for Values<'a, V> {
    type Item = &'a V;

    fn next(&mut self) -> Option<Self::Item> { self.iter.next() }
}

pub struct ValuesMut<'a, V: 'a> {
    iter: slice::IterMut<'a, V>,
}

impl<'a, V> Iterator for ValuesMut<'a, V> {
    type Item = &'a mut V;

    fn next(&mut self) -> Option<Self::Item> { self.iter.next() }
}

pub struct Iter<'a, 'b, 'c>  where
'a: 'b,
'b: 'c {
    map: &'c MKeyMap<'a, 'b>,
    keys: Keys<'c, usize>,
}

impl <'a, 'b, 'c> Iterator for Iter<'a, 'b, 'c>
{
    type Item = (&'c KeyType<'a>, &'c Arg<'a, 'b>);

    fn next(&mut self) -> Option<Self::Item> {
        if let Some(key) = self.keys.next() {
            Some((key, self.map.get(key.clone()).unwrap()))
        } else {
            None
        }
    }
}

#[cfg(test)]
mod tests {
    use self::KeyType::*;
    use super::*;
    use std::ffi::OsStr;

    #[test]
    fn get_some_value() {
        let mut map: MKeyMap = MKeyMap::new();

        {
            map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));
        }

        assert_eq!(map.get(Long(&OsStr::new("One"))), &Arg::with_name("Value1"));
    }

    #[test]
    #[should_panic]
    fn get_none_value() {
        let mut map: MKeyMap = MKeyMap::new();

        map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));
        map.get(Long(&OsStr::new("Two")));
    }

    //    #[test]
    //    fn insert_delete_value() {
    //        let mut map = MKeyMap::new();
    //        map.insert("One", clap::Arg::with_name("Value1"));
    //        assert_eq!(map.remove("One"), Some(clap::Arg::with_name("Value1")));
    //        assert!(map.is_empty());
    //    }

    #[test]
    fn insert_duplicate_key() {
        let mut map: MKeyMap = MKeyMap::new();

        map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));

        assert_eq!(
            map.insert(Long(&OsStr::new("One")), Arg::with_name("Value2")),
            1
        );
    }

    #[test]
    fn insert_duplicate_value() {
        let mut map: MKeyMap = MKeyMap::new();

        map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));

        let orig_len = map.values.len();

        map.insert(Long(&OsStr::new("Two")), Arg::with_name("Value1"));

        assert_eq!(map.values.len(), orig_len);
        assert_eq!(
            map.get(Long(&OsStr::new("One"))),
            map.get(Long(&OsStr::new("Two")))
        );
    }

    //    #[test]
    //    fn insert_delete_none() {
    //        let mut map = MKeyMap::new();
    //        map.insert("One", clap::Arg::with_name("Value1"));
    //        assert_eq!(map.remove("Two"), None);
    //        assert!(!map.is_empty());
    //        assert_eq!(map.get("One"), Some(clap::Arg::with_name("Value1")));
    //    }

    #[test]
    fn insert_multiple_keys() {
        let mut map: MKeyMap = MKeyMap::new();
        let index = map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));

        map.insert_key(Long(&OsStr::new("Two")), index);

        assert_eq!(
            map.get(Long(&OsStr::new("One"))),
            map.get(Long(&OsStr::new("Two")))
        );
        assert_eq!(map.values.len(), 1);
    }

    #[test]
    fn insert_by_name() {
        let mut map: MKeyMap = MKeyMap::new();
        let index = map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));

        map.insert_key_by_name(Long(&OsStr::new("Two")), "Value1");

        assert_eq!(
            map.get(Long(&OsStr::new("One"))),
            map.get(Long(&OsStr::new("Two")))
        );
        assert_eq!(map.values.len(), 1);
    }

    #[test]
    fn get_mutable() {
        let mut map: MKeyMap = MKeyMap::new();

        map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));

        assert_eq!(
            map.get_mut(Long(&OsStr::new("One"))),
            &mut Arg::with_name("Value1")
        );
    }

    #[test]
    fn remove_key() {
        let mut map: MKeyMap = MKeyMap::new();
        let index = map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));

        map.insert_key(Long(&OsStr::new("Two")), index);
        map.remove_key(Long(&OsStr::new("One")));

        assert_eq!(map.keys.len(), 1);
        assert_eq!(map.values.len(), 1);
    }

    #[test]
    fn iter_keys() {
        let mut map: MKeyMap = MKeyMap::new();

        map.insert(Long(&OsStr::new("One")), Arg::with_name("Value1"));
        map.insert(Long(&OsStr::new("Two")), Arg::with_name("Value2"));
        map.insert(Position(1), Arg::with_name("Value1"));

        let iter = map.keys().cloned();
        let mut ground_truth = HashSet::new();

        ground_truth.insert(Long(&OsStr::new("One")));
        ground_truth.insert(Long(&OsStr::new("Two")));
        ground_truth.insert(Position(1));

        assert_eq!(
            ground_truth.symmetric_difference(&iter.collect()).count(),
            0
        );
    }
}
<|endoftext|>


<commit_before>
use token::{Token, TokenKind};
use error::Error;

pub struct Scanner {
    source: Vec<u8>,
    tokens: Vec<Token>,
    start: usize,
    current: usize,
    line: u64,
}

impl Scanner {
    pub fn new(source: String) -> Self {
        Scanner {
            source: source.into_bytes(),
            tokens: Vec::new(),
            start: 0,
            current: 0,
            line: 1,
        }
    }

    pub fn scan_tokens(&mut self) -> Result<Vec<Token>, Error> {
        while !self.is_at_end() {
            self.start = self.current;
            match self.scan_token() {
                Ok(_) => {},
                Err(e) => return Err(e)
            }
        }

        self.tokens.push(Token::new(TokenKind::EOF, "".into(), self.line));
        Ok(self.tokens.clone())
    }

    fn scan_token(&mut self) -> Result<(), Error> {
        match self.advance() {
            b':' => {
                self.add_token(TokenKind::Colon);
                while self.peek() == b' ' && !self.is_at_end() {
                    self.advance();
                }
                if self.is_at_end() {
                    return Err(Error::ParseError);
                }
            },
            b'#' => {
                while self.peek() != b'\n' && !self.is_at_end() {
                    self.advance();
                }
            },
            b' ' => {
                let mut spaces = 0;
                while self.peek() == b' ' && !self.is_at_end() {
                    self.advance();
                }
                if self.is_at_end() || spaces != 4 {
                    return Err(Error::ParseError);
                }
            },
            b'\n' => self.add_token(TokenKind::Newline),
            _ => return Err(Error::ParseError)
        }
        Ok(())
    }

    fn is_at_end(&mut self) -> bool {
        self.current >= self.source.len()
    }

    fn advance(&mut self) -> u8 {
        self.current += 1;
        self.source[self.current]
    }

    fn add_token(&mut self, kind: TokenKind) {
        // assume valid UTF8
        let text = String::from_utf8(self.source[self.start..self.current].to_vec()).unwrap();
        self.tokens.push(Token::new(kind, text, self.line));
    }

    fn matches(&mut self, expected: char) -> bool {
        if self.is_at_end() {
            false
        } else if self.source[self.current] != expected as u8 {
            false
        } else {
            self.current += 1;
            true
        }
    }

    fn peek(&mut self) -> u8 {
        if self.current >= self.source.len() {
            b'\0'
        } else {
            self.source[self.current]
        }
    }
}

<commit_msg>continue parser<commit_after>
use token::{Token, TokenKind};
use error::Error;

// ranked worst to least
enum Indent {
    Neither,
    Tabs,
    Spaces(u8),
}

pub struct Scanner {
    source: Vec<u8>,
    tokens: Vec<Token>,
    start: usize,
    current: usize,
    line: u64,
    indent: Indent,
}

impl Scanner {
    pub fn new(source: String) -> Self {
        Scanner {
            source: source.into_bytes(),
            tokens: Vec::new(),
            start: 0,
            current: 0,
            line: 1,
            indent: Indent::Neither,
        }
    }

    pub fn scan_tokens(&mut self) -> Result<Vec<Token>, Error> {
        while !self.is_at_end() {
            self.start = self.current;
            match self.scan_token() {
                Ok(_) => {},
                Err(e) => return Err(e)
            }
        }

        self.tokens.push(Token::new(TokenKind::EOF, "".into(), self.line));
        Ok(self.tokens.clone())
    }

    fn scan_token(&mut self) -> Result<(), Error> {
        match self.advance() {
            b':' => {
                self.add_token(TokenKind::Colon);
                while self.peek() == b' ' && !self.is_at_end() {
                    self.advance();
                }
                if self.is_at_end() {
                    return Err(Error::ParseError);
                }
            },
            b'#' => {
                while self.peek() != b'\n' && !self.is_at_end() {
                    self.advance();
                }
            },
            b' ' => {
                match self.indent {
                    Indent::Neither => {
                        let mut spaces = 0;
                        while self.peek() == b' ' && !self.is_at_end() {
                            self.advance();
                            spaces += 1;
                        }
                        if self.is_at_end() {
                            return Err(Error::ParseError);
                        }
                        self.indent = Indent::Spaces(spaces);
                        self.add_token(TokenKind::Indent);
                    }
                    Indent::Spaces(s) => {
                        let mut spaces = 0;
                        while spaces <= s && self.peek() == b' ' && !self.is_at_end() {
                            self.advance();
                            spaces += 1;
                        }
                        if self.is_at_end() {
                            return Err(Error::ParseError);
                        }
                        if spaces != s {
                            return Err(Error::IndentationError);
                        }
                        self.add_token(TokenKind::Indent);
                    },
                    Indent::Tabs => return Err(Error::IndentationError)
                }
            },
            b'\t' => {
                match self.indent {
                    Indent::Neither => {
                        self.add_token(TokenKind::Indent);
                        self.indent = Indent::Tabs;
                    },
                    Indent::Tabs => {
                        self.add_token(TokenKind::Indent);
                    },
                    Indent::Spaces(_) => return Err(Error::IndentationError)
                }
            }
            b'\n' => self.add_token(TokenKind::Newline),
            _ => return Err(Error::ParseError)
        }
        Ok(())
    }

    fn is_at_end(&mut self) -> bool {
        self.current >= self.source.len()
    }

    fn advance(&mut self) -> u8 {
        self.current += 1;
        self.source[self.current]
    }

    fn add_token(&mut self, kind: TokenKind) {
        // assume valid UTF8
        let text = String::from_utf8(self.source[self.start..self.current].to_vec()).unwrap();
        self.tokens.push(Token::new(kind, text, self.line));
    }

    fn matches(&mut self, expected: char) -> bool {
        if self.is_at_end() {
            false
        } else if self.source[self.current] != expected as u8 {
            false
        } else {
            self.current += 1;
            true
        }
    }

    fn peek(&mut self) -> u8 {
        if self.current >= self.source.len() {
            b'\0'
        } else {
            self.source[self.current]
        }
    }
}

<|endoftext|>


<commit_before>//! Networking primitives for Uni.rs

use cell::GlobalCell;

use thread::Scheduler;

mod imp;

mod pkt;
mod intf;
mod conn;

mod eth;

pub mod defs;

pub use self::pkt::Packet;
pub use self::imp::{Instance, InstanceWeak};

pub use self::intf::{Interface, InterfaceWeak, InterfaceRaw, V4Configuration};

static STACK: GlobalCell<Instance> = GlobalCell::new();

/// Uni.rs network stack
pub struct Stack;

impl Stack {
    #[doc(hidden)]
    pub fn init() {
        STACK.set(Instance::new());

        // Spawn the network thread
        Scheduler::spawn(|| {
            Instance::network_thread(STACK.as_ref().clone());
        });
    }

    /// Returns interfaces registered in the network stack
    pub fn instance() -> Instance {
        STACK.as_ref().clone()
    }
}
<commit_msg>net: Module conn is now public<commit_after>//! Networking primitives for Uni.rs

use cell::GlobalCell;

use thread::Scheduler;

mod imp;

mod pkt;
mod intf;
pub mod conn;

mod eth;

pub mod defs;

pub use self::pkt::Packet;
pub use self::imp::{Instance, InstanceWeak};

pub use self::intf::{Interface, InterfaceWeak, InterfaceRaw, V4Configuration};

static STACK: GlobalCell<Instance> = GlobalCell::new();

/// Uni.rs network stack
pub struct Stack;

impl Stack {
    #[doc(hidden)]
    pub fn init() {
        STACK.set(Instance::new());

        // Spawn the network thread
        Scheduler::spawn(|| {
            Instance::network_thread(STACK.as_ref().clone());
        });
    }

    /// Returns interfaces registered in the network stack
    pub fn instance() -> Instance {
        STACK.as_ref().clone()
    }
}
<|endoftext|>


<commit_before>extern crate semver;

use std::collections::HashMap;
use std::io::net::ip::IpAddr;

#[deriving(PartialEq, Show, Clone)]
pub enum Scheme {
    Http,
    Https
}

#[deriving(PartialEq, Show, Clone)]
pub enum Host<'a> {
    HostName(&'a str),
    HostIp(IpAddr)
}

#[deriving(PartialEq, Show, Clone)]
pub enum Method<'a> {
    Get,
    Post,
    Put,
    Patch,
    Delete,
    Other(&'a str)
}

pub trait Request {
    /// The version of HTTP being used
    fn http_version(&self) -> semver::Version;

    /// The version of the conduit spec being used
    fn conduit_version(&self) -> semver::Version;

    /// The request method, such as GET, POST, PUT, DELETE or PATCH
    fn method<'a>(&'a self) -> Method<'a>;

    /// The scheme part of the request URL
    fn scheme(&self) -> Scheme;

    /// The host part of the requested URL
    fn host<'a>(&'a self) -> Host<'a>;

    /// The initial part of the request URL's path that corresponds
    /// to a virtual root. This allows an application to have a
    /// virtual location that consumes part of the path.
    fn virtual_root<'a>(&'a self) -> Option<&'a str>;

    /// The remainder of the path.
    fn path<'a>(&'a self) -> &'a str;

    /// The portion of the request URL that follows the "?"
    fn query_string<'a>(&'a self) -> Option<&'a str>;

    /// The remote IP address of the client or the last proxy that
    /// sent the request.
    fn remote_ip(&self) -> IpAddr;

    /// The byte-size of the body, if any
    fn content_length(&self) -> Option<uint>;

    /// A Reader for the body of the request
    fn body<'a>(&'a mut self) -> &'a mut Reader;
}

pub struct Response {
    /// The status code as a tuple of the return code and status string
    pub status: (uint, &'static str),

    /// A Map of the headers
    pub headers: HashMap<String, String>,

    /// A Writer for body of the response
    pub body: Box<Reader + Send>
}

pub type Handler = fn(&mut Request) -> Response;
<commit_msg>Add headers<commit_after>extern crate semver;

use std::collections::HashMap;
use std::io::net::ip::IpAddr;

#[deriving(PartialEq, Show, Clone)]
pub enum Scheme {
    Http,
    Https
}

#[deriving(PartialEq, Show, Clone)]
pub enum Host<'a> {
    HostName(&'a str),
    HostIp(IpAddr)
}

#[deriving(PartialEq, Show, Clone)]
pub enum Method<'a> {
    Get,
    Post,
    Put,
    Patch,
    Delete,
    Other(&'a str)
}

pub trait Request {
    /// The version of HTTP being used
    fn http_version(&self) -> semver::Version;

    /// The version of the conduit spec being used
    fn conduit_version(&self) -> semver::Version;

    /// The request method, such as GET, POST, PUT, DELETE or PATCH
    fn method<'a>(&'a self) -> Method<'a>;

    /// The scheme part of the request URL
    fn scheme(&self) -> Scheme;

    /// The host part of the requested URL
    fn host<'a>(&'a self) -> Host<'a>;

    /// The initial part of the request URL's path that corresponds
    /// to a virtual root. This allows an application to have a
    /// virtual location that consumes part of the path.
    fn virtual_root<'a>(&'a self) -> Option<&'a str>;

    /// The remainder of the path.
    fn path<'a>(&'a self) -> &'a str;

    /// The portion of the request URL that follows the "?"
    fn query_string<'a>(&'a self) -> Option<&'a str>;

    /// The remote IP address of the client or the last proxy that
    /// sent the request.
    fn remote_ip(&self) -> IpAddr;

    /// The byte-size of the body, if any
    fn content_length(&self) -> Option<uint>;

    fn headers<'a>(&'a self) -> &'a mut Headers;

    /// A Reader for the body of the request
    fn body<'a>(&'a mut self) -> &'a mut Reader;
}

pub trait Headers {
    /// Find the value of a given header. Multi-line headers are represented
    /// as an array.
    fn find<'a>(&'a str) -> Option<&'a [&'a str]>;

    /// Returns true if a particular header exists
    fn has(&str) -> bool;

    /// Iterate over all of the available headers.
    fn iter<'a>(&'a self) -> &'a Iterator<(&'a str, &'a [&'a str])>;
}

pub struct Response {
    /// The status code as a tuple of the return code and status string
    pub status: (uint, &'static str),

    /// A Map of the headers
    pub headers: HashMap<String, String>,

    /// A Writer for body of the response
    pub body: Box<Reader + Send>
}

pub type Handler = fn(&mut Request) -> Response;
<|endoftext|>


<commit_before>//! Serialization support for the `application/x-www-form-urlencoded` format.

mod key;
mod pair;
mod value;

use serde::ser;
use std::borrow::Cow;
use std::error;
use std::fmt;
use std::str;
use url::form_urlencoded;

/// A serializer for the `application/x-www-form-urlencoded` format.
///
/// * Supported top-level inputs are structs, maps and sequences of pairs,
///   with or without a given length.
///
/// * Supported keys and values are integers, bytes (if convertible to strings),
///   unit structs and unit variants.
///
/// * Newtype structs defer to their inner values.
pub struct Serializer<T>(form_urlencoded::Serializer<T>)
    where T: form_urlencoded::Target;

/// Errors returned during serializing to `application/x-www-form-urlencoded`.
#[derive(Clone, Debug)]
pub enum Error {
    Custom(Cow<'static, str>),
    InvalidValue(Cow<'static, str>),
    Utf8(str::Utf8Error),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match *self {
            Error::Custom(ref msg) => msg.fmt(f),
            Error::InvalidValue(ref msg) => write!(f, "invalid value: {}", msg),
            Error::Utf8(ref err) => write!(f, "invalid UTF-8: {}", err),
        }
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::Custom(ref msg) => msg,
            Error::InvalidValue(ref msg) => msg,
            Error::Utf8(ref err) => error::Error::description(err),
        }
    }

    /// The lower-level cause of this error, in the case of a `Utf8` error.
    fn cause(&self) -> Option<&error::Error> {
        match *self {
            Error::Custom(_) | Error::InvalidValue(_) => None,
            Error::Utf8(ref err) => Some(err),
        }
    }
}

impl ser::Error for Error {
    fn custom<T: Into<String>>(msg: T) -> Self {
        Error::Custom(msg.into().into())
    }

    fn invalid_value(msg: &str) -> Self {
        Error::InvalidValue(String::from(msg).into())
    }
}

/// State used when serializing sequences.
pub struct SeqState(());

/// State used when serializing tuples.
pub struct TupleState(());

/// State used when serializing tuple structs.
pub struct TupleStructState(());

/// State used when serializing tuple variants.
pub struct TupleVariantState(());

/// State used when serializing maps.
pub struct MapState(Option<Cow<'static, str>>);

/// State used when serializing structs.
pub struct StructState(());

/// State used when serializing struct variants.
pub struct StructVariantState(());

impl<Target: form_urlencoded::Target> ser::Serializer for Serializer<Target> {
    type Error = Error;

    /// State used when serializing sequences.
    type SeqState = SeqState;

    /// State used when serializing tuples.
    type TupleState = TupleState;

    /// State used when serializing tuple structs.
    type TupleStructState = TupleStructState;

    /// State used when serializing tuple variants.
    type TupleVariantState = TupleVariantState;

    /// State used when serializing maps.
    type MapState = MapState;

    /// State used when serializing structs.
    type StructState = StructState;

    /// State used when serializing struct variants.
    type StructVariantState = StructVariantState;

    /// Returns an error.
    fn serialize_bool(&mut self, _v: bool) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_isize(&mut self, _v: isize) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_i8(&mut self, _v: i8) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_i16(&mut self, _v: i16) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_i32(&mut self, _v: i32) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_i64(&mut self, _v: i64) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_usize(&mut self, _v: usize) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_u8(&mut self, _v: u8) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_u16(&mut self, _v: u16) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_u32(&mut self, _v: u32) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_u64(&mut self, _v: u64) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_f32(&mut self, _v: f32) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_f64(&mut self, _v: f64) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_char(&mut self, _v: char) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_str(&mut self, _value: &str) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_bytes(&mut self, _value: &[u8]) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_unit(&mut self) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_unit_struct(
            &mut self, _name: &'static str)
            -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_unit_variant(
            &mut self,
            _name: &'static str,
            _variant_index: usize,
            _variant: &'static str)
            -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Serializes the inner value, ignoring the newtype name.
    fn serialize_newtype_struct<T>(
            &mut self, _name: &'static str, value: T)
            -> Result<(), Error>
        where T: ser::Serialize
    {
        value.serialize(self)
    }

    /// Returns an error.
    fn serialize_newtype_variant<T>(
            &mut self,
            _name: &'static str,
            _variant_index: usize,
            _variant: &'static str,
            _value: T)
            -> Result<(), Error>
        where T: ser::Serialize
    {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_none(&mut self) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_some<T>(&mut self, _value: T) -> Result<(), Error>
        where T: ser::Serialize
    {
        Err(Error::top_level())
    }

    /// Begins to serialize a sequence, given length (if any) is ignored.
    fn serialize_seq(
            &mut self, _len: Option<usize>)
            -> Result<SeqState, Error> {
        Ok(SeqState(()))
    }

    /// Serializes a sequence element.
    fn serialize_seq_elt<T>(
            &mut self, _state: &mut SeqState, value: T)
            -> Result<(), Error>
        where T: ser::Serialize
    {
        value.serialize(&mut pair::PairSerializer::new(&mut self.0))
    }

    /// Finishes serializing a sequence.
    fn serialize_seq_end(&mut self, _state: SeqState) -> Result<(), Error> {
        Ok(())
    }

    /// Begins to serialize a sequence, given length is ignored.
    fn serialize_seq_fixed_size(
            &mut self, _length: usize)
            -> Result<SeqState, Error> {
        Ok(SeqState(()))
    }

    /// Returns an error.
    fn serialize_tuple(&mut self, _len: usize) -> Result<TupleState, Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_tuple_elt<T>(
            &mut self, _state: &mut TupleState, _value: T)
            -> Result<(), Error>
        where T: ser::Serialize
    {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_tuple_end(&mut self, _state: TupleState) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_tuple_struct(
            &mut self, _name: &'static str, _len: usize)
            -> Result<TupleStructState, Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_tuple_struct_elt<T>(
            &mut self, _state: &mut TupleStructState, _value: T)
            -> Result<(), Error>
        where T: ser::Serialize
    {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_tuple_struct_end(
            &mut self, _state: TupleStructState)
            -> Result<(), Error>
    {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_tuple_variant(
            &mut self,
            _name: &'static str,
            _variant_index: usize,
            _variant: &'static str,
            _len: usize)
            -> Result<TupleVariantState, Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_tuple_variant_elt<T>(
            &mut self, _state: &mut TupleVariantState, _value: T)
            -> Result<(), Error>
        where T: ser::Serialize
    {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_tuple_variant_end(
            &mut self, _state: TupleVariantState)
            -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Begins to serialize a map, given length (if any) is ignored.
    fn serialize_map(
            &mut self, _len: Option<usize>)
            -> Result<MapState, Error> {
        Ok(MapState(None))
    }

    /// Serializes a map key.
    fn serialize_map_key<T>(
            &mut self, state: &mut MapState, key: T)
            -> Result<(), Error>
        where T: ser::Serialize
    {
        key.serialize(&mut key::MapKeySerializer::new(&mut state.0))
    }

    /// Serializes a map value.
    fn serialize_map_value<T>(
            &mut self, state: &mut MapState, value: T)
            -> Result<(), Error>
        where T: ser::Serialize
    {
        let mut value_serializer =
            try!(value::ValueSerializer::new(&mut state.0, &mut self.0));
        value.serialize(&mut value_serializer)
    }

    /// Finishes serializing a map.
    fn serialize_map_end(&mut self, _state: MapState) -> Result<(), Error> {
        Ok(())
    }

    /// Begins to serialize a struct, given length is ignored.
    fn serialize_struct(
            &mut self, _name: &'static str, _len: usize)
            -> Result<StructState, Error> {
        Ok(StructState(()))
    }

    /// Serializes a struct element.
    fn serialize_struct_elt<T>(
            &mut self,
            _state: &mut StructState,
            key: &'static str,
            value: T)
            -> Result<(), Error>
        where T: ser::Serialize
    {
        let mut key = Some(key.into());
        let mut value_serializer =
            value::ValueSerializer::new(&mut key, &mut self.0).unwrap();
        value.serialize(&mut value_serializer)
    }

    /// Finishes serializing a struct.
    fn serialize_struct_end(&mut self, _state: StructState)
                            -> Result<(), Error> {
        Ok(())
    }

    /// Returns an error.
    fn serialize_struct_variant(
            &mut self,
            _name: &'static str,
            _variant_index: usize,
            _variant: &'static str,
            _len: usize)
            -> Result<StructVariantState, Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_struct_variant_elt<T>(
            &mut self,
            _state: &mut StructVariantState,
            _key: &'static str,
            _value: T)
            -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_struct_variant_end(
            &mut self, _state: StructVariantState)
            -> Result<(), Error> {
        Err(Error::top_level())
    }
}

impl Error {
    fn top_level() -> Self {
        Error::Custom(
            "top-level serializer supports only maps and structs".into())
    }
}
<commit_msg>Make Serializer borrow its inner url-encoded serializer<commit_after>//! Serialization support for the `application/x-www-form-urlencoded` format.

mod key;
mod pair;
mod value;

use serde::ser;
use std::borrow::Cow;
use std::error;
use std::fmt;
use std::str;
use url::form_urlencoded::Serializer as UrlEncodedSerializer;
use url::form_urlencoded::Target as UrlEncodedTarget;

/// A serializer for the `application/x-www-form-urlencoded` format.
///
/// * Supported top-level inputs are structs, maps and sequences of pairs,
///   with or without a given length.
///
/// * Supported keys and values are integers, bytes (if convertible to strings),
///   unit structs and unit variants.
///
/// * Newtype structs defer to their inner values.
pub struct Serializer<'output, T: 'output>(&'output mut UrlEncodedSerializer<T>)
    where T: UrlEncodedTarget;

impl<'output, T: 'output + UrlEncodedTarget> Serializer<'output, T> {
    /// Returns a new `Serializer`.
    pub fn new(urlencoder: &'output mut UrlEncodedSerializer<T>) -> Self {
        Serializer(urlencoder)
    }
}

/// Errors returned during serializing to `application/x-www-form-urlencoded`.
#[derive(Clone, Debug)]
pub enum Error {
    Custom(Cow<'static, str>),
    InvalidValue(Cow<'static, str>),
    Utf8(str::Utf8Error),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        match *self {
            Error::Custom(ref msg) => msg.fmt(f),
            Error::InvalidValue(ref msg) => write!(f, "invalid value: {}", msg),
            Error::Utf8(ref err) => write!(f, "invalid UTF-8: {}", err),
        }
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::Custom(ref msg) => msg,
            Error::InvalidValue(ref msg) => msg,
            Error::Utf8(ref err) => error::Error::description(err),
        }
    }

    /// The lower-level cause of this error, in the case of a `Utf8` error.
    fn cause(&self) -> Option<&error::Error> {
        match *self {
            Error::Custom(_) | Error::InvalidValue(_) => None,
            Error::Utf8(ref err) => Some(err),
        }
    }
}

impl ser::Error for Error {
    fn custom<T: Into<String>>(msg: T) -> Self {
        Error::Custom(msg.into().into())
    }

    fn invalid_value(msg: &str) -> Self {
        Error::InvalidValue(String::from(msg).into())
    }
}

/// State used when serializing sequences.
pub struct SeqState(());

/// State used when serializing tuples.
pub struct TupleState(());

/// State used when serializing tuple structs.
pub struct TupleStructState(());

/// State used when serializing tuple variants.
pub struct TupleVariantState(());

/// State used when serializing maps.
pub struct MapState(Option<Cow<'static, str>>);

/// State used when serializing structs.
pub struct StructState(());

/// State used when serializing struct variants.
pub struct StructVariantState(());

impl<'output, Target> ser::Serializer for Serializer<'output, Target>
    where Target: 'output + UrlEncodedTarget
{
    type Error = Error;

    /// State used when serializing sequences.
    type SeqState = SeqState;

    /// State used when serializing tuples.
    type TupleState = TupleState;

    /// State used when serializing tuple structs.
    type TupleStructState = TupleStructState;

    /// State used when serializing tuple variants.
    type TupleVariantState = TupleVariantState;

    /// State used when serializing maps.
    type MapState = MapState;

    /// State used when serializing structs.
    type StructState = StructState;

    /// State used when serializing struct variants.
    type StructVariantState = StructVariantState;

    /// Returns an error.
    fn serialize_bool(&mut self, _v: bool) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_isize(&mut self, _v: isize) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_i8(&mut self, _v: i8) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_i16(&mut self, _v: i16) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_i32(&mut self, _v: i32) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_i64(&mut self, _v: i64) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_usize(&mut self, _v: usize) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_u8(&mut self, _v: u8) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_u16(&mut self, _v: u16) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_u32(&mut self, _v: u32) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_u64(&mut self, _v: u64) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_f32(&mut self, _v: f32) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_f64(&mut self, _v: f64) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_char(&mut self, _v: char) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_str(&mut self, _value: &str) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_bytes(&mut self, _value: &[u8]) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_unit(&mut self) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_unit_struct(
            &mut self, _name: &'static str)
            -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_unit_variant(
            &mut self,
            _name: &'static str,
            _variant_index: usize,
            _variant: &'static str)
            -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Serializes the inner value, ignoring the newtype name.
    fn serialize_newtype_struct<T>(
            &mut self, _name: &'static str, value: T)
            -> Result<(), Error>
        where T: ser::Serialize
    {
        value.serialize(self)
    }

    /// Returns an error.
    fn serialize_newtype_variant<T>(
            &mut self,
            _name: &'static str,
            _variant_index: usize,
            _variant: &'static str,
            _value: T)
            -> Result<(), Error>
        where T: ser::Serialize
    {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_none(&mut self) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_some<T>(&mut self, _value: T) -> Result<(), Error>
        where T: ser::Serialize
    {
        Err(Error::top_level())
    }

    /// Begins to serialize a sequence, given length (if any) is ignored.
    fn serialize_seq(
            &mut self, _len: Option<usize>)
            -> Result<SeqState, Error> {
        Ok(SeqState(()))
    }

    /// Serializes a sequence element.
    fn serialize_seq_elt<T>(
            &mut self, _state: &mut SeqState, value: T)
            -> Result<(), Error>
        where T: ser::Serialize
    {
        value.serialize(&mut pair::PairSerializer::new(self.0))
    }

    /// Finishes serializing a sequence.
    fn serialize_seq_end(&mut self, _state: SeqState) -> Result<(), Error> {
        Ok(())
    }

    /// Begins to serialize a sequence, given length is ignored.
    fn serialize_seq_fixed_size(
            &mut self, _length: usize)
            -> Result<SeqState, Error> {
        Ok(SeqState(()))
    }

    /// Returns an error.
    fn serialize_tuple(&mut self, _len: usize) -> Result<TupleState, Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_tuple_elt<T>(
            &mut self, _state: &mut TupleState, _value: T)
            -> Result<(), Error>
        where T: ser::Serialize
    {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_tuple_end(&mut self, _state: TupleState) -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_tuple_struct(
            &mut self, _name: &'static str, _len: usize)
            -> Result<TupleStructState, Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_tuple_struct_elt<T>(
            &mut self, _state: &mut TupleStructState, _value: T)
            -> Result<(), Error>
        where T: ser::Serialize
    {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_tuple_struct_end(
            &mut self, _state: TupleStructState)
            -> Result<(), Error>
    {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_tuple_variant(
            &mut self,
            _name: &'static str,
            _variant_index: usize,
            _variant: &'static str,
            _len: usize)
            -> Result<TupleVariantState, Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_tuple_variant_elt<T>(
            &mut self, _state: &mut TupleVariantState, _value: T)
            -> Result<(), Error>
        where T: ser::Serialize
    {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_tuple_variant_end(
            &mut self, _state: TupleVariantState)
            -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Begins to serialize a map, given length (if any) is ignored.
    fn serialize_map(
            &mut self, _len: Option<usize>)
            -> Result<MapState, Error> {
        Ok(MapState(None))
    }

    /// Serializes a map key.
    fn serialize_map_key<T>(
            &mut self, state: &mut MapState, key: T)
            -> Result<(), Error>
        where T: ser::Serialize
    {
        key.serialize(&mut key::MapKeySerializer::new(&mut state.0))
    }

    /// Serializes a map value.
    fn serialize_map_value<T>(
            &mut self, state: &mut MapState, value: T)
            -> Result<(), Error>
        where T: ser::Serialize
    {
        let mut value_serializer =
            try!(value::ValueSerializer::new(&mut state.0, self.0));
        value.serialize(&mut value_serializer)
    }

    /// Finishes serializing a map.
    fn serialize_map_end(&mut self, _state: MapState) -> Result<(), Error> {
        Ok(())
    }

    /// Begins to serialize a struct, given length is ignored.
    fn serialize_struct(
            &mut self, _name: &'static str, _len: usize)
            -> Result<StructState, Error> {
        Ok(StructState(()))
    }

    /// Serializes a struct element.
    fn serialize_struct_elt<T>(
            &mut self,
            _state: &mut StructState,
            key: &'static str,
            value: T)
            -> Result<(), Error>
        where T: ser::Serialize
    {
        let mut key = Some(key.into());
        let mut value_serializer =
            value::ValueSerializer::new(&mut key, self.0).unwrap();
        value.serialize(&mut value_serializer)
    }

    /// Finishes serializing a struct.
    fn serialize_struct_end(&mut self, _state: StructState)
                            -> Result<(), Error> {
        Ok(())
    }

    /// Returns an error.
    fn serialize_struct_variant(
            &mut self,
            _name: &'static str,
            _variant_index: usize,
            _variant: &'static str,
            _len: usize)
            -> Result<StructVariantState, Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_struct_variant_elt<T>(
            &mut self,
            _state: &mut StructVariantState,
            _key: &'static str,
            _value: T)
            -> Result<(), Error> {
        Err(Error::top_level())
    }

    /// Returns an error.
    fn serialize_struct_variant_end(
            &mut self, _state: StructVariantState)
            -> Result<(), Error> {
        Err(Error::top_level())
    }
}

impl Error {
    fn top_level() -> Self {
        Error::Custom(
            "top-level serializer supports only maps and structs".into())
    }
}
<|endoftext|>


<commit_before>use diesel;
use diesel::prelude::*;

use data::types::*;
use data::researches::get_research_list;
use data::helper::{get_research_dependency_strings, dependencies_fulfilled};
use helpers::db::DB;
use responses::{APIResponse, bad_request, created, ok};

use models::user::User;
use models::research::{Research, NewResearch};
use models::resource::Resource;
use models::queue::{QueueEntry, NewQueueEntry};

use schema::researches;
use schema::researches::dsl as research_dsl;
use schema::queue_entries::dsl as queue_entry_dsl;

/// The user needs to be logged in to access this route!
///
/// This route returns the list of all researches and their levels/costs,
/// as well as the current level of the research for the pod of the current user.
#[get("/pod")]
pub fn get_researches(current_user: User, db: DB) -> APIResponse {

    let mut research_list = get_research_list();

    // Ger current pod and pod researches
    let pod = current_user.get_pod(&db);

    let researches = pod.get_researches(&db);
    for research in researches {
        let type_result = ResearchTypes::from_string(&research.name);
        if type_result.is_err() {
            return bad_request()
                       .message(format!("Found research {}, but no matching ResearchType!",
                                        research.name)
                                        .as_str());
        }
        let research_type = type_result.unwrap();
        let list_result = research_list.get_mut(&research_type);
        if list_result.is_none() {
            return bad_request().message(format!("Found type {}, but no matching entry in our research list!", research_type).as_str());
        }

        let mut list_entry = list_result.unwrap();
        list_entry.current_level = research.level;
    }

    ok().message("Research data.").data(json!(&research_list))
}

/// Add a new research to the queue of the pod
/// This endpoint:
/// - Checks if dependencies for research are fulfilled
/// - Checks if there are enough resources
/// - Removes resources from db
#[post("/pod/<research_name>")]
pub fn start_research(research_name: String,
                          current_user: User,
                          db: DB)
                          -> APIResponse {

    // Check if the given research name maps to a research type.
    // Early return if we don't know this research name
    let research_result = ResearchTypes::from_string(&research_name);
    if research_result.is_err() {
        return bad_request().message(format!("No such research type `{}`", research_name).as_str());
    }
    let research_type =  research_result.unwrap();

    // Get and set some variables we need for querying and dependency checking.
    let dependency_strings = get_research_dependency_strings(&research_type);
    let mut research_level: i32;
    let research_list = get_research_list();

    let (pod, queue) = current_user.get_pod_and_queue(&db);

    let mut research_result = pod.get_research(research_type.to_string(), &db);

    let research: Research;
    if research_result.is_ok() {
        research = research_result.unwrap();
        research_level = research.level + 1;
    }
    else {
        let dependencies = research_dsl::researches
            .filter(research_dsl::name.eq_any(dependency_strings))
            .get_results::<Research>(&*db);

        let fulfilled = dependencies_fulfilled(&research_type,
                                               dependencies,
                                               &research_list);
        if !fulfilled {
            return bad_request().message("Dependencies not fulfilled.");
        }
        // Create a new module in the
        let new_research = NewResearch {
            name: research_type.to_string(),
            pod_id: Some(pod.id),
            base_id: None,
        };

        research_result = diesel::insert(&new_research)
            .into(researches::table)
            .get_result::<Research>(&*db);

        research = research_result.expect("Failed to create research.");

        research_level = 1;
    }

    // Check if there already are existing queue entries for this research.
    // In case there are, we increase the level by the amount of existing entries.
    let existing_entries: i64 = queue_entry_dsl::queue_entries
        .count()
        .filter(queue_entry_dsl::queue_id.eq(queue.id))
        .filter(queue_entry_dsl::research_name.eq(research_type.to_string()))
        .get_result(&*db)
        .unwrap_or(0);

    let pod_resources = pod.get_resources(&db);
    research_level += existing_entries as i32;

    let all_levels = &research_list
                          .get(&research_type)
                          .as_ref()
                          .expect("No research in yml for this type.")
                          .levels;

    if research_level > all_levels.len() as i32 {
        return bad_request().message("Already at max level.");
    }

    let level_index: usize = (research_level-1) as usize;
    let costs = &all_levels[level_index].resources;

    if costs.is_some() && !Resource::check_resources(costs, pod_resources, &db) {
        return bad_request().message("Insufficient resources.");
    }

    // Create a new queue entry with the given research type.
    let new_queue_entry = NewQueueEntry {
        queue_id: queue.id.clone(),
        research_id: Some(research.id.clone()),
        research_name: Some(research_name.to_string().clone()),
        module_name: None,
        module_id: None,
        level: research_level,
        duration: all_levels[level_index].time,
    };
    queue.add_entry(new_queue_entry, &db);

    created().message("Queue entry added.")
}

/// Remove research from queue
#[delete("/pod/<research_name>")]
pub fn stop_research(research_name: String, current_user: User, db: DB) -> APIResponse {

    // Check if there is a research for this research_name
    let research_type_result = ResearchTypes::from_string(&research_name);
    // Early return if we don't know this research name
    if research_type_result.is_err() {
        return bad_request().message(format!("No such research type `{}`", research_name).as_str());
    }
    let research_type = research_type_result.unwrap();

    // Get user pod and pod queue
    let (pod, queue) = current_user.get_pod_and_queue(&db);

    // Check if there exists a queue entry for this research and this pod.
    // Early return if this isn't the case.
    let research_entry_result = queue_entry_dsl::queue_entries
        .filter(queue_entry_dsl::queue_id.eq(queue.id))
        .filter(queue_entry_dsl::research_name.eq(research_type.to_string()))
        .order(queue_entry_dsl::level.desc())
        .get_result::<QueueEntry>(&*db);
    if research_entry_result.is_ok() {
        return bad_request().message("Can't delete. There is no queue entry for this research.");
    }
    let research_entry = research_entry_result.unwrap();

    // Get all needed info for resource manipulation
    let research_list = get_research_list();

    let pod_resources = pod.get_resources(&db);

    // Add resources from research to pod resources
    let all_levels = &research_list
                          .get(&research_type)
                          .unwrap()
                          .levels;
    let costs_result = &all_levels[research_entry.level as usize].resources;

    if let Some(ref costs) = *costs_result {
        Resource::update_resources(costs, pod_resources, false, &db);
    }

    // Remove queue_entry from database
    diesel::delete(queue_entry_dsl::queue_entries
                       .filter(queue_entry_dsl::id.eq(research_entry.id)))
            .execute(&*db)
            .expect("Failed to remove queue_entry.");

    ok().message("Resource removed.")
}
<commit_msg>Refactor research pod<commit_after>use diesel;
use diesel::prelude::*;

use data::types::*;
use data::researches::get_research_list;
use data::helper::{get_research_dependency_strings, dependencies_fulfilled};
use helpers::db::DB;
use responses::{APIResponse, bad_request, created, ok};

use models::user::User;
use models::research::{Research, NewResearch};
use models::resource::Resource;
use models::queue::{QueueEntry, NewQueueEntry};

use schema::researches;
use schema::researches::dsl as research_dsl;
use schema::queue_entries::dsl as queue_entry_dsl;

/// The user needs to be logged in to access this route!
///
/// This route returns the list of all researches and their levels/costs,
/// as well as the current level of the research for the pod of the current user.
#[get("/pod")]
pub fn get_researches(current_user: User, db: DB) -> APIResponse {

    let mut research_list = get_research_list();

    // Ger current pod and pod researches
    let pod = current_user.get_pod(&db);

    let researches = pod.get_researches(&db);
    for research in researches {
        let type_result = ResearchTypes::from_string(&research.name);
        if type_result.is_err() {
            return bad_request()
                       .message(format!("Found research {}, but no matching ResearchType!",
                                        research.name)
                                        .as_str());
        }
        let research_type = type_result.unwrap();
        let list_result = research_list.get_mut(&research_type);
        if list_result.is_none() {
            return bad_request().message(format!("Found type {}, but no matching entry in our research list!", research_type).as_str());
        }

        let mut list_entry = list_result.unwrap();
        list_entry.current_level = research.level;
    }

    ok().message("Research data.").data(json!(&research_list))
}

/// Add a new research to the queue of the pod
/// This endpoint:
/// - Checks if dependencies for research are fulfilled
/// - Checks if there are enough resources
/// - Removes resources from db
#[post("/pod/<research_name>")]
pub fn start_research(research_name: String,
                          current_user: User,
                          db: DB)
                          -> Result<APIResponse, APIResponse> {

    // Check if the given research name maps to a research type.
    // Early return if we don't know this research name
    let research_type = ResearchTypes::from_string(&research_name).or(
        Err(bad_request().message(format!("No such research type `{}`", research_name).as_str())))?;

    // Get and set some variables we need for querying and dependency checking.
    let dependency_strings = get_research_dependency_strings(&research_type);
    let mut research_level: i32;
    let research_list = get_research_list();

    let (pod, queue) = current_user.get_pod_and_queue(&db);

    let mut research_result = pod.get_research(research_type.to_string(), &db);

    let research: Research;
    if research_result.is_ok() {
        research = research_result.unwrap();
        research_level = research.level + 1;
    }
    else {
        let dependencies = research_dsl::researches
            .filter(research_dsl::name.eq_any(dependency_strings))
            .get_results::<Research>(&*db);

        let fulfilled = dependencies_fulfilled(&research_type,
                                               dependencies,
                                               &research_list);
        if !fulfilled {
            return Err(bad_request().message("Dependencies not fulfilled."));
        }
        // Create a new module in the
        let new_research = NewResearch {
            name: research_type.to_string(),
            pod_id: Some(pod.id),
            base_id: None,
        };

        research_result = diesel::insert(&new_research)
            .into(researches::table)
            .get_result::<Research>(&*db);

        research = research_result.expect("Failed to create research.");

        research_level = 1;
    }

    // Check if there already are existing queue entries for this research.
    // In case there are, we increase the level by the amount of existing entries.
    let existing_entries: i64 = queue_entry_dsl::queue_entries
        .count()
        .filter(queue_entry_dsl::queue_id.eq(queue.id))
        .filter(queue_entry_dsl::research_name.eq(research_type.to_string()))
        .get_result(&*db)
        .unwrap_or(0);

    let pod_resources = pod.get_resources(&db);
    research_level += existing_entries as i32;

    let all_levels = &research_list
                          .get(&research_type)
                          .as_ref()
                          .expect("No research in yml for this type.")
                          .levels;

    if research_level > all_levels.len() as i32 {
        return Err(bad_request().message("Already at max level."));
    }

    let level_index: usize = (research_level-1) as usize;
    let costs = &all_levels[level_index].resources;

    if costs.is_some() && !Resource::check_resources(costs, pod_resources, &db) {
        return Err(bad_request().message("Insufficient resources."));
    }

    // Create a new queue entry with the given research type.
    let new_queue_entry = NewQueueEntry {
        queue_id: queue.id.clone(),
        research_id: Some(research.id.clone()),
        research_name: Some(research_name.to_string().clone()),
        module_name: None,
        module_id: None,
        level: research_level,
        duration: all_levels[level_index].time,
    };
    queue.add_entry(new_queue_entry, &db);

    Ok(created().message("Queue entry added."))
}

/// Remove research from queue
#[delete("/pod/<research_name>")]
pub fn stop_research(research_name: String, current_user: User, db: DB) -> Result<APIResponse, APIResponse> {

    // Check if there is a research for this research_name
    // Early return if we don't know this research name
    let research_type = ResearchTypes::from_string(&research_name).or(
        Err(bad_request().message(format!("No such research type `{}`", research_name).as_str())))?;
    // Get user pod and pod queue
    let (pod, queue) = current_user.get_pod_and_queue(&db);

    // Check if there exists a queue entry for this research and this pod.
    // Early return if this isn't the case.
    let research_entry_result = queue_entry_dsl::queue_entries
        .filter(queue_entry_dsl::queue_id.eq(queue.id))
        .filter(queue_entry_dsl::research_name.eq(research_type.to_string()))
        .order(queue_entry_dsl::level.desc())
        .get_result::<QueueEntry>(&*db);
    if research_entry_result.is_ok() {
        return Err(bad_request().message("Can't delete. There is no queue entry for this research."));
    }
    let research_entry = research_entry_result.unwrap();

    // Get all needed info for resource manipulation
    let research_list = get_research_list();
    let pod_resources = pod.get_resources(&db);

    // Add resources from research to pod resources
    let all_levels = &research_list
                          .get(&research_type)
                          .unwrap()
                          .levels;
    let costs_result = &all_levels[research_entry.level as usize].resources;

    if let Some(ref costs) = *costs_result {
        Resource::update_resources(costs, pod_resources, false, &db);
    }

    // Remove queue_entry from database
    diesel::delete(queue_entry_dsl::queue_entries
                       .filter(queue_entry_dsl::id.eq(research_entry.id)))
            .execute(&*db)
            .expect("Failed to remove queue_entry.");

    Ok(ok().message("Resource removed."))
}
<|endoftext|>


<commit_before>pub struct Interval {
  lo: f64,
  hi: f64,
}

impl Interval {
  pub fn median(&self) -> f64 {
    let half = (self.hi - self.lo) / 2.0;
    self.lo + half
  }

  #[inline]
  pub fn low(&self) -> f64 {
    self.lo
  }

  #[inline]
  pub fn high(&self) -> f64 {
    self.hi
  }

  pub fn upper_half(&self) -> Interval { Interval{ lo:self.median(), hi:self.hi } }
  pub fn lower_half(&self) -> Interval { Interval{ lo:self.lo, hi:self.median() } }
}

pub fn contract_interval(interval:&mut Interval, contract_hi:bool) {
  if (contract_hi) {
    interval.lo = interval.median();
  } else {
    interval.hi = interval.median();
  }
}
<commit_msg>Removes unused *_half methods<commit_after>pub struct Interval {
  lo: f64,
  hi: f64,
}

impl Interval {
  pub fn median(&self) -> f64 {
    let half = (self.hi - self.lo) / 2.0;
    self.lo + half
  }

  #[inline]
  pub fn low(&self) -> f64 {
    self.lo
  }

  #[inline]
  pub fn high(&self) -> f64 {
    self.hi
  }
}

pub fn contract_interval(interval:&mut Interval, contract_hi:bool) {
  if (contract_hi) {
    interval.lo = interval.median();
  } else {
    interval.hi = interval.median();
  }
}
<|endoftext|>


<commit_before>use crate::iter::{InPlaceIterable, Iterator};
use crate::ops::{ControlFlow, Try};

mod chain;
mod cloned;
mod copied;
mod cycle;
mod enumerate;
mod filter;
mod filter_map;
mod flatten;
mod fuse;
mod inspect;
mod intersperse;
mod map;
mod map_while;
mod peekable;
mod rev;
mod scan;
mod skip;
mod skip_while;
mod step_by;
mod take;
mod take_while;
mod zip;

pub use self::{
    chain::Chain, cycle::Cycle, enumerate::Enumerate, filter::Filter, filter_map::FilterMap,
    flatten::FlatMap, fuse::Fuse, inspect::Inspect, map::Map, peekable::Peekable, rev::Rev,
    scan::Scan, skip::Skip, skip_while::SkipWhile, take::Take, take_while::TakeWhile, zip::Zip,
};

#[stable(feature = "iter_cloned", since = "1.1.0")]
pub use self::cloned::Cloned;

#[stable(feature = "iterator_step_by", since = "1.28.0")]
pub use self::step_by::StepBy;

#[stable(feature = "iterator_flatten", since = "1.29.0")]
pub use self::flatten::Flatten;

#[stable(feature = "iter_copied", since = "1.36.0")]
pub use self::copied::Copied;

#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
pub use self::intersperse::{Intersperse, IntersperseWith};

#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
pub use self::map_while::MapWhile;

#[unstable(feature = "trusted_random_access", issue = "none")]
pub use self::zip::TrustedRandomAccess;

/// This trait provides transitive access to source-stage in an interator-adapter pipeline
/// under the conditions that
/// * the iterator source `S` itself implements `SourceIter<Source = S>`
/// * there is a delegating implementation of this trait for each adapter in the pipeline between
///   the source and the pipeline consumer.
///
/// When the source is an owning iterator struct (commonly called `IntoIter`) then
/// this can be useful for specializing [`FromIterator`] implementations or recovering the
/// remaining elements after an iterator has been partially exhausted.
///
/// Note that implementations do not necessarily have to provide access to the inner-most
/// source of a pipeline. A stateful intermediate adapter might eagerly evaluate a part
/// of the pipeline and expose its internal storage as source.
///
/// The trait is unsafe because implementers must uphold additional safety properties.
/// See [`as_inner`] for details.
///
/// # Examples
///
/// Retrieving a partially consumed source:
///
/// ```
/// # #![feature(inplace_iteration)]
/// # use std::iter::SourceIter;
///
/// let mut iter = vec![9, 9, 9].into_iter().map(|i| i * i);
/// let _ = iter.next();
/// let mut remainder = std::mem::replace(unsafe { iter.as_inner() }, Vec::new().into_iter());
/// println!("n = {} elements remaining", remainder.len());
/// ```
///
/// [`FromIterator`]: crate::iter::FromIterator
/// [`as_inner`]: SourceIter::as_inner
#[unstable(issue = "none", feature = "inplace_iteration")]
pub unsafe trait SourceIter {
    /// A source stage in an iterator pipeline.
    type Source: Iterator;

    /// Retrieve the source of an iterator pipeline.
    ///
    /// # Safety
    ///
    /// Implementations of must return the same mutable reference for their lifetime, unless
    /// replaced by a caller.
    /// Callers may only replace the reference when they stopped iteration and drop the
    /// iterator pipeline after extracting the source.
    ///
    /// This means iterator adapters can rely on the source not changing during
    /// iteration but they cannot rely on it in their Drop implementations.
    ///
    /// Implementing this method means adapters relinquish private-only access to their
    /// source and can only rely on guarantees made based on method receiver types.
    /// The lack of restricted access also requires that adapters must uphold the source's
    /// public API even when they have access to its internals.
    ///
    /// Callers in turn must expect the source to be in any state that is consistent with
    /// its public API since adapters sitting between it and the source have the same
    /// access. In particular an adapter may have consumed more elements than strictly necessary.
    ///
    /// The overall goal of these requirements is to let the consumer of a pipeline use
    /// * whatever remains in the source after iteration has stopped
    /// * the memory that has become unused by advancing a consuming iterator
    ///
    /// [`next()`]: Iterator::next()
    unsafe fn as_inner(&mut self) -> &mut Self::Source;
}

/// An iterator adapter that produces output as long as the underlying
/// iterator produces `Result::Ok` values.
///
/// If an error is encountered, the iterator stops and the error is
/// stored.
pub(crate) struct ResultShunt<'a, I, E> {
    iter: I,
    error: &'a mut Result<(), E>,
}

/// Process the given iterator as if it yielded a `T` instead of a
/// `Result<T, _>`. Any errors will stop the inner iterator and
/// the overall result will be an error.
pub(crate) fn process_results<I, T, E, F, U>(iter: I, mut f: F) -> Result<U, E>
where
    I: Iterator<Item = Result<T, E>>,
    for<'a> F: FnMut(ResultShunt<'a, I, E>) -> U,
{
    let mut error = Ok(());
    let shunt = ResultShunt { iter, error: &mut error };
    let value = f(shunt);
    error.map(|()| value)
}

impl<I, T, E> Iterator for ResultShunt<'_, I, E>
where
    I: Iterator<Item = Result<T, E>>,
{
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        self.find(|_| true)
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        if self.error.is_err() {
            (0, Some(0))
        } else {
            let (_, upper) = self.iter.size_hint();
            (0, upper)
        }
    }

    fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
    where
        F: FnMut(B, Self::Item) -> R,
        R: Try<Ok = B>,
    {
        let error = &mut *self.error;
        self.iter
            .try_fold(init, |acc, x| match x {
                Ok(x) => ControlFlow::from_try(f(acc, x)),
                Err(e) => {
                    *error = Err(e);
                    ControlFlow::Break(try { acc })
                }
            })
            .into_try()
    }

    fn fold<B, F>(mut self, init: B, fold: F) -> B
    where
        Self: Sized,
        F: FnMut(B, Self::Item) -> B,
    {
        #[inline]
        fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
            move |acc, x| Ok(f(acc, x))
        }

        self.try_fold(init, ok(fold)).unwrap()
    }
}
<commit_msg>Implement SourceIterator and InPlaceIterable for ResultShunt<commit_after>use crate::iter::{InPlaceIterable, Iterator};
use crate::ops::{ControlFlow, Try};

mod chain;
mod cloned;
mod copied;
mod cycle;
mod enumerate;
mod filter;
mod filter_map;
mod flatten;
mod fuse;
mod inspect;
mod intersperse;
mod map;
mod map_while;
mod peekable;
mod rev;
mod scan;
mod skip;
mod skip_while;
mod step_by;
mod take;
mod take_while;
mod zip;

pub use self::{
    chain::Chain, cycle::Cycle, enumerate::Enumerate, filter::Filter, filter_map::FilterMap,
    flatten::FlatMap, fuse::Fuse, inspect::Inspect, map::Map, peekable::Peekable, rev::Rev,
    scan::Scan, skip::Skip, skip_while::SkipWhile, take::Take, take_while::TakeWhile, zip::Zip,
};

#[stable(feature = "iter_cloned", since = "1.1.0")]
pub use self::cloned::Cloned;

#[stable(feature = "iterator_step_by", since = "1.28.0")]
pub use self::step_by::StepBy;

#[stable(feature = "iterator_flatten", since = "1.29.0")]
pub use self::flatten::Flatten;

#[stable(feature = "iter_copied", since = "1.36.0")]
pub use self::copied::Copied;

#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
pub use self::intersperse::{Intersperse, IntersperseWith};

#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
pub use self::map_while::MapWhile;

#[unstable(feature = "trusted_random_access", issue = "none")]
pub use self::zip::TrustedRandomAccess;

/// This trait provides transitive access to source-stage in an interator-adapter pipeline
/// under the conditions that
/// * the iterator source `S` itself implements `SourceIter<Source = S>`
/// * there is a delegating implementation of this trait for each adapter in the pipeline between
///   the source and the pipeline consumer.
///
/// When the source is an owning iterator struct (commonly called `IntoIter`) then
/// this can be useful for specializing [`FromIterator`] implementations or recovering the
/// remaining elements after an iterator has been partially exhausted.
///
/// Note that implementations do not necessarily have to provide access to the inner-most
/// source of a pipeline. A stateful intermediate adapter might eagerly evaluate a part
/// of the pipeline and expose its internal storage as source.
///
/// The trait is unsafe because implementers must uphold additional safety properties.
/// See [`as_inner`] for details.
///
/// # Examples
///
/// Retrieving a partially consumed source:
///
/// ```
/// # #![feature(inplace_iteration)]
/// # use std::iter::SourceIter;
///
/// let mut iter = vec![9, 9, 9].into_iter().map(|i| i * i);
/// let _ = iter.next();
/// let mut remainder = std::mem::replace(unsafe { iter.as_inner() }, Vec::new().into_iter());
/// println!("n = {} elements remaining", remainder.len());
/// ```
///
/// [`FromIterator`]: crate::iter::FromIterator
/// [`as_inner`]: SourceIter::as_inner
#[unstable(issue = "none", feature = "inplace_iteration")]
pub unsafe trait SourceIter {
    /// A source stage in an iterator pipeline.
    type Source: Iterator;

    /// Retrieve the source of an iterator pipeline.
    ///
    /// # Safety
    ///
    /// Implementations of must return the same mutable reference for their lifetime, unless
    /// replaced by a caller.
    /// Callers may only replace the reference when they stopped iteration and drop the
    /// iterator pipeline after extracting the source.
    ///
    /// This means iterator adapters can rely on the source not changing during
    /// iteration but they cannot rely on it in their Drop implementations.
    ///
    /// Implementing this method means adapters relinquish private-only access to their
    /// source and can only rely on guarantees made based on method receiver types.
    /// The lack of restricted access also requires that adapters must uphold the source's
    /// public API even when they have access to its internals.
    ///
    /// Callers in turn must expect the source to be in any state that is consistent with
    /// its public API since adapters sitting between it and the source have the same
    /// access. In particular an adapter may have consumed more elements than strictly necessary.
    ///
    /// The overall goal of these requirements is to let the consumer of a pipeline use
    /// * whatever remains in the source after iteration has stopped
    /// * the memory that has become unused by advancing a consuming iterator
    ///
    /// [`next()`]: Iterator::next()
    unsafe fn as_inner(&mut self) -> &mut Self::Source;
}

/// An iterator adapter that produces output as long as the underlying
/// iterator produces `Result::Ok` values.
///
/// If an error is encountered, the iterator stops and the error is
/// stored.
pub(crate) struct ResultShunt<'a, I, E> {
    iter: I,
    error: &'a mut Result<(), E>,
}

/// Process the given iterator as if it yielded a `T` instead of a
/// `Result<T, _>`. Any errors will stop the inner iterator and
/// the overall result will be an error.
pub(crate) fn process_results<I, T, E, F, U>(iter: I, mut f: F) -> Result<U, E>
where
    I: Iterator<Item = Result<T, E>>,
    for<'a> F: FnMut(ResultShunt<'a, I, E>) -> U,
{
    let mut error = Ok(());
    let shunt = ResultShunt { iter, error: &mut error };
    let value = f(shunt);
    error.map(|()| value)
}

impl<I, T, E> Iterator for ResultShunt<'_, I, E>
where
    I: Iterator<Item = Result<T, E>>,
{
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        self.find(|_| true)
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        if self.error.is_err() {
            (0, Some(0))
        } else {
            let (_, upper) = self.iter.size_hint();
            (0, upper)
        }
    }

    fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
    where
        F: FnMut(B, Self::Item) -> R,
        R: Try<Ok = B>,
    {
        let error = &mut *self.error;
        self.iter
            .try_fold(init, |acc, x| match x {
                Ok(x) => ControlFlow::from_try(f(acc, x)),
                Err(e) => {
                    *error = Err(e);
                    ControlFlow::Break(try { acc })
                }
            })
            .into_try()
    }

    fn fold<B, F>(mut self, init: B, fold: F) -> B
    where
        Self: Sized,
        F: FnMut(B, Self::Item) -> B,
    {
        #[inline]
        fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
            move |acc, x| Ok(f(acc, x))
        }

        self.try_fold(init, ok(fold)).unwrap()
    }
}

#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<S: Iterator, I, E> SourceIter for ResultShunt<'_, I, E>
where
    I: SourceIter<Source = S>,
{
    type Source = S;

    #[inline]
    unsafe fn as_inner(&mut self) -> &mut S {
        // SAFETY: unsafe function forwarding to unsafe function with the same requirements
        unsafe { SourceIter::as_inner(&mut self.iter) }
    }
}

// SAFETY: ResultShunt::next calls I::find, which has to advance `iter` in order to
// return `Some(_)`. Since `iter` has type `I: InPlaceIterable` it's guaranteed that
// at least one item will be moved out from the underlying source.
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<I, T, E> InPlaceIterable for ResultShunt<'_, I, E> where
    I: Iterator<Item = Result<T, E>> + InPlaceIterable
{
}
<|endoftext|>


<commit_before>//! Validating and decomposing a decimal string of the form:
//!
//! `(digits | digits? '.'? digits?) (('e' | 'E') ('+' | '-')? digits)?`
//!
//! In other words, standard floating-point syntax, with two exceptions: No sign, and no
//! handling of "inf" and "NaN". These are handled by the driver function (super::dec2flt).
//!
//! Although recognizing valid inputs is relatively easy, this module also has to reject the
//! countless invalid variations, never panic, and perform numerous checks that the other
//! modules rely on to not panic (or overflow) in turn.
//! To make matters worse, all that happens in a single pass over the input.
//! So, be careful when modifying anything, and double-check with the other modules.
use self::ParseResult::{Invalid, ShortcutToInf, ShortcutToZero, Valid};
use super::num;

#[derive(Debug)]
pub enum Sign {
    Positive,
    Negative,
}

#[derive(Debug, PartialEq, Eq)]
/// The interesting parts of a decimal string.
pub struct Decimal<'a> {
    pub integral: &'a [u8],
    pub fractional: &'a [u8],
    /// The decimal exponent, guaranteed to have fewer than 18 decimal digits.
    pub exp: i64,
}

impl<'a> Decimal<'a> {
    pub fn new(integral: &'a [u8], fractional: &'a [u8], exp: i64) -> Decimal<'a> {
        Decimal { integral, fractional, exp }
    }
}

#[derive(Debug, PartialEq, Eq)]
pub enum ParseResult<'a> {
    Valid(Decimal<'a>),
    ShortcutToInf,
    ShortcutToZero,
    Invalid,
}

/// Checks if the input string is a valid floating point number and if so, locate the integral
/// part, the fractional part, and the exponent in it. Does not handle signs.
pub fn parse_decimal(s: &str) -> ParseResult<'_> {
    if s.is_empty() {
        return Invalid;
    }

    let s = s.as_bytes();
    let (integral, s) = eat_digits(s);

    match s.first() {
        None => Valid(Decimal::new(integral, b"", 0)),
        Some(&b'e' | &b'E') => {
            if integral.is_empty() {
                return Invalid; // No digits before 'e'
            }

            parse_exp(integral, b"", &s[1..])
        }
        Some(&b'.') => {
            let (fractional, s) = eat_digits(&s[1..]);
            if integral.is_empty() && fractional.is_empty() {
                // We require at least a single digit before or after the point.
                return Invalid;
            }

            match s.first() {
                None => Valid(Decimal::new(integral, fractional, 0)),
                Some(&b'e' | &b'E') => parse_exp(integral, fractional, &s[1..]),
                _ => Invalid, // Trailing junk after fractional part
            }
        }
        _ => Invalid, // Trailing junk after first digit string
    }
}

/// Carves off decimal digits up to the first non-digit character.
fn eat_digits(s: &[u8]) -> (&[u8], &[u8]) {
    let mut i = 0;
    while i < s.len() && b'0' <= s[i] && s[i] <= b'9' {
        i += 1;
    }
    (&s[..i], &s[i..])
}

/// Exponent extraction and error checking.
fn parse_exp<'a>(integral: &'a [u8], fractional: &'a [u8], rest: &'a [u8]) -> ParseResult<'a> {
    let (sign, rest) = match rest.first() {
        Some(&b'-') => (Sign::Negative, &rest[1..]),
        Some(&b'+') => (Sign::Positive, &rest[1..]),
        _ => (Sign::Positive, rest),
    };
    let (mut number, trailing) = eat_digits(rest);
    if !trailing.is_empty() {
        return Invalid; // Trailing junk after exponent
    }
    if number.is_empty() {
        return Invalid; // Empty exponent
    }
    // At this point, we certainly have a valid string of digits. It may be too long to put into
    // an `i64`, but if it's that huge, the input is certainly zero or infinity. Since each zero
    // in the decimal digits only adjusts the exponent by +/- 1, at exp = 10^18 the input would
    // have to be 17 exabyte (!) of zeros to get even remotely close to being finite.
    // This is not exactly a use case we need to cater to.
    while number.first() == Some(&b'0') {
        number = &number[1..];
    }
    if number.len() >= 18 {
        return match sign {
            Sign::Positive => ShortcutToInf,
            Sign::Negative => ShortcutToZero,
        };
    }
    let abs_exp = num::from_str_unchecked(number);
    let e = match sign {
        Sign::Positive => abs_exp as i64,
        Sign::Negative => -(abs_exp as i64),
    };
    Valid(Decimal::new(integral, fractional, e))
}
<commit_msg>Auto merge of #81427 - klensy:eat-digits, r=m-ou-se<commit_after>//! Validating and decomposing a decimal string of the form:
//!
//! `(digits | digits? '.'? digits?) (('e' | 'E') ('+' | '-')? digits)?`
//!
//! In other words, standard floating-point syntax, with two exceptions: No sign, and no
//! handling of "inf" and "NaN". These are handled by the driver function (super::dec2flt).
//!
//! Although recognizing valid inputs is relatively easy, this module also has to reject the
//! countless invalid variations, never panic, and perform numerous checks that the other
//! modules rely on to not panic (or overflow) in turn.
//! To make matters worse, all that happens in a single pass over the input.
//! So, be careful when modifying anything, and double-check with the other modules.
use self::ParseResult::{Invalid, ShortcutToInf, ShortcutToZero, Valid};
use super::num;

#[derive(Debug)]
pub enum Sign {
    Positive,
    Negative,
}

#[derive(Debug, PartialEq, Eq)]
/// The interesting parts of a decimal string.
pub struct Decimal<'a> {
    pub integral: &'a [u8],
    pub fractional: &'a [u8],
    /// The decimal exponent, guaranteed to have fewer than 18 decimal digits.
    pub exp: i64,
}

impl<'a> Decimal<'a> {
    pub fn new(integral: &'a [u8], fractional: &'a [u8], exp: i64) -> Decimal<'a> {
        Decimal { integral, fractional, exp }
    }
}

#[derive(Debug, PartialEq, Eq)]
pub enum ParseResult<'a> {
    Valid(Decimal<'a>),
    ShortcutToInf,
    ShortcutToZero,
    Invalid,
}

/// Checks if the input string is a valid floating point number and if so, locate the integral
/// part, the fractional part, and the exponent in it. Does not handle signs.
pub fn parse_decimal(s: &str) -> ParseResult<'_> {
    if s.is_empty() {
        return Invalid;
    }

    let s = s.as_bytes();
    let (integral, s) = eat_digits(s);

    match s.first() {
        None => Valid(Decimal::new(integral, b"", 0)),
        Some(&b'e' | &b'E') => {
            if integral.is_empty() {
                return Invalid; // No digits before 'e'
            }

            parse_exp(integral, b"", &s[1..])
        }
        Some(&b'.') => {
            let (fractional, s) = eat_digits(&s[1..]);
            if integral.is_empty() && fractional.is_empty() {
                // We require at least a single digit before or after the point.
                return Invalid;
            }

            match s.first() {
                None => Valid(Decimal::new(integral, fractional, 0)),
                Some(&b'e' | &b'E') => parse_exp(integral, fractional, &s[1..]),
                _ => Invalid, // Trailing junk after fractional part
            }
        }
        _ => Invalid, // Trailing junk after first digit string
    }
}

/// Carves off decimal digits up to the first non-digit character.
fn eat_digits(s: &[u8]) -> (&[u8], &[u8]) {
    let pos = s.iter().position(|c| !c.is_ascii_digit()).unwrap_or(s.len());
    s.split_at(pos)
}

/// Exponent extraction and error checking.
fn parse_exp<'a>(integral: &'a [u8], fractional: &'a [u8], rest: &'a [u8]) -> ParseResult<'a> {
    let (sign, rest) = match rest.first() {
        Some(&b'-') => (Sign::Negative, &rest[1..]),
        Some(&b'+') => (Sign::Positive, &rest[1..]),
        _ => (Sign::Positive, rest),
    };
    let (mut number, trailing) = eat_digits(rest);
    if !trailing.is_empty() {
        return Invalid; // Trailing junk after exponent
    }
    if number.is_empty() {
        return Invalid; // Empty exponent
    }
    // At this point, we certainly have a valid string of digits. It may be too long to put into
    // an `i64`, but if it's that huge, the input is certainly zero or infinity. Since each zero
    // in the decimal digits only adjusts the exponent by +/- 1, at exp = 10^18 the input would
    // have to be 17 exabyte (!) of zeros to get even remotely close to being finite.
    // This is not exactly a use case we need to cater to.
    while number.first() == Some(&b'0') {
        number = &number[1..];
    }
    if number.len() >= 18 {
        return match sign {
            Sign::Positive => ShortcutToInf,
            Sign::Negative => ShortcutToZero,
        };
    }
    let abs_exp = num::from_str_unchecked(number);
    let e = match sign {
        Sign::Positive => abs_exp as i64,
        Sign::Negative => -(abs_exp as i64),
    };
    Valid(Decimal::new(integral, fractional, e))
}
<|endoftext|>