<commit_before>use std::ops::{Add, Sub, Div};
use std::collections::HashMap;
use std::iter::FromIterator;
use std::iter::repeat;
use std::fmt::{Debug, Formatter};
use std::fmt;
use std::cmp::Ordering::Equal;
use std::ops::Drop;
use std::cmp;
use std::path::Path;
use std::io::{BufWriter, Write, BufReader, Read, BufRead};
use std::io;
use std::fs::File;
use std::mem;

#[derive(Clone)]
pub struct WordVec {
    pub word: String,
    vec: Vec<f32>,
}

impl PartialEq for WordVec {
    fn eq(&self, other: &WordVec) -> bool {
        self.vec == other.vec
    }
}

impl Debug for WordVec {
    fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
        try!(self.word.fmt(fmt));
        try!(fmt.write_str(": "));
        try!(fmt.write_str(", "));
        self.vec.iter().take(5).collect::<Vec<_>>().fmt(fmt)
    }
}

impl WordVec {

    fn dot_prod(&self, other: &WordVec) -> f32 {
        self.vec.iter()
                .zip(other.vec.iter())
                .map(|(x, y)| x * y)
                .fold(0.0, |x, y| x + y)
    }

    fn magnitude(&self) -> f32 {
        self.vec.iter()
                .map(|x| x * x)
                .fold(0.0, |x, y| x + y)
                .sqrt()
    }

    pub fn distance(&self, other: &WordVec) -> f32 {
        self.vec.iter().zip(other.vec.iter())
                .map(|(x, y)| (x - y)*(x - y))
                .fold(0.0, |x, y| x + y)
                .sqrt()
    }

    fn new(word: String, num_words: usize) -> WordVec {
        WordVec {
            word: word,
            vec: repeat(0.0).take(num_words).collect(),
        }
    }

    fn normalize(&mut self) {
        let cooccurences = self.vec.iter().fold(0f32, |x, y| {
            assert!(!y.is_nan());
            x + *y
        });

        for f in &mut self.vec {
            *f /= cooccurences + 1.0;
        }
    }

    fn inc(&mut self, i: usize, dist: usize) {
        assert!(dist != 0);
        self.vec[i] += 1.0 / dist as f32;
    }

}

impl Div<i32> for WordVec {
    type Output = WordVec;

    fn div(mut self, i: i32) -> WordVec {
        for f in &mut self.vec {
            *f /= i as f32;
        }

        self
    }
}

impl<'a> Add<&'a WordVec> for WordVec {
    type Output = WordVec;

    fn add(self, other: &WordVec) -> WordVec {
        debug_assert!(self.vec.len() == other.vec.len());
        let mut newvec = WordVec {
            word: format!("{} + {}", &self.word, &other.word),
            vec: self.vec,
        };

        for i in 0..newvec.vec.len() {
            newvec.vec[i] += other.vec[i];
        }

        newvec
    }
}

impl<'a> Sub<&'a WordVec> for WordVec {
    type Output = WordVec;

    fn sub(self, other: &WordVec) -> WordVec {
        debug_assert!(self.vec.len() == other.vec.len());
        let mut newvec = WordVec {
            word: format!("{} - {}", &self.word, &other.word),
            vec: self.vec,
        };

        for i in 0..(newvec.vec.len()) {
            newvec.vec[i] -= other.vec[i];
        }

        newvec
    }
}

#[derive(Clone, PartialEq, Debug)]
pub struct LanguageModel {
    words: HashMap<String, usize>,
    word_vecs: Vec<WordVec>,
}

pub struct LanguageModelBuilder {
    window_radius: usize,
    words: HashMap<String, usize>,
    word_vecs: Vec<WordVec>,
    sentence: Vec<Option<usize>>,
}

pub struct WordAcceptor<'a> {
    builder: &'a mut LanguageModelBuilder,
}

impl LanguageModelBuilder {
    pub fn new(window_radius: usize, words: Vec<String>) -> LanguageModelBuilder {

        let word_vecs = words.iter()
                             .map(|s| WordVec::new(s.clone(), words.len()))
                             .collect();

        let words = HashMap::from_iter(
                        words.into_iter()
                             .enumerate()
                             .map(|(a, b)| (b, a)));

        LanguageModelBuilder {
            window_radius: window_radius,
            words: words,
            word_vecs: word_vecs,
            sentence: vec![],
        }
    }

    pub fn build(mut self) -> LanguageModel {
        for vec in self.word_vecs.iter_mut() {
            vec.normalize();
        }

        LanguageModel {
            words: self.words,
            word_vecs: self.word_vecs,
        }
    }

    pub fn new_sentence<'a>(&'a mut self) -> WordAcceptor<'a> {
        WordAcceptor {
            builder: self,
        }
    }

    pub fn save(&self, path: &Path) -> io::Result<()> {
        let mut file = BufWriter::new(File::create(path).unwrap());

        try!(write_raw(self.word_vecs.len(), &mut file));
        try!(file.write(&[b'\n']));

        for vec in &self.word_vecs {
            try!(file.write(vec.word.as_bytes()));
            try!(file.write(&[b':']));
            for f in &vec.vec {
                try!(write_raw(*f, &mut file));
            }
            try!(file.write(&[b'\n']));
        }
        Ok(())
    }

    pub fn load(path: &Path) -> io::Result<LanguageModelBuilder> {
        let mut file = BufReader::new(File::open(path).unwrap());
        let mut word_vecs = Vec::new();

        let size: u64 = unsafe { try!(read_raw::<u64, _>(&mut file)) };
        try!(read_byte(b'\n', &mut file));

        for _ in 0..size {
            let mut word: Vec<u8> = Vec::new();
            file.read_until(b':', &mut word).unwrap();
            assert_eq!(Some(b':'), word.pop());
            let word = String::from_utf8(word).unwrap();

            let mut vec: Vec<f32> = repeat(0f32).take(size as usize).collect();
            for f in &mut vec {
                unsafe {
                    *f = try!(read_raw::<f32, _>(&mut file));
                }
            }

            try!(read_byte(b'\n', &mut file));

            word_vecs.push(WordVec {
                word: word,
                vec: vec,
            });
        }

        let words: HashMap<_, _> = word_vecs.iter()
                                            .map(|v| v.word.clone())
                                            .enumerate()
                                            .map(|(i, w)| (w, i))
                                            .collect();

        Ok(LanguageModelBuilder {
            window_radius: 0,
            words: words,
            word_vecs: word_vecs,
            sentence: Vec::new(),
        })
    }
}

impl<'a> WordAcceptor<'a> {
    pub fn add_word(&mut self, word: &str) {
        let idx_opt = self.builder.words.get(word).map(|w| *w);

        self.builder.sentence.push(idx_opt);
    }
}

impl<'a> Drop for WordAcceptor<'a> {
    fn drop(&mut self) {
        let LanguageModelBuilder {
            ref mut sentence,
            ref mut word_vecs,
            window_radius,
            ..
        } = *self.builder;

        for (i, &from_word) in sentence.iter().enumerate() {
            let start = cmp::max(0, i as isize - window_radius as isize) as usize;
            let end = cmp::min(sentence.len(), i + window_radius + 1);
            for j in (start..i).chain(i + 1..end) {
                let dist = cmp::max(i, j) - cmp::min(i, j);

                if let (Some(f), Some(t)) = (from_word, sentence[j]) {
                    word_vecs[f].inc(t, dist);
                }
            }
        }

        sentence.clear();
    }
}

impl LanguageModel {
    pub fn get(&self, word: &str) -> Option<&WordVec> {
        self.words.get(word).map(|i| &self.word_vecs[*i])
    }

    pub fn nearest_words(&self, word: &WordVec) -> Vec<&WordVec> {
        let mut vec_refs = self.word_vecs.iter().filter_map(|w| {
            let dist = w.distance(word);
            if w.word != word.word {
                Some((dist, w))
            } else {
                None
            }
        }).collect::<Vec<_>>();
        vec_refs.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap_or_else(|| {
            println!("bad vector: {:?}, {:?}", a, b);
            Equal
        }));
        vec_refs.into_iter().map(|x| x.1).collect()
    }

}

fn read_byte<R: Read>(b: u8, read: &mut R) -> io::Result<()> {
    let buf = &mut [0];
    while try!(read.read(buf)) == 0 {}
    assert_eq!(&[b], buf);
    Ok(())
}

unsafe fn read_raw<T: Copy, R: Read>(reader: &mut BufReader<R>) -> io::Result<T> {
    let mut buffer = [0u8; 64];
    let t_size = mem::size_of::<T>();
    assert!(t_size <= buffer.len());

    let mut remainder = t_size;
    while remainder > 0 {
        let bytes_read = try!(reader.read(&mut buffer[(t_size-remainder)..t_size]));
        remainder -= bytes_read;
    }

    let bptr: *mut T = mem::transmute(buffer.as_ptr());
    Ok(*bptr)
}

fn write_raw<T: Copy, F: Write>(t: T, writer: &mut BufWriter<F>) -> io::Result<usize> {
    let buffer = [0u8; 64];
    let t_size = mem::size_of::<T>();
    assert!(t_size <= buffer.len());
    unsafe {
        let bptr: *mut T = mem::transmute(buffer.as_ptr());
        *bptr = t;
    }

    let mut start = 0;
    while start != t_size {
        start += try!(writer.write(&buffer[start..t_size]));
    }
    Ok((start))
}

#[cfg(test)]
mod test {
    use super::LanguageModelBuilder;
    use std::path::Path;

    fn get_builder() -> LanguageModelBuilder {
        let words = "foo bar baz blort".split(" ").map(|w| w.to_string()).collect::<Vec<_>>();
        let mut builder = LanguageModelBuilder::new(1, words);

        let input = "x foo bar baz x x x x x x x blort".split(" ");

        {
            let mut acc = builder.new_sentence();
            for word in input {
                acc.add_word(word);
            }
        }

        builder
    }

    #[test]
    fn test_accept_sentences() {
        let model = get_builder().build();
        let foo = model.get("foo").unwrap();
        let baz = model.get("baz").unwrap();
        let bar = model.get("bar").unwrap();
        let blort = model.get("blort").unwrap();

        assert!(foo.distance(baz) < foo.distance(blort));
        assert!(foo.distance(bar) == bar.distance(baz));
    }

    #[test]
    fn test_serialization() {
        let builder = get_builder();
        let path = Path::new("/tmp/model.data");
        builder.save(&path).unwrap();

        let loaded_model = LanguageModelBuilder::load(path).unwrap().build();
        assert_eq!(builder.build(), loaded_model);
    }
}
<commit_msg>Use Write instead of specifying a BufWriter<commit_after>use std::ops::{Add, Sub, Div};
use std::collections::HashMap;
use std::iter::FromIterator;
use std::iter::repeat;
use std::fmt::{Debug, Formatter};
use std::fmt;
use std::cmp::Ordering::Equal;
use std::ops::Drop;
use std::cmp;
use std::path::Path;
use std::io::{BufWriter, Write, BufReader, Read, BufRead};
use std::io;
use std::fs::File;
use std::mem;

#[derive(Clone)]
pub struct WordVec {
    pub word: String,
    vec: Vec<f32>,
}

impl PartialEq for WordVec {
    fn eq(&self, other: &WordVec) -> bool {
        self.vec == other.vec
    }
}

impl Debug for WordVec {
    fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
        try!(self.word.fmt(fmt));
        try!(fmt.write_str(": "));
        try!(fmt.write_str(", "));
        self.vec.iter().take(5).collect::<Vec<_>>().fmt(fmt)
    }
}

impl WordVec {

    fn dot_prod(&self, other: &WordVec) -> f32 {
        self.vec.iter()
                .zip(other.vec.iter())
                .map(|(x, y)| x * y)
                .fold(0.0, |x, y| x + y)
    }

