<commit_before>use std::convert::{From, Into};
use std::error::Error;
use std::fmt::{Debug, Display, Formatter};
use std::fmt;
use std::path::PathBuf;
use std::result::Result;
use std::str::FromStr;

use regex::Regex;

use storage::file::id_type::FileIDType;
use storage::file::hash::FileHash;

#[derive(Clone)]
pub struct FileID {
    id:         FileHash,
    id_type:    FileIDType,
}

impl FileID {

    pub fn new(id_type: FileIDType, id: FileHash) -> FileID {
        FileID {
            id: id,
            id_type: id_type,
        }
    }

    pub fn get_type(&self) -> FileIDType {
        self.id_type.clone()
    }

    pub fn get_id(&self) -> FileHash {
        self.id.clone()
    }

    pub fn parse(string: &String) -> Option<FileID> {
        // we assume that it is an path
        let regex = Regex::new(r"([:alnum:]*)-([:upper:]*)-([A-Za-z0-9-_]*)\.(.*)").unwrap();
        let s = string.split("/").last().unwrap_or("");

        debug!("Regex build: {:?}", regex);
        debug!("Matching string: '{}'", s);
        regex.captures(s).and_then(|capts| {
            // first one is the whole string, index 1-N are the matches.
            if capts.len() != 5 {
                debug!("Matches, but not expected number of groups");
                return None;
            }
            debug!("Matches: {}", capts.len());

            let modname     = capts.at(1).unwrap();
            let hashname    = capts.at(2).unwrap();
            let mut hash    = capts.at(3).unwrap();

            debug!("Destructure FilePath to ID:");
            debug!("                  FilePath: {:?}", s);
            debug!("               Module Name: {:?}", modname);
            debug!("                 Hash Name: {:?}", hashname);
            debug!("                      Hash: {:?}", hash);

            FileIDType::from_str(hashname).map(|idtype| {
                Some(FileID {
                    id: FileHash::from(hash),
                    id_type: idtype,
                })
            }).ok()
        }).unwrap_or({
            debug!("Did not match");
            debug!("It is no path, actually. So we assume it is an ID already");
            None
        })
    }

}

impl Debug for FileID {

    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        write!(fmt, "FileID[{:?}]: {:?}",
               self.id_type,
               self.id);
        Ok(())
    }

}

impl Display for FileID {

    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        write!(fmt, "FileID[{:?}]: {:?}",
               self.id_type,
               self.id);
        Ok(())
    }

}

impl Into<String> for FileID {

    fn into(self) -> String {
        let typestr : String = self.id_type.into();
        let idstr   : String = self.id.into();
        typestr + &idstr[..]
    }
}

#[cfg(test)]
mod test {

    use super::{FileID, FileIDType};

    #[test]
    fn file_id_from_string() {
        setup_logger();

        let s1 = String::from("/home/user/testmodule-UUID-some-id.imag");
        let s2 = String::from("/home/user/testmodule-UUID-some-id.extension.imag");
        let s3 = String::from("/home/user/testmodule-NOHASH-some-id.imag");

        let id1 = FileID::from(s1);
        let id2 = FileID::from(s2);
        let id3 = FileID::from(s3);

        println!("Id 1 : {:?}", id1);
        println!("Id 2 : {:?}", id2);
        println!("Id 3 : {:?}", id3);

        assert_eq!(FileIDType::UUID, id1.get_type());
        assert_eq!(FileIDType::UUID, id2.get_type());
        assert_eq!(FileIDType::NONE, id3.get_type());

        let f1 : String = id1.into();
        let f2 : String = id2.into();
        let f3 : String = id3.into();

        assert_eq!(String::from("some-id"), f1);
        assert_eq!(String::from("some-id"), f2);
        assert_eq!(String::from("INVALID"), f3);
    }

    fn setup_logger() {
        extern crate log;
        use log::{LogLevelFilter, set_logger};
        use runtime::ImagLogger;

        log::set_logger(|max_log_lvl| {
            let lvl = LogLevelFilter::Debug;
            max_log_lvl.set(lvl);
            Box::new(ImagLogger::new(lvl.to_log_level().unwrap()))
        });
        debug!("Init logger for test");
    }

}

<commit_msg>Derive: Hash for FileID<commit_after>use std::convert::{From, Into};
use std::error::Error;
use std::fmt::{Debug, Display, Formatter};
use std::fmt;
use std::hash::Hash;
use std::path::PathBuf;
use std::result::Result;
use std::str::FromStr;

use regex::Regex;

use storage::file::id_type::FileIDType;
use storage::file::hash::FileHash;

#[derive(Clone)]
#[derive(Hash)]
pub struct FileID {
    id:         FileHash,
    id_type:    FileIDType,
}

impl FileID {

    pub fn new(id_type: FileIDType, id: FileHash) -> FileID {
        FileID {
            id: id,
            id_type: id_type,
        }
    }

    pub fn get_type(&self) -> FileIDType {
        self.id_type.clone()
    }

    pub fn get_id(&self) -> FileHash {
        self.id.clone()
    }

    pub fn parse(string: &String) -> Option<FileID> {
        // we assume that it is an path
        let regex = Regex::new(r"([:alnum:]*)-([:upper:]*)-([A-Za-z0-9-_]*)\.(.*)").unwrap();
        let s = string.split("/").last().unwrap_or("");

        debug!("Regex build: {:?}", regex);
        debug!("Matching string: '{}'", s);
        regex.captures(s).and_then(|capts| {
            // first one is the whole string, index 1-N are the matches.
            if capts.len() != 5 {
                debug!("Matches, but not expected number of groups");
                return None;
            }
            debug!("Matches: {}", capts.len());

            let modname     = capts.at(1).unwrap();
            let hashname    = capts.at(2).unwrap();
            let mut hash    = capts.at(3).unwrap();

            debug!("Destructure FilePath to ID:");
            debug!("                  FilePath: {:?}", s);
            debug!("               Module Name: {:?}", modname);
            debug!("                 Hash Name: {:?}", hashname);
            debug!("                      Hash: {:?}", hash);

            FileIDType::from_str(hashname).map(|idtype| {
                Some(FileID {
                    id: FileHash::from(hash),
                    id_type: idtype,
                })
            }).ok()
        }).unwrap_or({
            debug!("Did not match");
            debug!("It is no path, actually. So we assume it is an ID already");
            None
        })
    }

}

impl Debug for FileID {

    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        write!(fmt, "FileID[{:?}]: {:?}",
               self.id_type,
               self.id);
        Ok(())
    }

}

impl Display for FileID {

    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        write!(fmt, "FileID[{:?}]: {:?}",
               self.id_type,
               self.id);
        Ok(())
    }

}

impl Into<String> for FileID {

    fn into(self) -> String {
        let typestr : String = self.id_type.into();
        let idstr   : String = self.id.into();
        typestr + &idstr[..]
    }
}

#[cfg(test)]
mod test {

    use super::{FileID, FileIDType};

    #[test]
    fn file_id_from_string() {
        setup_logger();

        let s1 = String::from("/home/user/testmodule-UUID-some-id.imag");
        let s2 = String::from("/home/user/testmodule-UUID-some-id.extension.imag");
        let s3 = String::from("/home/user/testmodule-NOHASH-some-id.imag");

        let id1 = FileID::from(s1);
        let id2 = FileID::from(s2);
        let id3 = FileID::from(s3);

        println!("Id 1 : {:?}", id1);
        println!("Id 2 : {:?}", id2);
        println!("Id 3 : {:?}", id3);

        assert_eq!(FileIDType::UUID, id1.get_type());
        assert_eq!(FileIDType::UUID, id2.get_type());
        assert_eq!(FileIDType::NONE, id3.get_type());

        let f1 : String = id1.into();
        let f2 : String = id2.into();
        let f3 : String = id3.into();

        assert_eq!(String::from("some-id"), f1);
        assert_eq!(String::from("some-id"), f2);
        assert_eq!(String::from("INVALID"), f3);
    }

    fn setup_logger() {
        extern crate log;
        use log::{LogLevelFilter, set_logger};
        use runtime::ImagLogger;

        log::set_logger(|max_log_lvl| {
            let lvl = LogLevelFilter::Debug;
            max_log_lvl.set(lvl);
            Box::new(ImagLogger::new(lvl.to_log_level().unwrap()))
        });
        debug!("Init logger for test");
    }

}

<|endoftext|>


<commit_before>extern crate clap;

use types::ToResult;
use std::path::PathBuf;
use std::fmt;
use std::env;
use std::fs;

#[derive(Debug)]
pub enum Action {
    Get,
    Put,
    Delete,
    List,
    Last,
    ChangeDirectory,
}

pub struct CLI<'a, 'b, 'd> where 'a: 'b, 'd {
    pub actions: [clap::Arg<'a, 'b>; 4],
    pub matches: clap::ArgMatches<'d>,
}

impl<'a, 'b, 'c> CLI<'a, 'b, 'c> {
    pub fn new<'d>(actions: [clap::Arg<'a, 'b>; 4], app: clap::App<'c, 'd>) -> Self {
        let matches = app.get_matches();

        println!("is_present delete: {:?}",  matches.is_present("delete"));
        println!("matches.value_of(\"action\"): {:?}",  matches.value_of("action"));

        // let names = actions.iter().map(|a| a.name).collect::<Vec<_>>();

        return CLI{ actions: actions, matches: matches};
    }
    //
    // pub fn run(&self) -> ToResult<Request> {
    //     for i in self.actions.iter() {
    //         println!("> {:?}", i.name);
    //     }
    //
    //
    //     return Ok(req);
    // }
}

pub fn parse_matches(matches: clap::ArgMatches) -> ToResult<Request> {
    let (get, put, delete, list, last) = (matches.is_present("get"),
                                          matches.is_present("put"),
                                          matches.is_present("delete"),
                                          matches.is_present("list"),
                                          matches.is_present("last"));

    let action = match (get, put, delete, list, last) {
        (true, _, _, _, _) => Action::Get,
        (_, true, _, _, _) => Action::Put,
        (_, _, true, _, _) => Action::Delete,
        (_, _, _, true, _) => Action::List,
        (_, _, _, _, true) => Action::Last,
        _               => Action::ChangeDirectory,
    };

    //     // to --save,--put # Save current dir as a bookmark
    //     // to --save,--put foo # Save current directory as bookmark foo
    //     // to --delete foo # Delete bookmark foo
    //     // to --info foo # Show details of the bookmark foo
    //     // to --list # List all the bookmarks
    //     // to foo # Go to the foo bookmark
    //     // reserve "-" so it can be used later.
    //     // to - # go to the last bookmark you visited

    println!("action: {:?}", action);
    let req = Request::new("foo", &PathBuf::from("."));
    return Ok(req);
}

