<commit_before>struct A;          // Concrete type `A`.
struct S(A);       // Concrete type `S`.
struct SGen<T>(T); // Generic type `SGen`.

// These functions all take ownership of the variable passed into
// them and immediately go out of scope freeing the variable.

// Define a function `reg_fn` that takes an argument `s` of type `S`.
// This has no `<T>` so this is not a generic function.
fn reg_fn(s: S) {}

// Define a function `gen_spec_t` that takes an argument `s` of type `SGen<T>`
// that has been explicitly given the type parameter `A`.
// This contains `<A>` but is not preceded by `<A>`, so it is not generic.
fn gen_spec_t(s: SGen<A>) {}

// Define a function `gen_spec_i32` that takes an argument `s` of type `SGen<i32>`
// that has been explicitly given the type parameter `i32`.
// This function is also not generic.
fn gen_spec_i32(s: SGen<i32>) {}

// Define a function `generic` that takes an argument `s` of type `SGen<T>`.
// Because `SGen<T>` is preceded by `<T>`, this function is generic over `T`.
fn generic<T>(s: SGen<T>) {}

fn main() {
    // Using the non-generic functions
    reg_fn(S(A));          // Concrete type.
    gen_spec_t(SGen(A));   // Implicitly specified type parameter `A`.
    gen_spec_i32(SGen(6)); // Implicitly specified type parameter `i32`.

    // Explicitly specified type parameter `char` to `generic()`.
    generic::<char>(SGen('a'));

    // Implicitly specified type parameter `char` to `generic()`.
    generic(SGen('c'));
}

<commit_msg>Reworded line 14 in fn.rs<commit_after>struct A;          // Concrete type `A`.
struct S(A);       // Concrete type `S`.
struct SGen<T>(T); // Generic type `SGen`.

// These functions all take ownership of the variable passed into
// them and immediately go out of scope freeing the variable.

// Define a function `reg_fn` that takes an argument `s` of type `S`.
// This has no `<T>` so this is not a generic function.
fn reg_fn(s: S) {}

// Define a function `gen_spec_t` that takes an argument `s` of type `SGen<T>`
// that has been explicitly given the type parameter `A`. Because A has not
// been specified as a generic type parameter for gen_spec_t, it is not generic.
fn gen_spec_t(s: SGen<A>) {}

// Define a function `gen_spec_i32` that takes an argument `s` of type `SGen<i32>`
// that has been explicitly given the type parameter `i32`.
// This function is also not generic.
fn gen_spec_i32(s: SGen<i32>) {}

// Define a function `generic` that takes an argument `s` of type `SGen<T>`.
// Because `SGen<T>` is preceded by `<T>`, this function is generic over `T`.
fn generic<T>(s: SGen<T>) {}

fn main() {
    // Using the non-generic functions
    reg_fn(S(A));          // Concrete type.
    gen_spec_t(SGen(A));   // Implicitly specified type parameter `A`.
    gen_spec_i32(SGen(6)); // Implicitly specified type parameter `i32`.

    // Explicitly specified type parameter `char` to `generic()`.
    generic::<char>(SGen('a'));

    // Implicitly specified type parameter `char` to `generic()`.
    generic(SGen('c'));
}

<|endoftext|>


<commit_before>fn main() {
    let mystr1: &'static str = "This is a readonly string";

    for c in mystr1.chars().rev() {
        print!("{}", c);
    }

    println!("");

    let mut mystr2 = String::new();
    for c in mystr1.chars() {
        mystr2.push(c);
    }

    println!("{}", mystr2);
}<commit_msg>updated string example<commit_after>fn main() {
    let mystr1: &'static str = "This is a readonly string";

    for c in mystr1.chars().rev() {
        print!("{}", c);
    }

    println!("");

    let mut mystr2 = String::new();
    for c in mystr1.chars() {
        mystr2.push(c);
    }

    println!("{}", mystr2);

    mystr2 = "Hello World".to_string();

    println!("{}", mystr2);

    let num: u32 = 12;

    mystr2 = num.to_string();

    println!("{}", mystr2);
}<|endoftext|>


<commit_before>extern crate image;
extern crate itertools;
extern crate rand;
extern crate rayon;
extern crate regex;
extern crate walkdir;

pub struct CifarDataset {
    pub labels: Vec<String>,
    pub train_count: usize,
    pub test_count: usize,
    pub train_dataset: Vec<super::CifarImage>,
    pub test_dataset: Vec<super::CifarImage>,
}

struct CifarFilePaths {
    meta_data_paths: Vec<::std::path::PathBuf>,
    train_data_paths: Vec<::std::path::PathBuf>,
    test_data_paths: Vec<::std::path::PathBuf>,
}

impl CifarDataset {
    pub fn new<P: AsRef<::std::path::Path>>(path: P) -> Result<Self, String> {
        use std::thread::spawn;
        let CifarFilePaths {
            meta_data_paths,
            train_data_paths,
            test_data_paths,
        } = CifarDataset::get_file_paths(path)?;
        let meta_data_handle = spawn(move || CifarDataset::get_meta_data(&meta_data_paths));
        let train_images_handle = spawn(move || {
            CifarDataset::get_images(CifarDataset::get_byte_datas(&train_data_paths)?)
        });
        let test_images_handle = spawn(move || {
            CifarDataset::get_images(CifarDataset::get_byte_datas(&test_data_paths)?)
        });
        let labels = CifarDataset::for_cifardataset_join_thread(meta_data_handle)?;
        let train_images = CifarDataset::for_cifardataset_join_thread(train_images_handle)?;
        let test_images = CifarDataset::for_cifardataset_join_thread(test_images_handle)?;
        let cifar_dataset = CifarDataset {
            labels: labels,
            train_count: train_images.len() as usize,
            train_dataset: train_images,
            test_count: test_images.len() as usize,
            test_dataset: test_images,
        };
        Ok(cifar_dataset)
    }
    fn for_cifardataset_join_thread<T>(
        p: ::std::thread::JoinHandle<Result<T, ::std::io::Error>>,
    ) -> Result<T, String> {
        p.join()
            .map(|content| content.map_err(|err| err.to_string()))
            .map_err(|_| "thread panicked".to_string())?
    }
    fn get_file_paths<P: AsRef<::std::path::Path>>(path: P) -> Result<CifarFilePaths, String> {
        use self::regex::Regex;
        let paths = &walkdir::WalkDir::new(path)
            .into_iter()
            .flat_map(|x| x.map(|x| x.path().to_path_buf()))
            .filter(|x| x.is_file())
            .collect::<Vec<::std::path::PathBuf>>();
        let train_data_path_re = Regex::new("data_batch_[1-5].bin").map_err(|err| err.to_string())?;
        let test_data_path_re = Regex::new("test_batch.bin").map_err(|err| err.to_string())?;
        let cifar_file_paths = CifarFilePaths {
            meta_data_paths: CifarDataset::get_meta_data_paths(paths)?,
            train_data_paths: CifarDataset::get_paths_regex(paths, &train_data_path_re)?,
            test_data_paths: CifarDataset::get_paths_regex(paths, &test_data_path_re)?,
        };
        Ok(cifar_file_paths)
    }
    fn get_meta_data_paths(
        paths: &[::std::path::PathBuf],
    ) -> Result<Vec<::std::path::PathBuf>, String> {
        use self::rayon::prelude::*;
        use std::path::{Path, PathBuf};
        let meta_data_file_name = Path::new("batches.meta.txt");
        let fpaths: Vec<PathBuf> = paths
            .into_par_iter()
            .filter(|path| {
                path.file_name()
                    .map(|file_name| file_name == meta_data_file_name)
                    .unwrap_or(false)
            })
            .cloned()
            .collect();
        if fpaths.is_empty() {
            Err("Can't Find Meta Data Files!!".to_string())
        } else {
            Ok(fpaths)
        }
    }
    fn get_paths_regex(
        paths: &[::std::path::PathBuf],
        re: &self::regex::Regex,
    ) -> Result<Vec<::std::path::PathBuf>, String> {
        use self::rayon::prelude::*;
        use std::path::PathBuf;
        let fpaths: Vec<PathBuf> = paths
            .par_iter()
            .filter(|path| {
                path.file_name()
                    .map(|file_name| {
                        let file_name = file_name.to_string_lossy();
                        re.is_match(file_name.as_ref())
                    })
                    .unwrap_or(false)
            })
            .cloned()
            .collect();
        if fpaths.is_empty() {
            Err("Can't Find Train Data Files!!".to_string())
        } else {
            Ok(fpaths)
        }
    }
    fn get_meta_data(paths: &[::std::path::PathBuf]) -> Result<Vec<String>, ::std::io::Error> {
        use std::io::Read;
        use self::itertools::Itertools;
        paths
            .iter()
            .map(|meta_path| -> Result<String, ::std::io::Error> {
                ::std::fs::File::open(meta_path).and_then(|mut file| {
                    let mut contents = String::new();
                    file.read_to_string(&mut contents).map(|_| contents)
                })
            })
            .map(|lines| -> Result<Vec<String>, ::std::io::Error> {
                lines.map(|l| -> Vec<String> {
                    l.lines()
                        .filter(|x| !x.is_empty())
                        .map(|x| x.into())
                        .collect_vec()
                })
            })
            .collect::<Result<Vec<Vec<String>>, ::std::io::Error>>()
            .map(|v| v.concat())
    }
    fn get_byte_datas(paths: &[::std::path::PathBuf]) -> Result<Vec<Vec<u8>>, ::std::io::Error> {
        use std::io::{BufReader, Read};
        use self::itertools::Itertools;
        use self::rayon::prelude::*;
        paths
            .par_iter()
            .map(|file_path| -> Result<Vec<u8>, ::std::io::Error> {
                ::std::fs::File::open(file_path).and_then(|file| {
                    let mut byte_data: Vec<u8> = Vec::new();
                    BufReader::new(file)
                        .read_to_end(&mut byte_data)
                        .map(|_| byte_data)
                })
            })
            .map(|byte_data| -> Result<Vec<Vec<u8>>, ::std::io::Error> {
                byte_data.map(|b| -> Vec<Vec<u8>> {
                    b.chunks(3073)
                        .map(|byte_img| -> Vec<u8> { byte_img.to_vec() })
                        .collect_vec()
                })
            })
            .collect::<Result<Vec<Vec<Vec<u8>>>, ::std::io::Error>>()
            .map(|v| v.concat())
    }
    fn get_images(byte_datas: Vec<Vec<u8>>) -> Result<Vec<super::CifarImage>, ::std::io::Error> {
        use self::rayon::prelude::*;
        byte_datas
            .into_par_iter()
            .map(|byte_img| {
                use super::CifarImageTrait;
                super::CifarImage::new(&byte_img)
            })
            .collect::<Result<Vec<super::CifarImage>, ::std::io::Error>>()
    }
    fn for_test_get_image_from_train_save(&self, rng: &mut rand::ThreadRng) -> Result<(), String> {
        use self::rand::Rng;
        let fout = &mut ::std::fs::File::create(&::std::path::Path::new("train.jpeg"))
            .map_err(|err| err.to_string())?;
        let nth: &usize = &rng.gen_range(0, self.train_count);
        let data: &super::CifarImage = &self.train_dataset[*nth];
        data.image
            .resize(500, 500, image::FilterType::Lanczos3)
            .save(fout, image::JPEG)
            .map_err(|err| err.to_string())?;
        println!("From Train No.{} {}", nth, self.labels[data.label as usize]);
        Ok(())
    }
    fn for_test_get_image_from_test_save(&self, rng: &mut rand::ThreadRng) -> Result<(), String> {
        use self::rand::Rng;
        let fout = &mut ::std::fs::File::create(&::std::path::Path::new("test.jpeg"))
            .map_err(|err| err.to_string())?;
        let nth: &usize = &rng.gen_range(0, self.test_count);
        let data: &super::CifarImage = &self.test_dataset[*nth];
        data.image
            .resize(500, 500, image::FilterType::Lanczos3)
            .save(fout, image::JPEG)
            .map_err(|err| err.to_string())?;
        println!("From test No.{} {}", nth, self.labels[data.label as usize]);
        Ok(())
    }
    pub fn info_output(&self) {
        println!("{:?}", self.labels);
        println!("Test Data Count: {}", self.test_count);
        println!("Train Data Count:{}", self.train_count);
    }
    pub fn test_output(&self, rng: &mut rand::ThreadRng) -> Result<(), String> {
        self.for_test_get_image_from_train_save(rng)?;
        self.for_test_get_image_from_test_save(rng)?;
        Ok(())
    }
}
<commit_msg>remove functions<commit_after>extern crate image;
extern crate itertools;
extern crate rand;
extern crate rayon;
extern crate regex;
extern crate walkdir;