    fn magnitude(&self) -> f32 {
        self.vec.iter()
                .map(|x| x * x)
                .fold(0.0, |x, y| x + y)
                .sqrt()
    }

    pub fn distance(&self, other: &WordVec) -> f32 {
        self.vec.iter().zip(other.vec.iter())
                .map(|(x, y)| (x - y)*(x - y))
                .fold(0.0, |x, y| x + y)
                .sqrt()
    }

    fn new(word: String, num_words: usize) -> WordVec {
        WordVec {
            word: word,
            vec: repeat(0.0).take(num_words).collect(),
        }
    }

    fn normalize(&mut self) {
        let cooccurences = self.vec.iter().fold(0f32, |x, y| {
            assert!(!y.is_nan());
            x + *y
        });

        for f in &mut self.vec {
            *f /= cooccurences + 1.0;
        }
    }

    fn inc(&mut self, i: usize, dist: usize) {
        assert!(dist != 0);
        self.vec[i] += 1.0 / dist as f32;
    }

}

impl Div<i32> for WordVec {
    type Output = WordVec;

    fn div(mut self, i: i32) -> WordVec {
        for f in &mut self.vec {
            *f /= i as f32;
        }

        self
    }
}

impl<'a> Add<&'a WordVec> for WordVec {
    type Output = WordVec;

    fn add(self, other: &WordVec) -> WordVec {
        debug_assert!(self.vec.len() == other.vec.len());
        let mut newvec = WordVec {
            word: format!("{} + {}", &self.word, &other.word),
            vec: self.vec,
        };

        for i in 0..newvec.vec.len() {
            newvec.vec[i] += other.vec[i];
        }

        newvec
    }
}

impl<'a> Sub<&'a WordVec> for WordVec {
    type Output = WordVec;

    fn sub(self, other: &WordVec) -> WordVec {
        debug_assert!(self.vec.len() == other.vec.len());
        let mut newvec = WordVec {
            word: format!("{} - {}", &self.word, &other.word),
            vec: self.vec,
        };

        for i in 0..(newvec.vec.len()) {
            newvec.vec[i] -= other.vec[i];
        }

        newvec
    }
}

#[derive(Clone, PartialEq, Debug)]
pub struct LanguageModel {
    words: HashMap<String, usize>,
    word_vecs: Vec<WordVec>,
}

pub struct LanguageModelBuilder {
    window_radius: usize,
    words: HashMap<String, usize>,
    word_vecs: Vec<WordVec>,
    sentence: Vec<Option<usize>>,
}

pub struct WordAcceptor<'a> {
    builder: &'a mut LanguageModelBuilder,
}

impl LanguageModelBuilder {
    pub fn new(window_radius: usize, words: Vec<String>) -> LanguageModelBuilder {

        let word_vecs = words.iter()
                             .map(|s| WordVec::new(s.clone(), words.len()))
                             .collect();

        let words = HashMap::from_iter(
                        words.into_iter()
                             .enumerate()
                             .map(|(a, b)| (b, a)));

        LanguageModelBuilder {
            window_radius: window_radius,
            words: words,
            word_vecs: word_vecs,
            sentence: vec![],
        }
    }

    pub fn build(mut self) -> LanguageModel {
        for vec in self.word_vecs.iter_mut() {
            vec.normalize();
        }

        LanguageModel {
            words: self.words,
            word_vecs: self.word_vecs,
        }
    }

    pub fn new_sentence<'a>(&'a mut self) -> WordAcceptor<'a> {
        WordAcceptor {
            builder: self,
        }
    }

    pub fn save(&self, path: &Path) -> io::Result<()> {
        let mut file = BufWriter::new(File::create(path).unwrap());

        try!(write_raw(self.word_vecs.len(), &mut file));
        try!(file.write(&[b'\n']));

        for vec in &self.word_vecs {
            try!(file.write(vec.word.as_bytes()));
            try!(file.write(&[b':']));
            for f in &vec.vec {
                try!(write_raw(*f, &mut file));
            }
            try!(file.write(&[b'\n']));
        }
        Ok(())
    }

    pub fn load(path: &Path) -> io::Result<LanguageModelBuilder> {
        let mut file = BufReader::new(File::open(path).unwrap());
        let mut word_vecs = Vec::new();

        let size: u64 = unsafe { try!(read_raw::<u64, _>(&mut file)) };
        try!(read_byte(b'\n', &mut file));

        for _ in 0..size {
            let mut word: Vec<u8> = Vec::new();
            file.read_until(b':', &mut word).unwrap();
            assert_eq!(Some(b':'), word.pop());
            let word = String::from_utf8(word).unwrap();

            let mut vec: Vec<f32> = repeat(0f32).take(size as usize).collect();
            for f in &mut vec {
                unsafe {
                    *f = try!(read_raw::<f32, _>(&mut file));
                }
            }

            try!(read_byte(b'\n', &mut file));

            word_vecs.push(WordVec {
                word: word,
                vec: vec,
            });
        }

        let words: HashMap<_, _> = word_vecs.iter()
                                            .map(|v| v.word.clone())
                                            .enumerate()
                                            .map(|(i, w)| (w, i))
                                            .collect();

        Ok(LanguageModelBuilder {
            window_radius: 0,
            words: words,
            word_vecs: word_vecs,
            sentence: Vec::new(),
        })
    }
}

impl<'a> WordAcceptor<'a> {
    pub fn add_word(&mut self, word: &str) {
        let idx_opt = self.builder.words.get(word).map(|w| *w);

        self.builder.sentence.push(idx_opt);
    }
}

impl<'a> Drop for WordAcceptor<'a> {
    fn drop(&mut self) {
        let LanguageModelBuilder {
            ref mut sentence,
            ref mut word_vecs,
            window_radius,
            ..
        } = *self.builder;

        for (i, &from_word) in sentence.iter().enumerate() {
            let start = cmp::max(0, i as isize - window_radius as isize) as usize;
            let end = cmp::min(sentence.len(), i + window_radius + 1);
            for j in (start..i).chain(i + 1..end) {
                let dist = cmp::max(i, j) - cmp::min(i, j);

                if let (Some(f), Some(t)) = (from_word, sentence[j]) {
                    word_vecs[f].inc(t, dist);
                }
            }
        }

        sentence.clear();
    }
}

impl LanguageModel {
    pub fn get(&self, word: &str) -> Option<&WordVec> {
        self.words.get(word).map(|i| &self.word_vecs[*i])
    }

    pub fn nearest_words(&self, word: &WordVec) -> Vec<&WordVec> {
        let mut vec_refs = self.word_vecs.iter().filter_map(|w| {
            let dist = w.distance(word);
            if w.word != word.word {
                Some((dist, w))
            } else {
                None
            }
        }).collect::<Vec<_>>();
        vec_refs.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap_or_else(|| {
            println!("bad vector: {:?}, {:?}", a, b);
            Equal
        }));
        vec_refs.into_iter().map(|x| x.1).collect()
    }

}

fn read_byte<R: Read>(b: u8, read: &mut R) -> io::Result<()> {
    let buf = &mut [0];
    while try!(read.read(buf)) == 0 {}
    assert_eq!(&[b], buf);
    Ok(())
}

unsafe fn read_raw<T: Copy, R: Read>(reader: &mut BufReader<R>) -> io::Result<T> {
    let mut buffer = [0u8; 64];
    let t_size = mem::size_of::<T>();
    assert!(t_size <= buffer.len());

    let mut remainder = t_size;
    while remainder > 0 {
        let bytes_read = try!(reader.read(&mut buffer[(t_size-remainder)..t_size]));
        remainder -= bytes_read;
    }

    let bptr: *mut T = mem::transmute(buffer.as_ptr());
    Ok(*bptr)
}

fn write_raw<T: Copy, F: Write>(t: T, writer: &mut F) -> io::Result<usize> {
    let buffer = [0u8; 64];
    let t_size = mem::size_of::<T>();
    assert!(t_size <= buffer.len());
    unsafe {
        let bptr: *mut T = mem::transmute(buffer.as_ptr());
        *bptr = t;
    }

    let mut start = 0;
    while start != t_size {
        start += try!(writer.write(&buffer[start..t_size]));
    }
    Ok((start))
}

#[cfg(test)]
mod test {
    use super::LanguageModelBuilder;
    use std::path::Path;

    fn get_builder() -> LanguageModelBuilder {
        let words = "foo bar baz blort".split(" ").map(|w| w.to_string()).collect::<Vec<_>>();
        let mut builder = LanguageModelBuilder::new(1, words);

        let input = "x foo bar baz x x x x x x x blort".split(" ");

        {
            let mut acc = builder.new_sentence();
            for word in input {
                acc.add_word(word);
            }
        }

        builder
    }

    #[test]
    fn test_accept_sentences() {
        let model = get_builder().build();
        let foo = model.get("foo").unwrap();
        let baz = model.get("baz").unwrap();
        let bar = model.get("bar").unwrap();
        let blort = model.get("blort").unwrap();

        assert!(foo.distance(baz) < foo.distance(blort));
        assert!(foo.distance(bar) == bar.distance(baz));
    }

    #[test]
    fn test_serialization() {
        let builder = get_builder();
        let path = Path::new("/tmp/model.data");
        builder.save(&path).unwrap();

        let loaded_model = LanguageModelBuilder::load(path).unwrap().build();
        assert_eq!(builder.build(), loaded_model);
    }
}
<|endoftext|>


<commit_before>//! Module for holding Monoid typeclass definitions and default implementations
//!
//! A `Monoid` is a Semigroup that has a defined empty/zero value. This allows us to
//! define a `combine_all` method to work on a list of said things:
//!
//! Have you ever wanted to combine 2 Hashmaps such that for a given key, if it exists in both maps,
//! their values are summed in the new map?
//!
//! # Examples
//!
//! ```
//! # use frunk::monoid::*;
//! # use std::collections::*;
//! let vec_of_no_hashmaps: Vec<HashMap<i32, String>> = Vec::new();
//! assert_eq!(combine_all(&vec_of_no_hashmaps),
//!                    <HashMap<i32, String> as Monoid>::empty());
//!
//! let mut h1: HashMap<i32, String> = HashMap::new();
//! h1.insert(1, String::from("Hello"));  // h1 is HashMap( 1 -> "Hello")
//! let mut h2: HashMap<i32, String> = HashMap::new();
//! h2.insert(1, String::from(" World"));
//! h2.insert(2, String::from("Goodbye"));  // h2 is HashMap( 1 -> " World", 2 -> "Goodbye")
//! let mut h3: HashMap<i32, String> = HashMap::new();
//! h3.insert(3, String::from("Cruel World"));
//! let vec_of_hashes = vec![h1, h2, h3];
//!
//! let mut h_expected: HashMap<i32, String> = HashMap::new();
//! h_expected.insert(1, String::from("Hello World"));
//! h_expected.insert(2, String::from("Goodbye"));
//! h_expected.insert(3, String::from("Cruel World")); // h_expected is HashMap ( 1 -> "Hello World", 2 -> "Goodbye", 3 -> "Cruel World")
//! assert_eq!(combine_all(&vec_of_hashes), h_expected);
//! ```
use super::semigroup::{Semigroup, Product, All, Any};
use std::collections::*;
use std::hash::Hash;

/// A Monoid is a Semigroup that has an empty/ zero value
pub trait Monoid: Semigroup {
    /// For a given Monoid, returns its empty/zero value
    ///
    /// # Examples
    ///
    /// ```
    /// # use frunk::monoid::*;
    ///
    /// assert_eq!(<i16 as Monoid>::empty(), 0);
    /// ```
    fn empty() -> Self;
}