//
//     // Take the matches from clap and convert them into name, directory, and
//     // action.
//     let request = match parse(program) {
//         Ok(value) => value,
//         Err(err) => panic!(err),
//     };
//
//
// }
//
// fn parse(cli: clap::App) -> ToResult<Request> {
//     let matches = cli.get_matches();
//     let pathname = matches.value_of("directory").unwrap_or("");
//
//     let directory = match resolve(pathname) {
//         Ok(value) => value,
//         Err(err) => return Err(err),
//     };
//
//     // Validate that the directory exists and is a directory.
//     // TODO: Move this into the resolve step.
//     if !is_valid_dir(&directory) {
//         panic!("invalid directory");
//     }
//
//     let name = match matches.value_of("name") {
//         Some(value) => value,
//         // directory.file_stem().map(|stem| stem.to_str()).unwrap()
//         None => "",
//     };
//
//     println!("directory: {:?}", directory);
//     println!("name: {:?}", name);
//
//     // let mut action = "save";
//     // // Increment the one requested (in a real program, we'd reset the lower numbers)
//     // let (save, delete, info, list) = (matches.is_present("save"),
//     //                              matches.is_present("delete"),
//     //                              matches.is_present("info"),
//     //                              matches.is_present("list"));
//     //
//     // match (save, delete, info, list) {
//     //     (true, _, _, _) => action = "save",
//     //     (_, true, _, _) => action = "delete",
//     //     (_, _, true, _) => action = "info",
//     //     (_, _, _, true) => action = "list",
//     //     _            => unreachable!(),
//     // };
//     //
//     // println!("action: {:?}", action);
//
//     let req = Request{ name: name.to_string(), directory: directory };
//
//     return Ok(req);
// }
//
// fn resolve(pathname: &str) -> ToResult<PathBuf> {
//     // TODO: Use a custom results tuple instead of panic!.
//     let mut absolute = match env::current_dir() {
//         Ok(value) => value,
//         Err(err) => return Err(ToError::Io(err)),
//     };
//
//     // Don't default to "." since it will be a literal translation creating
//     // dumb directories like "/foo/bar/."
//     if pathname != "." {
//         absolute.push(pathname);
//     }
//
//     return Ok(absolute);
// }
//
// fn is_valid_dir(directory: &PathBuf) -> bool {
//     let path = directory.clone();
//
//     let metadata = match fs::metadata(path) {
//         Ok(value) => value,
//         Err(_) => return false,
//     };
//
//     if metadata.is_dir() {
//         return true;
//     }
//
//     return false;
// }
//
//
// // static NUMBERS: &'static [i32] = &'static [1, 2, 3, 4, 5];
// // static C: [E; 3] = [E::V0, E::V1(0xDEADBEE), E::V0];
// static ACTIONS: [Arg; 1] = [
//     Arg::with_name("save")
//         .help("Saves bookmark")
//         .long("save")
//         .short("s")
// ];
//
// // .arg(Arg::with_name("delete")
// //     .help("Delete bookmark")
// //     .long("delete")
// //     .short("d"))
//
// // ["save", "delete", "info", "list"];

#[derive(Debug)]
pub struct Request {
    pub name: String,
    pub directory: PathBuf,
    pub action: Action,
}

impl Request {
    fn new(name: &str, directory: &PathBuf) -> Request {
        Request{ name: "foo".to_string(), directory: PathBuf::from("."), action: Action::Get}
    }
}
<commit_msg>Clenas up dead code.<commit_after>extern crate clap;

use types::ToResult;
use std::path::PathBuf;
use std::fmt;
use std::env;
use std::fs;

#[derive(Debug)]
pub enum Action {
    Get,
    Put,
    Delete,
    List,
    Last,
    ChangeDirectory,
}

pub fn parse_matches(matches: clap::ArgMatches) -> ToResult<Request> {
    let (get, put, delete, list, last) = (matches.is_present("get"),
                                          matches.is_present("put"),
                                          matches.is_present("delete"),
                                          matches.is_present("list"),
                                          matches.is_present("last"));

    let action = match (get, put, delete, list, last) {
        (true, _, _, _, _) => Action::Get,
        (_, true, _, _, _) => Action::Put,
        (_, _, true, _, _) => Action::Delete,
        (_, _, _, true, _) => Action::List,
        (_, _, _, _, true) => Action::Last,
        _                  => Action::ChangeDirectory,
    };

    // to --save,--put # Save current dir as a bookmark
    // to --save,--put foo # Save current directory as bookmark foo
    // to --delete foo # Delete bookmark foo
    // to --info foo # Show details of the bookmark foo
    // to --list # List all the bookmarks
    // to foo # Go to the foo bookmark
    // reserve "-" so it can be used later.
    // to - # go to the last bookmark you visited

    println!("action: {:?}", action);
    let req = Request::new("foo", &PathBuf::from("."));
    return Ok(req);
}

// fn parse(cli: clap::App) -> ToResult<Request> {
//     let matches = cli.get_matches();
//     let pathname = matches.value_of("directory").unwrap_or("");
//
//     let directory = match resolve(pathname) {
//         Ok(value) => value,
//         Err(err) => return Err(err),
//     };
//
//     // Validate that the directory exists and is a directory.
//     // TODO: Move this into the resolve step.
//     if !is_valid_dir(&directory) {
//         panic!("invalid directory");
//     }
//
//     let name = match matches.value_of("name") {
//         Some(value) => value,
//         // directory.file_stem().map(|stem| stem.to_str()).unwrap()
//         None => "",
//     };
//
//     println!("directory: {:?}", directory);
//     println!("name: {:?}", name);
//
//     // let mut action = "save";
//     // // Increment the one requested (in a real program, we'd reset the lower numbers)
//     // let (save, delete, info, list) = (matches.is_present("save"),
//     //                              matches.is_present("delete"),
//     //                              matches.is_present("info"),
//     //                              matches.is_present("list"));
//     //
//     // match (save, delete, info, list) {
//     //     (true, _, _, _) => action = "save",
//     //     (_, true, _, _) => action = "delete",
//     //     (_, _, true, _) => action = "info",
//     //     (_, _, _, true) => action = "list",
//     //     _            => unreachable!(),
//     // };
//     //
//     // println!("action: {:?}", action);
//
//     let req = Request{ name: name.to_string(), directory: directory };
//
//     return Ok(req);
// }
//
// fn resolve(pathname: &str) -> ToResult<PathBuf> {
//     // TODO: Use a custom results tuple instead of panic!.
//     let mut absolute = match env::current_dir() {
//         Ok(value) => value,
//         Err(err) => return Err(ToError::Io(err)),
//     };
//
//     // Don't default to "." since it will be a literal translation creating
//     // dumb directories like "/foo/bar/."
//     if pathname != "." {
//         absolute.push(pathname);
//     }
//
//     return Ok(absolute);
// }
//
// fn is_valid_dir(directory: &PathBuf) -> bool {
//     let path = directory.clone();
//
//     let metadata = match fs::metadata(path) {
//         Ok(value) => value,
//         Err(_) => return false,
//     };
//
//     if metadata.is_dir() {
//         return true;
//     }
//
//     return false;
// }
//
//
// // static NUMBERS: &'static [i32] = &'static [1, 2, 3, 4, 5];
// // static C: [E; 3] = [E::V0, E::V1(0xDEADBEE), E::V0];
// static ACTIONS: [Arg; 1] = [
//     Arg::with_name("save")
//         .help("Saves bookmark")
//         .long("save")
//         .short("s")
// ];
//
// // .arg(Arg::with_name("delete")
// //     .help("Delete bookmark")
// //     .long("delete")
// //     .short("d"))
//
// // ["save", "delete", "info", "list"];

#[derive(Debug)]
pub struct Request {
    pub name: String,
    pub directory: PathBuf,
    pub action: Action,
}

impl Request {
    fn new(name: &str, directory: &PathBuf) -> Request {
        Request{ name: "foo".to_string(), directory: PathBuf::from("."), action: Action::Get}
    }
}
<|endoftext|>


<commit_before>//! Useful parser combinators
//!
//! A number of useful parser combinators have already been implemented.
//! Some of them use macros, other are implemented through functions.
//! Hopefully, the syntax will converge to onely one way in the future,
//! but the macros system makes no promises.
//!

use std::fmt::Debug;
use internal::*;
use internal::IResult::*;
use std::mem::transmute;

pub fn tag_cl<'a,'b>(rec:&'a[u8]) ->  Box<Fn(&'b[u8]) -> IResult<&'b[u8], &'b[u8]> + 'a> {
  Box::new(move |i: &'b[u8]| -> IResult<&'b[u8], &'b[u8]> {
    if i.len() >= rec.len() && &i[0..rec.len()] == rec {
      Done(&i[rec.len()..], &i[0..rec.len()])
    } else {
      Error(0)
    }
  })
}

pub fn print<T: Debug>(input: T) -> IResult<T, ()> {
  println!("{:?}", input);
  Done(input, ())
}

pub fn begin<'a>(input: &'a [u8]) -> IResult<(), &'a [u8]> {
  Done((), input)
}

// FIXME: when rust-lang/rust#17436 is fixed, macros will be able to export
// public methods
//pub is_not!(line_ending b"\r\n")
pub fn not_line_ending(input:&[u8]) -> IResult<&[u8], &[u8]> {
  for idx in 0..input.len() {
    for &i in b"\r\n".iter() {
      if input[idx] == i {
        return Done(&input[idx..], &input[0..idx])
      }
    }
  }
  Done(b"", input)
}

named!(tag_ln<&[u8],&[u8]>, tag!("\n"));

pub fn line_ending(input:&[u8]) -> IResult<&[u8], &[u8]> {
  tag_ln(input)
}

pub fn is_alphabetic(chr:u8) -> bool {
  (chr >= 0x41 && chr <= 0x5A) || (chr >= 0x61 && chr <= 0x7A)
}

pub fn is_digit(chr: u8) -> bool {
  chr >= 0x30 && chr <= 0x39
}

pub fn is_alphanumeric(chr: u8) -> bool {
  is_alphabetic(chr) || is_digit(chr)
}

pub fn is_space(chr:u8) -> bool {
  chr == ' ' as u8 || chr == '\t' as u8
}

// FIXME: when rust-lang/rust#17436 is fixed, macros will be able to export
//pub filter!(alpha is_alphabetic)
//pub filter!(digit is_digit)
//pub filter!(alphanumeric is_alphanumeric)
pub fn alpha(input:&[u8]) -> IResult<&[u8], &[u8]> {
  for idx in 0..input.len() {
    if !is_alphabetic(input[idx]) {
      if idx == 0 {
        return Error(0)
      } else {
        return Done(&input[idx..], &input[0..idx])
      }
    }
  }
  Done(b"", input)
}

pub fn digit(input:&[u8]) -> IResult<&[u8], &[u8]> {
  for idx in 0..input.len() {
    if !is_digit(input[idx]) {
      if idx == 0 {
        return Error(0)
      } else {
        return Done(&input[idx..], &input[0..idx])
      }
    }
  }
  Done(b"", input)
}

pub fn alphanumeric(input:&[u8]) -> IResult<&[u8], &[u8]> {
  for idx in 0..input.len() {
    if !is_alphanumeric(input[idx]) {
      if idx == 0 {
        return Error(0)
      } else {
        return Done(&input[idx..], &input[0..idx])
      }
    }
  }
  Done(b"", input)
}

pub fn space(input:&[u8]) -> IResult<&[u8], &[u8]> {
  for idx in 0..input.len() {
    if !is_space(input[idx]) {
      if idx == 0 {
        return Error(0)
      } else {
        return Done(&input[idx..], &input[0..idx])
      }
    }
  }
  Done(b"", input)
}

pub fn multispace(input:&[u8]) -> IResult<&[u8], &[u8]> {
  for idx in 0..input.len() {
    println!("multispace at index: {}", idx);
    if !is_space(input[idx]) && input[idx] != '\r' as u8 && input[idx] != '\n' as u8 {
      if idx == 0 {
        return Error(0)
      } else {
        return Done(&input[idx..], &input[0..idx])
      }
    }
  }
  Done(b"", input)
}

pub fn sized_buffer(input:&[u8]) -> IResult<&[u8], &[u8]> {
  if input.len() == 0 {
    return Incomplete(Needed::Unknown)
  }

  let len = input[0] as usize;

  if input.len() >= len + 1 {
    return Done(&input[len+1..], &input[1..len+1])
  } else {
    return Incomplete(Needed::Size(1 + len as u32))
  }
}