pub struct CifarDataset {
    pub labels: Vec<String>,
    pub train_count: usize,
    pub test_count: usize,
    pub train_dataset: Vec<super::CifarImage>,
    pub test_dataset: Vec<super::CifarImage>,
}

struct CifarFilePaths {
    meta_data_paths: Vec<::std::path::PathBuf>,
    train_data_paths: Vec<::std::path::PathBuf>,
    test_data_paths: Vec<::std::path::PathBuf>,
}

impl CifarDataset {
    pub fn new<P: AsRef<::std::path::Path>>(path: P) -> Result<Self, String> {
        use std::thread::spawn;
        let CifarFilePaths {
            meta_data_paths,
            train_data_paths,
            test_data_paths,
        } = CifarDataset::get_file_paths(path)?;
        let meta_data_handle = spawn(move || CifarDataset::get_meta_data(&meta_data_paths));
        let train_images_handle = spawn(move || {
            CifarDataset::get_images(CifarDataset::get_byte_datas(&train_data_paths)?)
        });
        let test_images_handle = spawn(move || {
            CifarDataset::get_images(CifarDataset::get_byte_datas(&test_data_paths)?)
        });
        let labels = CifarDataset::for_cifardataset_join_thread(meta_data_handle)?;
        let train_images = CifarDataset::for_cifardataset_join_thread(train_images_handle)?;
        let test_images = CifarDataset::for_cifardataset_join_thread(test_images_handle)?;
        let cifar_dataset = CifarDataset {
            labels: labels,
            train_count: train_images.len() as usize,
            train_dataset: train_images,
            test_count: test_images.len() as usize,
            test_dataset: test_images,
        };
        Ok(cifar_dataset)
    }
    fn for_cifardataset_join_thread<T>(
        p: ::std::thread::JoinHandle<Result<T, ::std::io::Error>>,
    ) -> Result<T, String> {
        p.join()
            .map(|content| content.map_err(|err| err.to_string()))
            .map_err(|_| "thread panicked".to_string())?
    }
    fn get_file_paths<P: AsRef<::std::path::Path>>(path: P) -> Result<CifarFilePaths, String> {
        use self::regex::Regex;
        let paths = &walkdir::WalkDir::new(path)
            .into_iter()
            .flat_map(|x| x.map(|x| x.path().to_path_buf()))
            .filter(|x| x.is_file())
            .collect::<Vec<::std::path::PathBuf>>();
        let train_data_path_re = Regex::new("data_batch_[1-5].bin").map_err(|err| err.to_string())?;
        let test_data_path_re = Regex::new("test_batch.bin").map_err(|err| err.to_string())?;
        let cifar_file_paths = CifarFilePaths {
            meta_data_paths: CifarDataset::get_meta_data_paths(paths)?,
            train_data_paths: CifarDataset::get_paths_regex(paths, &train_data_path_re)?,
            test_data_paths: CifarDataset::get_paths_regex(paths, &test_data_path_re)?,
        };
        Ok(cifar_file_paths)
    }
    fn get_meta_data_paths(
        paths: &[::std::path::PathBuf],
    ) -> Result<Vec<::std::path::PathBuf>, String> {
        use self::rayon::prelude::*;
        use std::path::{Path, PathBuf};
        let meta_data_file_name = Path::new("batches.meta.txt");
        let fpaths: Vec<PathBuf> = paths
            .into_par_iter()
            .filter(|path| {
                path.file_name()
                    .map(|file_name| file_name == meta_data_file_name)
                    .unwrap_or(false)
            })
            .cloned()
            .collect();
        if fpaths.is_empty() {
            Err("Can't Find Meta Data Files!!".to_string())
        } else {
            Ok(fpaths)
        }
    }
    fn get_paths_regex(
        paths: &[::std::path::PathBuf],
        re: &self::regex::Regex,
    ) -> Result<Vec<::std::path::PathBuf>, String> {
        use self::rayon::prelude::*;
        use std::path::PathBuf;
        let fpaths: Vec<PathBuf> = paths
            .par_iter()
            .filter(|path| {
                path.file_name()
                    .map(|file_name| {
                        let file_name = file_name.to_string_lossy();
                        re.is_match(file_name.as_ref())
                    })
                    .unwrap_or(false)
            })
            .cloned()
            .collect();
        if fpaths.is_empty() {
            Err("Can't Find Train Data Files!!".to_string())
        } else {
            Ok(fpaths)
        }
    }
    fn get_meta_data(paths: &[::std::path::PathBuf]) -> Result<Vec<String>, ::std::io::Error> {
        use std::io::Read;
        use self::itertools::Itertools;
        paths
            .iter()
            .map(|meta_path| -> Result<String, ::std::io::Error> {
                ::std::fs::File::open(meta_path).and_then(|mut file| {
                    let mut contents = String::new();
                    file.read_to_string(&mut contents).map(|_| contents)
                })
            })
            .map(|lines| -> Result<Vec<String>, ::std::io::Error> {
                lines.map(|l| -> Vec<String> {
                    l.lines()
                        .filter(|x| !x.is_empty())
                        .map(|x| x.into())
                        .collect_vec()
                })
            })
            .collect::<Result<Vec<Vec<String>>, ::std::io::Error>>()
            .map(|v| v.concat())
    }
    fn get_byte_datas(paths: &[::std::path::PathBuf]) -> Result<Vec<Vec<u8>>, ::std::io::Error> {
        use std::io::{BufReader, Read};
        use self::itertools::Itertools;
        use self::rayon::prelude::*;
        paths
            .par_iter()
            .map(|file_path| -> Result<Vec<u8>, ::std::io::Error> {
                ::std::fs::File::open(file_path).and_then(|file| {
                    let mut byte_data: Vec<u8> = Vec::new();
                    BufReader::new(file)
                        .read_to_end(&mut byte_data)
                        .map(|_| byte_data)
                })
            })
            .map(|byte_data| -> Result<Vec<Vec<u8>>, ::std::io::Error> {
                byte_data.map(|b| -> Vec<Vec<u8>> {
                    b.chunks(3073)
                        .map(|byte_img| -> Vec<u8> { byte_img.to_vec() })
                        .collect_vec()
                })
            })
            .collect::<Result<Vec<Vec<Vec<u8>>>, ::std::io::Error>>()
            .map(|v| v.concat())
    }
    fn get_images(byte_datas: Vec<Vec<u8>>) -> Result<Vec<super::CifarImage>, ::std::io::Error> {
        use self::rayon::prelude::*;
        byte_datas
            .into_par_iter()
            .map(|byte_img| {
                use super::CifarImageTrait;
                super::CifarImage::new(&byte_img)
            })
            .collect::<Result<Vec<super::CifarImage>, ::std::io::Error>>()
    }
}
<|endoftext|>


<commit_before>// (c) 2016-2017 Productize SPRL <joost@productize.be>

use std::fmt;
use std::result;
use std::str::FromStr;
use std::mem;
use std::slice::Iter;

use Result;
/// like Into trait but works from a ref avoiding consumption or expensive clone
pub trait IntoSexp {
    /// convert self into a Sexp
    fn into_sexp(&self) -> Sexp;
}

impl Into<Sexp> for Vec<Sexp> {
    fn into(self: Vec<Sexp>) -> Sexp {
        Sexp::List(self)
    }
}

impl Into<Sexp> for String {
    fn into(self: String) -> Sexp {
        Sexp::String(self)
    }
}

impl<'a> From<&'a str> for Sexp {
    fn from(t: &str) -> Sexp {
        Sexp::String(t.into())
    }
}

impl<'a> From<&'a String> for Sexp {
    fn from(t: &String) -> Sexp {
        Sexp::String(t.clone())
    }
}

impl Into<Sexp> for i64 {
    fn into(self: i64) -> Sexp {
        Sexp::String(format!("{}", self))
    }
}

impl Into<Sexp> for f64 {
    fn into(self: f64) -> Sexp {
        Sexp::String(format!("{}", self))
    }
}

impl<'a> From<(&'a str, Sexp)> for Sexp {
    fn from(kv: (&str, Sexp)) -> Sexp {
        let (name, value) = kv;
        let mut v = vec![];
        v.push(name.into());
        v.push(value);
        v.into()
    }
}

impl<'a, T: fmt::Display> From<(&'a str, &'a T)> for Sexp {
    fn from(kv: (&str, &T)) -> Sexp {
        let (name, value) = kv;
        let mut v = vec![];
        v.push(name.into());
        v.push(format!("{}", value).into());
        v.into()
    }
}

/// a symbolic-expression
/// Can be a string or a list or nothing
#[derive(Debug, Clone, PartialEq)]
pub enum Sexp {
    /// plain String symbolic-expression
    String(String),
    /// list symbolic-expression
    List(Vec<Sexp>),
    /// empty, trivial symbolic-expression
    Empty,
}

// Following the KiCad file formats specification chapter 4.4 - Identifiers and Strings:
// A string may not contain an actual newline or carriage return,
// but it may use an escape sequence to encode a // newline, such as \n.
// If a string has any of the following conditions, then it must be quoted
// with a leading and trailing double quote
// character, otherwise it is acceptable to not quote the string:
// 1. has one or more of the following 4 separator bytes: ASCII space,
// tab, '(', or ')'.
// 2. has one or more of the following bytes: '%', '{', or '}'.
// 3. has a length of zero bytes, and you need a place holder for the field,
//  then use "".
// 4. includes a byte of '-', and this byte is not in the first position of
// the string.
//

// Joost remark: kicad no longer seems to follow Rule 4.
// so we don't either

/// encode a string according to the guidelines given by Kicad
pub fn encode_string(s: &str) -> String {
    // fn rule_4(s:&str) -> bool {
    // s.contains('-') && s.len() > 1 && s.as_bytes()[0] != 45
    // }
    if s.contains('(') || s.contains(' ') || s.contains(')') || s.contains('\t') ||
       s.contains('{') || s.contains('}') || s.contains('}') || s.contains('%') ||
       s.is_empty()
    // || rule_4(s)
    {
        format!("\"{}\"", s)
    } else {
        String::from(s)
    }
}

impl Sexp {
    /// create an empty symbolic-expression
    #[deprecated(since="4.0.0", note="please use `Sexp::default()` instead")]
    pub fn new_empty() -> Sexp {
        Sexp::Empty
    }

    /// create a String type symbolic-expression
    #[deprecated(since="4.0.3", note="please use `.into()` instead")]
    pub fn new_string<T>(s: T) -> Sexp
        where T: fmt::Display
    {
        format!("{}", s).into()
    }

    /// create a list type symbolic-expression
    #[deprecated(since="4.0.3", note="please use `.into()` instead")]
    pub fn new_list(v: Vec<Sexp>) -> Sexp {
        Sexp::List(v)
    }

    /// create an empty list type symbolic-expression
    pub fn start(name: &str) -> Sexp {
        let mut v = vec![];
        v.push(Sexp::String(name.into()));
        Sexp::List(v)
    }

    /// push an element in a list
    pub fn push<T: Into<Sexp>>(&mut self, element: T) {
        match *self {
            Sexp::List(ref mut v) => v.push(element.into()),
            _ => panic!("Only use push on lists!"),
        }
    }

    /// create a list type symbolic-expression where
    /// the first element of the list is a string that indicates
    /// the name, the remainder is filled in via the provided
    /// fill function
    pub fn new_named_list<F>(name: &str, fill: F) -> Sexp
        where F: Fn(&mut Vec<Sexp>)
    {
        let mut v = vec![];
        v.push(name.into());
        fill(&mut v);
        Sexp::List(v)
    }

    /// create a list type symbolic-expression where
    /// the first element of the list is a string that indicates
    /// the name
    #[deprecated(since="4.0.3", note="please use `.into()` instead")]
    pub fn new_named<T>(name: &str, value: T) -> Sexp
        where T: fmt::Display
    {
        let mut v = vec![];
        v.push(name.into());
        v.push(format!("{}", value).into());
        v.into()
    }