/// Return this combined with itself `n` times.
///
/// # Examples
///
/// ```
/// # use frunk::monoid::*;
///
/// assert_eq!(combine_n(&Some(2), 4), Some(8));
/// ```
pub fn combine_n<T>(o: &T, times: u32) -> T
where
    T: Monoid + Semigroup + Clone,
{
    if times == 0 {
        <T as Monoid>::empty()
    } else {
        super::semigroup::combine_n(o, times)
    }
}

/// Given a sequence of `xs`, combine them and return the total
///
/// # Examples
///
/// ```
/// # use frunk::monoid::*;
///
/// assert_eq!(combine_all(&vec![Some(1), Some(3)]), Some(4));
///
/// let empty_vec_opt_int:  Vec<Option<i32>> = Vec::new();
/// assert_eq!(combine_all(&empty_vec_opt_int), None);
///
/// let vec_of_some_strings = vec![Some(String::from("Hello")), Some(String::from(" World"))];
/// assert_eq!(combine_all(&vec_of_some_strings), Some(String::from("Hello World")));
/// ```
pub fn combine_all<T>(xs: &Vec<T>) -> T
where
    T: Monoid + Semigroup + Clone,
{
    xs.iter().fold(<T as Monoid>::empty(), |acc, next| {
        acc.combine(&next)
    })
}

impl<T> Monoid for Option<T>
where
    T: Semigroup + Clone,
{
    fn empty() -> Self {
        None
    }
}

impl Monoid for String {
    fn empty() -> Self {
        String::new()
    }
}

impl<T> Monoid for Vec<T>
where
    T: Clone,
{
    fn empty() -> Self {
        Vec::new()
    }
}

impl<T> Monoid for HashSet<T>
where
    T: Hash + Eq + Clone,
{
    fn empty() -> Self {
        HashSet::new()
    }
}

impl<K, V> Monoid for HashMap<K, V>
where
    K: Eq + Hash + Clone,
    V: Semigroup + Clone,
{
    fn empty() -> Self {
        HashMap::new()
    }
}

impl Monoid for All<bool> {
    fn empty() -> Self {
        All(true)
    }
}

impl Monoid for Any<bool> {
    fn empty() -> Self {
        Any(false)
    }
}

macro_rules! numeric_all_impls {
    ($($tr:ty)*) => {
      $(
        impl Monoid for All<$tr> {
            fn empty() -> Self { All(!0) }
        }
      )*
    }
}

numeric_all_impls! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 }

macro_rules! numeric_any_impls {
    ($($tr:ty)*) => {
      $(
        impl Monoid for Any<$tr> {
            fn empty() -> Self { Any(0) }
        }
      )*
    }
}

numeric_any_impls! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 }

macro_rules! numeric_monoid_imps {
  ($($zero: expr; $tr:ty),*) => {
    $(
      impl Monoid for $tr {
        fn empty() -> Self { $zero }
      }
    )*
  }
}

numeric_monoid_imps! {
    0; i8,
    0; i16,
    0; i32,
    0; i64,
    0; u8,
    0; u16,
    0; u32,
    0; u64,
    0; isize,
    0; usize,
    0f32; f32,
    0f64; f64
}

macro_rules! numeric_product_monoid_imps {
  ($($one: expr; $tr:ty),*) => {
    $(
      impl Monoid for Product<$tr> {
        fn empty() -> Self { Product($one) }
      }
    )*
  }
}

numeric_product_monoid_imps! {
    1; i8,
    1; i16,
    1; i32,
    1; i64,
    1; u8,
    1; u16,
    1; u32,
    1; u64,
    1; isize,
    1; usize,
    1f32; f32,
    1f64; f64
}

macro_rules! tuple_impls {
    () => {}; // no more

    (($idx:tt => $typ:ident), $( ($nidx:tt => $ntyp:ident), )*) => {
// Invoke recursive reversal of list that ends in the macro expansion implementation
// of the reversed list
//
        tuple_impls!([($idx, $typ);] $( ($nidx => $ntyp), )*);
        tuple_impls!($( ($nidx => $ntyp), )*); // invoke macro on tail
    };

// ([accumulatedList], listToReverse); recursively calls tuple_impls until the list to reverse
// + is empty (see next pattern)
//
    ([$(($accIdx: tt, $accTyp: ident);)+]  ($idx:tt => $typ:ident), $( ($nidx:tt => $ntyp:ident), )*) => {
      tuple_impls!([($idx, $typ); $(($accIdx, $accTyp); )*] $( ($nidx => $ntyp), ) *);
    };

// Finally expand into our implementation
    ([($idx:tt, $typ:ident); $( ($nidx:tt, $ntyp:ident); )*]) => {
        impl<$typ: Monoid, $( $ntyp: Monoid),*> Monoid for ($typ, $( $ntyp ),*) {
            fn empty() -> Self {
              (<$typ as Monoid>::empty(), $(<$ntyp as Monoid>::empty(), )*)
            }
        }
    }
}

tuple_impls! {
    (20 => U),
    (19 => T),
    (18 => S),
    (17 => R),
    (16 => Q),
    (15 => P),
    (14 => O),
    (13 => N),
    (12 => M),
    (11 => L),
    (10 => K),
    (9 => J),
    (8 => I),
    (7 => H),
    (6 => G),
    (5 => F),
    (4 => E),
    (3 => D),
    (2 => C),
    (1 => B),
    (0 => A),
}

#[cfg(test)]
mod tests {
    use super::*;
    use super::super::semigroup::{Product, All, Any};

    #[test]
    fn test_combine_n() {
        assert_eq!(combine_n(&1, 0), 0);
        assert_eq!(combine_n(&2, 1), 2);
        assert_eq!(combine_n(&Some(2), 0), None);
        assert_eq!(combine_n(&Some(2), 4), Some(8));
    }

    #[test]
    fn test_combine_all_basic() {
        assert_eq!(combine_all(&vec![1, 2, 3]), 6);

        let empty_vec_int: Vec<i32> = Vec::new();
        assert_eq!(combine_all(&empty_vec_int), 0);

        let empty_vec_opt_int: Vec<Option<i32>> = Vec::new();
        assert_eq!(combine_all(&empty_vec_opt_int), None);

        let vec_of_some_strings = vec![Some("Hello".to_owned()), Some(" World".to_owned())];
        assert_eq!(
            combine_all(&vec_of_some_strings),
            Some("Hello World".to_owned())
        );
    }

    #[test]
    fn test_combine_all_hashset() {
        let vec_of_no_hashes: Vec<HashSet<i32>> = Vec::new();
        assert_eq!(
            combine_all(&vec_of_no_hashes),
            <HashSet<i32> as Monoid>::empty()
        );

        let mut h1 = HashSet::new();
        h1.insert(1);
        let mut h2 = HashSet::new();
        h2.insert(2);
        let mut h3 = HashSet::new();
        h3.insert(3);
        let vec_of_hashes = vec![h1, h2, h3];
        let mut h_expected = HashSet::new();
        h_expected.insert(1);
        h_expected.insert(2);
        h_expected.insert(3);
        assert_eq!(combine_all(&vec_of_hashes), h_expected);
    }

    #[test]
    fn test_combine_all_hashmap() {
        let vec_of_no_hashmaps: Vec<HashMap<i32, String>> = Vec::new();
        assert_eq!(
            combine_all(&vec_of_no_hashmaps),
            <HashMap<i32, String> as Monoid>::empty()
        );

        let mut h1: HashMap<i32, String> = HashMap::new();
        h1.insert(1, String::from("Hello")); // h1 is HashMap( 1 -> "Hello")
        let mut h2: HashMap<i32, String> = HashMap::new();
        h2.insert(1, String::from(" World"));
        h2.insert(2, String::from("Goodbye")); // h2 is HashMap( 1 -> " World", 2 -> "Goodbye")
        let mut h3: HashMap<i32, String> = HashMap::new();
        h3.insert(3, String::from("Cruel World")); // h3 is HashMap( 3 -> "Cruel World")
        let vec_of_hashes = vec![h1, h2, h3];

        let mut h_expected: HashMap<i32, String> = HashMap::new();
        h_expected.insert(1, String::from("Hello World"));
        h_expected.insert(2, String::from("Goodbye"));
        h_expected.insert(3, String::from("Cruel World")); // h_expected is HashMap ( 1 -> "Hello World", 2 -> "Goodbye", 3 -> "Cruel World")
        assert_eq!(combine_all(&vec_of_hashes), h_expected);
    }

    #[test]
    fn test_combine_all_all() {
        let v1: Vec<All<i32>> = Vec::new();
        assert_eq!(combine_all(&v1), All(!0));
        assert_eq!(combine_all(&vec![All(3), All(7)]), All(3));

        let v2: Vec<All<bool>> = Vec::new();
        assert_eq!(combine_all(&v2), All(true));
        assert_eq!(combine_all(&vec![All(false), All(false)]), All(false));
        assert_eq!(combine_all(&vec![All(true), All(true)]), All(true));
    }

    #[test]
    fn test_combine_all_any() {
        let v1: Vec<Any<i32>> = Vec::new();
        assert_eq!(combine_all(&v1), Any(0));
        assert_eq!(combine_all(&vec![Any(3), Any(8)]), Any(11));

        let v2: Vec<Any<bool>> = Vec::new();
        assert_eq!(combine_all(&v2), Any(false));
        assert_eq!(combine_all(&vec![Any(false), Any(false)]), Any(false));
        assert_eq!(combine_all(&vec![Any(true), Any(false)]), Any(true));
    }

    #[test]
    fn test_combine_all_tuple() {
        let t1 = (1, 2.5f32, String::from("hi"), Some(3));
        let t2 = (1, 2.5f32, String::from(" world"), None);
        let t3 = (1, 2.5f32, String::from(", goodbye"), Some(10));
        let tuples = vec![t1, t2, t3];

        let expected = (3, 7.5f32, String::from("hi world, goodbye"), Some(13));
        assert_eq!(combine_all(&tuples), expected)
    }