pub fn length_value(input:&[u8]) -> IResult<&[u8], &[u8]> {
  let input_len = input.len();
  if input_len == 0 {
    return IResult::Error(0)
  }

  let len = input[0] as usize;
  if input_len - 1 >= len {
    return IResult::Done(&input[len+1..], &input[1..len+1])
  } else {
    // FIXME: return Incomplete
    return IResult::Incomplete(Needed::Size(1+len as u32))
  }
}

pub fn be_u8(i: &[u8]) -> IResult<&[u8], u8> {
  if i.len() < 1 {
    Incomplete(Needed::Size(1))
  } else {
    Done(&i[1..], i[0])
  }
}

pub fn be_u16(i: &[u8]) -> IResult<&[u8], u16> {
  if i.len() < 2 {
    Incomplete(Needed::Size(2))
  } else {
    let res = ((i[0] as u16) << 8) + i[1] as u16;
    Done(&i[2..], res)
  }
}

pub fn be_u32(i: &[u8]) -> IResult<&[u8], u32> {
  if i.len() < 4 {
    Incomplete(Needed::Size(4))
  } else {
    let res = ((i[0] as u32) << 24) + ((i[1] as u32) << 16) + ((i[2] as u32) << 8) + i[3] as u32;
    Done(&i[4..], res)
  }
}

pub fn be_u64(i: &[u8]) -> IResult<&[u8], u64> {
  if i.len() < 8 {
    Incomplete(Needed::Size(8))
  } else {
    let res = ((i[0] as u64) << 56) + ((i[1] as u64) << 48) + ((i[2] as u64) << 40) + ((i[3] as u64) << 32) +
      ((i[4] as u64) << 24) + ((i[5] as u64) << 16) + ((i[6] as u64) << 8) + i[7] as u64;
    Done(&i[8..], res)
  }
}

pub fn le_u8(i: &[u8]) -> IResult<&[u8], u8> {
  if i.len() < 1 {
    Incomplete(Needed::Size(1))
  } else {
    Done(&i[1..], i[0])
  }
}

pub fn le_u16(i: &[u8]) -> IResult<&[u8], u16> {
  if i.len() < 2 {
    Incomplete(Needed::Size(2))
  } else {
    let res = ((i[1] as u16) << 8) + i[0] as u16;
    Done(&i[2..], res)
  }
}

pub fn le_u32(i: &[u8]) -> IResult<&[u8], u32> {
  if i.len() < 4 {
    Incomplete(Needed::Size(4))
  } else {
    let res = ((i[3] as u32) << 24) + ((i[2] as u32) << 16) + ((i[1] as u32) << 8) + i[0] as u32;
    Done(&i[4..], res)
  }
}

pub fn le_u64(i: &[u8]) -> IResult<&[u8], u64> {
  if i.len() < 8 {
    Incomplete(Needed::Size(8))
  } else {
    let res = ((i[7] as u64) << 56) + ((i[6] as u64) << 48) + ((i[5] as u64) << 40) + ((i[4] as u64) << 32) +
      ((i[3] as u64) << 24) + ((i[2] as u64) << 16) + ((i[1] as u64) << 8) + i[0] as u64;
    Done(&i[8..], res)
  }
}

pub fn be_f32(input: &[u8]) -> IResult<&[u8], f32> {
  match be_u32(input) {
    Error(e)      => Error(e),
    Incomplete(e) => Incomplete(e),
    Done(i,o) => {
      unsafe {
        Done(i, transmute::<u32, f32>(o))
      }
    }
  }
}

pub fn be_f64(input: &[u8]) -> IResult<&[u8], f64> {
  match be_u64(input) {
    Error(e)      => Error(e),
    Incomplete(e) => Incomplete(e),
    Done(i,o) => {
      unsafe {
        Done(i, transmute::<u64, f64>(o))
      }
    }
  }
}

#[cfg(test)]
mod tests {
  use super::*;
  use internal::Needed;
  use internal::IResult::*;

  #[test]
  fn tag_closure() {
    let x = tag_cl(&b"abcd"[..]);
    let r = x(&b"abcdabcdefgh"[..]);
    assert_eq!(r, Done(&b"abcdefgh"[..], &b"abcd"[..]));

    let r2 = x(&b"abcefgh"[..]);
    assert_eq!(r2, Error(0));
  }

  #[test]
  fn character() {
    let empty: &[u8] = b"";
    let a: &[u8] = b"abcd";
    let b: &[u8] = b"1234";
    let c: &[u8] = b"a123";
    let d: &[u8] = "azé12".as_bytes();
    let e: &[u8] = b" ";
    assert_eq!(alpha(a), Done(empty, a));
    assert_eq!(alpha(b), Error(0));
    assert_eq!(alpha(c), Done(&c[1..], &b"a"[..]));
    assert_eq!(alpha(d), Done("é12".as_bytes(), &b"az"[..]));
    assert_eq!(digit(a), Error(0));
    assert_eq!(digit(b), Done(empty, b));
    assert_eq!(digit(c), Error(0));
    assert_eq!(digit(d), Error(0));
    assert_eq!(alphanumeric(a), Done(empty, a));
    assert_eq!(alphanumeric(b), Done(empty, b));
    assert_eq!(alphanumeric(c), Done(empty, c));
    assert_eq!(alphanumeric(d), Done("é12".as_bytes(), &b"az"[..]));
    assert_eq!(space(e), Done(&b""[..], &b" "[..]));
  }

  #[test]
  fn is_not() {
    let a: &[u8] = b"ab12cd\nefgh";
    assert_eq!(not_line_ending(a), Done(&b"\nefgh"[..], &b"ab12cd"[..]));

    let b: &[u8] = b"ab12cd\nefgh\nijkl";
    assert_eq!(not_line_ending(b), Done(&b"\nefgh\nijkl"[..], &b"ab12cd"[..]));

    let c: &[u8] = b"ab12cd";
    assert_eq!(not_line_ending(c), Done(&b""[..], c));
  }

  #[test]
  fn buffer_with_size() {
    let i:Vec<u8> = vec![7,8];
    let o:Vec<u8> = vec![4,5,6];
    //let arr:[u8; 6usize] = [3, 4, 5, 6, 7, 8];
    let arr:[u8; 6usize] = [3, 4, 5, 6, 7, 8];
    let res = sized_buffer(&arr[..]);
    assert_eq!(res, Done(&i[..], &o[..]))
  }

  /*#[test]
  fn t1() {
    let v1:Vec<u8> = vec![1,2,3];
    let v2:Vec<u8> = vec![4,5,6];
    let d = Done(&v1[..], &v2[..]);
    let res = d.flat_map(print);
    assert_eq!(res, Done(&v2[..], ()));
  }*/

  #[test]
  fn length_value_test() {
    let i1 = vec![7,8];
    let o1 = vec![4, 5, 6];
    let arr1:[u8; 6usize] = [3, 4, 5, 6, 7, 8];
    let res1 = length_value(&arr1);
    assert_eq!(Done(&i1[..], &o1[..]), res1);

    let i2:Vec<u8> = vec![4,5,6,7,8];
    let o2: &[u8] = b"";
    let arr2:[u8; 6usize] = [0, 4, 5, 6, 7, 8];
    let res2 = length_value(&arr2);
    assert_eq!(Done(&i2[..], o2), res2);

    let arr3:[u8; 7usize] = [8, 4, 5, 6, 7, 8, 9];
    let res3 = length_value(&arr3);
    //FIXME: should be incomplete
    assert_eq!(Incomplete(Needed::Size(9)), res3);
  }

}
<commit_msg>Removed debug message from multispace<commit_after>//! Useful parser combinators
//!
//! A number of useful parser combinators have already been implemented.
//! Some of them use macros, other are implemented through functions.
//! Hopefully, the syntax will converge to onely one way in the future,
//! but the macros system makes no promises.
//!

use std::fmt::Debug;
use internal::*;
use internal::IResult::*;
use std::mem::transmute;

pub fn tag_cl<'a,'b>(rec:&'a[u8]) ->  Box<Fn(&'b[u8]) -> IResult<&'b[u8], &'b[u8]> + 'a> {
  Box::new(move |i: &'b[u8]| -> IResult<&'b[u8], &'b[u8]> {
    if i.len() >= rec.len() && &i[0..rec.len()] == rec {
      Done(&i[rec.len()..], &i[0..rec.len()])
    } else {
      Error(0)
    }
  })
}

pub fn print<T: Debug>(input: T) -> IResult<T, ()> {
  println!("{:?}", input);
  Done(input, ())
}

pub fn begin<'a>(input: &'a [u8]) -> IResult<(), &'a [u8]> {
  Done((), input)
}

// FIXME: when rust-lang/rust#17436 is fixed, macros will be able to export
// public methods
//pub is_not!(line_ending b"\r\n")
pub fn not_line_ending(input:&[u8]) -> IResult<&[u8], &[u8]> {
  for idx in 0..input.len() {
    for &i in b"\r\n".iter() {
      if input[idx] == i {
        return Done(&input[idx..], &input[0..idx])
      }
    }
  }
  Done(b"", input)
}

named!(tag_ln<&[u8],&[u8]>, tag!("\n"));

pub fn line_ending(input:&[u8]) -> IResult<&[u8], &[u8]> {
  tag_ln(input)
}

pub fn is_alphabetic(chr:u8) -> bool {
  (chr >= 0x41 && chr <= 0x5A) || (chr >= 0x61 && chr <= 0x7A)
}

pub fn is_digit(chr: u8) -> bool {
  chr >= 0x30 && chr <= 0x39
}

pub fn is_alphanumeric(chr: u8) -> bool {
  is_alphabetic(chr) || is_digit(chr)
}

pub fn is_space(chr:u8) -> bool {
  chr == ' ' as u8 || chr == '\t' as u8
}

// FIXME: when rust-lang/rust#17436 is fixed, macros will be able to export
//pub filter!(alpha is_alphabetic)
//pub filter!(digit is_digit)
//pub filter!(alphanumeric is_alphanumeric)
pub fn alpha(input:&[u8]) -> IResult<&[u8], &[u8]> {
  for idx in 0..input.len() {
    if !is_alphabetic(input[idx]) {
      if idx == 0 {
        return Error(0)
      } else {
        return Done(&input[idx..], &input[0..idx])
      }
    }
  }
  Done(b"", input)
}

pub fn digit(input:&[u8]) -> IResult<&[u8], &[u8]> {
  for idx in 0..input.len() {
    if !is_digit(input[idx]) {
      if idx == 0 {
        return Error(0)
      } else {
        return Done(&input[idx..], &input[0..idx])
      }
    }
  }
  Done(b"", input)
}

pub fn alphanumeric(input:&[u8]) -> IResult<&[u8], &[u8]> {
  for idx in 0..input.len() {
    if !is_alphanumeric(input[idx]) {
      if idx == 0 {
        return Error(0)
      } else {
        return Done(&input[idx..], &input[0..idx])
      }
    }
  }
  Done(b"", input)
}

pub fn space(input:&[u8]) -> IResult<&[u8], &[u8]> {
  for idx in 0..input.len() {
    if !is_space(input[idx]) {
      if idx == 0 {
        return Error(0)
      } else {
        return Done(&input[idx..], &input[0..idx])
      }
    }
  }
  Done(b"", input)
}

pub fn multispace(input:&[u8]) -> IResult<&[u8], &[u8]> {
  for idx in 0..input.len() {
    // println!("multispace at index: {}", idx);
    if !is_space(input[idx]) && input[idx] != '\r' as u8 && input[idx] != '\n' as u8 {
      if idx == 0 {
        return Error(0)
      } else {
        return Done(&input[idx..], &input[0..idx])
      }
    }
  }
  Done(b"", input)
}

pub fn sized_buffer(input:&[u8]) -> IResult<&[u8], &[u8]> {
  if input.len() == 0 {
    return Incomplete(Needed::Unknown)
  }

  let len = input[0] as usize;

  if input.len() >= len + 1 {
    return Done(&input[len+1..], &input[1..len+1])
  } else {
    return Incomplete(Needed::Size(1 + len as u32))
  }
}