    /// create a list type symbolic-expression where
    /// the first element of the list is a string that indicates
    /// the name, and the second is another symbolic-expression
    /// created via the IntoSexp trait
    #[deprecated(since="4.0.5", note="please use `.into()` on a tuple instead")]
    pub fn new_named_sexp<T>(name: &str, value: &T) -> Sexp
        where T: IntoSexp
    {
        let mut v = vec![];
        v.push(name.into());
        v.push(value.into_sexp());
        Sexp::List(v)
    }

    /// if the expression is a list, take out the list and swap it with Empty
    pub fn take_list(&mut self) -> Result<Vec<Sexp>> {
        let mut e = Sexp::Empty;
        mem::swap(&mut e, self);
        match e {
            Sexp::List(v) => Ok(v),
            _ => Err(format!("Not a list: {}", e).into()),
        }
    }

    /// if the expression is a string, take it out and swap it with Empty
    pub fn take_string(&mut self) -> Result<String> {
        let mut e = Sexp::Empty;
        mem::swap(&mut e, self);
        match e {
            Sexp::String(s) => Ok(s),
            _ => Err(format!("Not a string: {}", e).into()),
        }
    }

    /// create a symbolic-expression via the IntoSexp trait
    pub fn from<T: IntoSexp>(t: &T) -> Sexp {
        t.into_sexp()
    }

    /// access the symbolic-expression as if it is a List
    pub fn list(&self) -> Result<&Vec<Sexp>> {
        match *self {
            Sexp::List(ref v) => Ok(v),
            _ => Err(format!("not a list: {}", self).into()),
        }
    }

    /// access the symbolic-expression as if it is a String
    pub fn string(&self) -> Result<&String> {
        match *self {
            Sexp::String(ref s) => Ok(s),
            _ => Err(format!("not a string: {}", self).into()),
        }
    }

    /// is this expression a string
    pub fn is_string(&self) -> bool {
        match *self {
            Sexp::String(_) => true,
            _ => false,
        }
    }

    /// is this expression a list
    pub fn is_list(&self) -> bool {
        match *self {
            Sexp::List(_) => true,
            _ => false,
        }
    }

    /// access the symbolic-expression as if it is a String
    /// that is a f64
    pub fn f(&self) -> Result<f64> {
        let s = self.string()?;
        let f = f64::from_str(s)?;
        Ok(f)
    }

    /// access the symbolic-expression as if it is a String
    /// that is an i64
    pub fn i(&self) -> Result<i64> {
        let s = self.string()?;
        let i = i64::from_str(s)?;
        Ok(i)
    }

    /// access the symbolic-expression as if it is a List
    /// assuming the first element is a String and return that
    pub fn list_name(&self) -> Result<&String> {
        let l = self.list()?;
        let l = &l[..];
        let a = l[0].string()?;
        Ok(a)
    }

    /// access the symbolic-expression as if it is a named List
    /// where the name is provided and returns the remaining elements
    /// after the name as a slice
    pub fn slice_atom(&self, s: &str) -> Result<&[Sexp]> {
        let v = self.list()?;
        let v2 = &v[..];
        let st = v2[0].string()?;
        if st != s {
            return Err(format!("list {} doesn't start with {}, but with {}", self, s, st).into());
        };
        Ok(&v[1..])
    }

    /// access the symbolic-expression as if it is a named List
    /// iterator experiment
    pub fn iter_atom(&self, s:&str) -> Result<Iter<Self> > {
        let v = self.list()?;
        let mut i = v.iter();
        let st = match i.next() {
            None => return Err(format!("missing first element {} in list {}", s, self).into()),
            Some(e) => e.string()?,

        };
        if st != s {
            return Err(format!("list {} doesn't start with {}, but with {}", self, s, st).into());
        };
        Ok(i)
    }

    /// access the symbolic-expression as if it is a named List
    /// with two elements where the name is provided and returns
    /// the next element in the list
    pub fn named_value(&self, s: &str) -> Result<&Sexp> {
        let v = self.list()?;
        if v.len() != 2 {
            return Err(format!("list {} is not a named_value", s).into());
        }
        let l = self.slice_atom(s)?;
        Ok(&l[0])
    }

    /// as named_value but converted to i64
    pub fn named_value_i(&self, s: &str) -> Result<i64> {
        self.named_value(s)?.i()
    }

    /// as named_value but converted to f64
    pub fn named_value_f(&self, s: &str) -> Result<f64> {
        self.named_value(s)?.f()
    }

    /// as named_value but converted to String
    pub fn named_value_string(&self, s: &str) -> Result<&String> {
        self.named_value(s)?.string()
    }

    /// get the symbolic-expression as a list which starts
    /// with a string that indicates the name and has num more
    /// elements, returns those elements
    pub fn slice_atom_num(&self, s: &str, num: usize) -> Result<&[Sexp]> {
        let v = self.list()?;
        let v2 = &v[..];
        let st = v2[0].string()?;
        if st != s {
            return Err(format!("list doesn't start with {}, but with {}", s, st).into());
        };
        if v.len() != (num + 1) {
            return Err(format!("list ({}) doesn't have {} elements but {}",
                               s,
                               num,
                               v.len() - 1)
                .into());
        }
        Ok(&v[1..])
    }
}

impl fmt::Display for Sexp {
    fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> {
        match *self {
            Sexp::String(ref s) => write!(f, "{}", encode_string(s)),
            Sexp::List(ref v) => {
                write!(f, "(")?;
                let l = v.len();
                for (i, x) in v.iter().enumerate() {
                    if i < l - 1 {
                        write!(f, "{} ", x)?;
                    } else {
                        write!(f, "{}", x)?;
                    }
                }
                write!(f, ")")
            }
            Sexp::Empty => Ok(()),
        }
    }
}

impl Default for Sexp {
    fn default() -> Sexp {
        Sexp::Empty
    }
}

fn expect<T,F>(sname:&str, name:&str, i:&mut Iter<Sexp>, get:F) -> Result<T>
    where F:Fn(&Sexp) -> Result<T>
{
    let x = match i.next() {
        Some(x) => get(x)?,
        None => return Err(format!("missing {} field in {}",name, sname).into()),
    };
    Ok(x)
}

fn optional<T,F>(i:&mut Iter<Sexp>, or:T, get:F) -> Result<T>
    where F:Fn(&Sexp) -> Result<T>
{
    let x = match i.next() {
        Some(x) => get(x)?,
        None => or,
    };
    Ok(x)
}

/// expect an integer while iterating a `Sexp` list
pub fn expect_i(sname:&str, name:&str, i:&mut Iter<Sexp>) -> Result<i64> {
    expect(sname, name, i, |x| x.i())
}

/// expect a float while iterating a `Sexp` list
pub fn expect_f(sname:&str, name:&str, i:&mut Iter<Sexp>) -> Result<f64> {
    expect(sname, name, i, |x| x.f())
}

/// expect a String while iterating a `Sexp` list
pub fn expect_s(sname:&str, name:&str, i:&mut Iter<Sexp>) -> Result<String> {
    expect(sname, name, i, |x| x.string().map(|y| y.clone()))
}

/// optional integer while iterating a `Sexp` list
pub fn optional_i(i:&mut Iter<Sexp>, or:i64) -> Result<i64> {
    optional(i, or, |x| x.i())

}

/// optional float while iterating a `Sexp` list
pub fn optional_f(i:&mut Iter<Sexp>, or:f64) -> Result<f64> {
    optional(i, or, |x| x.f())
}
<commit_msg>expect/optional rework<commit_after>// (c) 2016-2017 Productize SPRL <joost@productize.be>

use std::fmt;
use std::result;
use std::str::FromStr;
use std::mem;
use std::slice::Iter;

use Result;
/// like Into trait but works from a ref avoiding consumption or expensive clone
pub trait IntoSexp {
    /// convert self into a Sexp
    fn into_sexp(&self) -> Sexp;
}

impl Into<Sexp> for Vec<Sexp> {
    fn into(self: Vec<Sexp>) -> Sexp {
        Sexp::List(self)
    }
}

impl Into<Sexp> for String {
    fn into(self: String) -> Sexp {
        Sexp::String(self)
    }
}

impl<'a> From<&'a str> for Sexp {
    fn from(t: &str) -> Sexp {
        Sexp::String(t.into())
    }
}

impl<'a> From<&'a String> for Sexp {
    fn from(t: &String) -> Sexp {
        Sexp::String(t.clone())
    }
}

impl Into<Sexp> for i64 {
    fn into(self: i64) -> Sexp {
        Sexp::String(format!("{}", self))
    }
}

impl Into<Sexp> for f64 {
    fn into(self: f64) -> Sexp {
        Sexp::String(format!("{}", self))
    }
}

impl<'a> From<(&'a str, Sexp)> for Sexp {
    fn from(kv: (&str, Sexp)) -> Sexp {
        let (name, value) = kv;
        let mut v = vec![];
        v.push(name.into());
        v.push(value);
        v.into()
    }
}

impl<'a, T: fmt::Display> From<(&'a str, &'a T)> for Sexp {
    fn from(kv: (&str, &T)) -> Sexp {
        let (name, value) = kv;
        let mut v = vec![];
        v.push(name.into());
        v.push(format!("{}", value).into());
        v.into()
    }
}

/// a symbolic-expression
/// Can be a string or a list or nothing
#[derive(Debug, Clone, PartialEq)]
pub enum Sexp {
    /// plain String symbolic-expression
    String(String),
    /// list symbolic-expression
    List(Vec<Sexp>),
    /// empty, trivial symbolic-expression
    Empty,
}

/// Atom iterator wrapper
pub struct IterAtom<'a> {
    i:Iter<'a,Sexp>,
}

// Following the KiCad file formats specification chapter 4.4 - Identifiers and Strings:
// A string may not contain an actual newline or carriage return,
// but it may use an escape sequence to encode a // newline, such as \n.
// If a string has any of the following conditions, then it must be quoted
// with a leading and trailing double quote
// character, otherwise it is acceptable to not quote the string:
// 1. has one or more of the following 4 separator bytes: ASCII space,
// tab, '(', or ')'.
// 2. has one or more of the following bytes: '%', '{', or '}'.
// 3. has a length of zero bytes, and you need a place holder for the field,
//  then use "".
// 4. includes a byte of '-', and this byte is not in the first position of
// the string.
//

// Joost remark: kicad no longer seems to follow Rule 4.
// so we don't either

/// encode a string according to the guidelines given by Kicad
pub fn encode_string(s: &str) -> String {
    // fn rule_4(s:&str) -> bool {
    // s.contains('-') && s.len() > 1 && s.as_bytes()[0] != 45
    // }
    if s.contains('(') || s.contains(' ') || s.contains(')') || s.contains('\t') ||
       s.contains('{') || s.contains('}') || s.contains('}') || s.contains('%') ||
       s.is_empty()
    // || rule_4(s)
    {
        format!("\"{}\"", s)
    } else {
        String::from(s)
    }
}

impl Sexp {
    /// create an empty symbolic-expression
    #[deprecated(since="4.0.0", note="please use `Sexp::default()` instead")]
    pub fn new_empty() -> Sexp {
        Sexp::Empty
    }

    /// create a String type symbolic-expression
    #[deprecated(since="4.0.3", note="please use `.into()` instead")]
    pub fn new_string<T>(s: T) -> Sexp
        where T: fmt::Display
    {
        format!("{}", s).into()
    }

    /// create a list type symbolic-expression
    #[deprecated(since="4.0.3", note="please use `.into()` instead")]
    pub fn new_list(v: Vec<Sexp>) -> Sexp {
        Sexp::List(v)
    }

    /// create an empty list type symbolic-expression
    pub fn start(name: &str) -> Sexp {
        let mut v = vec![];
        v.push(Sexp::String(name.into()));
        Sexp::List(v)
    }

    /// push an element in a list
    pub fn push<T: Into<Sexp>>(&mut self, element: T) {
        match *self {
            Sexp::List(ref mut v) => v.push(element.into()),
            _ => panic!("Only use push on lists!"),
        }
    }

    /// create a list type symbolic-expression where
    /// the first element of the list is a string that indicates
    /// the name, the remainder is filled in via the provided
    /// fill function
    pub fn new_named_list<F>(name: &str, fill: F) -> Sexp
        where F: Fn(&mut Vec<Sexp>)
    {
        let mut v = vec![];
        v.push(name.into());
        fill(&mut v);
        Sexp::List(v)
    }