    #[test]
    fn test_combine_all_product() {
        let v = vec![Product(2), Product(3), Product(4)];
        assert_eq!(combine_all(&v), Product(24))
    }

}
<commit_msg>Fix documentation on monoid.rs (#76)<commit_after>//! Module for holding Monoid typeclass definitions and default implementations
//!
//! A `Monoid` is a Semigroup that has a defined empty/zero value. This allows us to
//! define a `combine_all` method to work on a list of said things:
//!
//! Have you ever wanted to combine 2 Hashmaps such that for a given key, if it exists in both maps,
//! their values are summed in the new map?
//!
//! # Examples
//!
//! ```
//! # use frunk::monoid::*;
//! # use std::collections::*;
//! let vec_of_no_hashmaps: Vec<HashMap<i32, String>> = Vec::new();
//! assert_eq!(combine_all(&vec_of_no_hashmaps),
//!                    <HashMap<i32, String> as Monoid>::empty());
//!
//! let mut h1: HashMap<i32, String> = HashMap::new();
//! h1.insert(1, String::from("Hello"));  // h1 is HashMap( 1 -> "Hello")
//! let mut h2: HashMap<i32, String> = HashMap::new();
//! h2.insert(1, String::from(" World"));
//! h2.insert(2, String::from("Goodbye"));  // h2 is HashMap( 1 -> " World", 2 -> "Goodbye")
//! let mut h3: HashMap<i32, String> = HashMap::new();
//! h3.insert(3, String::from("Cruel World")); // h3 is HashMap( 3 -> "Cruel World")
//! let vec_of_hashes = vec![h1, h2, h3];
//!
//! let mut h_expected: HashMap<i32, String> = HashMap::new();
//! h_expected.insert(1, String::from("Hello World"));
//! h_expected.insert(2, String::from("Goodbye"));
//! h_expected.insert(3, String::from("Cruel World")); // h_expected is HashMap ( 1 -> "Hello World", 2 -> "Goodbye", 3 -> "Cruel World")
//! assert_eq!(combine_all(&vec_of_hashes), h_expected);
//! ```
use super::semigroup::{Semigroup, Product, All, Any};
use std::collections::*;
use std::hash::Hash;

/// A Monoid is a Semigroup that has an empty/ zero value
pub trait Monoid: Semigroup {
    /// For a given Monoid, returns its empty/zero value
    ///
    /// # Examples
    ///
    /// ```
    /// # use frunk::monoid::*;
    ///
    /// assert_eq!(<i16 as Monoid>::empty(), 0);
    /// ```
    fn empty() -> Self;
}

/// Return this combined with itself `n` times.
///
/// # Examples
///
/// ```
/// # use frunk::monoid::*;
///
/// assert_eq!(combine_n(&Some(2), 4), Some(8));
/// ```
pub fn combine_n<T>(o: &T, times: u32) -> T
where
    T: Monoid + Semigroup + Clone,
{
    if times == 0 {
        <T as Monoid>::empty()
    } else {
        super::semigroup::combine_n(o, times)
    }
}

/// Given a sequence of `xs`, combine them and return the total
///
/// # Examples
///
/// ```
/// # use frunk::monoid::*;
///
/// assert_eq!(combine_all(&vec![Some(1), Some(3)]), Some(4));
///
/// let empty_vec_opt_int:  Vec<Option<i32>> = Vec::new();
/// assert_eq!(combine_all(&empty_vec_opt_int), None);
///
/// let vec_of_some_strings = vec![Some(String::from("Hello")), Some(String::from(" World"))];
/// assert_eq!(combine_all(&vec_of_some_strings), Some(String::from("Hello World")));
/// ```
pub fn combine_all<T>(xs: &Vec<T>) -> T
where
    T: Monoid + Semigroup + Clone,
{
    xs.iter().fold(<T as Monoid>::empty(), |acc, next| {
        acc.combine(&next)
    })
}

impl<T> Monoid for Option<T>
where
    T: Semigroup + Clone,
{
    fn empty() -> Self {
        None
    }
}

impl Monoid for String {
    fn empty() -> Self {
        String::new()
    }
}

impl<T> Monoid for Vec<T>
where
    T: Clone,
{
    fn empty() -> Self {
        Vec::new()
    }
}

impl<T> Monoid for HashSet<T>
where
    T: Hash + Eq + Clone,
{
    fn empty() -> Self {
        HashSet::new()
    }
}

impl<K, V> Monoid for HashMap<K, V>
where
    K: Eq + Hash + Clone,
    V: Semigroup + Clone,
{
    fn empty() -> Self {
        HashMap::new()
    }
}

impl Monoid for All<bool> {
    fn empty() -> Self {
        All(true)
    }
}

impl Monoid for Any<bool> {
    fn empty() -> Self {
        Any(false)
    }
}

macro_rules! numeric_all_impls {
    ($($tr:ty)*) => {
      $(
        impl Monoid for All<$tr> {
            fn empty() -> Self { All(!0) }
        }
      )*
    }
}

numeric_all_impls! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 }

macro_rules! numeric_any_impls {
    ($($tr:ty)*) => {
      $(
        impl Monoid for Any<$tr> {
            fn empty() -> Self { Any(0) }
        }
      )*
    }
}

numeric_any_impls! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 }

macro_rules! numeric_monoid_imps {
  ($($zero: expr; $tr:ty),*) => {
    $(
      impl Monoid for $tr {
        fn empty() -> Self { $zero }
      }
    )*
  }
}

numeric_monoid_imps! {
    0; i8,
    0; i16,
    0; i32,
    0; i64,
    0; u8,
    0; u16,
    0; u32,
    0; u64,
    0; isize,
    0; usize,
    0f32; f32,
    0f64; f64
}

macro_rules! numeric_product_monoid_imps {
  ($($one: expr; $tr:ty),*) => {
    $(
      impl Monoid for Product<$tr> {
        fn empty() -> Self { Product($one) }
      }
    )*
  }
}

numeric_product_monoid_imps! {
    1; i8,
    1; i16,
    1; i32,
    1; i64,
    1; u8,
    1; u16,
    1; u32,
    1; u64,
    1; isize,
    1; usize,
    1f32; f32,
    1f64; f64
}

macro_rules! tuple_impls {
    () => {}; // no more

    (($idx:tt => $typ:ident), $( ($nidx:tt => $ntyp:ident), )*) => {
// Invoke recursive reversal of list that ends in the macro expansion implementation
// of the reversed list
//
        tuple_impls!([($idx, $typ);] $( ($nidx => $ntyp), )*);
        tuple_impls!($( ($nidx => $ntyp), )*); // invoke macro on tail
    };

// ([accumulatedList], listToReverse); recursively calls tuple_impls until the list to reverse
// + is empty (see next pattern)
//
    ([$(($accIdx: tt, $accTyp: ident);)+]  ($idx:tt => $typ:ident), $( ($nidx:tt => $ntyp:ident), )*) => {
      tuple_impls!([($idx, $typ); $(($accIdx, $accTyp); )*] $( ($nidx => $ntyp), ) *);
    };

// Finally expand into our implementation
    ([($idx:tt, $typ:ident); $( ($nidx:tt, $ntyp:ident); )*]) => {
        impl<$typ: Monoid, $( $ntyp: Monoid),*> Monoid for ($typ, $( $ntyp ),*) {
            fn empty() -> Self {
              (<$typ as Monoid>::empty(), $(<$ntyp as Monoid>::empty(), )*)
            }
        }
    }
}

tuple_impls! {
    (20 => U),
    (19 => T),
    (18 => S),
    (17 => R),
    (16 => Q),
    (15 => P),
    (14 => O),
    (13 => N),
    (12 => M),
    (11 => L),
    (10 => K),
    (9 => J),
    (8 => I),
    (7 => H),
    (6 => G),
    (5 => F),
    (4 => E),
    (3 => D),
    (2 => C),
    (1 => B),
    (0 => A),
}

#[cfg(test)]
mod tests {
    use super::*;
    use super::super::semigroup::{Product, All, Any};

    #[test]
    fn test_combine_n() {
        assert_eq!(combine_n(&1, 0), 0);
        assert_eq!(combine_n(&2, 1), 2);
        assert_eq!(combine_n(&Some(2), 0), None);
        assert_eq!(combine_n(&Some(2), 4), Some(8));
    }

    #[test]
    fn test_combine_all_basic() {
        assert_eq!(combine_all(&vec![1, 2, 3]), 6);

        let empty_vec_int: Vec<i32> = Vec::new();
        assert_eq!(combine_all(&empty_vec_int), 0);

        let empty_vec_opt_int: Vec<Option<i32>> = Vec::new();
        assert_eq!(combine_all(&empty_vec_opt_int), None);

        let vec_of_some_strings = vec![Some("Hello".to_owned()), Some(" World".to_owned())];
        assert_eq!(
            combine_all(&vec_of_some_strings),
            Some("Hello World".to_owned())
        );
    }

    #[test]
    fn test_combine_all_hashset() {
        let vec_of_no_hashes: Vec<HashSet<i32>> = Vec::new();
        assert_eq!(
            combine_all(&vec_of_no_hashes),
            <HashSet<i32> as Monoid>::empty()
        );

        let mut h1 = HashSet::new();
        h1.insert(1);
        let mut h2 = HashSet::new();
        h2.insert(2);
        let mut h3 = HashSet::new();
        h3.insert(3);
        let vec_of_hashes = vec![h1, h2, h3];
        let mut h_expected = HashSet::new();
        h_expected.insert(1);
        h_expected.insert(2);
        h_expected.insert(3);
        assert_eq!(combine_all(&vec_of_hashes), h_expected);
    }

    #[test]
    fn test_combine_all_hashmap() {
        let vec_of_no_hashmaps: Vec<HashMap<i32, String>> = Vec::new();
        assert_eq!(
            combine_all(&vec_of_no_hashmaps),
            <HashMap<i32, String> as Monoid>::empty()
        );

        let mut h1: HashMap<i32, String> = HashMap::new();
        h1.insert(1, String::from("Hello")); // h1 is HashMap( 1 -> "Hello")
        let mut h2: HashMap<i32, String> = HashMap::new();
        h2.insert(1, String::from(" World"));
        h2.insert(2, String::from("Goodbye")); // h2 is HashMap( 1 -> " World", 2 -> "Goodbye")
        let mut h3: HashMap<i32, String> = HashMap::new();
        h3.insert(3, String::from("Cruel World")); // h3 is HashMap( 3 -> "Cruel World")
        let vec_of_hashes = vec![h1, h2, h3];

        let mut h_expected: HashMap<i32, String> = HashMap::new();
        h_expected.insert(1, String::from("Hello World"));
        h_expected.insert(2, String::from("Goodbye"));
        h_expected.insert(3, String::from("Cruel World")); // h_expected is HashMap ( 1 -> "Hello World", 2 -> "Goodbye", 3 -> "Cruel World")
        assert_eq!(combine_all(&vec_of_hashes), h_expected);
    }

    #[test]
    fn test_combine_all_all() {
        let v1: Vec<All<i32>> = Vec::new();
        assert_eq!(combine_all(&v1), All(!0));
        assert_eq!(combine_all(&vec![All(3), All(7)]), All(3));

        let v2: Vec<All<bool>> = Vec::new();
        assert_eq!(combine_all(&v2), All(true));
        assert_eq!(combine_all(&vec![All(false), All(false)]), All(false));
        assert_eq!(combine_all(&vec![All(true), All(true)]), All(true));
    }

    #[test]
    fn test_combine_all_any() {
        let v1: Vec<Any<i32>> = Vec::new();
        assert_eq!(combine_all(&v1), Any(0));
        assert_eq!(combine_all(&vec![Any(3), Any(8)]), Any(11));

        let v2: Vec<Any<bool>> = Vec::new();
        assert_eq!(combine_all(&v2), Any(false));
        assert_eq!(combine_all(&vec![Any(false), Any(false)]), Any(false));
        assert_eq!(combine_all(&vec![Any(true), Any(false)]), Any(true));
    }

    #[test]
    fn test_combine_all_tuple() {
        let t1 = (1, 2.5f32, String::from("hi"), Some(3));
        let t2 = (1, 2.5f32, String::from(" world"), None);
        let t3 = (1, 2.5f32, String::from(", goodbye"), Some(10));
        let tuples = vec![t1, t2, t3];

        let expected = (3, 7.5f32, String::from("hi world, goodbye"), Some(13));
        assert_eq!(combine_all(&tuples), expected)
    }

    #[test]
    fn test_combine_all_product() {
        let v = vec![Product(2), Product(3), Product(4)];
        assert_eq!(combine_all(&v), Product(24))
    }

}
<|endoftext|>


<commit_before>//pub use lang::Lang;

//#[derive(PartialEq, Eq, Debug)]
//pub enum Script {
//    Unknown,
//    Cyrillic,
//    Latin,
//    CMN,
//    KAT,
//}

//static CYRILLIC_LANGS: &'static [Lang] = &[Lang::RUS, Lang::UKR];
//static LATIN_LANGS: &'static [Lang] = &[Lang::ENG];

//static UNKNOWN_LANGS: &'static [Lang] = &[];
//static CMN_LANGS: &'static [Lang] = &[Lang::CMN];
//static KAT_LANGS: &'static [Lang] = &[Lang::KAT];

//pub fn detect_script(text : String) -> Script {
//    let mut latin_count = 0;
//    let mut cyrillic_count = 0;

//    for ch in text.chars() {
//        if Script::Cyrillic.has_char(ch) { cyrillic_count += 1; }
//        if Script::Latin.has_char(ch) {  latin_count += 1; }
//    }