pub fn length_value(input:&[u8]) -> IResult<&[u8], &[u8]> {
  let input_len = input.len();
  if input_len == 0 {
    return IResult::Error(0)
  }

  let len = input[0] as usize;
  if input_len - 1 >= len {
    return IResult::Done(&input[len+1..], &input[1..len+1])
  } else {
    // FIXME: return Incomplete
    return IResult::Incomplete(Needed::Size(1+len as u32))
  }
}

pub fn be_u8(i: &[u8]) -> IResult<&[u8], u8> {
  if i.len() < 1 {
    Incomplete(Needed::Size(1))
  } else {
    Done(&i[1..], i[0])
  }
}

pub fn be_u16(i: &[u8]) -> IResult<&[u8], u16> {
  if i.len() < 2 {
    Incomplete(Needed::Size(2))
  } else {
    let res = ((i[0] as u16) << 8) + i[1] as u16;
    Done(&i[2..], res)
  }
}

pub fn be_u32(i: &[u8]) -> IResult<&[u8], u32> {
  if i.len() < 4 {
    Incomplete(Needed::Size(4))
  } else {
    let res = ((i[0] as u32) << 24) + ((i[1] as u32) << 16) + ((i[2] as u32) << 8) + i[3] as u32;
    Done(&i[4..], res)
  }
}

pub fn be_u64(i: &[u8]) -> IResult<&[u8], u64> {
  if i.len() < 8 {
    Incomplete(Needed::Size(8))
  } else {
    let res = ((i[0] as u64) << 56) + ((i[1] as u64) << 48) + ((i[2] as u64) << 40) + ((i[3] as u64) << 32) +
      ((i[4] as u64) << 24) + ((i[5] as u64) << 16) + ((i[6] as u64) << 8) + i[7] as u64;
    Done(&i[8..], res)
  }
}

pub fn le_u8(i: &[u8]) -> IResult<&[u8], u8> {
  if i.len() < 1 {
    Incomplete(Needed::Size(1))
  } else {
    Done(&i[1..], i[0])
  }
}

pub fn le_u16(i: &[u8]) -> IResult<&[u8], u16> {
  if i.len() < 2 {
    Incomplete(Needed::Size(2))
  } else {
    let res = ((i[1] as u16) << 8) + i[0] as u16;
    Done(&i[2..], res)
  }
}

pub fn le_u32(i: &[u8]) -> IResult<&[u8], u32> {
  if i.len() < 4 {
    Incomplete(Needed::Size(4))
  } else {
    let res = ((i[3] as u32) << 24) + ((i[2] as u32) << 16) + ((i[1] as u32) << 8) + i[0] as u32;
    Done(&i[4..], res)
  }
}

pub fn le_u64(i: &[u8]) -> IResult<&[u8], u64> {
  if i.len() < 8 {
    Incomplete(Needed::Size(8))
  } else {
    let res = ((i[7] as u64) << 56) + ((i[6] as u64) << 48) + ((i[5] as u64) << 40) + ((i[4] as u64) << 32) +
      ((i[3] as u64) << 24) + ((i[2] as u64) << 16) + ((i[1] as u64) << 8) + i[0] as u64;
    Done(&i[8..], res)
  }
}

pub fn be_f32(input: &[u8]) -> IResult<&[u8], f32> {
  match be_u32(input) {
    Error(e)      => Error(e),
    Incomplete(e) => Incomplete(e),
    Done(i,o) => {
      unsafe {
        Done(i, transmute::<u32, f32>(o))
      }
    }
  }
}

pub fn be_f64(input: &[u8]) -> IResult<&[u8], f64> {
  match be_u64(input) {
    Error(e)      => Error(e),
    Incomplete(e) => Incomplete(e),
    Done(i,o) => {
      unsafe {
        Done(i, transmute::<u64, f64>(o))
      }
    }
  }
}

#[cfg(test)]
mod tests {
  use super::*;
  use internal::Needed;
  use internal::IResult::*;

  #[test]
  fn tag_closure() {
    let x = tag_cl(&b"abcd"[..]);
    let r = x(&b"abcdabcdefgh"[..]);
    assert_eq!(r, Done(&b"abcdefgh"[..], &b"abcd"[..]));

    let r2 = x(&b"abcefgh"[..]);
    assert_eq!(r2, Error(0));
  }

  #[test]
  fn character() {
    let empty: &[u8] = b"";
    let a: &[u8] = b"abcd";
    let b: &[u8] = b"1234";
    let c: &[u8] = b"a123";
    let d: &[u8] = "azé12".as_bytes();
    let e: &[u8] = b" ";
    assert_eq!(alpha(a), Done(empty, a));
    assert_eq!(alpha(b), Error(0));
    assert_eq!(alpha(c), Done(&c[1..], &b"a"[..]));
    assert_eq!(alpha(d), Done("é12".as_bytes(), &b"az"[..]));
    assert_eq!(digit(a), Error(0));
    assert_eq!(digit(b), Done(empty, b));
    assert_eq!(digit(c), Error(0));
    assert_eq!(digit(d), Error(0));
    assert_eq!(alphanumeric(a), Done(empty, a));
    assert_eq!(alphanumeric(b), Done(empty, b));
    assert_eq!(alphanumeric(c), Done(empty, c));
    assert_eq!(alphanumeric(d), Done("é12".as_bytes(), &b"az"[..]));
    assert_eq!(space(e), Done(&b""[..], &b" "[..]));
  }

  #[test]
  fn is_not() {
    let a: &[u8] = b"ab12cd\nefgh";
    assert_eq!(not_line_ending(a), Done(&b"\nefgh"[..], &b"ab12cd"[..]));

    let b: &[u8] = b"ab12cd\nefgh\nijkl";
    assert_eq!(not_line_ending(b), Done(&b"\nefgh\nijkl"[..], &b"ab12cd"[..]));

    let c: &[u8] = b"ab12cd";
    assert_eq!(not_line_ending(c), Done(&b""[..], c));
  }

  #[test]
  fn buffer_with_size() {
    let i:Vec<u8> = vec![7,8];
    let o:Vec<u8> = vec![4,5,6];
    //let arr:[u8; 6usize] = [3, 4, 5, 6, 7, 8];
    let arr:[u8; 6usize] = [3, 4, 5, 6, 7, 8];
    let res = sized_buffer(&arr[..]);
    assert_eq!(res, Done(&i[..], &o[..]))
  }

  /*#[test]
  fn t1() {
    let v1:Vec<u8> = vec![1,2,3];
    let v2:Vec<u8> = vec![4,5,6];
    let d = Done(&v1[..], &v2[..]);
    let res = d.flat_map(print);
    assert_eq!(res, Done(&v2[..], ()));
  }*/

  #[test]
  fn length_value_test() {
    let i1 = vec![7,8];
    let o1 = vec![4, 5, 6];
    let arr1:[u8; 6usize] = [3, 4, 5, 6, 7, 8];
    let res1 = length_value(&arr1);
    assert_eq!(Done(&i1[..], &o1[..]), res1);

    let i2:Vec<u8> = vec![4,5,6,7,8];
    let o2: &[u8] = b"";
    let arr2:[u8; 6usize] = [0, 4, 5, 6, 7, 8];
    let res2 = length_value(&arr2);
    assert_eq!(Done(&i2[..], o2), res2);

    let arr3:[u8; 7usize] = [8, 4, 5, 6, 7, 8, 9];
    let res3 = length_value(&arr3);
    //FIXME: should be incomplete
    assert_eq!(Incomplete(Needed::Size(9)), res3);
  }

}
<|endoftext|>


<commit_before>//! Interface to C-libs.
//!
//! Currently only libbitcoinconsensus

extern crate libc;

#[link(name = "bitcoinconsensus")]
extern {

/* EXPORT_SYMBOL int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen,
                                                 const unsigned char *txTo        , unsigned int txToLen,
                                                 unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err);
*/

    pub fn bitcoinconsensus_verify_script(
        prevout_script:      *const u8,
        prevout_script_size: u32,
        transaction:         *const u8,
        transaction_size:    u32,
        tx_input_index:      u32,
        flags:               u32,
        err:                 *mut i32
    )

        -> i32;
}

#[derive(Debug)]
pub enum VerifyScriptError {
    UnknownError
}

/// Verifies whether the given `input` of the transaction spends the given `output`
/// using libbitcoin-consensus

pub fn verify_script(previous_tx_out: &[u8], transaction: &[u8], input: u32) -> Result<(), VerifyScriptError> {
    let flags = 0;
    let mut err: i32 = 0;
    let result = unsafe { bitcoinconsensus_verify_script(
        previous_tx_out.as_ptr(),
        previous_tx_out.len()  as u32,
        transaction.as_ptr(),
        transaction.len() as u32,
        input as u32,
        flags,
        &mut err
    ) };

    if result == 1 {
        Ok(())
    }
    else {
        Err(VerifyScriptError::UnknownError)
    }
}

#[cfg(test)]
mod tests {

}
<commit_msg>Update ffi::verify_script to return useful errors<commit_after>//! Interface to C-libs.
//!
//! Currently only libbitcoinconsensus

extern crate libc;

#[link(name = "bitcoinconsensus")]
extern {

/* EXPORT_SYMBOL int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen,
                                                 const unsigned char *txTo        , unsigned int txToLen,
                                                 unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err);
*/

    pub fn bitcoinconsensus_verify_script(
        prevout_script:      *const u8,
        prevout_script_size: u32,
        transaction:         *const u8,
        transaction_size:    u32,
        tx_input_index:      u32,
        flags:               u32,
        err:                 *mut i32
    )

        -> i32;
}

// typedef enum bitcoinconsensus_error_t
// {
//     bitcoinconsensus_ERR_OK = 0,
//     bitcoinconsensus_ERR_TX_INDEX,
//     bitcoinconsensus_ERR_TX_SIZE_MISMATCH,
//     bitcoinconsensus_ERR_TX_DESERIALIZE,
//     bitcoinconsensus_ERR_AMOUNT_REQUIRED,
//     bitcoinconsensus_ERR_INVALID_FLAGS,
// } bitcoinconsensus_error;

#[derive(Debug)]
pub enum VerifyScriptError {
    Index,
    SizeMismatch,
    Deserialize,
    AmountRequired,
    InvalidFlags,
}

/// Verifies whether the given `input` of the transaction spends the given `output`
/// using libbitcoin-consensus

pub fn verify_script(previous_tx_out: &[u8], transaction: &[u8], input: u32) -> Result<(), VerifyScriptError> {
    let flags = 0;
    let mut err: i32 = 0;
    let result = unsafe { bitcoinconsensus_verify_script(
        previous_tx_out.as_ptr(),
        previous_tx_out.len()  as u32,
        transaction.as_ptr(),
        transaction.len() as u32,
        input as u32,
        flags,
        &mut err
    ) };

    if result == 1 {
        Ok(())
    }
    else {
        Err(match err {
            0 => VerifyScriptError::Index,
            1 => VerifyScriptError::SizeMismatch,
            2  => VerifyScriptError::Deserialize,
            3  => VerifyScriptError::AmountRequired,
            4  => VerifyScriptError::InvalidFlags,
            _ => unreachable!()
        })
    }
}

#[cfg(test)]
mod tests {

}
<|endoftext|>


<commit_before>use libc;
use instruction::Insn;
use constants::{CsArch, CsMode, CsErr};
use csh;