    /// create a list type symbolic-expression where
    /// the first element of the list is a string that indicates
    /// the name
    #[deprecated(since="4.0.3", note="please use `.into()` instead")]
    pub fn new_named<T>(name: &str, value: T) -> Sexp
        where T: fmt::Display
    {
        let mut v = vec![];
        v.push(name.into());
        v.push(format!("{}", value).into());
        v.into()
    }

    /// create a list type symbolic-expression where
    /// the first element of the list is a string that indicates
    /// the name, and the second is another symbolic-expression
    /// created via the IntoSexp trait
    #[deprecated(since="4.0.5", note="please use `.into()` on a tuple instead")]
    pub fn new_named_sexp<T>(name: &str, value: &T) -> Sexp
        where T: IntoSexp
    {
        let mut v = vec![];
        v.push(name.into());
        v.push(value.into_sexp());
        Sexp::List(v)
    }

    /// if the expression is a list, take out the list and swap it with Empty
    pub fn take_list(&mut self) -> Result<Vec<Sexp>> {
        let mut e = Sexp::Empty;
        mem::swap(&mut e, self);
        match e {
            Sexp::List(v) => Ok(v),
            _ => Err(format!("Not a list: {}", e).into()),
        }
    }

    /// if the expression is a string, take it out and swap it with Empty
    pub fn take_string(&mut self) -> Result<String> {
        let mut e = Sexp::Empty;
        mem::swap(&mut e, self);
        match e {
            Sexp::String(s) => Ok(s),
            _ => Err(format!("Not a string: {}", e).into()),
        }
    }

    /// create a symbolic-expression via the IntoSexp trait
    pub fn from<T: IntoSexp>(t: &T) -> Sexp {
        t.into_sexp()
    }

    /// access the symbolic-expression as if it is a List
    pub fn list(&self) -> Result<&Vec<Sexp>> {
        match *self {
            Sexp::List(ref v) => Ok(v),
            _ => Err(format!("not a list: {}", self).into()),
        }
    }

    /// access the symbolic-expression as if it is a String
    pub fn string(&self) -> Result<&String> {
        match *self {
            Sexp::String(ref s) => Ok(s),
            _ => Err(format!("not a string: {}", self).into()),
        }
    }

    /// is this expression a string
    pub fn is_string(&self) -> bool {
        match *self {
            Sexp::String(_) => true,
            _ => false,
        }
    }

    /// is this expression a list
    pub fn is_list(&self) -> bool {
        match *self {
            Sexp::List(_) => true,
            _ => false,
        }
    }

    /// access the symbolic-expression as if it is a String
    /// that is a f64
    pub fn f(&self) -> Result<f64> {
        let s = self.string()?;
        let f = f64::from_str(s)?;
        Ok(f)
    }

    /// access the symbolic-expression as if it is a String
    /// that is an i64
    pub fn i(&self) -> Result<i64> {
        let s = self.string()?;
        let i = i64::from_str(s)?;
        Ok(i)
    }

    /// access the symbolic-expression as if it is a List
    /// assuming the first element is a String and return that
    pub fn list_name(&self) -> Result<&String> {
        let l = self.list()?;
        let l = &l[..];
        let a = l[0].string()?;
        Ok(a)
    }

    /// access the symbolic-expression as if it is a named List
    /// where the name is provided and returns the remaining elements
    /// after the name as a slice
    pub fn slice_atom(&self, s: &str) -> Result<&[Sexp]> {
        let v = self.list()?;
        let v2 = &v[..];
        let st = v2[0].string()?;
        if st != s {
            return Err(format!("list {} doesn't start with {}, but with {}", self, s, st).into());
        };
        Ok(&v[1..])
    }

    /// access the symbolic-expression as if it is a named List
    /// iterator experiment
    pub fn iter_atom(&self, s:&str) -> Result<IterAtom> {
        let v = self.list()?;
        let mut i = v.iter();
        let st = match i.next() {
            None => return Err(format!("missing first element {} in list {}", s, self).into()),
            Some(e) => e.string()?,

        };
        if st != s {
            return Err(format!("list {} doesn't start with {}, but with {}", self, s, st).into());
        };
        Ok(IterAtom { i:i })
    }

    /// access the symbolic-expression as if it is a named List
    /// with two elements where the name is provided and returns
    /// the next element in the list
    pub fn named_value(&self, s: &str) -> Result<&Sexp> {
        let v = self.list()?;
        if v.len() != 2 {
            return Err(format!("list {} is not a named_value", s).into());
        }
        let l = self.slice_atom(s)?;
        Ok(&l[0])
    }

    /// as named_value but converted to i64
    pub fn named_value_i(&self, s: &str) -> Result<i64> {
        self.named_value(s)?.i()
    }

    /// as named_value but converted to f64
    pub fn named_value_f(&self, s: &str) -> Result<f64> {
        self.named_value(s)?.f()
    }

    /// as named_value but converted to String
    pub fn named_value_string(&self, s: &str) -> Result<&String> {
        self.named_value(s)?.string()
    }

    /// get the symbolic-expression as a list which starts
    /// with a string that indicates the name and has num more
    /// elements, returns those elements
    pub fn slice_atom_num(&self, s: &str, num: usize) -> Result<&[Sexp]> {
        let v = self.list()?;
        let v2 = &v[..];
        let st = v2[0].string()?;
        if st != s {
            return Err(format!("list doesn't start with {}, but with {}", s, st).into());
        };
        if v.len() != (num + 1) {
            return Err(format!("list ({}) doesn't have {} elements but {}",
                               s,
                               num,
                               v.len() - 1)
                .into());
        }
        Ok(&v[1..])
    }
}

impl fmt::Display for Sexp {
    fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> {
        match *self {
            Sexp::String(ref s) => write!(f, "{}", encode_string(s)),
            Sexp::List(ref v) => {
                write!(f, "(")?;
                let l = v.len();
                for (i, x) in v.iter().enumerate() {
                    if i < l - 1 {
                        write!(f, "{} ", x)?;
                    } else {
                        write!(f, "{}", x)?;
                    }
                }
                write!(f, ")")
            }
            Sexp::Empty => Ok(()),
        }
    }
}

impl Default for Sexp {
    fn default() -> Sexp {
        Sexp::Empty
    }
}

impl<'a> IterAtom<'a> {

    fn expect<T,F>(&mut self, sname:&str, name:&str, get:F) -> Result<T>
        where F:Fn(&Sexp) -> Result<T>
    {
        let x = match self.i.next() {
            Some(x) => get(x)?,
            None => return Err(format!("missing {} field in {}",name, sname).into()),
        };
        Ok(x)
    }

    fn optional<T,F>(&mut self, or:T, get:F) -> Result<T>
        where F:Fn(&Sexp) -> Result<T>
    {
        let x = match self.i.next() {
            Some(x) => get(x)?,
            None => or,
        };
        Ok(x)
    }

    /// expect an integer while iterating a `Sexp` list
    pub fn expect_i(&mut self, sname:&str, name:&str) -> Result<i64> {
        self.expect(sname, name, |x| x.i())
    }

    /// expect a float while iterating a `Sexp` list
    pub fn expect_f(&mut self, sname:&str, name:&str) -> Result<f64> {
        self.expect(sname, name, |x| x.f())
    }

    /// expect a String while iterating a `Sexp` list
    pub fn expect_s(&mut self, sname:&str, name:&str) -> Result<String> {
        self.expect(sname, name, |x| x.string().map(|y| y.clone()))
    }

    /// optional integer while iterating a `Sexp` list
    pub fn optional_i(&mut self, or:i64) -> Result<i64> {
        self.optional(or, |x| x.i())
    }

    /// optional float while iterating a `Sexp` list
    pub fn optional_f(&mut self, or:f64) -> Result<f64> {
        self.optional(or, |x| x.f())
    }

    /// optional String while iterating a `Sexp` list
    pub fn optional_s(&mut self, or:String) -> Result<String> {
        self.optional(or, |x| x.string().map(|y| y.clone()))
    }
}
<|endoftext|>


<commit_before>extern crate quick_protobuf;

use std::io::{Write};
use quick_protobuf::{BytesReader, Writer, MessageWrite, Result};
use quick_protobuf::sizeofs::*;

macro_rules! write_read_primitive {
    ($name:ident, $read:ident, $write:ident) => (write_read_primitive!($name, $read, $write, 145););
    ($name:ident, $read:ident, $write:ident, $def:expr) => (
#[test]
fn $name(){
    let v = $def;
    let mut buf = Vec::new();
    {
        let mut w = Writer::new(&mut buf);
        w.$write(v).unwrap();
    }
    let mut r = BytesReader::from_bytes(&*buf);
    assert_eq!(v, r.$read(&buf).unwrap());
}
    );
}

write_read_primitive!(wr_int32, read_int32, write_int32);
write_read_primitive!(wr_int64, read_int64, write_int64);
write_read_primitive!(wr_uint32, read_uint32, write_uint32);
write_read_primitive!(wr_uint64, read_uint64, write_uint64);
write_read_primitive!(wr_sint32, read_sint32, write_sint32);
write_read_primitive!(wr_sint64, read_sint64, write_sint64);
write_read_primitive!(wr_bool, read_bool, write_bool, true);
write_read_primitive!(wr_fixed32, read_fixed32, write_fixed32);
write_read_primitive!(wr_fixed64, read_fixed64, write_fixed64);
write_read_primitive!(wr_sfixed32, read_sfixed32, write_sfixed32);
write_read_primitive!(wr_sfixed64, read_sfixed64, write_sfixed64);
write_read_primitive!(wr_float, read_float, write_float, 5.8);
write_read_primitive!(wr_double, read_double, write_double, 5.8);

#[test]
fn wr_bytes(){
    let v = b"test_write_read";
    let mut buf = Vec::new();
    {
        let mut w = Writer::new(&mut buf);
        w.write_bytes(v).unwrap();
    }
    let mut r = BytesReader::from_bytes(&*buf);
    assert_eq!(v, r.read_bytes(&buf).unwrap());
}

#[test]
fn wr_string(){
    let v = "test_write_read";
    let mut buf = Vec::new();
    {
        let mut w = Writer::new(&mut buf);
        w.write_string(v).unwrap();
    }
    let mut r = BytesReader::from_bytes(&buf);
    assert_eq!(v, r.read_string(&buf).unwrap());
}

#[derive(PartialEq, Eq, Debug, Clone, Copy)]
enum TestEnum {
    A = 0,
    B = 1,
    C = 2,
}

impl From<i32> for TestEnum {
    fn from(v: i32) -> TestEnum {
        match v {
            0 => TestEnum::A,
            1 => TestEnum::B,
            2 => TestEnum::C,
            _ => unreachable!(),
        }
    }
}

#[test]
fn wr_enum(){
    let v = TestEnum::C;
    let mut buf = Vec::new();
    {
        let mut w = Writer::new(&mut buf);
        w.write_enum(v as i32).unwrap();
    }
    let mut r = BytesReader::from_bytes(&buf);
    assert_eq!(v, r.read_enum(&buf).unwrap());
}

#[derive(PartialEq, Eq, Debug, Clone, Default)]
struct TestMessage {
    id: Option<u32>,
    val: Vec<i64>,
}

// impl MessageRead for TestMessage {
impl TestMessage {
    fn from_reader(r: &mut BytesReader, bytes: &[u8]) -> Result<TestMessage> {
        let mut msg = TestMessage::default();
        while !r.is_eof() {
            match r.next_tag(bytes) {
                Ok(10) => msg.id = Some(r.read_uint32(bytes)?),
                Ok(18) => msg.val.push(r.read_sint64(bytes)?),
                Ok(t) => { r.read_unknown(bytes, t)?; }
                Err(e) => return Err(e),
            }
        }
        Ok(msg)
    }
}

impl MessageWrite for TestMessage {
    fn get_size(&self) -> usize {
        self.id.as_ref().map_or(0, |m| 1 + sizeof_uint32(*m))
        + self.val.iter().map(|m| 1 + sizeof_sint64(*m)).sum::<usize>()
    }