//    if latin_count > 0 && latin_count > cyrillic_count {
//        Script::Latin
//    } else if cyrillic_count > 0 && cyrillic_count > latin_count {
//        Script::Cyrillic
//    } else {
//        Script::Unknown
//    }
//}

//// TODO: Use http://jrgraphix.net/research/unicode_blocks.php
//impl Script {
//    pub fn langs(&self) -> &'static [Lang] {
//        match *self {
//            Script::Unknown => UNKNOWN_LANGS,
//            Script::Cyrillic => CYRILLIC_LANGS,
//            Script::Latin => LATIN_LANGS,
//            Script::CMN => CMN_LANGS,
//            Script::KAT => KAT_LANGS
//        }
//    }

//    pub fn has_char(&self, ch: char) -> bool {
//        match *self {
//            Script::Unknown => false,
//            Script::Cyrillic => is_cyrillic(ch),
//            Script::Latin => is_latin(ch),
//            Script::CMN => is_cmn(ch),
//            Script::KAT => is_kat(ch)
//        }
//    }
//}

//fn is_cyrillic(ch: char) -> bool {
//    match ch {
//        '\u{0400}'...'\u{0484}' |
//        '\u{0487}'...'\u{052F}' |
//        '\u{2DE0}'...'\u{2DFF}' |
//        '\u{A640}'...'\u{A69D}' |
//        '\u{1D2B}' |
//        '\u{1D78}' |
//        '\u{A69F}' => true,
//        _ => false
//    }
//}

//// TODO: finish implementation, with all the Latin chars.
//fn is_latin(ch : char) -> bool {
//    match ch {
//        'a'...'z' | 'A'...'Z' => true,
//        _ => false
//    }
//}

//// TODO: implement
//fn is_cmn(ch : char) -> bool {
//    ch == 'x'
//}

//// Is Georgian char?
//fn is_kat(ch : char) -> bool {
//    match ch {
//        '\u{10A0}'...'\u{10FF}' => true,
//        _ => false
//    }
//}

//#[cfg(test)]
//mod tests {
//    use super::Script;
//    use super::is_cyrillic;
//    use super::is_latin;
//    use super::is_kat;
//    use super::detect_script;

//    #[test]
//    fn test_detect_script() {
//        assert_eq!(detect_script("1234567890-,;!".to_string()), Script::Unknown);
//        assert_eq!(detect_script("Hello!".to_string()), Script::Latin);
//        assert_eq!(detect_script("Привет всем!".to_string()), Script::Cyrillic);
//        assert_eq!(detect_script("Привет всем! Этот текст на русском with some English.".to_string()), Script::Cyrillic);
//        assert_eq!(detect_script("Russian word любовь means love.".to_string()), Script::Latin);
//    }

//    #[test]
//    fn test_is_cyrillic() {
//        assert_eq!(is_cyrillic('а'), true);
//        assert_eq!(is_cyrillic('Я'), true);
//        assert_eq!(is_cyrillic('Ґ'), true);
//        assert_eq!(is_cyrillic('ї'), true);
//        assert_eq!(is_cyrillic('Ꙕ'), true);

//        assert_eq!(is_cyrillic('L'), false);
//    }

//    #[test]
//    fn test_is_latin() {
//        assert_eq!(is_latin('z'), true);
//        assert_eq!(is_latin('A'), true);

//        assert_eq!(is_latin('ж'), false);
//    }

//    #[test]
//    fn test_is_kat() {
//        assert_eq!(is_kat('რ'), true);
//        assert_eq!(is_kat('ж'), false);
//    }

//    #[test]
//    fn test_script_langs() {
//        println!("{:?}", Script::Cyrillic.langs());
//        println!("Len: {:?}", Script::Cyrillic.langs().len());
//    }
//}
<commit_msg>make detect_script() return Option<commit_after>pub use lang::Lang;

#[derive(PartialEq, Eq, Debug)]
pub enum Script {
   Cyrillic,
   Latin,
   CMN,
   KAT,
}

pub fn detect_script(text : String) -> Option<Script> {
   let mut latin_count = 0;
   let mut cyrillic_count = 0;

   for ch in text.chars() {
       if Script::Cyrillic.has_char(ch) { cyrillic_count += 1; }
       if Script::Latin.has_char(ch) {  latin_count += 1; }
   }

   if latin_count > 0 && latin_count > cyrillic_count {
       Some(Script::Latin)
   } else if cyrillic_count > 0 && cyrillic_count > latin_count {
       Some(Script::Cyrillic)
   } else {
       None
   }
}

// TODO: Use http://jrgraphix.net/research/unicode_blocks.php
impl Script {
   pub fn has_char(&self, ch: char) -> bool {
       match *self {
           Script::Cyrillic => is_cyrillic(ch),
           Script::Latin => is_latin(ch),
           Script::CMN => is_cmn(ch),
           Script::KAT => is_kat(ch)
       }
   }
}

fn is_cyrillic(ch: char) -> bool {
   match ch {
       '\u{0400}'...'\u{0484}' |
       '\u{0487}'...'\u{052F}' |
       '\u{2DE0}'...'\u{2DFF}' |
       '\u{A640}'...'\u{A69D}' |
       '\u{1D2B}' |
       '\u{1D78}' |
       '\u{A69F}' => true,
       _ => false
   }
}

// TODO: finish implementation, with all the Latin chars.
fn is_latin(ch : char) -> bool {
   match ch {
       'a'...'z' | 'A'...'Z' => true,
       _ => false
   }
}

// TODO: implement
fn is_cmn(ch : char) -> bool {
   ch == 'x'
}

// Is Georgian char?
fn is_kat(ch : char) -> bool {
   match ch {
       '\u{10A0}'...'\u{10FF}' => true,
       _ => false
   }
}

#[cfg(test)]
mod tests {
   use super::Script;
   use super::is_cyrillic;
   use super::is_latin;
   use super::is_kat;
   use super::detect_script;

   #[test]
   fn test_detect_script() {
       assert_eq!(detect_script("1234567890-,;!".to_string()), None);
       assert_eq!(detect_script("Hello!".to_string()), Some(Script::Latin));
       assert_eq!(detect_script("Привет всем!".to_string()), Some(Script::Cyrillic));
       assert_eq!(detect_script("Привет всем! Этот текст на русском with some English.".to_string()), Some(Script::Cyrillic));
       assert_eq!(detect_script("Russian word любовь means love.".to_string()), Some(Script::Latin));
   }

   #[test]
   fn test_is_cyrillic() {
       assert_eq!(is_cyrillic('а'), true);
       assert_eq!(is_cyrillic('Я'), true);
       assert_eq!(is_cyrillic('Ґ'), true);
       assert_eq!(is_cyrillic('ї'), true);
       assert_eq!(is_cyrillic('Ꙕ'), true);

       assert_eq!(is_cyrillic('L'), false);
   }

   #[test]
   fn test_is_latin() {
       assert_eq!(is_latin('z'), true);
       assert_eq!(is_latin('A'), true);

       assert_eq!(is_latin('ж'), false);
   }

   #[test]
   fn test_is_kat() {
       assert_eq!(is_kat('რ'), true);
       assert_eq!(is_kat('ж'), false);
   }
}
<|endoftext|>


<commit_before>use ::{Guard, Nav};
use ::util::{ChildIndex, SiblingIndex};

use std::cell::{Ref, RefCell};
use std::clone::Clone;
use std::mem;
use std::rc::Rc;

/// Heap-allocated, reference-counted trees that can be shared freely.

struct TreeInternal<T> {
    data: T, children: RefCell<Vec<Tree<T>>>,
}

/// Reference to a heap-allocated tree.
///
/// This tree structure has the same characteristics as
/// [owned::Tree](../owned/struct.Tree.html), except that a parent does not own
/// its children. Internally, this is achieved by storing trees in `std::rc::Rc`
/// wrappers. As a result, this type can be cloned and shared as the child of
/// multiple parents. This may be useful for saving memory.
pub struct Tree<T> {
    internal: Rc<TreeInternal<T>>,
}

impl<T> Tree<T> {
    pub fn new(data: T, children: Vec<Tree<T>>) -> Self {
        Tree { internal: Rc::new(TreeInternal { data: data, children: RefCell::new(children), }), }
    }

    pub fn leaf(data: T) -> Self {
        Tree { internal: Rc::new(TreeInternal { data: data, children: RefCell::new(Vec::new()), }), }
    }

    pub fn push_child(&mut self, child: Tree<T>) {
        self.internal.children.borrow_mut().push(child);
    }

    pub fn remove_child(&mut self, index: usize) {
        assert![index < self.internal.children.borrow().len(),
                "cannot remove child at index {} (only {} children)", index, self.internal.children.borrow().len()];
        self.internal.children.borrow_mut().remove(index);
    }

    pub fn insert_child(&mut self, index: usize, child: Tree<T>) {
        self.internal.children.borrow_mut().insert(index, child);
    }

    pub fn nav<'s>(&'s self) -> Navigator<'s, T> {
        Navigator::new(self)
    }
}

/// Creates a new reference to this tree, such that modifying the reference also
/// modifies the original tree.
impl<T> Clone for Tree<T> {
    fn clone(&self) -> Self {
        Tree { internal: self.internal.clone(), }
    }
}

pub struct DataGuard<T> {
    tree: Tree<T>,
}

impl<'a, T: 'a> Guard<'a, T> for DataGuard<T> {
    fn super_deref<'s>(&'s self) -> &'a T {
        unsafe {
            mem::transmute(&self.tree.internal.data)
        }
    }
}

pub struct Navigator<'a, T: 'a> {
    root: &'a Tree<T>,
    path: Vec<(Ref<'a, Vec<Tree<T>>>, usize)>,
}

impl<'a, T: 'a> Navigator<'a, T> {
    fn new(root: &'a Tree<T>) -> Self {
        Navigator { root: root, path: Vec::new(), }
    }

    fn here<'s>(&'s self) -> &'s Tree<T> {
        match self.path.last() {
            None => self.root,
            Some(&(ref siblings, ref index)) => &siblings[*index],
        }
    }
}

/// Due to the internal representation of the path back from the tree root, this
/// `Clone` implementation retraces the path from the root. This may be less
/// efficient than is desirable.
impl<'a, T: 'a> Clone for Navigator<'a, T> {
    fn clone(&self) -> Self {
        // We can't clone self.path directly, so we rebuild it by hand.
        let mut new_nav = Navigator { root: self.root, path: Vec::new(), };
        new_nav.path.reserve(self.path.len());
        for &(_, index) in &self.path {
            new_nav.seek_child(index);
        }
        return new_nav;
    }
}

impl<'a, T: 'a> Nav<'a> for Navigator<'a, T> {
    type Data = T;
    type DataGuard = DataGuard<T>;

    fn seek_sibling(&mut self, offset: isize) {
        let new_index =
            match self.path.last() {
                None => SiblingIndex::Root,
                Some(&(ref siblings, ref index)) =>
                    SiblingIndex::compute(siblings.len(), *index, offset),
            }.unwrap();
        let (siblings, _) = self.path.pop().unwrap();
        self.path.push((siblings, new_index));
    }

    fn seek_child(&mut self, index: usize) {
        let new_index =
            ChildIndex::compute(self.here().internal.children.borrow().len(), index).unwrap();
        let children = unsafe {
            mem::transmute(self.here().internal.children.borrow())
        };
        self.path.push((children, new_index));
    }

    fn child_count(&self) -> usize {
        self.here().internal.children.borrow().len()
    }

    fn at_root(&self) -> bool {
        self.path.is_empty()
    }

    fn to_parent(&mut self) {
        self.path.pop().expect("already at root");
    }

    fn to_root(&mut self) {
        self.path.clear();
    }

    fn data(&self) -> DataGuard<T> {
        DataGuard { tree: self.here().clone(), }
    }
}
<commit_msg>Remove stray comment.<commit_after>use ::{Guard, Nav};
use ::util::{ChildIndex, SiblingIndex};