#[allow(dead_code)]
#[link(name = "capstone")]
extern "C" {
    pub fn cs_open(arch: CsArch, mode: CsMode, handle: *mut csh) -> CsErr;
    pub fn cs_close(handle: *mut csh) -> CsErr;
    pub fn cs_disasm(handle: csh,
                     code: *const u8,
                     code_size: libc::size_t,
                     address: u64,
                     count: libc::size_t,
                     insn: &mut *const Insn)
                     -> libc::size_t;
    pub fn cs_disasm_ex(handle: csh,
                        code: *const u8,
                        code_size: libc::size_t,
                        address: u64,
                        count: libc::size_t,
                        insn: &mut *const Insn)
                        -> libc::size_t;
    pub fn cs_free(insn: *const Insn, count: libc::size_t);
    pub fn cs_reg_name(handle: csh, reg_id: libc::size_t) -> *const libc::c_char;
    pub fn cs_insn_name(handle: csh, insn_id: libc::size_t) -> *const libc::c_char;
    pub fn cs_errno(handle: csh) -> CsErr;
    pub fn cs_strerror(err: CsErr) -> *const libc::c_char;
}
<commit_msg>Remove deprecated function<commit_after>use libc;
use instruction::Insn;
use constants::{CsArch, CsMode, CsErr};
use csh;

#[allow(dead_code)]
#[link(name = "capstone")]
extern "C" {
    pub fn cs_open(arch: CsArch, mode: CsMode, handle: *mut csh) -> CsErr;
    pub fn cs_close(handle: *mut csh) -> CsErr;
    pub fn cs_disasm(handle: csh,
                     code: *const u8,
                     code_size: libc::size_t,
                     address: u64,
                     count: libc::size_t,
                     insn: &mut *const Insn)
                     -> libc::size_t;
    pub fn cs_free(insn: *const Insn, count: libc::size_t);
    pub fn cs_reg_name(handle: csh, reg_id: libc::size_t) -> *const libc::c_char;
    pub fn cs_insn_name(handle: csh, insn_id: libc::size_t) -> *const libc::c_char;
    pub fn cs_errno(handle: csh) -> CsErr;
    pub fn cs_strerror(err: CsErr) -> *const libc::c_char;
}
<|endoftext|>


<commit_before>//! Utilities related to FFI bindings.

use vec::Vec;
use boxed::Box;

/// Represents an owned C style string
///
/// This type generates compatible C-strings from Rust. It guarantees that
/// there is no null bytes in the string and that the string is ended by a null
/// byte.
pub struct CString {
    data: Box<[u8]>,
}

impl CString {
    /// Creates a new C style string
    ///
    /// This will ensure that no null byte is present in the string or return
    /// and error if that's the case. It will also add the final null byte.
    pub fn new<T: Into<Vec<u8>>>(t: T) -> Result<CString, ()> {
        let mut v = t.into();

        for b in &v {
            if *b == 0 {
                return Err(());
            }
        }

        v.push(0);

        Ok(CString {
            data: v.into_boxed_slice(),
        })
    }

    /// Return the raw representation of the string.
    ///
    /// This buffer is guaranteed without intermediate null bytes and includes
    /// the trailing null byte.
    pub fn as_bytes_with_nul(&self) -> &[u8] {
        &*self.data
    }
}
<commit_msg>ffi: CString now derives Clone<commit_after>//! Utilities related to FFI bindings.

use vec::Vec;
use boxed::Box;

#[derive(Clone)]
/// Represents an owned C style string
///
/// This type generates compatible C-strings from Rust. It guarantees that
/// there is no null bytes in the string and that the string is ended by a null
/// byte.
pub struct CString {
    data: Box<[u8]>,
}

impl CString {
    /// Creates a new C style string
    ///
    /// This will ensure that no null byte is present in the string or return
    /// and error if that's the case. It will also add the final null byte.
    pub fn new<T: Into<Vec<u8>>>(t: T) -> Result<CString, ()> {
        let mut v = t.into();

        for b in &v {
            if *b == 0 {
                return Err(());
            }
        }

        v.push(0);

        Ok(CString {
            data: v.into_boxed_slice(),
        })
    }

    /// Return the raw representation of the string.
    ///
    /// This buffer is guaranteed without intermediate null bytes and includes
    /// the trailing null byte.
    pub fn as_bytes_with_nul(&self) -> &[u8] {
        &*self.data
    }
}
<|endoftext|>


<commit_before>use raw::*;
use context::Context;
use function::CompiledFunction;
use libc::c_uint;
use util::NativeRef;
use std::fmt::Show;
use std::kinds::marker::ContravariantLifetime;
use std::mem::transmute;
use std::iter::Iterator;
use std::c_str::ToCStr;
/// An ELF dependency iterator
pub struct Needed<'a> {
    _reader: jit_readelf_t,
    index: c_uint,
    length: c_uint,
    marker: ContravariantLifetime<'a>
}
impl<'a> Needed<'a> {
    #[inline(always)]
    fn new(read:&ReadElf<'a>) -> Needed<'a> {
        unsafe {
            Needed {
                _reader: read.as_ptr(),
                index: 0 as c_uint,
                length: jit_readelf_num_needed(read.as_ptr()),
                marker: ContravariantLifetime::<'a>
            }
        }
    }
}
impl<'a> Iterator<String> for Needed<'a> {
    fn next(&mut self) -> Option<String> {
        let index = self.index;
        self.index += 1;
        unsafe {
            if index < self.length {
                let c_name = jit_readelf_get_needed(self._reader, index);
                let name = String::from_raw_buf(transmute(c_name));
                Some(name)
            } else {
                None
            }
        }
    }
    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        ((self.length - self.index) as uint, None)
    }
    #[inline]
    fn count(&mut self) -> uint {
        let count = self.length - self.index;
        self.index = self.length;
        count as uint
    }
    #[inline]
    fn nth(&mut self, n:uint) -> Option<String> {
        self.index += n as c_uint;
        self.next()
    }
}
/// An ELF binary reader
native_ref!(ReadElf, _reader, jit_readelf_t, ContravariantLifetime)
impl<'a> ReadElf<'a> {
    /// Open a new ELF binary
    pub fn new<S:ToCStr+Show>(filename:S) -> ReadElf<'a> {
        unsafe {
            let mut this = RawPtr::null();
            let code = filename.with_c_str(|c_name|
                jit_readelf_open(&mut this, c_name, 0)
            );
            if this.is_null() {
                panic!("'{}' couldn't be opened due to {}", filename, code);
            } else {
                NativeRef::from_ptr(this)
            }
        }
    }
    #[inline]
    /// Get the name of this ELF binary
    pub fn get_name(&self) -> String {
        unsafe {
            String::from_raw_buf(transmute(jit_readelf_get_name(self.as_ptr())))
        }
    }
    #[inline]
    pub fn add_to_context(&self, ctx:&Context<'a>) {
        unsafe {
            jit_readelf_add_to_context(self.as_ptr(), ctx.as_ptr())
        }
    }
    #[inline]
    /// Get a symbol in the ELF binary
    pub unsafe fn get_symbol<T, S:ToCStr>(&self, symbol:S) -> &'a mut T {
        symbol.with_c_str(|c_symbol|
            transmute(jit_readelf_get_symbol(self.as_ptr(), c_symbol))
        )
    }
    #[inline]
    /// Iterate over the needed libraries
    pub fn needed<'a>(&'a self) -> Needed<'a> {
        Needed::new(self)
    }
}
#[unsafe_destructor]
impl<'a> Drop for ReadElf<'a> {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            jit_readelf_close(self.as_ptr())
        }
    }
}

/// An ELF binary reader
native_ref!(WriteElf, _writer, jit_writeelf_t, ContravariantLifetime)
impl<'a> WriteElf<'a> {
    #[inline]
    /// Create a new ELF binary reader
    pub fn new<S:ToCStr>(lib_name:S) -> WriteElf<'a> {
        lib_name.with_c_str(|c_lib_name| unsafe {
            NativeRef::from_ptr(jit_writeelf_create(c_lib_name))
        })
    }
    #[inline]
    /// Write to the filename given (not implemented by LibJIT yet)
    pub fn write<S:ToCStr>(&self, filename:S) -> bool {
        filename.with_c_str(|c_filename| unsafe {
            jit_writeelf_write(self.as_ptr(), c_filename) != 0
        })
    }
    #[inline]
    /// Add a function to the ELF
    pub fn add_function<S:ToCStr>(&self, func:&'a CompiledFunction<'a>, name:S) -> bool {
        name.with_c_str(|c_name| unsafe {
            jit_writeelf_add_function(self.as_ptr(), func.as_ptr(), c_name) != 0
        })
    }
    #[inline]
    /// Add a dependency to the ELF
    pub fn add_needed<S:ToCStr>(&self, lib_name:S) -> bool {
        lib_name.with_c_str(|c_lib_name| unsafe {
            jit_writeelf_add_needed(self.as_ptr(), c_lib_name) != 0
        })
    }
}
#[unsafe_destructor]
impl<'a> Drop for WriteElf<'a> {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            jit_writeelf_destroy(self.as_ptr())
        }
    }
}<commit_msg>Fix for latest Rust by not implementing old Iterator methods<commit_after>use raw::*;
use context::Context;
use function::CompiledFunction;
use libc::c_uint;
use util::NativeRef;
use std::fmt::Show;
use std::kinds::marker::ContravariantLifetime;
use std::mem::transmute;
use std::iter::Iterator;
use std::c_str::ToCStr;
/// An ELF dependency iterator
pub struct Needed<'a> {
    _reader: jit_readelf_t,
    index: c_uint,
    length: c_uint,
    marker: ContravariantLifetime<'a>
}
impl<'a> Needed<'a> {
    #[inline(always)]
    fn new(read:&ReadElf<'a>) -> Needed<'a> {
        unsafe {
            Needed {
                _reader: read.as_ptr(),
                index: 0 as c_uint,
                length: jit_readelf_num_needed(read.as_ptr()),
                marker: ContravariantLifetime::<'a>
            }
        }
    }
}
impl<'a> Iterator<String> for Needed<'a> {
    fn next(&mut self) -> Option<String> {
        let index = self.index;
        self.index += 1;
        unsafe {
            if index < self.length {
                let c_name = jit_readelf_get_needed(self._reader, index);
                let name = String::from_raw_buf(transmute(c_name));
                Some(name)
            } else {
                None
            }
        }
    }
    #[inline]
    fn size_hint(&self) -> (uint, Option<uint>) {
        ((self.length - self.index) as uint, None)
    }
}
/// An ELF binary reader
native_ref!(ReadElf, _reader, jit_readelf_t, ContravariantLifetime)
impl<'a> ReadElf<'a> {
    /// Open a new ELF binary
    pub fn new<S:ToCStr+Show>(filename:S) -> ReadElf<'a> {
        unsafe {
            let mut this = RawPtr::null();
            let code = filename.with_c_str(|c_name|
                jit_readelf_open(&mut this, c_name, 0)
            );
            if this.is_null() {
                panic!("'{}' couldn't be opened due to {}", filename, code);
            } else {
                NativeRef::from_ptr(this)
            }
        }
    }
    #[inline]
    /// Get the name of this ELF binary
    pub fn get_name(&self) -> String {
        unsafe {
            String::from_raw_buf(transmute(jit_readelf_get_name(self.as_ptr())))
        }
    }
    #[inline]
    pub fn add_to_context(&self, ctx:&Context<'a>) {
        unsafe {
            jit_readelf_add_to_context(self.as_ptr(), ctx.as_ptr())
        }
    }
    #[inline]
    /// Get a symbol in the ELF binary
    pub unsafe fn get_symbol<T, S:ToCStr>(&self, symbol:S) -> &'a mut T {
        symbol.with_c_str(|c_symbol|
            transmute(jit_readelf_get_symbol(self.as_ptr(), c_symbol))
        )
    }
    #[inline]
    /// Iterate over the needed libraries
    pub fn needed<'a>(&'a self) -> Needed<'a> {
        Needed::new(self)
    }
}
#[unsafe_destructor]
impl<'a> Drop for ReadElf<'a> {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            jit_readelf_close(self.as_ptr())
        }
    }
}