    fn write_message<W: Write>(&self, r: &mut Writer<W>) -> Result<()> {
        if let Some(ref s) = self.id { r.write_with_tag(10, |r| r.write_uint32(*s))?; }
        for s in &self.val { r.write_with_tag(18, |r| r.write_sint64(*s))?; }
        Ok(())
    }
}

#[test]
fn wr_message(){

    let v = TestMessage {
        id: Some(63),
        val: vec![53, 5, 76, 743, 23, 753],
    };
    let mut buf = Vec::new();
    {
        let mut w = Writer::new(&mut buf);
        w.write_message(&v).unwrap();
    }
    let mut r = BytesReader::from_bytes(&buf);
    assert_eq!(v, r.read_message(&buf, TestMessage::from_reader).unwrap());

    // test get_size!
    assert_eq!(buf.len(), sizeof_varint(8) + v.get_size());
}

#[derive(PartialEq, Eq, Debug, Clone, Default)]
struct TestMessageBorrow<'a> {
    id: Option<u32>,
    val: Vec<&'a str>,
}

impl<'a> TestMessageBorrow<'a> {
    fn from_reader(r: &mut BytesReader, bytes: &'a[u8]) -> Result<TestMessageBorrow<'a>> {
        let mut msg = TestMessageBorrow::default();
        while !r.is_eof() {
            match r.next_tag(bytes) {
                Ok(10) => msg.id = Some(r.read_uint32(bytes)?),
                Ok(18) => msg.val.push(r.read_string(bytes)?),
                Ok(t) => { r.read_unknown(bytes, t)?; }
                Err(e) => return Err(e),
            }
            println!("{:?}", msg);
        }
        Ok(msg)
    }
}

impl<'a> MessageWrite for TestMessageBorrow<'a> {
    fn get_size(&self) -> usize {
        self.id.as_ref().map_or(0, |m| 1 + sizeof_uint32(*m))
        + self.val.iter().map(|m| 1 + sizeof_len(m.len())).sum::<usize>()
    }

    fn write_message<W: Write>(&self, r: &mut Writer<W>) -> Result<()> {
        if let Some(ref s) = self.id { r.write_with_tag(10, |r| r.write_uint32(*s))?; }
        for s in &self.val { r.write_with_tag(18, |r| r.write_string(*s))?; }
        Ok(())
    }
}

#[test]
fn wr_message_borrow(){

    let test = "eajhawbdkjblncljbdskjbclas";

    let v = TestMessageBorrow {
        id: Some(63),
        val: vec![&test[0..2], &test[3..7], &test[7..10]],
    };
    let mut buf = Vec::new();
    {
        let mut w = Writer::new(&mut buf);
        w.write_message(&v).unwrap();
    }
    let mut r = BytesReader::from_bytes(&buf);
    assert_eq!(v, r.read_message(&buf, TestMessageBorrow::from_reader).unwrap());

    // test get_size!
    assert_eq!(buf.len(), sizeof_varint(8) + v.get_size());
}

#[test]
fn wr_packed_uint32(){
    let v = vec![43, 54, 64, 234, 6123, 643];
    let mut buf = Vec::new();
    {
        let mut w = Writer::new(&mut buf);
        w.write_packed(&v, |r, m| r.write_uint32(*m), &|m| sizeof_uint32(*m)).unwrap();
    }
    let mut r = BytesReader::from_bytes(&buf);
    assert_eq!(v, r.read_packed(&buf, |r, b| r.read_uint32(b)).unwrap());
}

#[test]
fn wr_map(){
    let v = {
        let mut v = HasgMap::new();
        v.insert(Cow::Borrowed("foo"), 1u32);
        v.insert(Cow::Borrowed("bar"), 2);
        v
    };
    let mut buf = Vec::new();
    {
        let mut w = Writer::new(&mut buf);
        w.write_map(v,
                    sizeof_len(v.iter().map(|(k, v)| 2 + sizeof_len(k.len()) + sizeof_uint32(v)).sum::<usize>()),

        w.write_packed(&v, |r, m| r.write_uint32(*m), &|m| sizeof_uint32(*m)).unwrap();
    }
    let mut r = BytesReader::from_bytes(&buf);
    assert_eq!(v, r.read_packed(&buf, |r, b| r.read_uint32(b)).unwrap());
}
<commit_msg>add wr_map test<commit_after>extern crate quick_protobuf;

use std::collections::HashMap;
use std::borrow::Cow;
use std::io::{Write};
use quick_protobuf::{BytesReader, Writer, MessageWrite, Result};
use quick_protobuf::sizeofs::*;

macro_rules! write_read_primitive {
    ($name:ident, $read:ident, $write:ident) => (write_read_primitive!($name, $read, $write, 145););
    ($name:ident, $read:ident, $write:ident, $def:expr) => (
#[test]
fn $name(){
    let v = $def;
    let mut buf = Vec::new();
    {
        let mut w = Writer::new(&mut buf);
        w.$write(v).unwrap();
    }
    let mut r = BytesReader::from_bytes(&*buf);
    assert_eq!(v, r.$read(&buf).unwrap());
}
    );
}

write_read_primitive!(wr_int32, read_int32, write_int32);
write_read_primitive!(wr_int64, read_int64, write_int64);
write_read_primitive!(wr_uint32, read_uint32, write_uint32);
write_read_primitive!(wr_uint64, read_uint64, write_uint64);
write_read_primitive!(wr_sint32, read_sint32, write_sint32);
write_read_primitive!(wr_sint64, read_sint64, write_sint64);
write_read_primitive!(wr_bool, read_bool, write_bool, true);
write_read_primitive!(wr_fixed32, read_fixed32, write_fixed32);
write_read_primitive!(wr_fixed64, read_fixed64, write_fixed64);
write_read_primitive!(wr_sfixed32, read_sfixed32, write_sfixed32);
write_read_primitive!(wr_sfixed64, read_sfixed64, write_sfixed64);
write_read_primitive!(wr_float, read_float, write_float, 5.8);
write_read_primitive!(wr_double, read_double, write_double, 5.8);

#[test]
fn wr_bytes(){
    let v = b"test_write_read";
    let mut buf = Vec::new();
    {
        let mut w = Writer::new(&mut buf);
        w.write_bytes(v).unwrap();
    }
    let mut r = BytesReader::from_bytes(&*buf);
    assert_eq!(v, r.read_bytes(&buf).unwrap());
}

#[test]
fn wr_string(){
    let v = "test_write_read";
    let mut buf = Vec::new();
    {
        let mut w = Writer::new(&mut buf);
        w.write_string(v).unwrap();
    }
    let mut r = BytesReader::from_bytes(&buf);
    assert_eq!(v, r.read_string(&buf).unwrap());
}

#[derive(PartialEq, Eq, Debug, Clone, Copy)]
enum TestEnum {
    A = 0,
    B = 1,
    C = 2,
}

impl From<i32> for TestEnum {
    fn from(v: i32) -> TestEnum {
        match v {
            0 => TestEnum::A,
            1 => TestEnum::B,
            2 => TestEnum::C,
            _ => unreachable!(),
        }
    }
}

#[test]
fn wr_enum(){
    let v = TestEnum::C;
    let mut buf = Vec::new();
    {
        let mut w = Writer::new(&mut buf);
        w.write_enum(v as i32).unwrap();
    }
    let mut r = BytesReader::from_bytes(&buf);
    assert_eq!(v, r.read_enum(&buf).unwrap());
}

#[derive(PartialEq, Eq, Debug, Clone, Default)]
struct TestMessage {
    id: Option<u32>,
    val: Vec<i64>,
}

// impl MessageRead for TestMessage {
impl TestMessage {
    fn from_reader(r: &mut BytesReader, bytes: &[u8]) -> Result<TestMessage> {
        let mut msg = TestMessage::default();
        while !r.is_eof() {
            match r.next_tag(bytes) {
                Ok(10) => msg.id = Some(r.read_uint32(bytes)?),
                Ok(18) => msg.val.push(r.read_sint64(bytes)?),
                Ok(t) => { r.read_unknown(bytes, t)?; }
                Err(e) => return Err(e),
            }
        }
        Ok(msg)
    }
}

impl MessageWrite for TestMessage {
    fn get_size(&self) -> usize {
        self.id.as_ref().map_or(0, |m| 1 + sizeof_uint32(*m))
        + self.val.iter().map(|m| 1 + sizeof_sint64(*m)).sum::<usize>()
    }

    fn write_message<W: Write>(&self, r: &mut Writer<W>) -> Result<()> {
        if let Some(ref s) = self.id { r.write_with_tag(10, |r| r.write_uint32(*s))?; }
        for s in &self.val { r.write_with_tag(18, |r| r.write_sint64(*s))?; }
        Ok(())
    }
}

#[test]
fn wr_message(){

    let v = TestMessage {
        id: Some(63),
        val: vec![53, 5, 76, 743, 23, 753],
    };
    let mut buf = Vec::new();
    {
        let mut w = Writer::new(&mut buf);
        w.write_message(&v).unwrap();
    }
    let mut r = BytesReader::from_bytes(&buf);
    assert_eq!(v, r.read_message(&buf, TestMessage::from_reader).unwrap());

    // test get_size!
    assert_eq!(buf.len(), sizeof_varint(8) + v.get_size());
}

#[derive(PartialEq, Eq, Debug, Clone, Default)]
struct TestMessageBorrow<'a> {
    id: Option<u32>,
    val: Vec<&'a str>,
}

impl<'a> TestMessageBorrow<'a> {
    fn from_reader(r: &mut BytesReader, bytes: &'a[u8]) -> Result<TestMessageBorrow<'a>> {
        let mut msg = TestMessageBorrow::default();
        while !r.is_eof() {
            match r.next_tag(bytes) {
                Ok(10) => msg.id = Some(r.read_uint32(bytes)?),
                Ok(18) => msg.val.push(r.read_string(bytes)?),
                Ok(t) => { r.read_unknown(bytes, t)?; }
                Err(e) => return Err(e),
            }
            println!("{:?}", msg);
        }
        Ok(msg)
    }
}

impl<'a> MessageWrite for TestMessageBorrow<'a> {
    fn get_size(&self) -> usize {
        self.id.as_ref().map_or(0, |m| 1 + sizeof_uint32(*m))
        + self.val.iter().map(|m| 1 + sizeof_len(m.len())).sum::<usize>()
    }

    fn write_message<W: Write>(&self, r: &mut Writer<W>) -> Result<()> {
        if let Some(ref s) = self.id { r.write_with_tag(10, |r| r.write_uint32(*s))?; }
        for s in &self.val { r.write_with_tag(18, |r| r.write_string(*s))?; }
        Ok(())
    }
}

#[test]
fn wr_message_borrow(){

    let test = "eajhawbdkjblncljbdskjbclas";

    let v = TestMessageBorrow {
        id: Some(63),
        val: vec![&test[0..2], &test[3..7], &test[7..10]],
    };
    let mut buf = Vec::new();
    {
        let mut w = Writer::new(&mut buf);
        w.write_message(&v).unwrap();
    }
    let mut r = BytesReader::from_bytes(&buf);
    assert_eq!(v, r.read_message(&buf, TestMessageBorrow::from_reader).unwrap());

    // test get_size!
    assert_eq!(buf.len(), sizeof_varint(8) + v.get_size());
}

#[test]
fn wr_packed_uint32(){
    let v = vec![43, 54, 64, 234, 6123, 643];
    let mut buf = Vec::new();
    {
        let mut w = Writer::new(&mut buf);
        w.write_packed(&v, |r, m| r.write_uint32(*m), &|m| sizeof_uint32(*m)).unwrap();
    }
    let mut r = BytesReader::from_bytes(&buf);
    assert_eq!(v, r.read_packed(&buf, |r, b| r.read_uint32(b)).unwrap());
}

#[test]
fn wr_map(){
    let v = {
        let mut v = HashMap::new();
        v.insert(Cow::Borrowed("foo"), 1i32);
        v.insert(Cow::Borrowed("bar"), 2);
        v
    };
    let mut buf = Vec::new();
    {
        let mut w = Writer::new(&mut buf);
        for (k, v) in v.iter() {
            w.write_map(2 + sizeof_len(k.len()) + sizeof_varint(*v as u64), 10, |w| w.write_string(&**k), 16, |w| w.write_int32(*v)).unwrap();
        }
    }
    let mut r = BytesReader::from_bytes(&buf);
    let mut read_back = HashMap::new();
    while !r.is_eof() {
        let (key, value) = r.read_map(&buf, |r, bytes| r.read_string(bytes).map(Cow::Borrowed), |r, bytes| r.read_int32(bytes)).unwrap();
        read_back.insert(key, value);
    }
    assert_eq!(v, read_back);
}
<|endoftext|>


<commit_before>use std::borrow::Borrow;
use std::convert::TryFrom;
use std::{cmp, fmt, hash, ops};

use unsigned_varint::{decode as varint_decode, encode as varint_encode};

use crate::errors::{DecodeError, DecodeOwnedError};
use crate::hashes::Code;
use crate::storage::Storage;

/// Represents a valid multihash.
#[derive(Clone)]
pub struct Multihash {
    storage: Storage,
}

impl fmt::Debug for Multihash {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_tuple("Multihash").field(&self.as_bytes()).finish()
    }
}

impl PartialEq for Multihash {
    fn eq(&self, other: &Self) -> bool {
        self.storage.bytes() == other.storage.bytes()
    }
}

impl Eq for Multihash {}

impl hash::Hash for Multihash {
    fn hash<H: hash::Hasher>(&self, state: &mut H) {
        self.storage.bytes().hash(state);
    }
}

impl Multihash {
    /// Verifies whether `bytes` contains a valid multihash, and if so returns a `Multihash`.
    pub fn from_bytes(bytes: Vec<u8>) -> Result<Multihash, DecodeOwnedError> {
        if let Err(err) = MultihashRef::from_slice(&bytes) {
            return Err(DecodeOwnedError {
                error: err,
                data: bytes,
            });
        }
        Ok(Multihash {
            storage: Storage::from_slice(&bytes),
        })
    }