use std::cell::{Ref, RefCell};
use std::clone::Clone;
use std::mem;
use std::rc::Rc;

struct TreeInternal<T> {
    data: T, children: RefCell<Vec<Tree<T>>>,
}

/// Reference to a heap-allocated tree.
///
/// This tree structure has the same characteristics as
/// [owned::Tree](../owned/struct.Tree.html), except that a parent does not own
/// its children. Internally, this is achieved by storing trees in `std::rc::Rc`
/// wrappers. As a result, this type can be cloned and shared as the child of
/// multiple parents. This may be useful for saving memory.
pub struct Tree<T> {
    internal: Rc<TreeInternal<T>>,
}

impl<T> Tree<T> {
    pub fn new(data: T, children: Vec<Tree<T>>) -> Self {
        Tree { internal: Rc::new(TreeInternal { data: data, children: RefCell::new(children), }), }
    }

    pub fn leaf(data: T) -> Self {
        Tree { internal: Rc::new(TreeInternal { data: data, children: RefCell::new(Vec::new()), }), }
    }

    pub fn push_child(&mut self, child: Tree<T>) {
        self.internal.children.borrow_mut().push(child);
    }

    pub fn remove_child(&mut self, index: usize) {
        assert![index < self.internal.children.borrow().len(),
                "cannot remove child at index {} (only {} children)", index, self.internal.children.borrow().len()];
        self.internal.children.borrow_mut().remove(index);
    }

    pub fn insert_child(&mut self, index: usize, child: Tree<T>) {
        self.internal.children.borrow_mut().insert(index, child);
    }

    pub fn nav<'s>(&'s self) -> Navigator<'s, T> {
        Navigator::new(self)
    }
}

/// Creates a new reference to this tree, such that modifying the reference also
/// modifies the original tree.
impl<T> Clone for Tree<T> {
    fn clone(&self) -> Self {
        Tree { internal: self.internal.clone(), }
    }
}

pub struct DataGuard<T> {
    tree: Tree<T>,
}

impl<'a, T: 'a> Guard<'a, T> for DataGuard<T> {
    fn super_deref<'s>(&'s self) -> &'a T {
        unsafe {
            mem::transmute(&self.tree.internal.data)
        }
    }
}

pub struct Navigator<'a, T: 'a> {
    root: &'a Tree<T>,
    path: Vec<(Ref<'a, Vec<Tree<T>>>, usize)>,
}

impl<'a, T: 'a> Navigator<'a, T> {
    fn new(root: &'a Tree<T>) -> Self {
        Navigator { root: root, path: Vec::new(), }
    }

    fn here<'s>(&'s self) -> &'s Tree<T> {
        match self.path.last() {
            None => self.root,
            Some(&(ref siblings, ref index)) => &siblings[*index],
        }
    }
}

/// Due to the internal representation of the path back from the tree root, this
/// `Clone` implementation retraces the path from the root. This may be less
/// efficient than is desirable.
impl<'a, T: 'a> Clone for Navigator<'a, T> {
    fn clone(&self) -> Self {
        // We can't clone self.path directly, so we rebuild it by hand.
        let mut new_nav = Navigator { root: self.root, path: Vec::new(), };
        new_nav.path.reserve(self.path.len());
        for &(_, index) in &self.path {
            new_nav.seek_child(index);
        }
        return new_nav;
    }
}

impl<'a, T: 'a> Nav<'a> for Navigator<'a, T> {
    type Data = T;
    type DataGuard = DataGuard<T>;

    fn seek_sibling(&mut self, offset: isize) {
        let new_index =
            match self.path.last() {
                None => SiblingIndex::Root,
                Some(&(ref siblings, ref index)) =>
                    SiblingIndex::compute(siblings.len(), *index, offset),
            }.unwrap();
        let (siblings, _) = self.path.pop().unwrap();
        self.path.push((siblings, new_index));
    }

    fn seek_child(&mut self, index: usize) {
        let new_index =
            ChildIndex::compute(self.here().internal.children.borrow().len(), index).unwrap();
        let children = unsafe {
            mem::transmute(self.here().internal.children.borrow())
        };
        self.path.push((children, new_index));
    }

    fn child_count(&self) -> usize {
        self.here().internal.children.borrow().len()
    }

    fn at_root(&self) -> bool {
        self.path.is_empty()
    }

    fn to_parent(&mut self) {
        self.path.pop().expect("already at root");
    }

    fn to_root(&mut self) {
        self.path.clear();
    }

    fn data(&self) -> DataGuard<T> {
        DataGuard { tree: self.here().clone(), }
    }
}
<|endoftext|>


<commit_before>use std::rc::Rc;
use std::sync::{Arc, RwLock};
use std::borrow::Cow;
use std::any::Any;
use std::fmt;
use stream::Stream;

/// Represents a continuous value that changes over time.
///
/// Signals are usually constructed by stream operations and can be read using the `sample` or
/// `sample_with` methods.
///
/// This type is meant to be used as a black box, but you can fiddle with the enum variants if
/// you know what you're doing.
#[derive(Clone)]
pub enum Signal<T>
{
    /// A signal with constant value.
    Constant(T),
    /// A signal that reads from shared data.
    ///
    /// This is produced by stream methods that create a signal.
    /// It also can contain a reference to it's parent stream to avoid it's deletion.
    Shared(Arc<RwLock<T>>, Option<Rc<Any>>),
    /// A signal that generates it's values from a function.
    ///
    /// This is produced by `Signal::map`
    Dynamic(Rc<Fn() -> T>),
    /// A signal that contains a signal, and allows sampling the inner signal directly.
    ///
    /// This is produced by `Signal::switch`
    Nested(Rc<Fn() -> Signal<T>>),
}

impl<T> Signal<T>
{
    /// Creates a signal that samples it's values from the supplied function.
    pub fn from_fn<F>(f: F) -> Self
        where F: Fn() -> T + 'static
    {
        Signal::Dynamic(Rc::new(f))
    }

    /// Attempts to extract the inner storage from a signal.
    ///
    /// The returned value can be moved across threads and converted back into a signal.
    /// This also drops the reference to it's parent signal, so it can delete the signal
    /// chain as a side effect.
    pub fn into_rwlock(self) -> Result<Arc<RwLock<T>>, Self>
    {
        if let Signal::Shared(val, _) = self { Ok(val) } else { Err(self) }
    }
}

impl<T: Clone> Signal<T>
{
    /// Sample by value.
    ///
    /// This will clone the content of the signal.
    pub fn sample(&self) -> T
    {
        match *self
        {
            Signal::Constant(ref val) => val.clone(),
            Signal::Shared(ref val, _) => val.read().unwrap().clone(),
            Signal::Dynamic(ref f) => f(),
            Signal::Nested(ref f) => f().sample(),
        }
    }

    /// Sample by reference.
    ///
    /// This is meant to be the most efficient way when cloning is undesirable,
    /// but it requires a callback to prevent outliving internal `RwLock` borrows.
    pub fn sample_with<F, R>(&self, cb: F) -> R
        where F: FnOnce(Cow<T>) -> R
    {
        match *self
        {
            Signal::Constant(ref val) => cb(Cow::Borrowed(val)),
            Signal::Shared(ref val, _) => cb(Cow::Borrowed(&val.read().unwrap())),
            Signal::Dynamic(ref f) => cb(Cow::Owned(f())),
            Signal::Nested(ref f) => f().sample_with(cb),
        }
    }
}

impl<T: Clone + 'static> Signal<T>
{
    /// Maps a signal with the provided function.
    pub fn map<F, R>(&self, f: F) -> Signal<R>
        where F: Fn(Cow<T>) -> R + 'static,
    {
        let this = self.clone();
        Signal::from_fn(move || this.sample_with(&f))
    }

    /// Samples the value of this signal every time the trigger stream fires.
    pub fn snapshot<S, F, R>(&self, trigger: &Stream<S>, f: F) -> Stream<R>
        where F: Fn(Cow<T>, Cow<S>) -> R + 'static,
        S: Clone + 'static, R: Clone + 'static
    {
        let this = self.clone();
        trigger.map(move |b| this.sample_with(|a| f(a, b)))
    }
}

impl<T: Clone + 'static> Signal<Signal<T>>
{
    /// Creates a new signal that samples the inner value of a nested signal.
    pub fn switch(&self) -> Signal<T>
    {
        let this = self.clone();
        Signal::Nested(Rc::new(move || this.sample()))
    }
}

impl<T> From<T> for Signal<T>
{
    fn from(val: T) -> Self
    {
        Signal::Constant(val)
    }
}

impl<T> From<Arc<RwLock<T>>> for Signal<T>
{
    fn from(val: Arc<RwLock<T>>) -> Self
    {
        Signal::Shared(val, None)
    }
}

impl<T: fmt::Debug> fmt::Debug for Signal<T>
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
    {
        match *self
        {
            Signal::Constant(ref val) => write!(f, "Signal::Constant({:?})", val),
            Signal::Shared(ref val, ref r) => write!(f, "Signal::Shared({:?}, {:?})", val, r),
            Signal::Dynamic(ref rf) => write!(f, "Signal::Dynamic(Fn@{:p})", rf),
            Signal::Nested(ref rf) => write!(f, "Signal::Nested(Fn@{:p})", rf),
        }
    }
}
<commit_msg>require Clone for all Signal methods<commit_after>use std::rc::Rc;
use std::sync::{Arc, RwLock};
use std::borrow::Cow;
use std::any::Any;
use std::fmt;
use stream::Stream;

/// Represents a continuous value that changes over time.
///
/// Signals are usually constructed by stream operations and can be read using the `sample` or
/// `sample_with` methods.
///
/// This type is meant to be used as a black box, but you can fiddle with the enum variants if
/// you know what you're doing.
#[derive(Clone)]
pub enum Signal<T>
{
    /// A signal with constant value.
    Constant(T),
    /// A signal that reads from shared data.
    ///
    /// This is produced by stream methods that create a signal.
    /// It also can contain a reference to it's parent stream to avoid it's deletion.
    Shared(Arc<RwLock<T>>, Option<Rc<Any>>),
    /// A signal that generates it's values from a function.
    ///
    /// This is produced by `Signal::map`
    Dynamic(Rc<Fn() -> T>),
    /// A signal that contains a signal, and allows sampling the inner signal directly.
    ///
    /// This is produced by `Signal::switch`
    Nested(Rc<Fn() -> Signal<T>>),
}

impl<T: Clone> Signal<T>
{
    /// Creates a signal that samples it's values from the supplied function.
    pub fn from_fn<F>(f: F) -> Self
        where F: Fn() -> T + 'static
    {
        Signal::Dynamic(Rc::new(f))
    }

    /// Attempts to extract the inner storage from a signal.
    ///
    /// The returned value can be moved across threads and converted back into a signal.
    /// This also drops the reference to it's parent signal, so it can delete the signal
    /// chain as a side effect.
    pub fn into_rwlock(self) -> Result<Arc<RwLock<T>>, Self>
    {
        if let Signal::Shared(val, _) = self { Ok(val) } else { Err(self) }
    }

    /// Sample by value.
    ///
    /// This will clone the content of the signal.
    pub fn sample(&self) -> T
    {
        match *self
        {
            Signal::Constant(ref val) => val.clone(),
            Signal::Shared(ref val, _) => val.read().unwrap().clone(),
            Signal::Dynamic(ref f) => f(),
            Signal::Nested(ref f) => f().sample(),
        }
    }