/// An ELF binary reader
native_ref!(WriteElf, _writer, jit_writeelf_t, ContravariantLifetime)
impl<'a> WriteElf<'a> {
    #[inline]
    /// Create a new ELF binary reader
    pub fn new<S:ToCStr>(lib_name:S) -> WriteElf<'a> {
        lib_name.with_c_str(|c_lib_name| unsafe {
            NativeRef::from_ptr(jit_writeelf_create(c_lib_name))
        })
    }
    #[inline]
    /// Write to the filename given (not implemented by LibJIT yet)
    pub fn write<S:ToCStr>(&self, filename:S) -> bool {
        filename.with_c_str(|c_filename| unsafe {
            jit_writeelf_write(self.as_ptr(), c_filename) != 0
        })
    }
    #[inline]
    /// Add a function to the ELF
    pub fn add_function<S:ToCStr>(&self, func:&'a CompiledFunction<'a>, name:S) -> bool {
        name.with_c_str(|c_name| unsafe {
            jit_writeelf_add_function(self.as_ptr(), func.as_ptr(), c_name) != 0
        })
    }
    #[inline]
    /// Add a dependency to the ELF
    pub fn add_needed<S:ToCStr>(&self, lib_name:S) -> bool {
        lib_name.with_c_str(|c_lib_name| unsafe {
            jit_writeelf_add_needed(self.as_ptr(), c_lib_name) != 0
        })
    }
}
#[unsafe_destructor]
impl<'a> Drop for WriteElf<'a> {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            jit_writeelf_destroy(self.as_ptr())
        }
    }
}<|endoftext|>


<commit_before>use super::Vector;
use super::Vector4;

pub struct Vector4f {
    pub x: f32,
    pub y: f32,
    pub z: f32,
    pub w: f32,
}

impl Vector<f32> for Vector4f {
    fn add<'a, V>(&mut self, rhs: &'a V) -> &mut Self
        where Self: From<&'a V>
    {
        unimplemented!()
    }

    fn add_into<'a, V>(&self, rhs: &'a V, dest: &mut Self)
        where Self: From<&'a V>
    {
        unimplemented!()
    }

    fn angle<'a, V>(&self, rhs: &'a V) -> f32
        where Self: From<&'a V>
    {
        unimplemented!()
    }

    fn angle_cos<'a, V>(&self, rhs: &'a V) -> f32
        where Self: From<&'a V>
    {
        unimplemented!()
    }

    fn distance<'a, V>(&self, rhs: &'a V) -> f32
        where Self: From<&'a V>
    {
        unimplemented!()
    }

    fn distance_sq<'a, V>(&self, rhs: &'a V) -> f32
        where Self: From<&'a V>
    {
        unimplemented!()
    }

    fn dot<'a, V>(&self, rhs: &'a V) -> f32
        where Self: From<&'a V>
    {
        unimplemented!()
    }

    fn fma<'a, V>(&mut self, a: &'a V, b: &'a V) -> &mut Self
        where Self: From<&'a V>
    {
        unimplemented!()
    }

    fn fma_into<'a, V>(&self, a: &'a V, b: &'a V, dest: &mut Self)
        where Self: From<&'a V>
    {
        unimplemented!()
    }

    fn length(&self) -> f32 {
        unimplemented!()
    }

    fn length_sq(&self) -> f32 {
        unimplemented!()
    }

    fn lerp<'a, V>(&mut self, other: &'a V, t: f32) -> &mut Self
        where Self: From<&'a V>
    {
        unimplemented!()
    }

    fn lerp_into<'a, V>(&self, other: &'a V, t: f32, dest: &mut Self)
        where Self: From<&'a V>
    {
        unimplemented!()
    }

    fn mul<'a, V>(&mut self, rhs: &'a V) -> &mut Self
        where Self: From<&'a V>
    {
        unimplemented!()
    }

    fn mul_into<'a, V>(&self, rhs: &'a V, dest: &mut Self)
        where Self: From<&'a V>
    {
        unimplemented!()
    }

    fn negate(&mut self) -> &mut Self {
        unimplemented!()
    }

    fn negate_into(&self, dest: &mut Self) {
        unimplemented!()
    }

    fn normalize(&mut self) -> &mut Self {
        unimplemented!()
    }

    fn normalize_into(&self, dest: &mut Self) {
        unimplemented!()
    }

    fn set<'a, V>(&mut self, rhs: &'a V) -> &mut Self
        where Self: From<&'a V>
    {
        unimplemented!()
    }

    fn sub<'a, V>(&mut self, rhs: &'a V) -> &mut Self
        where Self: From<&'a V>
    {
        unimplemented!()
    }

    fn sub_into<'a, V>(&self, rhs: &'a V, dest: &mut Self)
        where Self: From<&'a V>
    {
        unimplemented!()
    }

    fn zero(&mut self) -> &mut Self {
        unimplemented!()
    }
}

impl Vector4<f32> for Vector4f {
    fn new(x: f32, y: f32, z: f32, w: f32) -> Self {
        unimplemented!()
    }
}
<commit_msg>Add some impls and tests for Vector4f<commit_after>use vector::Vector;
use vector::Vector4;
use FourTuple;

pub struct Vector4f {
    pub x: f32,
    pub y: f32,
    pub z: f32,
    pub w: f32,
}

impl Vector4<f32> for Vector4f {
    fn new(x: f32, y: f32, z: f32, w: f32) -> Self {
        Vector4f {
            x: x,
            y: y,
            z: z,
            w: w,
        }
    }
}

impl Vector<f32> for Vector4f {
    fn add<'a, V>(&mut self, rhs: &'a V) -> &mut Self
        where Self: From<&'a V>
    {
        let rhs = Vector4f::from(rhs);
        self.x += rhs.x;
        self.y += rhs.y;
        self.z += rhs.z;
        self.w += rhs.w;
        self
    }

    fn add_into<'a, V>(&self, rhs: &'a V, dest: &mut Self)
        where Self: From<&'a V>
    {
        let rhs = Vector4f::from(rhs);
        dest.x = self.x + rhs.x;
        dest.y = self.y + rhs.y;
        dest.z = self.z + rhs.z;
        dest.w = self.w + rhs.w;
    }

    fn angle<'a, V>(&self, rhs: &'a V) -> f32
        where Self: From<&'a V>
    {
        unimplemented!()
    }

    fn angle_cos<'a, V>(&self, rhs: &'a V) -> f32
        where Self: From<&'a V>
    {
        unimplemented!()
    }

    fn distance<'a, V>(&self, rhs: &'a V) -> f32
        where Self: From<&'a V>
    {
        self.distance_sq(rhs).sqrt()
    }

    fn distance_sq<'a, V>(&self, rhs: &'a V) -> f32
        where Self: From<&'a V>
    {
        let rhs = Vector4f::from(rhs);
        let dx = self.x - rhs.x;
        let dy = self.y - rhs.y;
        let dz = self.z - rhs.z;
        let dw = self.w - rhs.w;
        (dx * dx) + (dy * dy) + (dz * dz) + (dw * dw)
    }

    fn dot<'a, V>(&self, rhs: &'a V) -> f32
        where Self: From<&'a V>
    {
        let v = Vector4f::from(rhs);
        (self.x * v.x) + (self.y * v.y) + (self.z * v.z) + (self.w * v.w)
    }

    fn fma<'a, V>(&mut self, a: &'a V, b: &'a V) -> &mut Self
        where Self: From<&'a V>
    {
        unimplemented!()
    }

    fn fma_into<'a, V>(&self, a: &'a V, b: &'a V, dest: &mut Self)
        where Self: From<&'a V>
    {
        unimplemented!()
    }

    fn length(&self) -> f32 {
        self.length_sq().sqrt()
    }

    fn length_sq(&self) -> f32 {
        (self.x * self.x) + (self.y * self.y) + (self.z * self.z) + (self.w * self.w)
    }

    fn lerp<'a, V>(&mut self, other: &'a V, t: f32) -> &mut Self
        where Self: From<&'a V>
    {
        unimplemented!()
    }

    fn lerp_into<'a, V>(&self, other: &'a V, t: f32, dest: &mut Self)
        where Self: From<&'a V>
    {
        unimplemented!()
    }

    fn mul<'a, V>(&mut self, rhs: &'a V) -> &mut Self
        where Self: From<&'a V>
    {
        let rhs = Vector4f::from(rhs);
        self.x *= rhs.x;
        self.y *= rhs.y;
        self.z *= rhs.z;
        self.w *= rhs.w;
        self
    }

    fn mul_into<'a, V>(&self, rhs: &'a V, dest: &mut Self)
        where Self: From<&'a V>
    {
        let rhs = Vector4f::from(rhs);
        dest.x = self.x * rhs.x;
        dest.y = self.y * rhs.y;
        dest.z = self.z * rhs.z;
        dest.w = self.w * rhs.w;
    }

    fn negate(&mut self) -> &mut Self {
        self.x = -self.x;
        self.y = -self.y;
        self.z = -self.z;
        self.w = -self.w;
        self
    }

    fn negate_into(&self, dest: &mut Self) {
        dest.x = -self.x;
        dest.y = -self.y;
        dest.z = -self.z;
        dest.w = -self.w;
    }

    fn normalize(&mut self) -> &mut Self {
        let inv_length = 1f32 / self.length();
        self.x *= inv_length;
        self.y *= inv_length;
        self.z *= inv_length;
        self.w *= inv_length;
        self
    }

    fn normalize_into(&self, dest: &mut Self) {
        let inv_length = 1f32 / self.length();
        dest.x = self.x * inv_length;
        dest.y = self.y * inv_length;
        dest.z = self.z * inv_length;
        dest.w = self.w * inv_length;
    }

    fn set<'a, V>(&mut self, rhs: &'a V) -> &mut Self
        where Self: From<&'a V>
    {
        let rhs = Vector4f::from(rhs);
        self.x = rhs.x;
        self.y = rhs.y;
        self.z = rhs.z;
        self.w = rhs.w;
        self
    }

    fn sub<'a, V>(&mut self, rhs: &'a V) -> &mut Self
        where Self: From<&'a V>
    {
        let rhs = Vector4f::from(rhs);
        self.x -= rhs.x;
        self.y -= rhs.y;
        self.z -= rhs.z;
        self.w -= rhs.w;
        self
    }

    fn sub_into<'a, V>(&self, rhs: &'a V, dest: &mut Self)
        where Self: From<&'a V>
    {
        let rhs = Vector4f::from(rhs);
        dest.x = self.x - rhs.x;
        dest.y = self.y - rhs.y;
        dest.z = self.z - rhs.z;
        dest.w = self.w - rhs.w;
    }

    fn zero(&mut self) -> &mut Self {
        self.x = 0f32;
        self.y = 0f32;
        self.z = 0f32;
        self.w = 0f32;
        self
    }
}

impl<'a> From<&'a Vector4f> for Vector4f {
    fn from(other: &'a Vector4f) -> Self {
        Vector4f {
            x: other.x,
            y: other.y,
            z: other.z,
            w: other.w,
        }
    }
}

impl<'a> From<&'a FourTuple<f32>> for Vector4f {
    fn from(other: &'a FourTuple<f32>) -> Self {
        Vector4f {
            x: other.0,
            y: other.1,
            z: other.2,
            w: other.3,
        }
    }
}

impl<'a> From<&'a f32> for Vector4f {
    fn from(other: &'a f32) -> Self {
        Vector4f {
            x: *other,
            y: *other,
            z: *other,
            w: *other,
        }
    }
}