    /// Returns the bytes representation of the multihash.
    pub fn into_bytes(self) -> Vec<u8> {
        self.to_vec()
    }

    /// Returns the bytes representation of the multihash.
    pub fn to_vec(&self) -> Vec<u8> {
        Vec::from(self.as_bytes())
    }

    /// Returns the bytes representation of this multihash.
    pub fn as_bytes(&self) -> &[u8] {
        self.storage.bytes()
    }

    /// Builds a `MultihashRef` corresponding to this `Multihash`.
    pub fn as_ref(&self) -> MultihashRef {
        MultihashRef {
            bytes: self.as_bytes(),
        }
    }

    /// Returns which hashing algorithm is used in this multihash.
    pub fn algorithm(&self) -> Code {
        self.as_ref().algorithm()
    }

    /// Returns the hashed data.
    pub fn digest(&self) -> &[u8] {
        self.as_ref().digest()
    }
}

impl AsRef<[u8]> for Multihash {
    fn as_ref(&self) -> &[u8] {
        self.as_bytes()
    }
}

impl ops::Deref for Multihash {
    type Target = [u8];

    fn deref(&self) -> &Self::Target {
        &self.as_bytes()
    }
}

impl Borrow<[u8]> for Multihash {
    fn borrow(&self) -> &[u8] {
        self.as_bytes()
    }
}

impl<'a> PartialEq<MultihashRef<'a>> for Multihash {
    fn eq(&self, other: &MultihashRef<'a>) -> bool {
        &*self.as_bytes() == other.as_bytes()
    }
}

impl TryFrom<Vec<u8>> for Multihash {
    type Error = DecodeOwnedError;

    fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
        Multihash::from_bytes(value)
    }
}

impl Into<Vec<u8>> for Multihash {
    fn into(self) -> Vec<u8> {
        self.to_vec()
    }
}

impl PartialOrd for Multihash {
    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Multihash {
    fn cmp(&self, other: &Self) -> cmp::Ordering {
        self.as_ref().cmp(&other.as_ref())
    }
}

/// Represents a valid multihash.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct MultihashRef<'a> {
    bytes: &'a [u8],
}

impl<'a> MultihashRef<'a> {
    /// Creates a `MultihashRef` from the given `input`.
    pub fn from_slice(input: &'a [u8]) -> Result<Self, DecodeError> {
        if input.is_empty() {
            return Err(DecodeError::BadInputLength);
        }

        let (_code, bytes) = varint_decode::u64(&input).map_err(|_| DecodeError::BadInputLength)?;

        let (hash_len, bytes) =
            varint_decode::u64(&bytes).map_err(|_| DecodeError::BadInputLength)?;
        if (bytes.len() as u64) != hash_len {
            return Err(DecodeError::BadInputLength);
        }

        Ok(MultihashRef { bytes: input })
    }

    /// Returns which hashing algorithm is used in this multihash.
    pub fn algorithm(&self) -> Code {
        let (code, _bytes) =
            varint_decode::u64(&self.bytes).expect("multihash is known to be valid algorithm");
        Code::from_u64(code)
    }

    /// Returns the hashed data.
    pub fn digest(&self) -> &'a [u8] {
        let (_code, bytes) =
            varint_decode::u64(&self.bytes).expect("multihash is known to be valid digest");
        let (_hash_len, bytes) =
            varint_decode::u64(&bytes).expect("multihash is known to be a valid digest");
        &bytes[..]
    }

    /// Builds a `Multihash` that owns the data.
    ///
    /// This operation allocates.
    pub fn to_owned(&self) -> Multihash {
        Multihash {
            storage: Storage::from_slice(self.bytes),
        }
    }

    /// Returns the bytes representation of this multihash.
    pub fn as_bytes(&self) -> &'a [u8] {
        &self.bytes
    }
}

impl<'a> PartialEq<Multihash> for MultihashRef<'a> {
    fn eq(&self, other: &Multihash) -> bool {
        self.as_bytes() == &*other.as_bytes()
    }
}

impl<'a> ops::Deref for MultihashRef<'a> {
    type Target = [u8];

    fn deref(&self) -> &Self::Target {
        self.as_bytes()
    }
}

impl<'a> Into<Vec<u8>> for MultihashRef<'a> {
    fn into(self) -> Vec<u8> {
        self.to_vec()
    }
}

/// The `MultihashDigest` trait specifies an interface common for all multihash functions.
pub trait MultihashDigest {
    /// The Mutlihash byte value.
    fn code(&self) -> Code;

    /// Hash some input and return the digest.
    ///
    /// # Panics
    ///
    /// Panics if the digest length is bigger than 2^32. This only happens for identity hasing.
    fn digest(&self, data: &[u8]) -> Multihash;
}

/// Wraps a hash digest in Multihash with the given Mutlihash code.
///
/// The size of the hash is determoned by the size of the input hash. If it should be truncated
/// the input data must already be the truncated hash.
pub fn wrap(code: Code, data: &[u8]) -> Multihash {
    let mut code_buf = varint_encode::u64_buffer();
    let code = varint_encode::u64(code.to_u64(), &mut code_buf);

    let mut size_buf = varint_encode::u64_buffer();
    let size = varint_encode::u64(data.len() as u64, &mut size_buf);

    Multihash {
        storage: Storage::from_slices(&[code, &size, &data]),
    }
}
<commit_msg>docs: add more documentation<commit_after>use std::borrow::Borrow;
use std::convert::TryFrom;
use std::{cmp, fmt, hash, ops};

use unsigned_varint::{decode as varint_decode, encode as varint_encode};

use crate::errors::{DecodeError, DecodeOwnedError};
use crate::hashes::Code;
use crate::storage::Storage;

/// Representation of a valid multihash. This enforces validity on construction,
/// so it can be assumed this is always a valid multihash.
#[derive(Clone)]
pub struct Multihash {
    storage: Storage,
}

impl fmt::Debug for Multihash {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_tuple("Multihash").field(&self.as_bytes()).finish()
    }
}

impl PartialEq for Multihash {
    fn eq(&self, other: &Self) -> bool {
        self.storage.bytes() == other.storage.bytes()
    }
}

impl Eq for Multihash {}

impl hash::Hash for Multihash {
    fn hash<H: hash::Hasher>(&self, state: &mut H) {
        self.storage.bytes().hash(state);
    }
}

impl Multihash {
    /// Creates a new `Multihash` from a `Vec<u8>`, consuming it.
    /// If the input data is not a valid multihash an error is returned.
    ///
    /// # Example
    ///
    /// ```
    /// use multihash::{Sha2_256, Multihash};
    ///
    /// let mh = Sha2_256::digest(b"hello world");
    ///
    /// // valid multihash
    /// let mh2 = Multihash::from_bytes(mh.into_bytes()).unwrap();
    ///
    /// // invalid multihash
    /// assert!(Multihash::from_bytes(vec![1,2,3]).is_err());
    /// ```
    pub fn from_bytes(bytes: Vec<u8>) -> Result<Multihash, DecodeOwnedError> {
        if let Err(err) = MultihashRef::from_slice(&bytes) {
            return Err(DecodeOwnedError {
                error: err,
                data: bytes,
            });
        }
        Ok(Multihash {
            storage: Storage::from_slice(&bytes),
        })
    }

    /// Returns the bytes representation of the multihash.
    pub fn into_bytes(self) -> Vec<u8> {
        self.to_vec()
    }

    /// Returns the bytes representation of the multihash.
    pub fn to_vec(&self) -> Vec<u8> {
        Vec::from(self.as_bytes())
    }

    /// Returns the bytes representation of this multihash.
    pub fn as_bytes(&self) -> &[u8] {
        self.storage.bytes()
    }

    /// Builds a `MultihashRef` corresponding to this `Multihash`.
    pub fn as_ref(&self) -> MultihashRef {
        MultihashRef {
            bytes: self.as_bytes(),
        }
    }

    /// Returns the algorithm used in this multihash.
    ///
    /// # Example
    ///
    /// ```
    /// use multihash::{Code, Sha2_256};
    ///
    /// let mh = Sha2_256::digest(b"hello world");
    /// assert_eq!(mh.algorithm(), Code::Sha2_256);
    /// ```
    pub fn algorithm(&self) -> Code {
        self.as_ref().algorithm()
    }

    /// Returns the hashed data.
    pub fn digest(&self) -> &[u8] {
        self.as_ref().digest()
    }
}

impl AsRef<[u8]> for Multihash {
    fn as_ref(&self) -> &[u8] {
        self.as_bytes()
    }
}

impl ops::Deref for Multihash {
    type Target = [u8];

    fn deref(&self) -> &Self::Target {
        &self.as_bytes()
    }
}

impl Borrow<[u8]> for Multihash {
    fn borrow(&self) -> &[u8] {
        self.as_bytes()
    }
}

impl<'a> PartialEq<MultihashRef<'a>> for Multihash {
    fn eq(&self, other: &MultihashRef<'a>) -> bool {
        &*self.as_bytes() == other.as_bytes()
    }
}

impl TryFrom<Vec<u8>> for Multihash {
    type Error = DecodeOwnedError;

    fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
        Multihash::from_bytes(value)
    }
}

impl Into<Vec<u8>> for Multihash {
    fn into(self) -> Vec<u8> {
        self.to_vec()
    }
}

impl PartialOrd for Multihash {
    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Multihash {
    fn cmp(&self, other: &Self) -> cmp::Ordering {
        self.as_ref().cmp(&other.as_ref())
    }
}

/// Represents a valid multihash.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct MultihashRef<'a> {
    bytes: &'a [u8],
}

impl<'a> MultihashRef<'a> {
    /// Creates a new `MultihashRef` from a `&[u8]`.
    /// If the input data is not a valid multihash an error is returned.
    ///
    /// # Example
    ///
    /// ```
    /// use multihash::{Sha2_256, Multihash, MultihashRef};
    ///
    /// let mh = Sha2_256::digest(b"hello world");
    ///
    /// // valid multihash
    /// let mh2 = MultihashRef::from_slice(&mh).unwrap();
    ///
    /// // invalid multihash
    /// assert!(MultihashRef::from_slice(&vec![1,2,3]).is_err());
    /// ```
    pub fn from_slice(input: &'a [u8]) -> Result<Self, DecodeError> {
        if input.is_empty() {
            return Err(DecodeError::BadInputLength);
        }

        let (_code, bytes) = varint_decode::u64(&input).map_err(|_| DecodeError::BadInputLength)?;

        let (hash_len, bytes) =
            varint_decode::u64(&bytes).map_err(|_| DecodeError::BadInputLength)?;
        if (bytes.len() as u64) != hash_len {
            return Err(DecodeError::BadInputLength);
        }

        Ok(MultihashRef { bytes: input })
    }