    /// Sample by reference.
    ///
    /// This is meant to be the most efficient way when cloning is undesirable,
    /// but it requires a callback to prevent outliving internal `RwLock` borrows.
    pub fn sample_with<F, R>(&self, cb: F) -> R
        where F: FnOnce(Cow<T>) -> R
    {
        match *self
        {
            Signal::Constant(ref val) => cb(Cow::Borrowed(val)),
            Signal::Shared(ref val, _) => cb(Cow::Borrowed(&val.read().unwrap())),
            Signal::Dynamic(ref f) => cb(Cow::Owned(f())),
            Signal::Nested(ref f) => f().sample_with(cb),
        }
    }
}

impl<T: Clone + 'static> Signal<T>
{
    /// Maps a signal with the provided function.
    pub fn map<F, R>(&self, f: F) -> Signal<R>
        where F: Fn(Cow<T>) -> R + 'static,
        R: Clone + 'static
    {
        let this = self.clone();
        Signal::from_fn(move || this.sample_with(&f))
    }

    /// Samples the value of this signal every time the trigger stream fires.
    pub fn snapshot<S, F, R>(&self, trigger: &Stream<S>, f: F) -> Stream<R>
        where F: Fn(Cow<T>, Cow<S>) -> R + 'static,
        S: Clone + 'static, R: Clone + 'static
    {
        let this = self.clone();
        trigger.map(move |b| this.sample_with(|a| f(a, b)))
    }
}

impl<T: Clone + 'static> Signal<Signal<T>>
{
    /// Creates a new signal that samples the inner value of a nested signal.
    pub fn switch(&self) -> Signal<T>
    {
        let this = self.clone();
        Signal::Nested(Rc::new(move || this.sample()))
    }
}

impl<T: Clone> From<T> for Signal<T>
{
    fn from(val: T) -> Self
    {
        Signal::Constant(val)
    }
}

impl<T: Clone> From<Arc<RwLock<T>>> for Signal<T>
{
    fn from(val: Arc<RwLock<T>>) -> Self
    {
        Signal::Shared(val, None)
    }
}

impl<T: fmt::Debug> fmt::Debug for Signal<T>
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
    {
        match *self
        {
            Signal::Constant(ref val) => write!(f, "Signal::Constant({:?})", val),
            Signal::Shared(ref val, ref r) => write!(f, "Signal::Shared({:?}, {:?})", val, r),
            Signal::Dynamic(ref rf) => write!(f, "Signal::Dynamic(Fn@{:p})", rf),
            Signal::Nested(ref rf) => write!(f, "Signal::Nested(Fn@{:p})", rf),
        }
    }
}
<|endoftext|>


<commit_before>use std::io::{self, Buffer, Reader, Writer, IoResult, BufferedStream, standard_error};
use std::mem;
use std::collections::BTreeMap;
use std::rand::{thread_rng, Rng};
use std::{u64, u16};
use std::num::{Int, FromPrimitive, ToPrimitive};
use url::Url;

#[cfg(test)]
use test::Bencher;

use nonce::Nonce;
use message::{WSMessage, WSHeader, WS_MASK, WS_LEN, WS_LEN16, WS_LEN64, WS_OPTERM};
use stream::NetworkStream;

pub struct WebSocket<S = NetworkStream> {
    stream: Option<BufferedStream<S>>,
    pub url: Url,
    hostname: String,
    use_ssl: bool,
}

impl WebSocket {
    pub fn new(url: Url) -> WebSocket {
        let use_ssl = url.scheme[] == "wss";

        let port = match url.port() {
            Some(p) => p,
            None if use_ssl => 443,
            _ => 80
        };

        WebSocket {
            stream: None,
            hostname: format!("{}:{}", url.serialize_host().unwrap(), port),
            url: url,
            use_ssl: use_ssl,
        }
    }

    fn try_connect(&mut self) -> IoResult<()> {
        self.stream = Some(BufferedStream::new(try!(NetworkStream::connect(self.hostname[], self.use_ssl))));
        Ok(())
    }

    fn write_request(&mut self, nonce: &str) -> IoResult<()> {
        let s = match self.stream { Some(ref mut s) => s, None => return Err(standard_error(io::IoErrorKind::NotConnected)) };

        try!(s.write(format!("GET {} HTTP/1.1\r\n", self.url.serialize_path().unwrap_or("/".to_string())).as_bytes()));
        try!(s.write(format!("Host: {}\r\n", self.url.host().unwrap()).as_bytes()));
        try!(s.write(format!("Origin: {}\r\n", self.url.serialize_no_fragment()).as_bytes()));
        try!(s.write(format!("Sec-WebSocket-Key: {}\r\n", nonce).as_bytes()));

        try!(s.write(b"Upgrade: websocket\r\n"));
        try!(s.write(b"Connection: Upgrade\r\n"));
        try!(s.write(b"Sec-WebSocket-Protocol: chat, superchat\r\n"));
        try!(s.write(b"Sec-WebSocket-Version: 13\r\n"));
        try!(s.write(b"\r\n"));

        s.flush()
    }

    fn read_response(&mut self, nonce: &str) -> IoResult<()> {
        let spaces: &[_] = &[' ', '\t', '\r', '\n'];
        let s = match self.stream { Some(ref mut s) => s, None => return Err(standard_error(io::IoErrorKind::NotConnected)) };
        let status = try!(s.read_line())[].splitn(2, ' ').nth(1).and_then(|s| s.parse::<uint>());

        match status {
            Some(101) => (),
            _ => return Err(standard_error(io::InvalidInput))
        }

        let headers = s.lines().map(|r| r.unwrap_or("\r\n".to_string())) .take_while(|l| l[] != "\r\n")
            .map(|s| s[].splitn(1, ':').map(|s| s.trim_matches(spaces).to_string()).collect::<Vec<String>>())
            .map(|p| (p[0].to_string(), p[1].to_string()))
            .collect::<BTreeMap<String, String>>();

        try!(s.flush());

        let response = headers.get("Sec-WebSocket-Accept");
        match response {
            Some(r) if nonce == r[] => (),
            _ => return Err(standard_error(io::InvalidInput))
        }

        Ok(())
    }

    pub fn connect(&mut self) -> IoResult<()> {
        let mut nonce = Nonce::new();

        try!(self.try_connect());
        try!(self.write_request(nonce[]));

        nonce = nonce.encode();
        try!(self.read_response(nonce[]));

        Ok(())
    }

    fn read_header(&mut self) -> IoResult<WSHeader> {
        // XXX: this is a bug, WSHeader should accept u16
        Ok(WSHeader::from_bits_truncate(try!(self.read_be_u16())))
    }

    fn read_length(&mut self, header: &WSHeader) -> IoResult<uint> {
        let wslen = *header & WS_LEN;
        if wslen == WS_LEN16 { self.read_be_u16().map(|v| v as uint) }
        else if wslen == WS_LEN64 { self.read_be_u64().map(|v| v as uint) }
        else { Ok(wslen.bits() as uint) }
    }

    pub fn read_message(&mut self) -> IoResult<WSMessage> {
        let header = try!(self.read_header());
        let mut len = try!(self.read_length(&header));

        let mask = if header.contains(WS_MASK) {
            Some(try!(self.read_be_u32()))
        } else {
            None
        };

        // If this is the terminating frame (close command),
        // first two bytes of data MUST BE u16 status code
        let mut status = if header.contains(WS_OPTERM) {
            // compensate length of status code
            len = len - 2;
            Some(try!(self.read_be_u16()))
        } else {
            None
        };

        let mut data = try!(self.read_exact(len));

        // If we have mask, decrypt data
        if let Some(mut m) = mask {
            // decrypt status if present
            if let Some(s) = status {
                status = Some(s ^ (m & 0xffff) as u16);
                // compensate the usage of two mask bytes
                m = m.rotate_right(16);
            }
            data = WebSocket::mask_data(data[], m);
        }

        Ok(WSMessage { header: header, data: data, status: status.and_then(FromPrimitive::from_u16) })
    }

    fn mask_data(data: &[u8], mask: u32) -> Vec<u8> {
        data.iter().enumerate().map(|(i, b)| *b ^ (mask >> ((i % 4) << 3) & 0xff) as u8).collect::<Vec<u8>>()
    }

    pub fn send_message(&mut self, msg: &WSMessage) -> IoResult<()> {
        let mut len = msg.data.len();
        let mut hdr = msg.header - WS_LEN;

        // If we have status set, the data length is increased by status size
        if msg.status.is_some() {
            len = len + 2;
        }

        // Encode and send length along with header
        if len < u16::MAX as uint {
            hdr = hdr | WSHeader::from_bits_truncate(len as u16);
            try!(self.write_be_u16(hdr.bits()));

        } else if len < u64::MAX as uint {
            hdr = hdr | WS_LEN16;
            try!(self.write_be_u16(hdr.bits()));
            try!(self.write_be_u16(len as u16));

        } else {
            hdr = hdr | WS_LEN64;
            try!(self.write_be_u16(hdr.bits()));
            try!(self.write_be_u64(len as u64));
        }

        // If user required masking, encrypt all data
        if hdr.contains(WS_MASK) {
            // Generate and send random mask
            let mut mask = thread_rng().gen::<u32>();
            try!(self.write_be_u32(mask));

            // Encrypt status code if present
            if let Some(status) = msg.status {
                try!(self.write_be_u16(status.to_u16().unwrap() ^ (mask & 0xffff) as u16));
                // compensate for mask already used for status encryption
                mask = mask.rotate_right(16);
            }

            try!(self.write(WebSocket::mask_data(msg.data[], mask)[]));
        } else {
            // Send status code if present
            if let Some(status) = msg.status {
                try!(self.write_be_u16(status.to_u16().unwrap()));
            }
            try!(self.write(msg.data[]));
        }

        self.flush()
    }

    pub fn iter(&mut self) -> WSMessages {
        WSMessages { sock: self }
    }
}

impl Reader for WebSocket {
    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
        match self.stream {
            Some(ref mut s) => s.read(buf),
            None => Err(standard_error(io::IoErrorKind::NotConnected))
        }
    }
}

impl Writer for WebSocket {
    fn write(&mut self, buf: &[u8]) -> IoResult<()> {
        match self.stream {
            Some(ref mut s) => s.write(buf),
            None => Err(standard_error(io::IoErrorKind::NotConnected))
        }
    }

    fn flush(&mut self) -> IoResult<()> {
        match self.stream {
            Some(ref mut s) => s.flush(),
            None => Err(standard_error(io::IoErrorKind::NotConnected))
        }
    }
}

impl Buffer for WebSocket {
    fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
        match self.stream {
            Some(ref mut s) => s.fill_buf(),
            None => Err(standard_error(io::IoErrorKind::NotConnected))
        }
    }

    fn consume(&mut self, amt: uint) {
        match self.stream {
            Some(ref mut s) => s.consume(amt),
            None => ()
        }
    }
}

pub struct WSMessages<'a> {
    sock: &'a mut WebSocket
}

pub struct WSDefragMessages<'a> {
    underlying: &'a mut WSMessages<'a>,
    buffer: WSMessage
}

impl<'a> WSMessages<'a> {
    pub fn defrag(&'a mut self) -> WSDefragMessages<'a> {
        WSDefragMessages{ underlying: self, buffer: WSMessage{ header: WSHeader::empty(), data: Vec::new(), status: None } }
    }
}

impl<'a> Iterator for WSMessages<'a> {
    type Item = WSMessage;
    fn next(&mut self) -> Option<WSMessage> {
        self.sock.read_message().ok()
    }
}

impl<'a> WSDefragMessages<'a> {
    fn popbuf(&mut self) -> Option<WSMessage> {
        if self.buffer.data.is_empty() {
            None
        } else {
            let mut buf = WSMessage{ header: WSHeader::empty(), data: Vec::new(), status: None };
            mem::swap(&mut self.buffer, &mut buf);
            Some(buf)
        }
    }