#[cfg(test)]
mod tests {
    use vector::Vector;
    use vector::Vector4;
    use vector::vector4f::Vector4f;

    use std;

    #[test]
    fn test_new() {
        let a = Vector4f::new(1f32, 2f32, 3f32, 4f32);

        assert_eq!(a.x, 1f32);
        assert_eq!(a.y, 2f32);
        assert_eq!(a.z, 3f32);
        assert_eq!(a.w, 4f32);
    }

    #[test]
    fn test_from_vector() {
        let a = Vector4f::new(1f32, 2f32, 3f32, 4f32);
        let b = Vector4f::from(&a);

        assert_eq!(b.x, 1f32);
        assert_eq!(b.y, 2f32);
        assert_eq!(b.z, 3f32);
        assert_eq!(b.w, 4f32);
    }

    #[test]
    fn test_from_tuple() {
        let a = Vector4f::from(&(1f32, 2f32, 3f32, 4f32));

        assert_eq!(a.x, 1f32);
        assert_eq!(a.y, 2f32);
        assert_eq!(a.z, 3f32);
        assert_eq!(a.w, 4f32);
    }

    #[test]
    fn test_from_f32() {
        let a = Vector4f::from(&1f32);

        assert_eq!(a.x, 1f32);
        assert_eq!(a.y, 1f32);
        assert_eq!(a.z, 1f32);
        assert_eq!(a.w, 1f32);
    }

    #[test]
    fn test_add() {
        let mut a = Vector4f::new(1f32, 2f32, 3f32, 4f32);
        let b = Vector4f::new(1f32, 2f32, 3f32, 4f32);

        a.add(&b);

        assert_eq!(a.x, 2f32);
        assert_eq!(a.y, 4f32);
        assert_eq!(a.z, 6f32);
        assert_eq!(a.w, 8f32);
    }

    #[test]
    fn test_add_into() {
        let a = Vector4f::new(1f32, 2f32, 3f32, 4f32);
        let b = Vector4f::new(1f32, 2f32, 3f32, 4f32);
        let mut c = Vector4f::new(0f32, 0f32, 0f32, 0f32);

        a.add_into(&b, &mut c);

        assert_eq!(c.x, 2f32);
        assert_eq!(c.y, 4f32);
        assert_eq!(c.z, 6f32);
        assert_eq!(c.w, 8f32);
    }
//
//    #[test]
//    fn test_angle() {
//        let a = Vector3f::new(1f32, 0f32, 0f32);
//        let b = Vector3f::new(0f32, 1f32, 0f32);
//
//        let target_angle = 90f32.to_radians();
//        let angle = a.angle(&b);
//
//        assert!((target_angle - angle).abs() <= std::f32::EPSILON);
//    }
//
//    #[test]
//    fn test_angle_cos() {
//        let a = Vector3f::new(1f32, 0f32, 0f32);
//        let b = Vector3f::new(0f32, 1f32, 0f32);
//
//        let target_angle_cos = 90f32.to_radians().cos();
//        let angle_cos = a.angle_cos(&b);
//
//        assert!((target_angle_cos - angle_cos).abs() <= std::f32::EPSILON);
//    }
//
    #[test]
    fn test_distance() {
        let a = Vector4f::new(1f32, 2f32, 3f32, 4f32);
        let b = Vector4f::new(-1f32, 2f32, 3f32, 4f32);

        let target_distance = 2f32;
        let distance = a.distance(&b);

        assert_eq!(target_distance, distance);
    }

    #[test]
    fn test_distance_sq() {
        let a = Vector4f::new(1f32, 2f32, 3f32, 4f32);
        let b = Vector4f::new(-1f32, 2f32, 3f32, 4f32);

        let target_distance_sq = 4f32; // target distance is 2
        let distance_sq = a.distance_sq(&b);

        assert_eq!(target_distance_sq, distance_sq);
    }

    #[test]
    fn test_dot() {
        let a = Vector4f::new(1f32, 2f32, 3f32, 4f32);
        let b = Vector4f::new(1f32, 2f32, 3f32, 4f32);

        let target_dot = 30f32;
        let dot = a.dot(&b);

        assert_eq!(target_dot, dot);
    }

//    #[test]
//    fn test_fma() {
//        let mut a = Vector3f::new(1f32, 1f32, 1f32);
//        let b = Vector3f::new(2f32, 3f32, 4f32);
//        let c = Vector3f::new(2f32, 3f32, 4f32);
//
//        a.fma(&b, &c);
//
//        assert_eq!(a.x, 5f32);
//        assert_eq!(a.y, 10f32);
//        assert_eq!(a.z, 17f32);
//    }
//
//    #[test]
//    fn test_fma_into() {
//        let a = Vector3f::new(1f32, 1f32, 1f32);
//        let b = Vector3f::new(2f32, 3f32, 4f32);
//        let c = Vector3f::new(2f32, 3f32, 4f32);
//        let mut d = Vector3f::new(0f32, 0f32, 0f32);
//
//        a.fma_into(&b, &c, &mut d);
//
//        assert_eq!(d.x, 5f32);
//        assert_eq!(d.y, 10f32);
//        assert_eq!(d.z, 17f32);
//    }
//
    #[test]
    fn test_length() {
        let a = Vector4f::new(1f32, 0f32, 2f32, 2f32);

        let target_length = 3f32;
        let length = a.length();

        assert_eq!(target_length, length);
    }

    #[test]
    fn test_length_squared() {
        let a = Vector4f::new(1f32, 2f32, 3f32, 4f32);

        let target_length_sq = 30f32;
        let length_sq = a.length_sq();

        assert_eq!(target_length_sq, length_sq);
    }

//    #[test]
//    fn test_lerp() {
//        let mut a = Vector3f::new(1f32, 0f32, 0f32);
//        let b = Vector3f::new(2f32, 2f32, 3f32);
//
//        a.lerp(&b, 0.5f32);
//
//        assert_eq!(a.x, 1.5f32);
//        assert_eq!(a.y, 1.0f32);
//        assert_eq!(a.z, 1.5f32);
//    }
//
//    #[test]
//    fn test_lerp_into() {
//        let a = Vector3f::new(1f32, 0f32, 0f32);
//        let b = Vector3f::new(2f32, 2f32, 3f32);
//        let mut c = Vector3f::new(0f32, 0f32, 0f32);
//
//        a.lerp_into(&b, 0.5f32, &mut c);
//
//        assert_eq!(c.x, 1.5f32);
//        assert_eq!(c.y, 1.0f32);
//        assert_eq!(c.z, 1.5f32);
//    }
//
    #[test]
    fn test_mul() {
        let mut a = Vector4f::new(1f32, 2f32, 3f32, 4f32);
        let b = Vector4f::new(1f32, 2f32, 3f32, 4f32);

        a.mul(&b);

        assert_eq!(a.x, 1f32);
        assert_eq!(a.y, 4f32);
        assert_eq!(a.z, 9f32);
        assert_eq!(a.w, 16f32);
    }

    #[test]
    fn test_mul_into() {
        let a = Vector4f::new(1f32, 2f32, 3f32, 4f32);
        let b = Vector4f::new(1f32, 2f32, 3f32, 4f32);
        let mut c = Vector4f::new(0f32, 0f32, 0f32, 0f32);

        a.mul_into(&b, &mut c);

        assert_eq!(c.x, 1f32);
        assert_eq!(c.y, 4f32);
        assert_eq!(c.z, 9f32);
        assert_eq!(c.w, 16f32);
    }

    #[test]
    fn test_negate() {
        let mut a = Vector4f::new(1f32, 2f32, 3f32, 4f32);

        a.negate();

        assert_eq!(a.x, -1f32);
        assert_eq!(a.y, -2f32);
        assert_eq!(a.z, -3f32);
        assert_eq!(a.w, -4f32);
    }

    #[test]
    fn test_negate_into() {
        let a = Vector4f::new(1f32, 2f32, 3f32, 4f32);
        let mut b = Vector4f::new(0f32, 0f32, 0f32, 0f32);

        a.negate_into(&mut b);

        assert_eq!(b.x, -1f32);
        assert_eq!(b.y, -2f32);
        assert_eq!(b.z, -3f32);
        assert_eq!(b.w, -4f32);
    }

    #[test]
    fn test_normalize() {
        let mut a = Vector4f::new(1f32, 2f32, 3f32, 4f32);

        a.normalize();

        assert!((1f32 - a.length()).abs() <= std::f32::EPSILON);
    }

    #[test]
    fn test_normalize_into() {
        let a = Vector4f::new(1f32, 2f32, 3f32, 4f32);
        let mut b = Vector4f::new(0f32, 0f32, 0f32, 0f32);

        a.normalize_into(&mut b);

        assert!((1f32 - b.length()).abs() <= std::f32::EPSILON);
    }

    #[test]
    fn test_set() {
        let mut a = Vector4f::new(0f32, 0f32, 0f32, 0f32);
        let b = Vector4f::new(1f32, 2f32, 3f32, 4f32);

        a.set(&b);

        assert_eq!(a.x, 1f32);
        assert_eq!(a.y, 2f32);
        assert_eq!(a.z, 3f32);
        assert_eq!(a.w, 4f32);
    }

    #[test]
    fn test_sub() {
        let mut a = Vector4f::new(1f32, 2f32, 3f32, 4f32);
        let b = Vector4f::new(0f32, 1f32, 2f32, 3f32);

        a.sub(&b);

        assert_eq!(a.x, 1f32);
        assert_eq!(a.y, 1f32);
        assert_eq!(a.z, 1f32);
        assert_eq!(a.w, 1f32);
    }

    #[test]
    fn test_sub_into() {
        let a = Vector4f::new(1f32, 2f32, 3f32, 4f32);
        let b = Vector4f::new(0f32, 1f32, 2f32, 3f32);
        let mut c = Vector4f::new(0f32, 0f32, 0f32, 0f32);

        a.sub_into(&b, &mut c);

        assert_eq!(c.x, 1f32);
        assert_eq!(c.y, 1f32);
        assert_eq!(c.z, 1f32);
        assert_eq!(c.w, 1f32);
    }

    #[test]
    fn test_zero() {
        let mut a = Vector4f::new(1f32, 2f32, 3f32, 4f32);

        a.zero();

        assert_eq!(a.x, 0f32);
        assert_eq!(a.y, 0f32);
        assert_eq!(a.z, 0f32);
        assert_eq!(a.w, 0f32);
    }
}

<|endoftext|>


<commit_before>use crate::chain::Chain;
use crate::error::ErrorImpl;
use core::fmt::{self, Debug, Write};

impl ErrorImpl<()> {
    pub(crate) fn display(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.error())?;

        if f.alternate() {
            for cause in self.chain().skip(1) {
                write!(f, ": {}", cause)?;
            }
        }

        Ok(())
    }

    pub(crate) fn debug(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let error = self.error();

        if f.alternate() {
            return Debug::fmt(error, f);
        }

        write!(f, "{}", error)?;

        if let Some(cause) = error.source() {
            write!(f, "\n\nCaused by:")?;
            let multiple = cause.source().is_some();
            for (n, error) in Chain::new(cause).enumerate() {
                writeln!(f)?;
                let mut indented = Indented {
                    inner: f,
                    number: if multiple { Some(n) } else { None },
                    started: false,
                };
                write!(indented, "{}", error)?;
            }
        }

        #[cfg(backtrace)]
        {
            use std::backtrace::BacktraceStatus;

            let backtrace = self.backtrace();
            if let BacktraceStatus::Captured = backtrace.status() {
                let mut backtrace = backtrace.to_string();
                if backtrace.starts_with("stack backtrace:") {
                    // Capitalize to match "Caused by:"
                    backtrace.replace_range(0..1, "S");
                }
                backtrace.truncate(backtrace.trim_end().len());
                write!(f, "\n\n{}", backtrace)?;
            }
        }

        Ok(())
    }
}