    /// Returns the algorithm used in this multihash.
    ///
    /// # Example
    ///
    /// ```
    /// use multihash::{Code, Sha2_256, MultihashRef};
    ///
    /// let mh = Sha2_256::digest(b"hello world");
    ///
    /// // valid multihash
    /// let mh2 = MultihashRef::from_slice(&mh).unwrap();
    /// assert_eq!(mh2.algorithm(), Code::Sha2_256);
    /// ```
    pub fn algorithm(&self) -> Code {
        let (code, _bytes) =
            varint_decode::u64(&self.bytes).expect("multihash is known to be valid algorithm");
        Code::from_u64(code)
    }

    /// Returns the hash digest.
    ///
    /// # Example
    ///
    /// ```
    /// use multihash::{wrap, Code, Sha2_256};
    ///
    /// let mh = Sha2_256::digest(b"hello world");
    /// let digest = mh.digest();
    /// let wrapped = wrap(Code::Sha2_256, &digest);
    /// assert_eq!(wrapped.digest(), digest);
    /// ```
    pub fn digest(&self) -> &'a [u8] {
        let (_code, bytes) =
            varint_decode::u64(&self.bytes).expect("multihash is known to be valid digest");
        let (_hash_len, bytes) =
            varint_decode::u64(&bytes).expect("multihash is known to be a valid digest");
        &bytes[..]
    }

    /// Builds a `Multihash` that owns the data.
    ///
    /// This operation allocates.
    pub fn to_owned(&self) -> Multihash {
        Multihash {
            storage: Storage::from_slice(self.bytes),
        }
    }

    /// Returns the bytes representation of this multihash.
    pub fn as_bytes(&self) -> &'a [u8] {
        &self.bytes
    }
}

impl<'a> PartialEq<Multihash> for MultihashRef<'a> {
    fn eq(&self, other: &Multihash) -> bool {
        self.as_bytes() == &*other.as_bytes()
    }
}

impl<'a> ops::Deref for MultihashRef<'a> {
    type Target = [u8];

    fn deref(&self) -> &Self::Target {
        self.as_bytes()
    }
}

impl<'a> Into<Vec<u8>> for MultihashRef<'a> {
    fn into(self) -> Vec<u8> {
        self.to_vec()
    }
}

/// The `MultihashDigest` trait specifies an interface common for all multihash functions.
pub trait MultihashDigest {
    /// The Mutlihash byte value.
    fn code(&self) -> Code;

    /// Hash some input and return the digest.
    ///
    /// # Panics
    ///
    /// Panics if the digest length is bigger than 2^32. This only happens for identity hasing.
    fn digest(&self, data: &[u8]) -> Multihash;
}

/// Wraps a hash digest in Multihash with the given Mutlihash code.
///
/// The size of the hash is determoned by the size of the input hash. If it should be truncated
/// the input data must already be the truncated hash.
///
/// # Example
///
/// ```
/// use multihash::{wrap, Code, Sha2_256};
///
/// let mh = Sha2_256::digest(b"hello world");
/// let digest = mh.digest();
/// let wrapped = wrap(Code::Sha2_256, &digest);
/// assert_eq!(wrapped.digest(), digest);
/// ```
pub fn wrap(code: Code, data: &[u8]) -> Multihash {
    let mut code_buf = varint_encode::u64_buffer();
    let code = varint_encode::u64(code.to_u64(), &mut code_buf);

    let mut size_buf = varint_encode::u64_buffer();
    let size = varint_encode::u64(data.len() as u64, &mut size_buf);

    Multihash {
        storage: Storage::from_slices(&[code, &size, &data]),
    }
}
<|endoftext|>


<commit_before>use crate::direction::Direction;

pub struct Ship {
    state: ShipState,
    position: Vec<[u8; 2]>,
    dir: Direction,
}

impl Ship {
    pub fn new(pos: Vec<[u8; 2]>, dir: Direction) -> Ship {
        Ship {
            state: ShipState::Active,
            position: pos,
            dir: dir,
        }
    }

    pub fn pos(&self) -> &[[u8; 2]] {
        &self.position
    }

    pub fn dir(&self) -> Direction {
        self.dir
    }

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

    pub fn is_active(&self) -> bool {
        self.state == ShipState::Active
    }

    pub fn is_sunk(&self) -> bool {
        self.state == ShipState::Sunk
    }

    pub fn sink(&mut self) {
        self.state = ShipState::Sunk;
    }
}

#[derive(PartialEq)]
enum ShipState {
    Placement,
    Active,
    Sunk
}

<commit_msg>Ship: add set_pos()<commit_after>use crate::direction::Direction;

pub struct Ship {
    state: ShipState,
    position: Vec<[u8; 2]>,
    dir: Direction,
}

impl Ship {
    pub fn new(pos: Vec<[u8; 2]>, dir: Direction) -> Ship {
        Ship {
            state: ShipState::Active,
            position: pos,
            dir: dir,
        }
    }

    pub fn pos(&self) -> &[[u8; 2]] {
        &self.position
    }

    pub fn set_pos(&mut self, pos: Vec<[u8; 2]>) -> Result<(), &'static str> {
        let dir = Direction::from_positions(&pos[1], &pos[0])?;

        self.position = pos;
        self.dir = dir;

        Ok(())
    }

    pub fn dir(&self) -> Direction {
        self.dir
    }

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

    pub fn is_active(&self) -> bool {
        self.state == ShipState::Active
    }

    pub fn is_sunk(&self) -> bool {
        self.state == ShipState::Sunk
    }

    pub fn sink(&mut self) {
        self.state = ShipState::Sunk;
    }
}

#[derive(PartialEq)]
enum ShipState {
    Placement,
    Active,
    Sunk
}

<|endoftext|>


<commit_before>use std::fmt;
use std::result;
use types::js_var::{JsVar, JsPtrEnum};
use gc_error::GcError;

#[derive(Debug)]
pub enum JsError {
    ParseError(String),
    GcError(GcError),
    TypeError(String),
    ReferenceError(String),
    JsVar((JsVar, Option<JsPtrEnum>)),
    TestError(String),
    UnimplementedError(String),
}

impl JsError {
    pub fn invalid_lhs() -> JsError {
        JsError::ReferenceError(String::from("Invalid left-hand side in assignment"))
    }

    #[allow(dead_code)]
    pub fn unimplemented(typ: &str) -> JsError {
        JsError::UnimplementedError(format!("{} not implemented", typ))
    }

    /// Meta errors are problems with the interpreter -- parsing, gc, or unimplemented methods.
    pub fn is_meta_error(&self) -> bool {
        match self {
            &JsError::ParseError(_) => true,
            &JsError::GcError(_) => true,
            &JsError::TypeError(_) => false,
            &JsError::ReferenceError(_) => false,
            &JsError::JsVar(_) => false,
            &JsError::TestError(_) => false,
            &JsError::UnimplementedError(_) => true,
        }
    }
}

impl fmt::Display for JsError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            JsError::ParseError(ref s) => write!(f, "ParseError: {}", s),
            JsError::GcError(ref gc) => write!(f, "GcError: {}", gc),
            JsError::TypeError(ref s) => write!(f, "TypeError: {}", s),
            JsError::ReferenceError(ref s) => write!(f, "ReferenceError: {}", s),
            JsError::JsVar(ref var_value) => write!(f, "{:?}", var_value),
            JsError::TestError(ref s) => write!(f, "TestError: {}", s),
            JsError::UnimplementedError(ref s) => write!(f, "UnimplementedError: {}", s),
        }
    }
}

impl From<GcError> for JsError {
    fn from(e: GcError)-> Self {
        JsError::GcError(e)
    }
}

pub type Result<T> = result::Result<T, JsError>;
<commit_msg>add JsError helper fns<commit_after>use std::fmt;
use std::result;
use types::js_var::{JsVar, JsPtrEnum};
use gc_error::GcError;

#[derive(Debug)]
pub enum JsError {
    ParseError(String),
    GcError(GcError),
    TypeError(String),
    ReferenceError(String),
    JsVar((JsVar, Option<JsPtrEnum>)),
    TestError(String),
    UnimplementedError(String),
}

impl JsError {
    pub fn invalid_lhs() -> JsError {
        JsError::ReferenceError(String::from("Invalid left-hand side in assignment"))
    }

    #[allow(dead_code)]
    pub fn unimplemented(typ: &str) -> JsError {
        JsError::UnimplementedError(format!("{}", typ))
    }

    #[allow(dead_code)]
    pub fn undefined(binding: &str) -> JsError {
        JsError::ReferenceError(format!("{} is not defined", binding))
    }

    /// Meta errors are problems with the interpreter -- parsing, gc, or unimplemented methods.
    pub fn is_meta_error(&self) -> bool {
        match self {
            &JsError::ParseError(_) => true,
            &JsError::GcError(_) => true,
            &JsError::TypeError(_) => false,
            &JsError::ReferenceError(_) => false,
            &JsError::JsVar(_) => false,
            &JsError::TestError(_) => false,
            &JsError::UnimplementedError(_) => true,
        }
    }
}

impl fmt::Display for JsError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            JsError::ParseError(ref s) => write!(f, "ParseError: {}", s),
            JsError::GcError(ref gc) => write!(f, "GcError: {}", gc),
            JsError::TypeError(ref s) => write!(f, "TypeError: {}", s),
            JsError::ReferenceError(ref s) => write!(f, "ReferenceError: {}", s),
            JsError::JsVar(ref var_value) => write!(f, "{:?}", var_value),
            JsError::TestError(ref s) => write!(f, "TestError: {}", s),
            JsError::UnimplementedError(ref s) =>
                write!(f, "UnimplementedError: {} is not implemented", s),
        }
    }
}

impl From<GcError> for JsError {
    fn from(e: GcError)-> Self {
        JsError::GcError(e)
    }
}

pub type Result<T> = result::Result<T, JsError>;
<|endoftext|>


<commit_before>//! JSON bi-directional serialization.
//!
//! The `FromJsonnable` trait provides an abstract way of handling types, that can be deserialized from JSON
//!
//! The `ToJsonnable` trait provides an abstract way of handling types, that can be serialized to JSON
//!
//!
//! # Examples
//!
//! Consider a user information struct `UserInfo`, that needs to be stored somehow:
//!
//! ```
//! extern crate serde;
//! extern crate serde_json;
//! extern crate chattium_oxide_lib;
//!
//! use serde::de::{Error, Type};
//! use serde_json::value::Value;
//! use serde_json::error::Error as JsonError;
//! use serde_json::builder::ObjectBuilder;
//! use chattium_oxide_lib::json::{ToJsonnable, FromJsonnable};
//!
//! #[derive(Debug, PartialEq)]
//! struct UserInfo {
//! 	name: String,
//! 	id: i64,
//! 	address: (String, String),
//! }
//!
//! impl ToJsonnable for UserInfo {
//! 	fn to_json(&self) -> Value {
//! 		ObjectBuilder::new().insert("name", &self.name)
//! 		                    .insert("id", &self.id)
//! 		                    .insert("address", &self.address)  // Tuples serialize to a JSON array
//! 		                    .unwrap()
//! 	}
//! }
//!
//! impl FromJsonnable for UserInfo {
//! 	// Verbose, but safe, matching algorithm
//! 	fn from_json(json: Value) -> Result<Self, JsonError> {
//!			match json {
//!				Value::Object(map) => {
//!					let name =
//!						match map.get("name") {
//!							Some(name) =>
//!								match name {
//!									&Value::String(ref name) => name,
//!									_ => return Err(JsonError::type_mismatch(Type::String)),
//!								},
//!							None => return Err(JsonError::missing_field("Missing \"name\"")),
//!						};
//!					let id =
//!						match map.get("id") {
//!							Some(id) =>
//!								match id {
//!									&Value::I64(id) => id,
//!									&Value::U64(id) => id as i64,
//!									_ => return Err(JsonError::type_mismatch(Type::I64)),
//!								},
//!							None => return Err(JsonError::missing_field("Missing \"id\"")),
//!						};
//!					let address =
//!						match map.get("address") {
//!							Some(address) =>
//!								match address {
//!									&Value::Array(ref address) =>
//!										match address.len() {
//!											2 =>
//!												match (&address[0], &address[1]) {
//!													(&Value::String(ref laddress), &Value::String(ref raddress)) => (laddress.clone(), raddress.clone()),
//!													_ => return Err(JsonError::type_mismatch(Type::String)),
//!												},
//!											_ => return Err(JsonError::length_mismatch(2)),
//!										},
//!									_ => return Err(JsonError::type_mismatch(Type::String)),
//!								},
//!							None => return Err(JsonError::missing_field("Missing \"address\"")),
//!						};
//!
//!					Ok(UserInfo{
//!						name: name.clone(),
//!						id: id,
//!						address: address,//(address.0.clone(), address.1.clone()),
//!					})
//!				},
//!				_ => Err(JsonError::type_mismatch(Type::Struct)),
//!			}
//! 	}
//! }
//!
//! fn main() {
//! 	let original = UserInfo{
//! 		name: "user".to_owned(),
//! 		id: 50030,
//! 		address: ("Diagon Alley".to_owned(), "London, UK".to_owned()),
//! 	};
//! 	let serialized = (original.to_json_string()).ok().unwrap();
//! 	println!("{}", serialized);  // Space-efficient "ugly" format
//! 	let deserialized = (UserInfo::from_json_string(&serialized)).ok().unwrap();
//! 	assert_eq!(original, deserialized);
//! }
//! ```