    fn swapbuf(&mut self, msg: &mut WSMessage) {
        mem::swap(&mut self.buffer, msg);
    }
}

impl<'a> Iterator for WSDefragMessages<'a> {
    type Item = WSMessage;
    fn next(&mut self) -> Option<WSMessage> {
        loop {
            match self.underlying.next() {
                None => return self.popbuf(),
                Some(mut msg) => {
                    if msg.is_whole() {
                        return Some(msg);
                    } else if msg.is_first() {
                        self.swapbuf(&mut msg);
                    } else if msg.is_more() {
                        self.buffer.push(msg);
                    } else if msg.is_last() {
                        self.buffer.push(msg);
                        return self.popbuf().map(|v| v.last());
                    }
                }
            }
        }
    }
}

#[bench]
#[allow(dead_code, unused_variables, unused_imports)]
fn test_connect(b: &mut Bencher) {
    use message::WSStatusCode;
    use rustc_serialize::json::ToJson;

    let url = Url::parse("ws://echo.websocket.org").unwrap();
    let mut ws = WebSocket::new(url);
    ws.connect().unwrap();

    let msg = WSMessage::text("Hello, World!"); //.mask();
    b.bytes = msg.data.len() as u64;

    let msg1 = WSMessage::text("Hello,").first();
    let msg2 = WSMessage::text(" world!").last();

    //b.bench_n(1, |b| {
        //b.iter(|| {
            println!("sent: {} {}", msg1, msg1.to_string());
            ws.send_message(&msg1).unwrap();
            println!("sent: {} {}", msg2, msg2.to_string());
            ws.send_message(&msg2).unwrap();

            let reply = ws.iter().defrag().next().unwrap();
            println!("received: {} {}", reply, reply.to_string());
        //})
    //});

    //for msg in ws.iter() {
        //println!("{}", msg.to_string());
    //}
}
<commit_msg>remove trash test code<commit_after>use std::io::{self, Buffer, Reader, Writer, IoResult, BufferedStream, standard_error};
use std::mem;
use std::collections::BTreeMap;
use std::rand::{thread_rng, Rng};
use std::{u64, u16};
use std::num::{Int, FromPrimitive, ToPrimitive};
use url::Url;

#[cfg(test)]
use test::Bencher;

use nonce::Nonce;
use message::{WSMessage, WSHeader, WS_MASK, WS_LEN, WS_LEN16, WS_LEN64, WS_OPTERM};
use stream::NetworkStream;

pub struct WebSocket<S = NetworkStream> {
    stream: Option<BufferedStream<S>>,
    pub url: Url,
    hostname: String,
    use_ssl: bool,
}

impl WebSocket {
    pub fn new(url: Url) -> WebSocket {
        let use_ssl = url.scheme[] == "wss";

        let port = match url.port() {
            Some(p) => p,
            None if use_ssl => 443,
            _ => 80
        };

        WebSocket {
            stream: None,
            hostname: format!("{}:{}", url.serialize_host().unwrap(), port),
            url: url,
            use_ssl: use_ssl,
        }
    }

    fn try_connect(&mut self) -> IoResult<()> {
        self.stream = Some(BufferedStream::new(try!(NetworkStream::connect(self.hostname[], self.use_ssl))));
        Ok(())
    }

    fn write_request(&mut self, nonce: &str) -> IoResult<()> {
        let s = match self.stream { Some(ref mut s) => s, None => return Err(standard_error(io::IoErrorKind::NotConnected)) };

        try!(s.write(format!("GET {} HTTP/1.1\r\n", self.url.serialize_path().unwrap_or("/".to_string())).as_bytes()));
        try!(s.write(format!("Host: {}\r\n", self.url.host().unwrap()).as_bytes()));
        try!(s.write(format!("Origin: {}\r\n", self.url.serialize_no_fragment()).as_bytes()));
        try!(s.write(format!("Sec-WebSocket-Key: {}\r\n", nonce).as_bytes()));

        try!(s.write(b"Upgrade: websocket\r\n"));
        try!(s.write(b"Connection: Upgrade\r\n"));
        try!(s.write(b"Sec-WebSocket-Protocol: chat, superchat\r\n"));
        try!(s.write(b"Sec-WebSocket-Version: 13\r\n"));
        try!(s.write(b"\r\n"));

        s.flush()
    }

    fn read_response(&mut self, nonce: &str) -> IoResult<()> {
        let spaces: &[_] = &[' ', '\t', '\r', '\n'];
        let s = match self.stream { Some(ref mut s) => s, None => return Err(standard_error(io::IoErrorKind::NotConnected)) };
        let status = try!(s.read_line())[].splitn(2, ' ').nth(1).and_then(|s| s.parse::<uint>());

        match status {
            Some(101) => (),
            _ => return Err(standard_error(io::InvalidInput))
        }

        let headers = s.lines().map(|r| r.unwrap_or("\r\n".to_string())) .take_while(|l| l[] != "\r\n")
            .map(|s| s[].splitn(1, ':').map(|s| s.trim_matches(spaces).to_string()).collect::<Vec<String>>())
            .map(|p| (p[0].to_string(), p[1].to_string()))
            .collect::<BTreeMap<String, String>>();

        try!(s.flush());

        let response = headers.get("Sec-WebSocket-Accept");
        match response {
            Some(r) if nonce == r[] => (),
            _ => return Err(standard_error(io::InvalidInput))
        }

        Ok(())
    }

    pub fn connect(&mut self) -> IoResult<()> {
        let mut nonce = Nonce::new();

        try!(self.try_connect());
        try!(self.write_request(nonce[]));

        nonce = nonce.encode();
        try!(self.read_response(nonce[]));

        Ok(())
    }

    fn read_header(&mut self) -> IoResult<WSHeader> {
        // XXX: this is a bug, WSHeader should accept u16
        Ok(WSHeader::from_bits_truncate(try!(self.read_be_u16())))
    }

    fn read_length(&mut self, header: &WSHeader) -> IoResult<uint> {
        let wslen = *header & WS_LEN;
        if wslen == WS_LEN16 { self.read_be_u16().map(|v| v as uint) }
        else if wslen == WS_LEN64 { self.read_be_u64().map(|v| v as uint) }
        else { Ok(wslen.bits() as uint) }
    }

    pub fn read_message(&mut self) -> IoResult<WSMessage> {
        let header = try!(self.read_header());
        let mut len = try!(self.read_length(&header));

        let mask = if header.contains(WS_MASK) {
            Some(try!(self.read_be_u32()))
        } else {
            None
        };

        // If this is the terminating frame (close command),
        // first two bytes of data MUST BE u16 status code
        let mut status = if header.contains(WS_OPTERM) {
            // compensate length of status code
            len = len - 2;
            Some(try!(self.read_be_u16()))
        } else {
            None
        };

        let mut data = try!(self.read_exact(len));

        // If we have mask, decrypt data
        if let Some(mut m) = mask {
            // decrypt status if present
            if let Some(s) = status {
                status = Some(s ^ (m & 0xffff) as u16);
                // compensate the usage of two mask bytes
                m = m.rotate_right(16);
            }
            data = WebSocket::mask_data(data[], m);
        }

        Ok(WSMessage { header: header, data: data, status: status.and_then(FromPrimitive::from_u16) })
    }

    fn mask_data(data: &[u8], mask: u32) -> Vec<u8> {
        data.iter().enumerate().map(|(i, b)| *b ^ (mask >> ((i % 4) << 3) & 0xff) as u8).collect::<Vec<u8>>()
    }

    pub fn send_message(&mut self, msg: &WSMessage) -> IoResult<()> {
        let mut len = msg.data.len();
        let mut hdr = msg.header - WS_LEN;

        // If we have status set, the data length is increased by status size
        if msg.status.is_some() {
            len = len + 2;
        }

        // Encode and send length along with header
        if len < u16::MAX as uint {
            hdr = hdr | WSHeader::from_bits_truncate(len as u16);
            try!(self.write_be_u16(hdr.bits()));

        } else if len < u64::MAX as uint {
            hdr = hdr | WS_LEN16;
            try!(self.write_be_u16(hdr.bits()));
            try!(self.write_be_u16(len as u16));

        } else {
            hdr = hdr | WS_LEN64;
            try!(self.write_be_u16(hdr.bits()));
            try!(self.write_be_u64(len as u64));
        }

        // If user required masking, encrypt all data
        if hdr.contains(WS_MASK) {
            // Generate and send random mask
            let mut mask = thread_rng().gen::<u32>();
            try!(self.write_be_u32(mask));

            // Encrypt status code if present
            if let Some(status) = msg.status {
                try!(self.write_be_u16(status.to_u16().unwrap() ^ (mask & 0xffff) as u16));
                // compensate for mask already used for status encryption
                mask = mask.rotate_right(16);
            }

            try!(self.write(WebSocket::mask_data(msg.data[], mask)[]));
        } else {
            // Send status code if present
            if let Some(status) = msg.status {
                try!(self.write_be_u16(status.to_u16().unwrap()));
            }
            try!(self.write(msg.data[]));
        }

        self.flush()
    }

    pub fn iter(&mut self) -> WSMessages {
        WSMessages { sock: self }
    }
}

impl Reader for WebSocket {
    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
        match self.stream {
            Some(ref mut s) => s.read(buf),
            None => Err(standard_error(io::IoErrorKind::NotConnected))
        }
    }
}

impl Writer for WebSocket {
    fn write(&mut self, buf: &[u8]) -> IoResult<()> {
        match self.stream {
            Some(ref mut s) => s.write(buf),
            None => Err(standard_error(io::IoErrorKind::NotConnected))
        }
    }

    fn flush(&mut self) -> IoResult<()> {
        match self.stream {
            Some(ref mut s) => s.flush(),
            None => Err(standard_error(io::IoErrorKind::NotConnected))
        }
    }
}

impl Buffer for WebSocket {
    fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
        match self.stream {
            Some(ref mut s) => s.fill_buf(),
            None => Err(standard_error(io::IoErrorKind::NotConnected))
        }
    }

    fn consume(&mut self, amt: uint) {
        match self.stream {
            Some(ref mut s) => s.consume(amt),
            None => ()
        }
    }
}

pub struct WSMessages<'a> {
    sock: &'a mut WebSocket
}

pub struct WSDefragMessages<'a> {
    underlying: &'a mut WSMessages<'a>,
    buffer: WSMessage
}

impl<'a> WSMessages<'a> {
    pub fn defrag(&'a mut self) -> WSDefragMessages<'a> {
        WSDefragMessages{ underlying: self, buffer: WSMessage{ header: WSHeader::empty(), data: Vec::new(), status: None } }
    }
}

impl<'a> Iterator for WSMessages<'a> {
    type Item = WSMessage;
    fn next(&mut self) -> Option<WSMessage> {
        self.sock.read_message().ok()
    }
}

impl<'a> WSDefragMessages<'a> {
    fn popbuf(&mut self) -> Option<WSMessage> {
        if self.buffer.data.is_empty() {
            None
        } else {
            let mut buf = WSMessage{ header: WSHeader::empty(), data: Vec::new(), status: None };
            mem::swap(&mut self.buffer, &mut buf);
            Some(buf)
        }
    }

    fn swapbuf(&mut self, msg: &mut WSMessage) {
        mem::swap(&mut self.buffer, msg);
    }
}

impl<'a> Iterator for WSDefragMessages<'a> {
    type Item = WSMessage;
    fn next(&mut self) -> Option<WSMessage> {
        loop {
            match self.underlying.next() {
                None => return self.popbuf(),
                Some(mut msg) => {
                    if msg.is_whole() {
                        return Some(msg);
                    } else if msg.is_first() {
                        self.swapbuf(&mut msg);
                    } else if msg.is_more() {
                        self.buffer.push(msg);
                    } else if msg.is_last() {
                        self.buffer.push(msg);
                        return self.popbuf().map(|v| v.last());
                    }
                }
            }
        }
    }
}

<|endoftext|>