struct Indented<'a, D> {
    inner: &'a mut D,
    number: Option<usize>,
    started: bool,
}

impl<T> Write for Indented<'_, T>
where
    T: Write,
{
    fn write_str(&mut self, s: &str) -> fmt::Result {
        for (i, line) in s.split('\n').enumerate() {
            if !self.started {
                self.started = true;
                match self.number {
                    Some(number) => write!(self.inner, "{: >5}: ", number)?,
                    None => self.inner.write_str("    ")?,
                }
            } else if i > 0 {
                self.inner.write_char('\n')?;
                if self.number.is_some() {
                    self.inner.write_str("       ")?;
                } else {
                    self.inner.write_str("    ")?;
                }
            }

            self.inner.write_str(line)?;
        }

        Ok(())
    }
}

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

    #[test]
    fn one_digit() {
        let input = "verify\nthis";
        let expected = "    2: verify\n       this";
        let mut output = String::new();

        Indented {
            inner: &mut output,
            number: Some(2),
            started: false,
        }
        .write_str(input)
        .unwrap();

        assert_eq!(expected, output);
    }

    #[test]
    fn two_digits() {
        let input = "verify\nthis";
        let expected = "   12: verify\n       this";
        let mut output = String::new();

        Indented {
            inner: &mut output,
            number: Some(12),
            started: false,
        }
        .write_str(input)
        .unwrap();

        assert_eq!(expected, output);
    }

    #[test]
    fn no_digits() {
        let input = "verify\nthis";
        let expected = "    verify\n    this";
        let mut output = String::new();

        Indented {
            inner: &mut output,
            number: None,
            started: false,
        }
        .write_str(input)
        .unwrap();

        assert_eq!(expected, output);
    }
}
<commit_msg>Restore 'Stack backtrace:' above the backtrace<commit_after>use crate::chain::Chain;
use crate::error::ErrorImpl;
use core::fmt::{self, Debug, Write};

impl ErrorImpl<()> {
    pub(crate) fn display(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.error())?;

        if f.alternate() {
            for cause in self.chain().skip(1) {
                write!(f, ": {}", cause)?;
            }
        }

        Ok(())
    }

    pub(crate) fn debug(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let error = self.error();

        if f.alternate() {
            return Debug::fmt(error, f);
        }

        write!(f, "{}", error)?;

        if let Some(cause) = error.source() {
            write!(f, "\n\nCaused by:")?;
            let multiple = cause.source().is_some();
            for (n, error) in Chain::new(cause).enumerate() {
                writeln!(f)?;
                let mut indented = Indented {
                    inner: f,
                    number: if multiple { Some(n) } else { None },
                    started: false,
                };
                write!(indented, "{}", error)?;
            }
        }

        #[cfg(backtrace)]
        {
            use std::backtrace::BacktraceStatus;

            let backtrace = self.backtrace();
            if let BacktraceStatus::Captured = backtrace.status() {
                let mut backtrace = backtrace.to_string();
                write!(f, "\n\n")?;
                if backtrace.starts_with("stack backtrace:") {
                    // Capitalize to match "Caused by:"
                    backtrace.replace_range(0..1, "S");
                } else {
                    // "stack backtrace:" prefix was removed in
                    // https://github.com/rust-lang/backtrace-rs/pull/286
                    writeln!(f, "Stack backtrace:")?;
                }
                backtrace.truncate(backtrace.trim_end().len());
                write!(f, "{}", backtrace)?;
            }
        }

        Ok(())
    }
}

struct Indented<'a, D> {
    inner: &'a mut D,
    number: Option<usize>,
    started: bool,
}

impl<T> Write for Indented<'_, T>
where
    T: Write,
{
    fn write_str(&mut self, s: &str) -> fmt::Result {
        for (i, line) in s.split('\n').enumerate() {
            if !self.started {
                self.started = true;
                match self.number {
                    Some(number) => write!(self.inner, "{: >5}: ", number)?,
                    None => self.inner.write_str("    ")?,
                }
            } else if i > 0 {
                self.inner.write_char('\n')?;
                if self.number.is_some() {
                    self.inner.write_str("       ")?;
                } else {
                    self.inner.write_str("    ")?;
                }
            }

            self.inner.write_str(line)?;
        }

        Ok(())
    }
}

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

    #[test]
    fn one_digit() {
        let input = "verify\nthis";
        let expected = "    2: verify\n       this";
        let mut output = String::new();

        Indented {
            inner: &mut output,
            number: Some(2),
            started: false,
        }
        .write_str(input)
        .unwrap();

        assert_eq!(expected, output);
    }

    #[test]
    fn two_digits() {
        let input = "verify\nthis";
        let expected = "   12: verify\n       this";
        let mut output = String::new();

        Indented {
            inner: &mut output,
            number: Some(12),
            started: false,
        }
        .write_str(input)
        .unwrap();

        assert_eq!(expected, output);
    }

    #[test]
    fn no_digits() {
        let input = "verify\nthis";
        let expected = "    verify\n    this";
        let mut output = String::new();

        Indented {
            inner: &mut output,
            number: None,
            started: false,
        }
        .write_str(input)
        .unwrap();

        assert_eq!(expected, output);
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::env;

use git2;

use config;
use errors::*;

pub struct Repo {
    repo: git2::Repository,
}

impl Repo {
    pub fn new() -> Result<Self> {
        let repo =
            env::current_dir()
                .chain_err(|| "")
                .and_then(|current_dir| git2::Repository::discover(current_dir).chain_err(|| ""))?;
        Ok(Repo { repo: repo })
    }

    pub fn config(&self) -> Result<Config> {
        self.repo
            .config()
            .map(|config| Config { config: config })
            .chain_err(|| "")
    }

    pub fn auto_include(&self, filename: &str) -> Result<()> {
        let include_path = format!("../{}", filename);

        let workdir = match self.repo.workdir() {
            Some(dir) => dir,
            _ => {
                return Ok(());
            }
        };

        let mut path_buf = workdir.to_path_buf();
        path_buf.push(filename);
        if !path_buf.exists() {
            return Ok(());
        }

        let include_paths = self.include_paths()?;
        if include_paths.contains(&include_path) {
            return Ok(());
        }

        let mut config = self.local_config()?;
        config
            .set_multivar("include.path", "^$", &include_path)
            .and(Ok(()))
            .chain_err(|| "")
    }

    fn include_paths(&self) -> Result<Vec<String>> {
        let config = self.local_config()?;
        let include_paths: Vec<String> = config
            .entries(Some("include.path"))
            .chain_err(|| "")?
            .into_iter()
            .map(|entry| {
                     entry
                         .chain_err(|| "")
                         .and_then(|entry| {
                                       entry.value().map(String::from).ok_or("".into())
                                   })
                 })
            .collect::<Result<_>>()?;
        Ok(include_paths)
    }

    fn local_config(&self) -> Result<git2::Config> {
        let config = self.repo.config().chain_err(|| "")?;
        config
            .open_level(git2::ConfigLevel::Local)
            .chain_err(|| "")
    }
}

pub struct Config {
    config: git2::Config,
}

impl Config {
    pub fn new() -> Result<Self> {
        git2::Config::open_default()
            .map(|config| Config { config: config })
            .chain_err(|| "")
    }
}

impl config::Config for Config {
    fn get(&self, name: &str) -> Result<String> {
        self.config
            .get_string(name)
            .chain_err(|| format!("error getting git config for '{}'", name))
    }

    fn get_all(&self, glob: &str) -> Result<HashMap<String, String>> {
        let mut result = HashMap::new();
        let entries = self.config
            .entries(Some(glob))
            .chain_err(|| "error getting git config entries")?;
        for entry in &entries {
            let entry = entry.chain_err(|| "error getting git config entry")?;
            if let (Some(name), Some(value)) = (entry.name(), entry.value()) {
                result.insert(name.into(), value.into());
            }
        }
        Ok(result)
    }

    fn add(&mut self, name: &str, value: &str) -> Result<()> {
        self.config
            .set_multivar(name, "^$", value)
            .chain_err(|| format!("error adding git config '{}': '{}'", name, value))
    }

    fn set(&mut self, name: &str, value: &str) -> Result<()> {
        self.config
            .set_str(name, value)
            .chain_err(|| format!("error setting git config '{}': '{}'", name, value))
    }
}
<commit_msg>small clippy refactoring<commit_after>use std::collections::HashMap;
use std::env;

use git2;

use config;
use errors::*;

pub struct Repo {
    repo: git2::Repository,
}

impl Repo {
    pub fn new() -> Result<Self> {
        let repo =
            env::current_dir()
                .chain_err(|| "")
                .and_then(|current_dir| git2::Repository::discover(current_dir).chain_err(|| ""))?;
        Ok(Repo { repo: repo })
    }

    pub fn config(&self) -> Result<Config> {
        self.repo
            .config()
            .map(|config| Config { config: config })
            .chain_err(|| "")
    }

    pub fn auto_include(&self, filename: &str) -> Result<()> {
        let include_path = format!("../{}", filename);

        let workdir = match self.repo.workdir() {
            Some(dir) => dir,
            _ => {
                return Ok(());
            }
        };

        let mut path_buf = workdir.to_path_buf();
        path_buf.push(filename);
        if !path_buf.exists() {
            return Ok(());
        }

        let include_paths = self.include_paths()?;
        if include_paths.contains(&include_path) {
            return Ok(());
        }

        let mut config = self.local_config()?;
        config
            .set_multivar("include.path", "^$", &include_path)
            .and(Ok(()))
            .chain_err(|| "")
    }

    fn include_paths(&self) -> Result<Vec<String>> {
        let config = self.local_config()?;
        let include_paths: Vec<String> = config
            .entries(Some("include.path"))
            .chain_err(|| "")?
            .into_iter()
            .map(|entry| {
                     entry.and_then(|entry| {
                                        entry.value().map(String::from).ok_or_else(|| "".into())
                                    })
                 })
            .collect::<Result<_>>()?;
        Ok(include_paths)
    }

    fn local_config(&self) -> Result<git2::Config> {
        let config = self.repo.config().chain_err(|| "")?;
        config
            .open_level(git2::ConfigLevel::Local)
            .chain_err(|| "")
    }
}

pub struct Config {
    config: git2::Config,
}

impl Config {
    pub fn new() -> Result<Self> {
        git2::Config::open_default()
            .map(|config| Config { config: config })
            .chain_err(|| "")
    }
}

impl config::Config for Config {
    fn get(&self, name: &str) -> Result<String> {
        self.config
            .get_string(name)
            .chain_err(|| format!("error getting git config for '{}'", name))
    }

    fn get_all(&self, glob: &str) -> Result<HashMap<String, String>> {
        let mut result = HashMap::new();
        let entries = self.config
            .entries(Some(glob))
            .chain_err(|| "error getting git config entries")?;
        for entry in &entries {
            let entry = entry.chain_err(|| "error getting git config entry")?;
            if let (Some(name), Some(value)) = (entry.name(), entry.value()) {
                result.insert(name.into(), value.into());
            }
        }
        Ok(result)
    }

    fn add(&mut self, name: &str, value: &str) -> Result<()> {
        self.config
            .set_multivar(name, "^$", value)
            .chain_err(|| format!("error adding git config '{}': '{}'", name, value))
    }

    fn set(&mut self, name: &str, value: &str) -> Result<()> {
        self.config
            .set_str(name, value)
            .chain_err(|| format!("error setting git config '{}': '{}'", name, value))
    }
}
<|endoftext|>