mod implementation;
pub use self::implementation::*;

use serde_json;
use serde_json::value::Value;
use serde_json::error::Error as JsonError;

/// A trait for types supporting deserialization from JSON
pub trait FromJsonnable: Sized {
	/// Deserialize a JSON value to `Self`
	///
	/// Returns `Err()` if the Value cannot be deserialized into `Self`
	fn from_json(json: Value) -> Result<Self, JsonError>;

	/// Convenience function for deserializing a JSON string representation directly into `Self`
	fn from_json_string(string: &String) -> Result<Self, JsonError> {
		let value: Value = try!(serde_json::from_str(&*&string));
		Self::from_json(value)
	}
}

/// A trait for types supporting serialization to JSON
pub trait ToJsonnable: Sized {
	/// Serialize `self` to a JSON `Value`.
	///
	/// If `Self` also implements [`FromJsonnable`](trait.FromJsonnable.html), it's highly recommended,
	/// that `self.from_json(self.to_json())` never returns `Err()`.
	fn to_json(&self) -> Value;

	/// Convenience function for converting `self` to a JSON ugly-string representation.
	///
	/// Returns `Err()` if `serde_json` couldn't convert the Value to a String
	fn to_json_string(&self) -> Result<String, JsonError> {
		serde_json::to_string(&self.to_json())
	}
}
<commit_msg>Fix Result<> handling in mod-doc for json<commit_after>//! JSON bi-directional serialization.
//!
//! The `FromJsonnable` trait provides an abstract way of handling types, that can be deserialized from JSON
//!
//! The `ToJsonnable` trait provides an abstract way of handling types, that can be serialized to JSON
//!
//!
//! # Examples
//!
//! Consider a user information struct `UserInfo`, that needs to be stored somehow:
//!
//! ```
//! extern crate serde;
//! extern crate serde_json;
//! extern crate chattium_oxide_lib;
//!
//! use serde::de::{Error, Type};
//! use serde_json::value::Value;
//! use serde_json::error::Error as JsonError;
//! use serde_json::builder::ObjectBuilder;
//! use chattium_oxide_lib::json::{ToJsonnable, FromJsonnable};
//!
//! #[derive(Debug, PartialEq)]
//! struct UserInfo {
//! 	name: String,
//! 	id: i64,
//! 	address: (String, String),
//! }
//!
//! impl ToJsonnable for UserInfo {
//! 	fn to_json(&self) -> Value {
//! 		ObjectBuilder::new().insert("name", &self.name)
//! 		                    .insert("id", &self.id)
//! 		                    .insert("address", &self.address)  // Tuples serialize to a JSON array
//! 		                    .unwrap()
//! 	}
//! }
//!
//! impl FromJsonnable for UserInfo {
//! 	// Verbose, but safe, matching algorithm
//! 	fn from_json(json: Value) -> Result<Self, JsonError> {
//!			match json {
//!				Value::Object(map) => {
//!					let name =
//!						match map.get("name") {
//!							Some(name) =>
//!								match name {
//!									&Value::String(ref name) => name,
//!									_ => return Err(JsonError::type_mismatch(Type::String)),
//!								},
//!							None => return Err(JsonError::missing_field("Missing \"name\"")),
//!						};
//!					let id =
//!						match map.get("id") {
//!							Some(id) =>
//!								match id {
//!									&Value::I64(id) => id,
//!									&Value::U64(id) => id as i64,
//!									_ => return Err(JsonError::type_mismatch(Type::I64)),
//!								},
//!							None => return Err(JsonError::missing_field("Missing \"id\"")),
//!						};
//!					let address =
//!						match map.get("address") {
//!							Some(address) =>
//!								match address {
//!									&Value::Array(ref address) =>
//!										match address.len() {
//!											2 =>
//!												match (&address[0], &address[1]) {
//!													(&Value::String(ref laddress), &Value::String(ref raddress)) => (laddress.clone(), raddress.clone()),
//!													_ => return Err(JsonError::type_mismatch(Type::String)),
//!												},
//!											_ => return Err(JsonError::length_mismatch(2)),
//!										},
//!									_ => return Err(JsonError::type_mismatch(Type::String)),
//!								},
//!							None => return Err(JsonError::missing_field("Missing \"address\"")),
//!						};
//!
//!					Ok(UserInfo{
//!						name: name.clone(),
//!						id: id,
//!						address: address,//(address.0.clone(), address.1.clone()),
//!					})
//!				},
//!				_ => Err(JsonError::type_mismatch(Type::Struct)),
//!			}
//! 	}
//! }
//!
//! fn main() {
//! 	let original = UserInfo{
//! 		name: "user".to_owned(),
//! 		id: 50030,
//! 		address: ("Diagon Alley".to_owned(), "London, UK".to_owned()),
//! 	};
//! 	let serialized = original.to_json_string().unwrap();
//! 	println!("{}", serialized);  // Space-efficient "ugly" format
//! 	let deserialized = UserInfo::from_json_string(&serialized).unwrap();
//! 	assert_eq!(original, deserialized);
//! }
//! ```

mod implementation;
pub use self::implementation::*;

use serde_json;
use serde_json::value::Value;
use serde_json::error::Error as JsonError;

/// A trait for types supporting deserialization from JSON
pub trait FromJsonnable: Sized {
	/// Deserialize a JSON value to `Self`
	///
	/// Returns `Err()` if the Value cannot be deserialized into `Self`
	fn from_json(json: Value) -> Result<Self, JsonError>;

	/// Convenience function for deserializing a JSON string representation directly into `Self`
	fn from_json_string(string: &String) -> Result<Self, JsonError> {
		let value: Value = try!(serde_json::from_str(&*&string));
		Self::from_json(value)
	}
}

/// A trait for types supporting serialization to JSON
pub trait ToJsonnable: Sized {
	/// Serialize `self` to a JSON `Value`.
	///
	/// If `Self` also implements [`FromJsonnable`](trait.FromJsonnable.html), it's highly recommended,
	/// that `self.from_json(self.to_json())` never returns `Err()`.
	fn to_json(&self) -> Value;

	/// Convenience function for converting `self` to a JSON ugly-string representation.
	///
	/// Returns `Err()` if `serde_json` couldn't convert the Value to a String
	fn to_json_string(&self) -> Result<String, JsonError> {
		serde_json::to_string(&self.to_json())
	}
}
<|endoftext|>


<commit_before>use std::env;
use std::ffi::OsStr;
use std::fs::create_dir_all;
use std::path::{PathBuf};

// used to index values in map
pub static CHANGED_KEY: &'static str = "changed";
pub static NEW_KEY: &'static str = "new";
pub static STAGED_KEY: &'static str = "staged";
pub static CONFLICTS_KEY: &'static str = "conflicts";

pub static CURRENT_CONFIG_VERSION: &'static str = "1";

pub static DEFAULT_CONFIG_NAME: &'static str = "pretty-git-prompt.yml";

pub static CLI_DEFAULT_CONFIG_SUBC_NAME: &'static str = "create-default-config";

pub fn get_default_config_path() -> PathBuf {
    let mut p = match env::var("XDG_CONFIG_HOME") {
        Ok(val) => PathBuf::from(&val),
        Err(_) => {
            match env::var("HOME") {
                Ok(home) => {
                    let mut p2 = PathBuf::from(&home);
                    p2.push(".config");
                    p2
                },
                // we tried hard
                Err(_) => PathBuf::from("/tmp"),
            }
        }
    };
    create_dir_all(p.to_str().unwrap());
    p.push(DEFAULT_CONFIG_NAME);
    p
}

#[test]
fn test_default_config_path() {
    let p = get_default_config_path();
    assert!(p.parent().unwrap().exists());
    assert_eq!(p.file_name().unwrap(), OsStr::new(DEFAULT_CONFIG_NAME));
}
<commit_msg>add fixme: host independent test env<commit_after>use std::env;
use std::ffi::OsStr;
use std::fs::create_dir_all;
use std::path::{PathBuf};

// used to index values in map
pub static CHANGED_KEY: &'static str = "changed";
pub static NEW_KEY: &'static str = "new";
pub static STAGED_KEY: &'static str = "staged";
pub static CONFLICTS_KEY: &'static str = "conflicts";

pub static CURRENT_CONFIG_VERSION: &'static str = "1";

pub static DEFAULT_CONFIG_NAME: &'static str = "pretty-git-prompt.yml";

pub static CLI_DEFAULT_CONFIG_SUBC_NAME: &'static str = "create-default-config";

pub fn get_default_config_path() -> PathBuf {
    let mut p = match env::var("XDG_CONFIG_HOME") {
        Ok(val) => PathBuf::from(&val),
        Err(_) => {
            match env::var("HOME") {
                Ok(home) => {
                    let mut p2 = PathBuf::from(&home);
                    p2.push(".config");
                    p2
                },
                // we tried hard
                Err(_) => PathBuf::from("/tmp"),
            }
        }
    };
    create_dir_all(p.to_str().unwrap());
    p.push(DEFAULT_CONFIG_NAME);
    p
}

#[test]
fn test_default_config_path() {
    // FIXME: create test dir and remove it aftet testing
    let p = get_default_config_path();
    assert!(p.parent().unwrap().exists());
    assert_eq!(p.file_name().unwrap(), OsStr::new(DEFAULT_CONFIG_NAME));
}
<|endoftext|>


<commit_before>use std::io;
use std::io::prelude::*;
use std::collections::HashMap;

pub fn main() {
    let value: HashMap<char, usize> = (b'A'..b'Z' + 1)
                                          .enumerate()
                                          .map(|(i, c)| (c as char, i + 1))
                                          .collect();

    let triangle = (1..).map(|n| n * (n + 1) / 2);
    let first50triangle = triangle.take(50).collect::<Vec<_>>();
    let stdin = io::stdin();
    for line in stdin.lock().lines() {
        let line = line.unwrap().replace("\"", "");
        let names: Vec<&str> = line.split(",").collect();
        println!("{}",
                 names.iter()
                      .map(|name| {
                          name.chars().map(|c| value.get(&c).unwrap()).fold(0, |acc, i| acc + i)
                      })
                      .filter(|n| first50triangle.contains(n))
                      .count());
    }
}
<commit_msg>clippy: using a single-character str where a char could be used<commit_after>use std::io;
use std::io::prelude::*;
use std::collections::HashMap;

pub fn main() {
    let value: HashMap<char, usize> = (b'A'..b'Z' + 1)
                                          .enumerate()
                                          .map(|(i, c)| (c as char, i + 1))
                                          .collect();

    let triangle = (1..).map(|n| n * (n + 1) / 2);
    let first50triangle = triangle.take(50).collect::<Vec<_>>();
    let stdin = io::stdin();
    for line in stdin.lock().lines() {
        let line = line.unwrap().replace("\"", "");
        let names: Vec<&str> = line.split(',').collect();
        println!("{}",
                 names.iter()
                      .map(|name| {
                          name.chars().map(|c| value.get(&c).unwrap()).fold(0, |acc, i| acc + i)
                      })
                      .filter(|n| first50triangle.contains(n))
                      .count());
    }
}
<|endoftext|>