<commit_before>#[macro_use]
extern crate clap;
extern crate to;

use to::{ToResult, ToError};
use to::cli::{Request};
use clap::{App, Arg};
use std::path::PathBuf;
use std::env;

fn main() {
    // Use the clap crate to handle argument parsing.
    let version = crate_version!();
    let program = App::new("to")
                    .about("Bookmark directories")
                    .version(version)
                    .author("Jason Campbell <jason@artifact.sh>")
                    .arg(Arg::with_name("name")
                        .help("Name of the bookamrk")
                        .index(1))
                    .arg(Arg::with_name("directory")
                        .help("Path of the bookamrk")
                        .index(2));

    // 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),
    };

    println!("CLI Request: {:?}", request);
}

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),
    };

    let name = match matches.value_of("name") {
        Some(value) => value,
        // directory.file_stem().map(|stem| stem.to_str()).unwrap()
        None => "",
    };

    // let pathame = .unwrap_or("");
    // let directory = resolve(pathame);
    // let basename = directory.file_stem().unwrap().to_str().unwrap();
    // let name = matches.value_of("name").unwrap_or(basename);

    println!("directory: {:?}", directory);
    println!("name: {:?}", name);

    let req = Request{ name: "foo".to_string(), directory: PathBuf::from(".")};

    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(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);
}
<commit_msg>Adds directory validation.<commit_after>#[macro_use]
extern crate clap;
extern crate to;

use to::{ToResult, ToError};
use to::cli::{Request};
use clap::{App, Arg};
use std::path::PathBuf;
use std::env;
use std::fs;

fn main() {
    // Use the clap crate to handle argument parsing.
    let version = crate_version!();
    let program = App::new("to")
                    .about("Bookmark directories")
                    .version(version)
                    .author("Jason Campbell <jason@artifact.sh>")
                    .arg(Arg::with_name("name")
                        .help("Name of the bookamrk")
                        .index(1))
                    .arg(Arg::with_name("directory")
                        .help("Path of the bookamrk")
                        .index(2));

    // 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),
    };

    println!("CLI Request: {:?}", request);
}

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 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;
}
<|endoftext|>


<commit_before>use std::process::{ Child, Command, Stdio, ExitStatus };
use std::io::{ BufRead, BufReader, BufWriter, Read,  Write };
use std::path::{ Path, PathBuf };
use std::net::{ TcpListener, TcpStream };
use std::thread;
use std::fs::File;

extern crate argparse;
extern crate rand;

use argparse::{ ArgumentParser };
use rand::distributions::{IndependentSample, Range};

struct ListenerData {
    listener: TcpListener,
    port: u16,
}

fn create_listener() -> Result<ListenerData, &'static str>
{
    let possible_port_values = Range::new( 1024, 65535 );
    let mut rng = rand::thread_rng();
    for _ in 1..5 {
        let try_port = possible_port_values.ind_sample( &mut rng );

        let result = TcpListener::bind( ( "127.0.0.1", try_port ) );
        if result.is_ok() {
            return Ok( ListenerData{ listener: result.unwrap(), port: try_port } )
        }
    }

    Err( &"Failed to bind port" )
}

struct Credentials {
    username: String,
    user_token: String,
}

fn parse_credentials( credentials_file: &Path ) -> Result<Credentials, &str>
{
    let f = File::open( credentials_file ).unwrap();
    let mut reader = BufReader::new( f );

    let mut credentials_version = String::new();
    reader.read_line( &mut credentials_version ).unwrap();
    match credentials_version.trim().as_ref() {
        "0.2.0" => {
            let mut username = String::new();
            let mut token = String::new();
            reader.read_line( &mut username ).unwrap();
            reader.read_line( &mut token ).unwrap();
            Ok( Credentials{ username: username.trim().to_string(), user_token: token.trim().to_string() } )
        },
        _ => Err( "Unknown version" ),
    }
}

fn main()
{
    let mut wrapper_id = String::new();
    let mut pid_path = String::new();
    let mut package_path = String::new();
    let mut game_path = String::new();
    let mut game_args: Vec<String> = std::vec::Vec::new();

    {
        let mut ap: ArgumentParser = ArgumentParser::new();
        ap.refer( &mut wrapper_id ).add_argument( "wrapper-id", argparse::Store, "A unique identifier for the wrapper" ).required();
        ap.refer( &mut pid_path ).add_argument( "pid-path", argparse::Store, "Path to the pid directory" ).required();
        ap.refer( &mut package_path ).add_argument( "package-path", argparse::Store, "Path to the package installation directory" ).required();
        ap.refer( &mut game_path ).add_argument( "game-path", argparse::Store, "Path to the game file relative to the package installation directory" ).required();
        ap.refer( &mut game_args ).add_argument( "game-args", argparse::Collect, "Additional arguments to the game file" );
        ap.parse_args_or_exit();
    }

    let listener_data = create_listener().unwrap();
    let listener = listener_data.listener;

    let task_wrapper_id = wrapper_id.clone();
    let task_package_path = package_path.clone();
    let task_game_path = game_path.clone();
    let task_game_args = game_args.clone();
    thread::spawn( move || {

        for stream in listener.incoming() {
            let mut stream: TcpStream = stream.unwrap_or_else( |e| panic!( "Could not get incoming connection stream: {}", e ) );
            let out_str = String::from( "v0.2.0:Game Wrapper:" ) + &task_wrapper_id + ":" + &task_package_path + ":" + &task_game_path + ":\"" + &task_game_args.join( &"\",\"" ) + "\"";
            stream.write( out_str.as_bytes() ).unwrap_or_else( |e| panic!( "Could not send reply to the new connection: {}", e ) );
        }
    } );

    let mut pid_path = PathBuf::from( pid_path );
    pid_path.push( wrapper_id );

    match File::create( &pid_path ) {
        Ok( f ) => {
            let mut writer = BufWriter::new( f );
            writer.write( listener_data.port.to_string().as_bytes() )
                .expect( "Failed to write pid file" );
            writer.flush()
                .expect( "Failed to flush pid file" );
            drop( writer );
        },
        Err( e ) => println!( "Failed to write pid file: {}", e ),
    };

    // Get the full game file path.
    let mut game_file = PathBuf::from( package_path.clone() );
    game_file.push( game_path );

    // Current working directory is the directory of the game executable
    let cwd: &Path = game_file.parent()
        .expect( "Could not get parent dir from path" );

    let mut package_credentials: PathBuf = PathBuf::from( &package_path );
    package_credentials.push( ".gj-credentials" );

    let mut game_file_credentials: PathBuf = PathBuf::from( cwd );
    game_file_credentials.push( ".gj-credentials" );

    // Copy over the credential file from the package directory to the game executable's directory.
    let mut supports_game_api = std::fs::copy( package_credentials.as_path(), game_file_credentials.as_path() ).is_ok();

    let mut credentials: Credentials = Credentials{ username: String::new(), user_token: String::new() };
    if supports_game_api {
        let get_credentials = parse_credentials( game_file_credentials.as_path() );
        supports_game_api = get_credentials.is_ok();
        credentials = get_credentials.unwrap();
    }

    if supports_game_api {
        game_args.push( String::from( "gjapi_username" ) );
        game_args.push( credentials.username.to_string() );
        game_args.push( String::from( "gjapi_token" ) );
        game_args.push( credentials.user_token.to_string() );
    }

    let mut game_handle: Child = Command::new( &game_file )
        .current_dir( cwd )
        .args( game_args.as_slice() )
        .stderr( Stdio::piped() )
        .spawn()
        .unwrap_or_else( |e| panic!( "Couldn't launch game: {}", e ) );

    let result: ExitStatus = game_handle.wait().unwrap_or_else( |e| panic!( "Couldn't wait for game to launch/finish {}", e ) );

    if std::fs::remove_file( &pid_path ).is_err() {
        println!( "Failed to remove pid file: {}", pid_path.display() );
    }

    println!( "Game exited with exit code {}", result.code().expect( "Could not discern wrapped game exit code" ) );

    if !result.success() {
        let mut err_str = String::new();
        match game_handle.stderr.expect( "Could not get err stream" ).read_to_string( &mut err_str )  {
            Err(e) => panic!( "Could not read err stream {}", e ),
            Ok(_) => println!( "Stderr: {}", err_str ),
        }
    }
}
<commit_msg>Accept 0.1.0 version credentials as well<commit_after>use std::process::{ Child, Command, Stdio, ExitStatus };
use std::io::{ BufRead, BufReader, BufWriter, Read,  Write };
use std::path::{ Path, PathBuf };
use std::net::{ TcpListener, TcpStream };
use std::thread;
use std::fs::File;

extern crate argparse;
extern crate rand;

use argparse::{ ArgumentParser };
use rand::distributions::{IndependentSample, Range};

struct ListenerData {
    listener: TcpListener,
    port: u16,
}

fn create_listener() -> Result<ListenerData, &'static str>
{
    let possible_port_values = Range::new( 1024, 65535 );
    let mut rng = rand::thread_rng();
    for _ in 1..5 {
        let try_port = possible_port_values.ind_sample( &mut rng );

        let result = TcpListener::bind( ( "127.0.0.1", try_port ) );
        if result.is_ok() {
            return Ok( ListenerData{ listener: result.unwrap(), port: try_port } )
        }
    }

    Err( &"Failed to bind port" )
}

struct Credentials {
    username: String,
    user_token: String,
}

fn parse_credentials( credentials_file: &Path ) -> Result<Credentials, &str>
{
    let f = File::open( credentials_file ).unwrap();
    let mut reader = BufReader::new( f );

    let mut credentials_version = String::new();
    reader.read_line( &mut credentials_version ).unwrap();
    match credentials_version.trim().as_ref() {
        "0.1.0" |
        "0.2.0" => {
            let mut username = String::new();
            let mut token = String::new();
            reader.read_line( &mut username ).unwrap();
            reader.read_line( &mut token ).unwrap();
            Ok( Credentials{ username: username.trim().to_string(), user_token: token.trim().to_string() } )
        },
        _ => Err( "Unknown version" ),
    }
}

fn main()
{
    let mut wrapper_id = String::new();
    let mut pid_path = String::new();
    let mut package_path = String::new();
    let mut game_path = String::new();
    let mut game_args: Vec<String> = std::vec::Vec::new();

    {
        let mut ap: ArgumentParser = ArgumentParser::new();
        ap.refer( &mut wrapper_id ).add_argument( "wrapper-id", argparse::Store, "A unique identifier for the wrapper" ).required();
        ap.refer( &mut pid_path ).add_argument( "pid-path", argparse::Store, "Path to the pid directory" ).required();
        ap.refer( &mut package_path ).add_argument( "package-path", argparse::Store, "Path to the package installation directory" ).required();
        ap.refer( &mut game_path ).add_argument( "game-path", argparse::Store, "Path to the game file relative to the package installation directory" ).required();
        ap.refer( &mut game_args ).add_argument( "game-args", argparse::Collect, "Additional arguments to the game file" );
        ap.parse_args_or_exit();
    }

    let listener_data = create_listener().unwrap();
    let listener = listener_data.listener;

    let task_wrapper_id = wrapper_id.clone();
    let task_package_path = package_path.clone();
    let task_game_path = game_path.clone();
    let task_game_args = game_args.clone();
    thread::spawn( move || {

        for stream in listener.incoming() {
            let mut stream: TcpStream = stream.unwrap_or_else( |e| panic!( "Could not get incoming connection stream: {}", e ) );
            let out_str = String::from( "v0.2.0:Game Wrapper:" ) + &task_wrapper_id + ":" + &task_package_path + ":" + &task_game_path + ":\"" + &task_game_args.join( &"\",\"" ) + "\"";
            stream.write( out_str.as_bytes() ).unwrap_or_else( |e| panic!( "Could not send reply to the new connection: {}", e ) );
        }
    } );

    let mut pid_path = PathBuf::from( pid_path );
    pid_path.push( wrapper_id );

    match File::create( &pid_path ) {
        Ok( f ) => {
            let mut writer = BufWriter::new( f );
            writer.write( listener_data.port.to_string().as_bytes() )
                .expect( "Failed to write pid file" );
            writer.flush()
                .expect( "Failed to flush pid file" );
            drop( writer );
        },
        Err( e ) => println!( "Failed to write pid file: {}", e ),
    };

    // Get the full game file path.
    let mut game_file = PathBuf::from( package_path.clone() );
    game_file.push( game_path );

    // Current working directory is the directory of the game executable
    let cwd: &Path = game_file.parent()
        .expect( "Could not get parent dir from path" );

    let mut package_credentials: PathBuf = PathBuf::from( &package_path );
    package_credentials.push( ".gj-credentials" );

    let mut game_file_credentials: PathBuf = PathBuf::from( cwd );
    game_file_credentials.push( ".gj-credentials" );

    // Copy over the credential file from the package directory to the game executable's directory.
    let mut supports_game_api = std::fs::copy( package_credentials.as_path(), game_file_credentials.as_path() ).is_ok();

    let mut credentials: Credentials = Credentials{ username: String::new(), user_token: String::new() };
    if supports_game_api {
        let get_credentials = parse_credentials( game_file_credentials.as_path() );
        supports_game_api = get_credentials.is_ok();
        credentials = get_credentials.unwrap();
    }

    if supports_game_api {
        game_args.push( String::from( "gjapi_username" ) );
        game_args.push( credentials.username.to_string() );
        game_args.push( String::from( "gjapi_token" ) );
        game_args.push( credentials.user_token.to_string() );
    }

    let mut game_handle: Child = Command::new( &game_file )
        .current_dir( cwd )
        .args( game_args.as_slice() )
        .stderr( Stdio::piped() )
        .spawn()
        .unwrap_or_else( |e| panic!( "Couldn't launch game: {}", e ) );

    let result: ExitStatus = game_handle.wait().unwrap_or_else( |e| panic!( "Couldn't wait for game to launch/finish {}", e ) );

    if std::fs::remove_file( &pid_path ).is_err() {
        println!( "Failed to remove pid file: {}", pid_path.display() );
    }

    println!( "Game exited with exit code {}", result.code().expect( "Could not discern wrapped game exit code" ) );

    if !result.success() {
        let mut err_str = String::new();
        match game_handle.stderr.expect( "Could not get err stream" ).read_to_string( &mut err_str )  {
            Err(e) => panic!( "Could not read err stream {}", e ),
            Ok(_) => println!( "Stderr: {}", err_str ),
        }
    }
}
<|endoftext|>


<commit_before>
extern crate crypto;
extern crate iron;
extern crate router;
extern crate params;
extern crate hyper;
extern crate logger;

use iron::prelude::*;
use router::{Router};
use iron::status;
use params::Params;
use logger::Logger;
use iron::{BeforeMiddleware};

/// generate the md5sum of a given file (io::Read)
pub fn md5sum<T : std::io::Read> (f: &mut T) -> String  {
  use crypto::digest::Digest;

  let mut digest = crypto::md5::Md5::new();
  let mut data: Vec<u8> = Vec::new();

  match f.read_to_end(&mut data) {
    Err(why) => { println!("Error reading the passed file to calculate the md5sum: {}", why); String::new() }
    Ok(size) => {
      if size > 0 {
        digest.input(&data);
        digest.result_str()
      } else {
        String::new()
      }
    }
  }
}

use params::FromValue;

macro_rules! bad_request {
  // `()` indicates that the macro takes no argument
  ($msg:expr) => (
    Err(IronError::new($msg, status::BadRequest))
  )
}

use std::error::Error;
use std::fmt::{self, Debug};

#[derive(Debug)]
struct StringError(String);

impl fmt::Display for StringError {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    Debug::fmt(self, f)
  }
}

impl Error for StringError {
  fn description(&self) -> &str { &*self.0 }
}

trait RequiredParam<T : params::FromValue = Self> {

  fn get_value(value: &params::Value) -> Option<T> {
    T::from_value(value)
  }

  fn check(req: &mut Request, name: &str) -> IronResult<()> {

    let param_res = req.get_ref::<Params>();
    return match param_res {
      Err(why) => {
        bad_request!(why)
      },
      Ok(ref params) => {
        match params.find(&[name]) {
          None => bad_request!(StringError(format!("the request doesn't contains the parameter {}", name).to_string())),
          Some(p) => if let Some(_) = Self::get_value(p) {
            Ok(())
          } else {
            bad_request!(StringError(format!("the '{}' parameter is not of type 'string'",name).to_string()))
          }

        }
      }
    }
  }

  fn get_param_value(req: &mut Request, name: &str) -> T {
    Self::check(req, name).unwrap();
    Self::get_value(req.get_ref::<Params>().unwrap().find(&[name]).unwrap()).unwrap()
  }
}

macro_rules! require_param {
  ($name:ident, $param_name:expr, $ty:ty) => {
    impl RequiredParam for $ty {}
    struct $name;

    impl BeforeMiddleware for $name {
      fn before(&self, req: &mut Request) -> IronResult<()> {
        <$ty>::check(req, $param_name)
      }
    }
  }
}

require_param!(RequireMd5sumParam3, "md5sum", String);
require_param!(RequireFileParam, "filename", params::File);

fn submit_form_file2(req: &mut Request) -> IronResult<Response> {

  let passed_md5sum = &String::get_param_value(req, "md5sum");
  let file_param = params::File::get_param_value(req, "filename");
  let file_path = file_param.path().display();
  match file_param.open() {
    Err(why) => {
      let msg = format!("cannot open the uploaded file '{:?}' in path '{}' : '{}'", file_param.filename(), file_path, why);
      println!("{}", msg);
      Ok(Response::with((status::InternalServerError, msg)))
    },
    Ok(ref mut file) => {
      let calculated_md5sum = &md5sum(file);
      if calculated_md5sum != passed_md5sum {
        let msg = format!(
          "the md5sum '{}' calculate for the file {} doesn't correspond to the parameter '{}'",
          calculated_md5sum, file_path, passed_md5sum
        );
        return Ok(Response::with((status::PreconditionRequired, msg)))
      }

      return Ok(Response::with((status::Ok, "ciao mondo")))
    }
  }
}

// curl -i "http://localhost:3000/openact"  -F "filename=@/home/costa/test.csv" -F "name=jason" -F
// "age=2"
fn submit_form_file(req: &mut Request) -> IronResult<Response> {
//   use params::FromValue;

  let param_res = req.get_ref::<Params>(); // Result<&params::Map, params::ParamsError>
    println!("DEBUG - received request: {:?}", &param_res);

    match param_res {
      Err(why) => {
        let msg = format!("{:?}", why);
        println!("{}", msg);
        Ok(Response::with((status::InternalServerError, msg)))
      },
      Ok(ref params) => match params.find(&["md5sum"]) {
        Some(ref passed_md5sum) => {

          match **passed_md5sum {
            params::Value::String(ref passed_md5sum) => {
              match params.find(&["filename"]) {
                None => {
                  let msg = format!("missing 'filename' field: {:?}", params);
                  println!("{}", msg);
                  Ok(Response::with((status::BadRequest, msg)))
                },
                Some(ref f) => {
                  match **f {
                    params::Value::File(ref file_param) => {
                      let file_path = file_param.path().display();
                      let msg = format!("the path is: {:?}", file_path);
                      println!("{}", msg);
                      match file_param.open() {
                        Err(why) => {
                          let msg = format!("cannot open the uploaded file '{:?}' in path '{}' : '{}'", file_param.filename(), file_path, why);
                          println!("{}", msg);
                          Ok(Response::with((status::InternalServerError, msg)))
                        },
                        Ok(ref mut file) => {
                          let calculated_md5sum = &md5sum(file);
                          if calculated_md5sum != passed_md5sum {
                            let msg = format!(
                              "the md5sum '{}' calculate for the file {} doesn't correspond to the parameter '{}'",
                              calculated_md5sum, file_path, passed_md5sum
                            );
                            return Ok(Response::with((status::PreconditionRequired, msg)))
                          }

                          return Ok(Response::with((status::Ok, "ciao mondo")))
//                           use std::process::Command;

//                           match Command::new("file")
//                             .arg("-b")
//                             .arg("--mime-type")
//                             .arg(file_path)
//                             .output() {
//                               Err(why) =>
//                             }
//                             .unwrap_or_else(|e| { Ok(Response::with((status::PreconditionRequired,
//                               format!("error finding the type of the uploaded file {:?}", file_param.filename()) )) });

                        }
                      }

                    },
                    _ => {
                      let msg = format!("The request parameter 'filename' doesn't correspond to a real file: {:?}", f);
                      println!("{}", msg);
                      Ok(Response::with((status::PreconditionRequired, msg)))
                    }
                  }
                }

              }
            }
            _ => {
              let msg = format!(
                "The request parameter 'md5sum':'{:?}'' in the request {:?} doesn't correspond to a string",
                passed_md5sum, param_res);
              println!("{}", msg);
              Ok(Response::with((status::BadRequest, msg)))
            }
          }

        },
        _ => {
          let msg = format!("The request parameter 'md5sum' is required");
          println!("{}", msg);
          Ok(Response::with((status::BadRequest, msg)))
        }
      },

    }

}

fn start_server() {
   let (logger_before, logger_after) = Logger::new(None);
   let mut router = Router::new();
   let mut chain_form_file = Chain::new(submit_form_file2);
   chain_form_file.link_before(logger_before);
   chain_form_file.link_before(RequireMd5sumParam3);
   chain_form_file.link_before(RequireFileParam);
   chain_form_file.link_after(logger_after);
   router.post("/openact", chain_form_file);
   println!("started server at http://localhost:3000/");
   Iron::new(router).http("localhost:3000").unwrap();
}

#[cfg(test)]
mod tests {

    use std::fs::File;
    use super::md5sum;

#[test]
    fn md5sum_of_file() {
        static FP : &'static str = "/home/costa/pkg/lav/regione/attiweb/attività/20150107/definizione procedura di riavvio/Procedure_Riavvio_omnia.odt";

        let mut odt = match File::open(FP) {
            Err(why) => panic!("Cannot open the test file: {}", why),
            Ok(file) => file,
        };

        assert_eq!(md5sum(&mut odt), "a381cbe043c38a94af0983ffa934f338");
    }

    #[test]
    fn simple_get() {
        use hyper::Client;
        use hyper::header::Connection;
        use std::io::Read;
        use super::start_server;

        // start_server();

        // Create a client.
        let client = Client::new();
        //
        // Creating an outgoing request.
        let mut res = client.get("http://localhost:3000/openact")
            // set a header
            .header(Connection::close())
            // let 'er go!
            .send().unwrap();

        // Read the Response.
        let mut body = String::new();
        res.read_to_string(&mut body).unwrap();

        println!("Response: {}", body);
        assert_eq!(body, "Hello World");
    }

}

fn main() {
    println!("Hello, world!");
    start_server();
}
<commit_msg>implemented the RequiredParam trait for each params::FromValue type<commit_after>
extern crate crypto;
extern crate iron;
extern crate router;
extern crate params;
extern crate hyper;
extern crate logger;

use iron::prelude::*;
use router::{Router};
use iron::status;
use logger::Logger;
use iron::{BeforeMiddleware};

/// generate the md5sum of a given file (io::Read)
pub fn md5sum<T : std::io::Read> (f: &mut T) -> String  {
  use crypto::digest::Digest;

  let mut digest = crypto::md5::Md5::new();
  let mut data: Vec<u8> = Vec::new();

  match f.read_to_end(&mut data) {
    Err(why) => { println!("Error reading the passed file to calculate the md5sum: {}", why); String::new() }
    Ok(size) => {
      if size > 0 {
        digest.input(&data);
        digest.result_str()
      } else {
        String::new()
      }
    }
  }
}

#[macro_use]
mod param_rules;

use param_rules::RequiredParam;

require_param!(RequireMd5sumParam, "md5sum", String);
require_param!(RequirePippoParam, "pippo", String);
require_param!(RequireFileParam, "filename", params::File);

fn submit_form_file(req: &mut Request) -> IronResult<Response> {

  let passed_md5sum = &String::get_param_value(req, "md5sum").unwrap();
  let file_param = params::File::get_param_value(req, "filename").unwrap();
  let file_path = file_param.path().display();
  match file_param.open() {
    Err(why) => {
      let msg = format!("cannot open the uploaded file '{:?}' in path '{}' : '{}'", file_param.filename(), file_path, why);
      println!("{}", msg);
      Ok(Response::with((status::InternalServerError, msg)))
    },
    Ok(ref mut file) => {
      let calculated_md5sum = &md5sum(file);
      if calculated_md5sum != passed_md5sum {
        let msg = format!(
          "the md5sum '{}' calculate for the file {} doesn't correspond to the parameter '{}'",
          calculated_md5sum, file_path, passed_md5sum
        );
        return Ok(Response::with((status::PreconditionRequired, msg)))
      }

      return Ok(Response::with((status::Ok, "ciao mondo")))
    }
  }
}

fn start_server() {
   let (logger_before, logger_after) = Logger::new(None);
   let mut router = Router::new();
   let mut chain_form_file = Chain::new(submit_form_file);
   chain_form_file.link_before(logger_before);

   chain_form_file.link_before(RequireMd5sumParam);
   chain_form_file.link_before(RequirePippoParam);
   chain_form_file.link_before(RequireFileParam);

   chain_form_file.link_after(logger_after);
   router.post("/openact", chain_form_file);
   println!("started server at http://localhost:3000/");
   Iron::new(router).http("localhost:3000").unwrap();
}

#[cfg(test)]
mod tests {

    use std::fs::File;
    use super::md5sum;

#[test]
    fn md5sum_of_file() {
        static FP : &'static str = "/home/costa/pkg/lav/regione/attiweb/attività/20150107/definizione procedura di riavvio/Procedure_Riavvio_omnia.odt";

        let mut odt = match File::open(FP) {
            Err(why) => panic!("Cannot open the test file: {}", why),
            Ok(file) => file,
        };

        assert_eq!(md5sum(&mut odt), "a381cbe043c38a94af0983ffa934f338");
    }

    #[test]
    fn simple_get() {
        use hyper::Client;
        use hyper::header::Connection;
        use std::io::Read;
        use super::start_server;

        // start_server();

        // Create a client.
        let client = Client::new();
        //
        // Creating an outgoing request.
        let mut res = client.get("http://localhost:3000/openact")
            // set a header
            .header(Connection::close())
            // let 'er go!
            .send().unwrap();

        // Read the Response.
        let mut body = String::new();
        res.read_to_string(&mut body).unwrap();

        println!("Response: {}", body);
        assert_eq!(body, "Hello World");
    }

}

fn main() {
    println!("Hello, world!");
    start_server();
}
<|endoftext|>


<commit_before>#[macro_use(bson, doc)]
extern crate bson;
extern crate mongodb;

use bson::Bson;
use mongodb::{Client, ThreadedClient};
use mongodb::db::ThreadedDatabase;
use mongodb::coll::options::{FindOptions, CursorType};

fn main() {
    let client = Client::connect("localhost", 27017)
        .ok().expect("Failed to connect to MongoDB.");

    let coll = client.db("local").collection("oplog.rs");

    let mut opts = FindOptions::new();
    opts.cursor_type = CursorType::Tailable;
    let mut cursor = coll.find(None, Some(opts)).expect("Failed to execute find");
    let results = cursor.next_n(3).expect("Failed to retrieve documents");

    for result in results {
        match result.get("op") {
            Some(&Bson::String(ref op)) => println!("op: {}", op),
            _ => panic!("Expected string!"),
        };
    }
}
<commit_msg>Loop over the oplog indefinitely<commit_after>#[macro_use(bson, doc)]
extern crate bson;
extern crate mongodb;

use bson::Bson;
use mongodb::{Client, ThreadedClient};
use mongodb::db::ThreadedDatabase;
use mongodb::coll::options::{FindOptions, CursorType};

fn main() {
    let client = Client::connect("localhost", 27017)
        .ok().expect("Failed to connect to MongoDB.");

    let coll = client.db("local").collection("oplog.rs");

    loop {
        let mut opts = FindOptions::new();
        opts.cursor_type = CursorType::TailableAwait;
        opts.no_cursor_timeout = true;
        let cursor = coll.find(None, Some(opts)).expect("Failed to execute find");
        for result in cursor {
            if let Ok(item) = result {
                if let Some(&Bson::String(ref op)) = item.get("op") {
                    println!("op: {}", op);
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>use crate::exercise::{Exercise, ExerciseList};
use crate::run::run;
use crate::verify::verify;
use clap::{crate_version, App, Arg, SubCommand};
use notify::DebouncedEvent;
use notify::{RecommendedWatcher, RecursiveMode, Watcher};
use std::ffi::OsStr;
use std::fs;
use std::path::Path;
use std::sync::mpsc::channel;
use std::time::Duration;

mod exercise;
mod run;
mod verify;

fn main() {
    let matches = App::new("rustlings")
        .version(crate_version!())
        .author("Olivia Hugger, Carol Nichols")
        .about("Rustlings is a collection of small exercises to get you used to writing and reading Rust code")
        .subcommand(SubCommand::with_name("verify").alias("v").about("Verifies all exercises according to the recommended order"))
        .subcommand(SubCommand::with_name("watch").alias("w").about("Reruns `verify` when files were edited"))
        .subcommand(
            SubCommand::with_name("run")
                .alias("r")
                .about("Runs/Tests a single exercise")
                .arg(Arg::with_name("name").required(true).index(1)),
        )
        .subcommand(
            SubCommand::with_name("hint")
                .alias("h")
                .about("Returns a hint for the current exercise")
                .arg(Arg::with_name("name").required(true).index(1)),
        )
        .get_matches();

    if None == matches.subcommand_name() {
        println!();
        println!(r#"       welcome to...                      "#);
        println!(r#"                 _   _ _                  "#);
        println!(r#"  _ __ _   _ ___| |_| (_)_ __   __ _ ___  "#);
        println!(r#" | '__| | | / __| __| | | '_ \ / _` / __| "#);
        println!(r#" | |  | |_| \__ \ |_| | | | | | (_| \__ \ "#);
        println!(r#" |_|   \__,_|___/\__|_|_|_| |_|\__, |___/ "#);
        println!(r#"                               |___/      "#);
        println!();
    }

    if !Path::new("info.toml").exists() {
        println!(
            "{} must be run from the rustlings directory",
            std::env::current_exe().unwrap().to_str().unwrap()
        );
        println!("Try `cd rustlings/`!");
        std::process::exit(1);
    }

    let toml_str = &fs::read_to_string("info.toml").unwrap();
    let exercises = toml::from_str::<ExerciseList>(toml_str).unwrap().exercises;

    if let Some(ref matches) = matches.subcommand_matches("run") {
        let name = matches.value_of("name").unwrap();

        let matching_exercise = |e: &&Exercise| name == e.name;

        let exercise = exercises.iter().find(matching_exercise).unwrap_or_else(|| {
            println!("No exercise found for your given name!");
            std::process::exit(1)
        });

        run(&exercise).unwrap_or_else(|_| std::process::exit(1));
    }

    if let Some(ref matches) = matches.subcommand_matches("hint") {
        let name = matches.value_of("name").unwrap();

        let exercise = exercises
            .iter()
            .find(|e| name == e.name)
            .unwrap_or_else(|| {
                println!("No exercise found for your given name!");
                std::process::exit(1)
            });

        println!("{}", exercise.hint);
    }

    if matches.subcommand_matches("verify").is_some() {
        verify(&exercises).unwrap_or_else(|_| std::process::exit(1));
    }

    if matches.subcommand_matches("watch").is_some() {
        watch(&exercises).unwrap();
    }

    if matches.subcommand_name().is_none() {
        let text = fs::read_to_string("default_out.txt").unwrap();
        println!("{}", text);
    }
}

fn watch(exercises: &[Exercise]) -> notify::Result<()> {
    /* Clears the terminal with an ANSI escape code.
    Works in UNIX and newer Windows terminals. */
    fn clear_screen() {
        println!("\x1Bc");
    }

    let (tx, rx) = channel();

    let mut watcher: RecommendedWatcher = Watcher::new(tx, Duration::from_secs(2))?;
    watcher.watch(Path::new("./exercises"), RecursiveMode::Recursive)?;

    clear_screen();
    let _ignored = verify(exercises.iter());

    loop {
        match rx.recv() {
            Ok(event) => match event {
                DebouncedEvent::Create(b) | DebouncedEvent::Chmod(b) | DebouncedEvent::Write(b) => {
                    if b.extension() == Some(OsStr::new("rs")) && b.exists() {
                        let filepath = b.as_path().canonicalize().unwrap();
                        let pending_exercises = exercises
                            .iter()
                            .skip_while(|e| !filepath.ends_with(&e.path));
                        clear_screen();
                        let _ignored = verify(pending_exercises);
                    }
                }
                _ => {}
            },
            Err(e) => println!("watch error: {:?}", e),
        }
    }
}
<commit_msg>Auto merge of #233 - jrvidal:rustc-check, r=fmoko<commit_after>use crate::exercise::{Exercise, ExerciseList};
use crate::run::run;
use crate::verify::verify;
use clap::{crate_version, App, Arg, SubCommand};
use notify::DebouncedEvent;
use notify::{RecommendedWatcher, RecursiveMode, Watcher};
use std::ffi::OsStr;
use std::fs;
use std::path::Path;
use std::process::{Command, Stdio};
use std::sync::mpsc::channel;
use std::time::Duration;

mod exercise;
mod run;
mod verify;

fn main() {
    let matches = App::new("rustlings")
        .version(crate_version!())
        .author("Olivia Hugger, Carol Nichols")
        .about("Rustlings is a collection of small exercises to get you used to writing and reading Rust code")
        .subcommand(SubCommand::with_name("verify").alias("v").about("Verifies all exercises according to the recommended order"))
        .subcommand(SubCommand::with_name("watch").alias("w").about("Reruns `verify` when files were edited"))
        .subcommand(
            SubCommand::with_name("run")
                .alias("r")
                .about("Runs/Tests a single exercise")
                .arg(Arg::with_name("name").required(true).index(1)),
        )
        .subcommand(
            SubCommand::with_name("hint")
                .alias("h")
                .about("Returns a hint for the current exercise")
                .arg(Arg::with_name("name").required(true).index(1)),
        )
        .get_matches();

    if None == matches.subcommand_name() {
        println!();
        println!(r#"       welcome to...                      "#);
        println!(r#"                 _   _ _                  "#);
        println!(r#"  _ __ _   _ ___| |_| (_)_ __   __ _ ___  "#);
        println!(r#" | '__| | | / __| __| | | '_ \ / _` / __| "#);
        println!(r#" | |  | |_| \__ \ |_| | | | | | (_| \__ \ "#);
        println!(r#" |_|   \__,_|___/\__|_|_|_| |_|\__, |___/ "#);
        println!(r#"                               |___/      "#);
        println!();
    }

    if !Path::new("info.toml").exists() {
        println!(
            "{} must be run from the rustlings directory",
            std::env::current_exe().unwrap().to_str().unwrap()
        );
        println!("Try `cd rustlings/`!");
        std::process::exit(1);
    }

    if !rustc_exists() {
        println!("We cannot find `rustc`.");
        println!("Try running `rustc --version` to diagnose your problem.");
        println!("For instructions on how to install Rust, check the README.");
        std::process::exit(1);
    }

    let toml_str = &fs::read_to_string("info.toml").unwrap();
    let exercises = toml::from_str::<ExerciseList>(toml_str).unwrap().exercises;

    if let Some(ref matches) = matches.subcommand_matches("run") {
        let name = matches.value_of("name").unwrap();

        let matching_exercise = |e: &&Exercise| name == e.name;

        let exercise = exercises.iter().find(matching_exercise).unwrap_or_else(|| {
            println!("No exercise found for your given name!");
            std::process::exit(1)
        });

        run(&exercise).unwrap_or_else(|_| std::process::exit(1));
    }

    if let Some(ref matches) = matches.subcommand_matches("hint") {
        let name = matches.value_of("name").unwrap();

        let exercise = exercises
            .iter()
            .find(|e| name == e.name)
            .unwrap_or_else(|| {
                println!("No exercise found for your given name!");
                std::process::exit(1)
            });

        println!("{}", exercise.hint);
    }

    if matches.subcommand_matches("verify").is_some() {
        verify(&exercises).unwrap_or_else(|_| std::process::exit(1));
    }

    if matches.subcommand_matches("watch").is_some() {
        watch(&exercises).unwrap();
    }

    if matches.subcommand_name().is_none() {
        let text = fs::read_to_string("default_out.txt").unwrap();
        println!("{}", text);
    }
}

fn watch(exercises: &[Exercise]) -> notify::Result<()> {
    /* Clears the terminal with an ANSI escape code.
    Works in UNIX and newer Windows terminals. */
    fn clear_screen() {
        println!("\x1Bc");
    }

    let (tx, rx) = channel();

    let mut watcher: RecommendedWatcher = Watcher::new(tx, Duration::from_secs(2))?;
    watcher.watch(Path::new("./exercises"), RecursiveMode::Recursive)?;

    clear_screen();
    let _ignored = verify(exercises.iter());

    loop {
        match rx.recv() {
            Ok(event) => match event {
                DebouncedEvent::Create(b) | DebouncedEvent::Chmod(b) | DebouncedEvent::Write(b) => {
                    if b.extension() == Some(OsStr::new("rs")) && b.exists() {
                        let filepath = b.as_path().canonicalize().unwrap();
                        let pending_exercises = exercises
                            .iter()
                            .skip_while(|e| !filepath.ends_with(&e.path));
                        clear_screen();
                        let _ignored = verify(pending_exercises);
                    }
                }
                _ => {}
            },
            Err(e) => println!("watch error: {:?}", e),
        }
    }
}

fn rustc_exists() -> bool {
    Command::new("rustc")
        .args(&["--version"])
        .stdout(Stdio::null())
        .spawn()
        .and_then(|mut child| child.wait())
        .map(|status| status.success())
        .unwrap_or(false)
}
<|endoftext|>


<commit_before>use std::ops::{Add, Sub};

#[derive(Clone, Copy, Debug)]
pub struct Vec2 {
	pub x: f32,
	pub y: f32
}

impl Vec2 {
	pub fn new(x: f32, y: f32) -> Vec2 {
		return Vec2 {x: x, y: y}
	}

	pub fn new_zero() -> Vec2 {
		return Vec2 {x: 0.0, y: 0.0}
	}

	pub fn set(&mut self, x: f32, y: f32) {
		self.x = x;
		self.y = y;
	}

	pub fn dot(&mut self, o: Vec2) -> f32 {
		return self.x * o.x + self.y * o.y;
	}

	pub fn length(self) -> f32 {
		return f32::sqrt(self.x * self.x + self.y * self.y);
	}

	pub fn multiply(self, n: f32) -> Vec2 {
		return Vec2 {x: self.x * n, y: self.y * n};
	}

	pub fn divide(self, n: f32) -> Vec2 {
		return Vec2 {x: self.x / n, y: self.y / n};
	}

	pub fn cross(self, o: Vec2) -> f32 {
		return self.x * o.y - self.y * o.x;
	}

	pub fn normal(self) -> Vec2 {
		let length = self.length();
		if length == 0.0 {
			panic!("Cannot find normal when length is zero");
		}
		return self.divide(length);
	}
}

impl Add for Vec2 {
	type Output = Vec2;

	fn add(self, _rhs: Vec2) -> Vec2 {
		return Vec2::new(self.x + _rhs.x, self.y + _rhs.y);
	}
}

impl Sub for Vec2 {
	type Output = Vec2;

	fn sub(self, _rhs: Vec2) -> Vec2 {
		return Vec2::new(self.x - _rhs.x, self.y - _rhs.y);
	}
}

/*
	Has the following format
	[a11 a12]
	[a21 a22]
*/
pub struct Mat22 {
	pub c1: Vec2,
	pub c2: Vec2
}

impl Mat22 {
	pub fn new(a11: f32, a12: f32, a21: f32, a22: f32) -> Mat22 {
		return Mat22 {
			c1: Vec2::new(a11, a21),
			c2: Vec2::new(a12, a22)
		}
	}
}
<commit_msg>Making math more like actual Box2D math<commit_after>use std::ops::{Add, Sub};

#[derive(Clone, Copy, Debug)]
pub struct Vec2 {
	pub x: f32,
	pub y: f32
}

impl Vec2 {
	pub fn new(x: f32, y: f32) -> Vec2 {
		return Vec2 {x: x, y: y}
	}

	pub fn zero() -> Vec2 {
		return Vec2 {x: 0.0, y: 0.0}
	}

	pub fn set(&mut self, x: f32, y: f32) {
		self.x = x;
		self.y = y;
	}

	pub fn set_zero(&mut self) {
		self.set(0.0, 0.0)
	}

	pub fn dot(&mut self, o: Vec2) -> f32 {
		return self.x * o.x + self.y * o.y;
	}

	pub fn length(self) -> f32 {
		return f32::sqrt(self.x * self.x + self.y * self.y);
	}

	pub fn multiply(self, n: f32) -> Vec2 {
		return Vec2 {x: self.x * n, y: self.y * n};
	}

	pub fn divide(self, n: f32) -> Vec2 {
		return Vec2 {x: self.x / n, y: self.y / n};
	}

	pub fn cross(self, o: Vec2) -> f32 {
		return self.x * o.y - self.y * o.x;
	}

	pub fn normal(self) -> Vec2 {
		let length = self.length();
		if length == 0.0 {
			panic!("Cannot find normal when length is zero");
		}
		return self.divide(length);
	}
}

impl Add for Vec2 {
	type Output = Vec2;

	fn add(self, _rhs: Vec2) -> Vec2 {
		return Vec2::new(self.x + _rhs.x, self.y + _rhs.y);
	}
}

impl Sub for Vec2 {
	type Output = Vec2;

	fn sub(self, _rhs: Vec2) -> Vec2 {
		return Vec2::new(self.x - _rhs.x, self.y - _rhs.y);
	}
}

/*
	Has the following format
	[a11 a12]
	[a21 a22]
*/
pub struct Mat22 {
	pub c1: Vec2,
	pub c2: Vec2
}

impl Mat22 {
	pub fn new(a11: f32, a12: f32, a21: f32, a22: f32) -> Mat22 {
		return Mat22 {
			c1: Vec2::new(a11, a21),
			c2: Vec2::new(a12, a22)
		}
	}
}
<|endoftext|>


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

use std::{collections, iter, slice};
use json;

use {Accessor, Gltf, Material};

pub use json::mesh::{Mode, Semantic};
use json::validation::Checked;

/// Vertex attribute data.
#[derive(Clone, Debug)]
pub enum Attribute<'a> {
    /// Vertex colors.
    Colors(u32, Accessor<'a>),

    /// User specific data.
    #[cfg(feature = "extras")]
    Extras(&'a str, Accessor<'a>),

    /// Vertex joints.
    Joints(u32, Accessor<'a>),

    /// XYZ vertex positions of type `[f32; 3]`.
    Positions(Accessor<'a>),

    /// XYZ vertex normals of type `[f32; 3]`.
    Normals(Accessor<'a>),

    /// XYZW vertex tangents of type `[f32; 4]` where the `w` component is a
    /// sign value (-1 or +1) indicating the handedness of the tangent basis.
    Tangents(Accessor<'a>),

    /// UV texture co-ordinates.
    TexCoords(u32, Accessor<'a>),

    /// Weights.
    Weights(u32, Accessor<'a>),
}

/// A single morph target for a mesh primitive.
#[derive(Clone, Debug)]
pub struct MorphTarget<'a> {
    /// XYZ vertex position displacements.
    positions: Option<Accessor<'a>>,

    /// XYZ vertex normal displacements.
    normals: Option<Accessor<'a>>,

    /// XYZ vertex tangent displacements.
    tangents: Option<Accessor<'a>>,
}

/// An `Iterator` that visits the morph targets of a `Primitive`.
#[derive(Clone, Debug)]
pub struct MorphTargets<'a> {
    /// The parent `Gltf` struct.
    gltf: &'a Gltf,

    /// The internal JSON iterator.
    iter: slice::Iter<'a, json::mesh::MorphTarget>,
}

/// A set of primitives to be rendered.
#[derive(Clone, Debug)]
pub struct Mesh<'a>  {
    /// The parent `Gltf` struct.
    gltf: &'a Gltf,

    /// The corresponding JSON index.
    index: usize,

    /// The corresponding JSON struct.
    json: &'a json::mesh::Mesh,
}

/// Geometry to be rendered with the given material.
#[derive(Clone, Debug)]
pub struct Primitive<'a>  {
    /// The parent `Mesh` struct.
    mesh: &'a Mesh<'a>,

    /// The corresponding JSON index.
    index: usize,

    /// The corresponding JSON struct.
    json: &'a json::mesh::Primitive,
}

/// An `Iterator` that visits the attributes of a `Primitive`.
#[derive(Clone, Debug)]
pub struct Attributes<'a> {
    /// The parent `Gltf` struct.
    gltf: &'a Gltf,

    /// The parent `Primitive` struct.
    prim: &'a Primitive<'a>,

    /// The internal attribute iterator.
    iter: collections::hash_map::Iter<
        'a,
        json::validation::Checked<json::mesh::Semantic>,
        json::Index<json::accessor::Accessor>,
    >,
}

/// An `Iterator` that visits the primitives of a `Mesh`.
#[derive(Clone, Debug)]
pub struct Primitives<'a>  {
    /// The parent `Mesh` struct.
    mesh: &'a Mesh<'a>,

    /// The internal JSON primitive iterator.
    iter: iter::Enumerate<slice::Iter<'a, json::mesh::Primitive>>,
}

/// The minimum and maximum values for a generic accessor.
#[derive(Clone, Debug, PartialEq)]
pub struct Bounds<T> {
    /// Minimum value.
    pub min: T,

    /// Maximum value.
    pub max: T,
}

impl<'a> Mesh<'a>  {
    /// Constructs a `Mesh`.
    pub(crate) fn new(
        gltf: &'a Gltf,
        index: usize,
        json: &'a json::mesh::Mesh,
    ) -> Self {
        Self {
            gltf: gltf,
            index: index,
            json: json,
        }
    }

    /// Returns the internal JSON index.
    pub fn index(&self) -> usize {
        self.index
    }

    /// Returns the internal JSON item.
    #[doc(hidden)]
    pub fn as_json(&self) ->  &json::mesh::Mesh {
        self.json
    }

    /// Optional application specific data.
    pub fn extras(&self) -> &json::Extras {
        &self.json.extras
    }

    /// Optional user-defined name for this object.
    #[cfg(feature = "names")]
    pub fn name(&self) -> Option<&str> {
        self.json.name.as_ref().map(String::as_str)
    }

    /// Defines the geometry to be renderered with a material.
    pub fn primitives(&'a self) -> Primitives<'a> {
        Primitives {
            mesh: self,
            iter: self.json.primitives.iter().enumerate(),
        }
    }

    /// Defines the weights to be applied to the morph targets.
    pub fn weights(&self) -> Option<&[f32]> {
        self.json.weights.as_ref().map(Vec::as_slice)
    }
}

impl<'a> Primitive<'a> {
    /// Constructs a `Primitive`.
    pub(crate) fn new(
        mesh: &'a Mesh<'a>,
        index: usize,
        json: &'a json::mesh::Primitive,
    ) -> Self {
        Self {
            mesh: mesh,
            index: index,
            json: json,
        }
    }

    /// Returns the internal JSON item.
    #[doc(hidden)]
    pub fn as_json(&self) ->  &json::mesh::Primitive {
        self.json
    }

    /// Returns the bounds of the `POSITION` vertex attribute when provided.
    ///
    /// # Panics
    ///
    /// Panics for `POSITION` accessors with missing bounds.
    ///
    /// Since `POSITION` accessors must include bounds information, one can
    /// call `Gltf::validate_minimally` to ensure this data exists.
    pub fn position_bounds(&self) -> Option<Bounds<[f32; 3]>> {
        if let Some(pos_accessor_index) = self.json.attributes.get(&Checked::Valid(Semantic::Positions)) {
            let pos_accessor = self.mesh.gltf.accessors().nth(pos_accessor_index.value()).unwrap();
            // NOTE: cannot panic if validated "minimally"
            let min: [f32; 3] = json::from_value(pos_accessor.min().unwrap()).unwrap();
            let max: [f32; 3] = json::from_value(pos_accessor.max().unwrap()).unwrap();
            Some(Bounds {
                min: [min[0], min[1], min[2]],
                max: [max[0], max[1], max[2]]
            })
        } else {
            None
        }
    }

    /// Optional application specific data.
    pub fn extras(&self) -> &json::Extras {
        &self.json.extras
    }

    /// Return the accessor with the given semantic.
    pub fn get(&self, semantic: &Semantic) -> Option<Accessor> {
        self.json.attributes
            .get(&json::validation::Checked::Valid(semantic.clone()))
            .map(|index| self.mesh.gltf.accessors().nth(index.value()).unwrap())
    }

    /// Returns the accessor containing the primitive indices, if provided.
    pub fn indices(&self) -> Option<Accessor> {
        self.json.indices
            .as_ref()
            .map(|index| self.mesh.gltf.accessors().nth(index.value()).unwrap())
    }

    /// Returns an `Iterator` that visits the vertex attributes.
    pub fn attributes(&self) -> Attributes {
        Attributes {
            gltf: self.mesh.gltf,
            prim: self,
            iter: self.json.attributes.iter(),
        }
    }

    /// Returns the material to apply to this primitive when rendering
    pub fn material(&self) -> Material {
        self.json.material
            .as_ref()
            .map(|index| self.mesh.gltf.materials().nth(index.value()).unwrap())
            .unwrap_or_else(|| Material::default(self.mesh.gltf))
    }

    /// The type of primitives to render.
    pub fn mode(&self) -> Mode {
        self.json.mode.unwrap()
    }

    /// Returns an `Iterator` that visits the morph targets of the primitive.
    pub fn morph_targets(&self) -> MorphTargets {
        if let Some(slice) = self.json.targets.as_ref() {
            MorphTargets {
                gltf: self.mesh.gltf,
                iter: slice.iter(),
            }
        } else {
            MorphTargets {
                gltf: self.mesh.gltf,
                iter: (&[]).iter(),
            }
        }
    }
}

impl<'a> MorphTarget<'a> {
    /// Returns the XYZ vertex position displacements.
    pub fn positions(&self) -> Option<Accessor<'a>> {
        self.positions.clone()
    }

    /// Returns the XYZ vertex normal displacements.
    pub fn normals(&self) -> Option<Accessor<'a>> {
        self.normals.clone()
    }

    /// Returns the XYZ vertex tangent displacements.
    pub fn tangents(&self) -> Option<Accessor<'a>> {
        self.tangents.clone()
    }
}

impl<'a> ExactSizeIterator for Attributes<'a> {}
impl<'a> Iterator for Attributes<'a> {
    type Item = Attribute<'a>;
    fn next(&mut self) -> Option<Self::Item> {
        use self::Semantic::*;
        self.iter
            .next()
            .map(|(key, index)| {
                let semantic = key.as_ref().unwrap();
                let accessor = self.gltf.accessors().nth(index.value()).unwrap();
                match *semantic {
                    Positions => Attribute::Positions(accessor),
                    Normals => Attribute::Normals(accessor),
                    Tangents => Attribute::Tangents(accessor),
                    Colors(set) => Attribute::Colors(set, accessor),
                    TexCoords(set) => Attribute::TexCoords(set, accessor),
                    Joints(set) => Attribute::Joints(set, accessor),
                    Weights(set) => Attribute::Weights(set, accessor),
                    #[cfg(feature = "extras")]
                    Extras(ref id) => Attribute::Extras(id, accessor),
                }
            })
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

impl<'a> ExactSizeIterator for Primitives<'a> {}
impl<'a> Iterator for Primitives<'a> {
    type Item = Primitive<'a>;
    fn next(&mut self) -> Option<Self::Item> {
        self.iter.next().map(|(index, json)| Primitive::new(self.mesh, index, json))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

impl<'a> ExactSizeIterator for MorphTargets<'a> {}
impl<'a> Iterator for MorphTargets<'a> {
    type Item = MorphTarget<'a>;
    fn next(&mut self) -> Option<Self::Item> {
        self.iter
            .next()
            .map(|json| {
                let positions = json.positions
                    .as_ref()
                    .map(|index| self.gltf.accessors().nth(index.value()).unwrap());
                let normals = json.normals
                    .as_ref()
                    .map(|index| self.gltf.accessors().nth(index.value()).unwrap());
                let tangents = json.tangents
                    .as_ref()
                    .map(|index| self.gltf.accessors().nth(index.value()).unwrap());
                MorphTarget {
                    positions,
                    normals,
                    tangents,
                }
            })
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}
<commit_msg>Replace Attribute type with tuple<commit_after>
// Copyright 2017 The gltf Library Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::{collections, iter, slice};
use json;

use {Accessor, Gltf, Material};

pub use json::mesh::{Mode, Semantic};
use json::validation::Checked;

/// Vertex attribute data.
pub type Attribute<'a> = (Semantic, Accessor<'a>);

/// A single morph target for a mesh primitive.
#[derive(Clone, Debug)]
pub struct MorphTarget<'a> {
    /// XYZ vertex position displacements.
    positions: Option<Accessor<'a>>,

    /// XYZ vertex normal displacements.
    normals: Option<Accessor<'a>>,

    /// XYZ vertex tangent displacements.
    tangents: Option<Accessor<'a>>,
}

/// An `Iterator` that visits the morph targets of a `Primitive`.
#[derive(Clone, Debug)]
pub struct MorphTargets<'a> {
    /// The parent `Gltf` struct.
    gltf: &'a Gltf,

    /// The internal JSON iterator.
    iter: slice::Iter<'a, json::mesh::MorphTarget>,
}

/// A set of primitives to be rendered.
#[derive(Clone, Debug)]
pub struct Mesh<'a>  {
    /// The parent `Gltf` struct.
    gltf: &'a Gltf,

    /// The corresponding JSON index.
    index: usize,

    /// The corresponding JSON struct.
    json: &'a json::mesh::Mesh,
}

/// Geometry to be rendered with the given material.
#[derive(Clone, Debug)]
pub struct Primitive<'a>  {
    /// The parent `Mesh` struct.
    mesh: &'a Mesh<'a>,

    /// The corresponding JSON index.
    index: usize,

    /// The corresponding JSON struct.
    json: &'a json::mesh::Primitive,
}

/// An `Iterator` that visits the attributes of a `Primitive`.
#[derive(Clone, Debug)]
pub struct Attributes<'a> {
    /// The parent `Gltf` struct.
    gltf: &'a Gltf,

    /// The parent `Primitive` struct.
    prim: &'a Primitive<'a>,

    /// The internal attribute iterator.
    iter: collections::hash_map::Iter<
        'a,
        json::validation::Checked<json::mesh::Semantic>,
        json::Index<json::accessor::Accessor>,
    >,
}

/// An `Iterator` that visits the primitives of a `Mesh`.
#[derive(Clone, Debug)]
pub struct Primitives<'a>  {
    /// The parent `Mesh` struct.
    mesh: &'a Mesh<'a>,

    /// The internal JSON primitive iterator.
    iter: iter::Enumerate<slice::Iter<'a, json::mesh::Primitive>>,
}

/// The minimum and maximum values for a generic accessor.
#[derive(Clone, Debug, PartialEq)]
pub struct Bounds<T> {
    /// Minimum value.
    pub min: T,

    /// Maximum value.
    pub max: T,
}

impl<'a> Mesh<'a>  {
    /// Constructs a `Mesh`.
    pub(crate) fn new(
        gltf: &'a Gltf,
        index: usize,
        json: &'a json::mesh::Mesh,
    ) -> Self {
        Self {
            gltf: gltf,
            index: index,
            json: json,
        }
    }

    /// Returns the internal JSON index.
    pub fn index(&self) -> usize {
        self.index
    }

    /// Returns the internal JSON item.
    #[doc(hidden)]
    pub fn as_json(&self) ->  &json::mesh::Mesh {
        self.json
    }

    /// Optional application specific data.
    pub fn extras(&self) -> &json::Extras {
        &self.json.extras
    }

    /// Optional user-defined name for this object.
    #[cfg(feature = "names")]
    pub fn name(&self) -> Option<&str> {
        self.json.name.as_ref().map(String::as_str)
    }

    /// Defines the geometry to be renderered with a material.
    pub fn primitives(&'a self) -> Primitives<'a> {
        Primitives {
            mesh: self,
            iter: self.json.primitives.iter().enumerate(),
        }
    }

    /// Defines the weights to be applied to the morph targets.
    pub fn weights(&self) -> Option<&[f32]> {
        self.json.weights.as_ref().map(Vec::as_slice)
    }
}

impl<'a> Primitive<'a> {
    /// Constructs a `Primitive`.
    pub(crate) fn new(
        mesh: &'a Mesh<'a>,
        index: usize,
        json: &'a json::mesh::Primitive,
    ) -> Self {
        Self {
            mesh: mesh,
            index: index,
            json: json,
        }
    }

    /// Returns the internal JSON item.
    #[doc(hidden)]
    pub fn as_json(&self) ->  &json::mesh::Primitive {
        self.json
    }

    /// Returns the bounds of the `POSITION` vertex attribute when provided.
    ///
    /// # Panics
    ///
    /// Panics for `POSITION` accessors with missing bounds.
    ///
    /// Since `POSITION` accessors must include bounds information, one can
    /// call `Gltf::validate_minimally` to ensure this data exists.
    pub fn position_bounds(&self) -> Option<Bounds<[f32; 3]>> {
        if let Some(pos_accessor_index) = self.json.attributes.get(&Checked::Valid(Semantic::Positions)) {
            let pos_accessor = self.mesh.gltf.accessors().nth(pos_accessor_index.value()).unwrap();
            // NOTE: cannot panic if validated "minimally"
            let min: [f32; 3] = json::from_value(pos_accessor.min().unwrap()).unwrap();
            let max: [f32; 3] = json::from_value(pos_accessor.max().unwrap()).unwrap();
            Some(Bounds {
                min: [min[0], min[1], min[2]],
                max: [max[0], max[1], max[2]]
            })
        } else {
            None
        }
    }

    /// Optional application specific data.
    pub fn extras(&self) -> &json::Extras {
        &self.json.extras
    }

    /// Return the accessor with the given semantic.
    pub fn get(&self, semantic: &Semantic) -> Option<Accessor> {
        self.json.attributes
            .get(&json::validation::Checked::Valid(semantic.clone()))
            .map(|index| self.mesh.gltf.accessors().nth(index.value()).unwrap())
    }

    /// Returns the accessor containing the primitive indices, if provided.
    pub fn indices(&self) -> Option<Accessor> {
        self.json.indices
            .as_ref()
            .map(|index| self.mesh.gltf.accessors().nth(index.value()).unwrap())
    }

    /// Returns an `Iterator` that visits the vertex attributes.
    pub fn attributes(&self) -> Attributes {
        Attributes {
            gltf: self.mesh.gltf,
            prim: self,
            iter: self.json.attributes.iter(),
        }
    }

    /// Returns the material to apply to this primitive when rendering
    pub fn material(&self) -> Material {
        self.json.material
            .as_ref()
            .map(|index| self.mesh.gltf.materials().nth(index.value()).unwrap())
            .unwrap_or_else(|| Material::default(self.mesh.gltf))
    }

    /// The type of primitives to render.
    pub fn mode(&self) -> Mode {
        self.json.mode.unwrap()
    }

    /// Returns an `Iterator` that visits the morph targets of the primitive.
    pub fn morph_targets(&self) -> MorphTargets {
        if let Some(slice) = self.json.targets.as_ref() {
            MorphTargets {
                gltf: self.mesh.gltf,
                iter: slice.iter(),
            }
        } else {
            MorphTargets {
                gltf: self.mesh.gltf,
                iter: (&[]).iter(),
            }
        }
    }
}

impl<'a> MorphTarget<'a> {
    /// Returns the XYZ vertex position displacements.
    pub fn positions(&self) -> Option<Accessor<'a>> {
        self.positions.clone()
    }

    /// Returns the XYZ vertex normal displacements.
    pub fn normals(&self) -> Option<Accessor<'a>> {
        self.normals.clone()
    }

    /// Returns the XYZ vertex tangent displacements.
    pub fn tangents(&self) -> Option<Accessor<'a>> {
        self.tangents.clone()
    }
}

impl<'a> ExactSizeIterator for Attributes<'a> {}
impl<'a> Iterator for Attributes<'a> {
    type Item = Attribute<'a>;
    fn next(&mut self) -> Option<Self::Item> {
        self.iter
            .next()
            .map(|(key, index)| {
                let semantic = key.as_ref().unwrap().clone();
                let accessor = self.gltf.accessors().nth(index.value()).unwrap();
                (semantic, accessor)
            })
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

impl<'a> ExactSizeIterator for Primitives<'a> {}
impl<'a> Iterator for Primitives<'a> {
    type Item = Primitive<'a>;
    fn next(&mut self) -> Option<Self::Item> {
        self.iter.next().map(|(index, json)| Primitive::new(self.mesh, index, json))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

impl<'a> ExactSizeIterator for MorphTargets<'a> {}
impl<'a> Iterator for MorphTargets<'a> {
    type Item = MorphTarget<'a>;
    fn next(&mut self) -> Option<Self::Item> {
        self.iter
            .next()
            .map(|json| {
                let positions = json.positions
                    .as_ref()
                    .map(|index| self.gltf.accessors().nth(index.value()).unwrap());
                let normals = json.normals
                    .as_ref()
                    .map(|index| self.gltf.accessors().nth(index.value()).unwrap());
                let tangents = json.tangents
                    .as_ref()
                    .map(|index| self.gltf.accessors().nth(index.value()).unwrap());
                MorphTarget {
                    positions,
                    normals,
                    tangents,
                }
            })
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}
<|endoftext|>


<commit_before>cfg_trace! {
    cfg_rt! {
        pub(crate) use tracing::instrument::Instrumented;

        #[inline]
        #[cfg_attr(tokio_track_caller, track_caller)]
        pub(crate) fn task<F>(task: F, kind: &'static str, name: Option<&str>) -> Instrumented<F> {
            use tracing::instrument::Instrument;
            #[cfg(tokio_track_caller)]
            let location = std::panic::Location::caller();
            #[cfg(tokio_track_caller)]
            let span = tracing::trace_span!(
                target: "tokio::task",
                "runtime.spawn",
                %kind,
                task.name = %name.unwrap_or_default(),
                spawn.location = %format_args!("{}:{}:{}", location.file(), location.line(), location.column()),
            );
            #[cfg(not(tokio_track_caller))]
            let span = tracing::trace_span!(
                target: "tokio::task",
                "runtime.spawn",
                %kind,
                task.name = %name.unwrap_or_default(),
            );
            task.instrument(span)
        }
    }
}
cfg_time! {
    #[cfg_attr(tokio_track_caller, track_caller)]
    pub(crate) fn caller_location() -> Option<&'static std::panic::Location<'static>> {
        #[cfg(all(tokio_track_caller, tokio_unstable, feature = "tracing"))]
        return Some(std::panic::Location::caller());
        #[cfg(not(all(tokio_track_caller, tokio_unstable, feature = "tracing")))]
        None
    }
}

cfg_not_trace! {
    cfg_rt! {
        #[inline]
        pub(crate) fn task<F>(task: F, _: &'static str, _name: Option<&str>) -> F {
            // nop
            task
        }
    }
}
<commit_msg>tracing: use structured location fields for spawned tasks (#4128)<commit_after>cfg_trace! {
    cfg_rt! {
        pub(crate) use tracing::instrument::Instrumented;

        #[inline]
        #[cfg_attr(tokio_track_caller, track_caller)]
        pub(crate) fn task<F>(task: F, kind: &'static str, name: Option<&str>) -> Instrumented<F> {
            use tracing::instrument::Instrument;
            #[cfg(tokio_track_caller)]
            let location = std::panic::Location::caller();
            #[cfg(tokio_track_caller)]
            let span = tracing::trace_span!(
                target: "tokio::task",
                "runtime.spawn",
                %kind,
                task.name = %name.unwrap_or_default(),
                loc.file = location.file(),
                loc.line = location.line(),
                loc.col = location.column(),
            );
            #[cfg(not(tokio_track_caller))]
            let span = tracing::trace_span!(
                target: "tokio::task",
                "runtime.spawn",
                %kind,
                task.name = %name.unwrap_or_default(),
            );
            task.instrument(span)
        }
    }
}
cfg_time! {
    #[cfg_attr(tokio_track_caller, track_caller)]
    pub(crate) fn caller_location() -> Option<&'static std::panic::Location<'static>> {
        #[cfg(all(tokio_track_caller, tokio_unstable, feature = "tracing"))]
        return Some(std::panic::Location::caller());
        #[cfg(not(all(tokio_track_caller, tokio_unstable, feature = "tracing")))]
        None
    }
}

cfg_not_trace! {
    cfg_rt! {
        #[inline]
        pub(crate) fn task<F>(task: F, _: &'static str, _name: Option<&str>) -> F {
            // nop
            task
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>[parser] Add more LazyDataSetReader constructors<commit_after><|endoftext|>


<commit_before>// Copyright 2020 The Evcxr Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use evcxr_runtime;
use image;

pub trait ImageDisplay {
    fn evcxr_display(&self);
}

impl ImageDisplay for image::RgbImage {
    fn evcxr_display(&self) {
        let mut buffer = Vec::new();
        image::png::PngEncoder::new(&mut buffer)
            .encode(&**self, self.width(), self.height(), image::ColorType::Rgb8)
            .unwrap();
        evcxr_runtime::mime_type("image/png").bytes(&buffer);
    }
}

impl ImageDisplay for image::GrayImage {
    fn evcxr_display(&self) {
        let mut buffer = Vec::new();
        image::png::PngEncoder::new(&mut buffer)
            .encode(&**self, self.width(), self.height(), image::ColorType::L8)
            .unwrap();
        evcxr_runtime::mime_type("image/png").bytes(&buffer);
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn rgb_image() {
        let img = image::ImageBuffer::from_fn(10, 10, |x, y| {
            if (x as i32 - y as i32).abs() < 3 {
                image::Rgb([0, 0, 255])
            } else {
                image::Rgb([0, 0, 0])
            }
        });
        use super::ImageDisplay;
        img.evcxr_display();
    }

    #[test]
    fn gray_image() {
        let img = image::ImageBuffer::from_fn(10, 10, |x, y| {
            if (x as i32 - y as i32).abs() < 3 {
                image::Luma([255])
            } else {
                image::Luma([0])
            }
        });
        use super::ImageDisplay;
        img.evcxr_display();
    }
}
<commit_msg>evcxr_image: Support all 8 bit per subpixel formats<commit_after>// Copyright 2020 The Evcxr Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::ops::Deref;

use evcxr_runtime;
use image;

pub trait ImageDisplay {
    fn evcxr_display(&self);
}

impl<P: image::Pixel<Subpixel = u8> + 'static, C> ImageDisplay for image::ImageBuffer<P, C>
where
    C: Deref<Target = [P::Subpixel]>,
{
    fn evcxr_display(&self) {
        let mut buffer = Vec::new();
        image::png::PngEncoder::new(&mut buffer)
            .encode(&**self, self.width(), self.height(), P::COLOR_TYPE)
            .unwrap();
        evcxr_runtime::mime_type("image/png").bytes(&buffer);
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn rgb_image() {
        let img = image::ImageBuffer::from_fn(10, 10, |x, y| {
            if (x as i32 - y as i32).abs() < 3 {
                image::Rgb([0, 0, 255])
            } else {
                image::Rgb([0, 0, 0])
            }
        });
        use super::ImageDisplay;
        img.evcxr_display();
    }

    #[test]
    fn gray_image() {
        let img = image::ImageBuffer::from_fn(10, 10, |x, y| {
            if (x as i32 - y as i32).abs() < 3 {
                image::Luma([255])
            } else {
                image::Luma([0])
            }
        });
        use super::ImageDisplay;
        img.evcxr_display();
    }
}
<|endoftext|>


<commit_before>use hyper;
use hyper::client::IntoUrl;
use hyper::header::{Headers, UserAgent};
use super::Response;
use super::Result;

const DEFAULT_USER_AGENT: &'static str = concat!("requests-rs/", env!("CARGO_PKG_VERSION"));

pub struct Request {
    headers: Headers,
    params: Vec<String>,
}

impl Default for Request {
    fn default() -> Self {
        let mut request = Request::new();
        request.user_agent(DEFAULT_USER_AGENT);
        request
    }
}

impl Request {
    pub fn new() -> Self {
        Request {
            headers: Headers::new(),
            params: Vec::<String>::new(),
        }
    }

    pub fn params<T, U>(&mut self, params: U) -> &mut Self
        where T: Into<String>,
              U: IntoIterator<Item = (T, T)>
    {
        for (key, value) in params {
            self.param(key, value);
        }
        self
    }

    pub fn param<T>(&mut self, key: T, value: T) -> &mut Self
        where T: Into<String>
    {
        self.params.push(format!("{}={}", key.into(), value.into()));
        self
    }

    pub fn user_agent(&mut self, ua: &str) {
        self.headers.set(UserAgent(ua.to_owned()))
    }

    pub fn get<U: IntoUrl>(&self, url: U) -> Result {
        hyper::Client::new()
            .get(url)
            .headers(self.headers.clone())
            .send()
            .map(Response::from)
    }

    pub fn post<U: IntoUrl>(&self, url: U) -> Result {
        hyper::Client::new()
            .post(url)
            .headers(self.headers.clone())
            .send()
            .map(Response::from)
    }

    pub fn put<U: IntoUrl>(&self, url: U) -> Result {
        hyper::Client::new()
            .put(url)
            .headers(self.headers.clone())
            .send()
            .map(Response::from)
    }

    pub fn head<U: IntoUrl>(&self, url: U) -> Result {
        hyper::Client::new()
            .head(url)
            .headers(self.headers.clone())
            .send()
            .map(Response::from)
    }

    pub fn delete<U: IntoUrl>(&self, url: U) -> Result {
        hyper::Client::new()
            .delete(url)
            .headers(self.headers.clone())
            .send()
            .map(Response::from)
    }
}
<commit_msg>params() and param() are not ready yet for public consumption<commit_after>use hyper;
use hyper::client::IntoUrl;
use hyper::header::{Headers, UserAgent};
use super::Response;
use super::Result;

const DEFAULT_USER_AGENT: &'static str = concat!("requests-rs/", env!("CARGO_PKG_VERSION"));

pub struct Request {
    headers: Headers,
    params: Vec<String>,
}

impl Default for Request {
    fn default() -> Self {
        let mut request = Request::new();
        request.user_agent(DEFAULT_USER_AGENT);
        request
    }
}

impl Request {
    pub fn new() -> Self {
        Request {
            headers: Headers::new(),
            params: Vec::<String>::new(),
        }
    }

    fn params<T, U>(&mut self, params: U) -> &mut Self
        where T: Into<String>,
              U: IntoIterator<Item = (T, T)>
    {
        for (key, value) in params {
            self.param(key, value);
        }
        self
    }

    fn param<T>(&mut self, key: T, value: T) -> &mut Self
        where T: Into<String>
    {
        self.params.push(format!("{}={}", key.into(), value.into()));
        self
    }

    pub fn user_agent(&mut self, ua: &str) {
        self.headers.set(UserAgent(ua.to_owned()))
    }

    pub fn get<U: IntoUrl>(&self, url: U) -> Result {
        hyper::Client::new()
            .get(url)
            .headers(self.headers.clone())
            .send()
            .map(Response::from)
    }

    pub fn post<U: IntoUrl>(&self, url: U) -> Result {
        hyper::Client::new()
            .post(url)
            .headers(self.headers.clone())
            .send()
            .map(Response::from)
    }

    pub fn put<U: IntoUrl>(&self, url: U) -> Result {
        hyper::Client::new()
            .put(url)
            .headers(self.headers.clone())
            .send()
            .map(Response::from)
    }

    pub fn head<U: IntoUrl>(&self, url: U) -> Result {
        hyper::Client::new()
            .head(url)
            .headers(self.headers.clone())
            .send()
            .map(Response::from)
    }

    pub fn delete<U: IntoUrl>(&self, url: U) -> Result {
        hyper::Client::new()
            .delete(url)
            .headers(self.headers.clone())
            .send()
            .map(Response::from)
    }
}
<|endoftext|>


<commit_before>use super::game;
use super::cards;
use super::pos;

#[derive(PartialEq)]
pub enum Target {
    Contract80,
    Contract90,
    Contract100,
    Contract110,
    Contract120,
    Contract130,
    Contract140,
    Contract150,
    Contract160,
    ContractCapot,
}

impl Target {
    pub fn score(&self) -> i32 {
        match *self {
            Target::Contract80 => 80,
            Target::Contract90 => 90,
            Target::Contract100 => 100,
            Target::Contract110 => 110,
            Target::Contract120 => 120,
            Target::Contract130 => 130,
            Target::Contract140 => 140,
            Target::Contract150 => 150,
            Target::Contract160 => 160,
            Target::ContractCapot => 250,
        }
    }

    pub fn victory(&self, score: i32, capot: bool) -> bool {
        match *self {
            Target::Contract80 => score >= 80,
            Target::Contract90 => score >= 90,
            Target::Contract100 => score >= 100,
            Target::Contract110 => score >= 110,
            Target::Contract120 => score >= 120,
            Target::Contract130 => score >= 130,
            Target::Contract140 => score >= 140,
            Target::Contract150 => score >= 150,
            Target::Contract160 => score >= 160,
            Target::ContractCapot => capot,
        }
    }
}

pub struct Contract {
    pub trump: cards::Suit,
    pub author: pos::PlayerPos,
    pub target: Target,
    pub coinche_level: i32,
}

pub struct Auction {
    history: Vec<Contract>,
    pass_count: usize,
    first: pos::PlayerPos,
    stopped: bool,
    players: [cards::Hand; 4],
}

pub fn new_auction(first: pos::PlayerPos) -> Auction {
    Auction {
        history: Vec::new(),
        pass_count: 0,
        stopped: false,
        first: first,
        players: super::deal_hands(),
    }
}

impl Auction {
    // Bid a new, higher contract.
    pub fn bid(&mut self, contract: Contract) -> Result<bool,String> {
        if self.stopped {
            return Err("auction is closed".to_string());
        }

        if contract.coinche_level != 0 {
            return Err("cannot bid pre-coinched contract".to_string());
        }

        if !self.history.is_empty() {
            if contract.author != self.current_contract().expect("no contract found").author.next_n(self.pass_count + 1) {
                return Err("wrong player order".to_string());
            }
            if contract.target.score() <= self.history[self.history.len()-1].target.score() {
                return Err("must bid higher than current contract".to_string());
            }
        } else {
            if contract.author != self.first.next_n(self.pass_count) {
                return Err(format!("wrong player order: expected {}", self.first.next_n(self.pass_count).0));
            }
        }

        self.stopped = contract.target == Target::ContractCapot;

        self.history.push(contract);
        self.pass_count = 0;

        // Only stops the bids if the guy asked for a capot
        Ok(self.stopped)
    }

    pub fn current_contract(&self) -> Option<&Contract> {
        if self.history.is_empty() {
            None
        } else {
            Some(&self.history[self.history.len() - 1])
        }
    }

    pub fn hands(&self) -> &[cards::Hand; 4] {
        &self.players
    }

    pub fn pass(&mut self) -> bool {
        self.pass_count += 1;

        // After 3 passes, we're back to the contract author, and we can start.
        let pass_limit = if !self.history.is_empty() {
            3
        } else {
            4
        };

        self.stopped = self.pass_count == pass_limit;

        self.stopped
    }

    pub fn coinche(&mut self) -> Result<bool,String> {
        if self.history.is_empty() {
            Err("no contract to coinche".to_string())
        } else {
            self.stopped = true;
            let i = self.history.len() - 1;
            if self.history[i].coinche_level > 1 {
                Err("constract is already sur-coinched".to_string())
            } else {
                self.history[i].coinche_level += 1;
                // Stop if we are already sur-coinching
                Ok(self.history[i].coinche_level == 2)
            }
        }
    }

    // Moves the auction to kill it
    pub fn complete(mut self) -> Result<game::GameState,String> {
        if !self.stopped {
            Err("auction is still running".to_string())
        } else if self.history.is_empty() {
            Err("no contract to start the game with".to_string())
        } else {
            Ok(game::new_game(self.first, self.players, self.history.pop().expect("contract history empty")))
        }
    }
}

#[test]
fn test_auction() {
    let mut auction = new_auction(pos::PlayerPos(0));

    assert!(!auction.stopped);

    // First three people pass.
    assert!(!auction.pass());
    assert!(!auction.pass());
    assert!(!auction.pass());

    // Someone bids.
    assert_eq!(auction.bid(Contract{
        author: pos::PlayerPos(3),
        trump: cards::HEART,
        target: Target::Contract80,
        coinche_level: 0,
    }), Ok(false));
    assert_eq!(auction.bid(Contract{
        author: pos::PlayerPos(0),
        trump: cards::CLUB,
        target: Target::Contract80,
        coinche_level: 0,
    }).ok(), None);
    assert_eq!(auction.bid(Contract{
        author: pos::PlayerPos(1),
        trump: cards::CLUB,
        target: Target::Contract100,
        coinche_level: 0,
    }).ok(), None);
    assert!(!auction.pass());
    // Partner surbids
    assert_eq!(auction.bid(Contract{
        author: pos::PlayerPos(1),
        trump: cards::HEART,
        target: Target::Contract100,
        coinche_level: 0,
    }), Ok(false));
    assert!(!auction.pass());
    assert!(!auction.pass());
    assert!(auction.pass());

    assert!(auction.stopped);

    match auction.complete() {
        Err(_) => assert!(false),
        _=> {},
    }
}
<commit_msg>Split Auction::bid() into bid() and can_bid()<commit_after>use super::game;
use super::cards;
use super::pos;

#[derive(PartialEq)]
pub enum Target {
    Contract80,
    Contract90,
    Contract100,
    Contract110,
    Contract120,
    Contract130,
    Contract140,
    Contract150,
    Contract160,
    ContractCapot,
}

impl Target {
    pub fn score(&self) -> i32 {
        match *self {
            Target::Contract80 => 80,
            Target::Contract90 => 90,
            Target::Contract100 => 100,
            Target::Contract110 => 110,
            Target::Contract120 => 120,
            Target::Contract130 => 130,
            Target::Contract140 => 140,
            Target::Contract150 => 150,
            Target::Contract160 => 160,
            Target::ContractCapot => 250,
        }
    }

    pub fn victory(&self, score: i32, capot: bool) -> bool {
        match *self {
            Target::Contract80 => score >= 80,
            Target::Contract90 => score >= 90,
            Target::Contract100 => score >= 100,
            Target::Contract110 => score >= 110,
            Target::Contract120 => score >= 120,
            Target::Contract130 => score >= 130,
            Target::Contract140 => score >= 140,
            Target::Contract150 => score >= 150,
            Target::Contract160 => score >= 160,
            Target::ContractCapot => capot,
        }
    }
}

pub struct Contract {
    pub trump: cards::Suit,
    pub author: pos::PlayerPos,
    pub target: Target,
    pub coinche_level: i32,
}

pub struct Auction {
    history: Vec<Contract>,
    pass_count: usize,
    first: pos::PlayerPos,
    stopped: bool,
    players: [cards::Hand; 4],
}

pub fn new_auction(first: pos::PlayerPos) -> Auction {
    Auction {
        history: Vec::new(),
        pass_count: 0,
        stopped: false,
        first: first,
        players: super::deal_hands(),
    }
}

impl Auction {

    fn can_bid(&self, contract: &Contract) -> Result<(),String> {
        if self.stopped {
            return Err("auction is closed".to_string());
        }

        if contract.coinche_level != 0 {
            return Err("cannot bid pre-coinched contract".to_string());
        }

        if !self.history.is_empty() {
            if contract.author != self.current_contract().expect("no contract found").author.next_n(self.pass_count + 1) {
                return Err("wrong player order".to_string());
            }
            if contract.target.score() <= self.history[self.history.len()-1].target.score() {
                return Err("must bid higher than current contract".to_string());
            }
        } else {
            if contract.author != self.first.next_n(self.pass_count) {
                return Err(format!("wrong player order: expected {}", self.first.next_n(self.pass_count).0));
            }
        }

        Ok(())
    }

    // Bid a new, higher contract.
    pub fn bid(&mut self, contract: Contract) -> Result<bool,String> {
        match self.can_bid(&contract) {
            Err(msg) => return Err(msg),
            Ok(_) => (),
        }

        self.stopped = contract.target == Target::ContractCapot;

        self.history.push(contract);
        self.pass_count = 0;

        // Only stops the bids if the guy asked for a capot
        Ok(self.stopped)
    }

    pub fn current_contract(&self) -> Option<&Contract> {
        if self.history.is_empty() {
            None
        } else {
            Some(&self.history[self.history.len() - 1])
        }
    }

    pub fn hands(&self) -> &[cards::Hand; 4] {
        &self.players
    }

    pub fn pass(&mut self) -> bool {
        self.pass_count += 1;

        // After 3 passes, we're back to the contract author, and we can start.
        let pass_limit = if !self.history.is_empty() {
            3
        } else {
            4
        };

        self.stopped = self.pass_count == pass_limit;

        self.stopped
    }

    pub fn coinche(&mut self) -> Result<bool,String> {
        if self.history.is_empty() {
            Err("no contract to coinche".to_string())
        } else {
            self.stopped = true;
            let i = self.history.len() - 1;
            if self.history[i].coinche_level > 1 {
                Err("constract is already sur-coinched".to_string())
            } else {
                self.history[i].coinche_level += 1;
                // Stop if we are already sur-coinching
                Ok(self.history[i].coinche_level == 2)
            }
        }
    }

    // Moves the auction to kill it
    pub fn complete(mut self) -> Result<game::GameState,String> {
        if !self.stopped {
            Err("auction is still running".to_string())
        } else if self.history.is_empty() {
            Err("no contract to start the game with".to_string())
        } else {
            Ok(game::new_game(self.first, self.players, self.history.pop().expect("contract history empty")))
        }
    }
}

#[test]
fn test_auction() {
    let mut auction = new_auction(pos::PlayerPos(0));

    assert!(!auction.stopped);

    // First three people pass.
    assert!(!auction.pass());
    assert!(!auction.pass());
    assert!(!auction.pass());

    // Someone bids.
    assert_eq!(auction.bid(Contract{
        author: pos::PlayerPos(3),
        trump: cards::HEART,
        target: Target::Contract80,
        coinche_level: 0,
    }), Ok(false));
    assert_eq!(auction.bid(Contract{
        author: pos::PlayerPos(0),
        trump: cards::CLUB,
        target: Target::Contract80,
        coinche_level: 0,
    }).ok(), None);
    assert_eq!(auction.bid(Contract{
        author: pos::PlayerPos(1),
        trump: cards::CLUB,
        target: Target::Contract100,
        coinche_level: 0,
    }).ok(), None);
    assert!(!auction.pass());
    // Partner surbids
    assert_eq!(auction.bid(Contract{
        author: pos::PlayerPos(1),
        trump: cards::HEART,
        target: Target::Contract100,
        coinche_level: 0,
    }), Ok(false));
    assert!(!auction.pass());
    assert!(!auction.pass());
    assert!(auction.pass());

    assert!(auction.stopped);

    match auction.complete() {
        Err(_) => assert!(false),
        _=> {},
    }
}
<|endoftext|>


<commit_before>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Operations on managed box types

use ptr::to_unsafe_ptr;

#[cfg(not(test))] use cmp::*;

pub static RC_MANAGED_UNIQUE : uint = (-2) as uint;
pub static RC_IMMORTAL : uint = 0x77777777;

/// Returns the refcount of a shared box (as just before calling this)
#[inline]
pub fn refcount<T>(t: @T) -> uint {
    use unstable::raw::Repr;
    unsafe { (*t.repr()).ref_count }
}

/// Determine if two shared boxes point to the same object
#[inline]
pub fn ptr_eq<T>(a: @T, b: @T) -> bool {
    let (a_ptr, b_ptr): (*T, *T) = (to_unsafe_ptr(&*a), to_unsafe_ptr(&*b));
    a_ptr == b_ptr
}

/// Determine if two mutable shared boxes point to the same object
#[inline]
pub fn mut_ptr_eq<T>(a: @mut T, b: @mut T) -> bool {
    let (a_ptr, b_ptr): (*T, *T) = (to_unsafe_ptr(&*a), to_unsafe_ptr(&*b));
    a_ptr == b_ptr
}

#[cfg(not(test))]
impl<T:Eq> Eq for @T {
    #[inline]
    fn eq(&self, other: &@T) -> bool { *(*self) == *(*other) }
    #[inline]
    fn ne(&self, other: &@T) -> bool { *(*self) != *(*other) }
}

#[cfg(not(test))]
impl<T:Eq> Eq for @mut T {
    #[inline]
    fn eq(&self, other: &@mut T) -> bool { *(*self) == *(*other) }
    #[inline]
    fn ne(&self, other: &@mut T) -> bool { *(*self) != *(*other) }
}

#[cfg(not(test))]
impl<T:Ord> Ord for @T {
    #[inline]
    fn lt(&self, other: &@T) -> bool { *(*self) < *(*other) }
    #[inline]
    fn le(&self, other: &@T) -> bool { *(*self) <= *(*other) }
    #[inline]
    fn ge(&self, other: &@T) -> bool { *(*self) >= *(*other) }
    #[inline]
    fn gt(&self, other: &@T) -> bool { *(*self) > *(*other) }
}

#[cfg(not(test))]
impl<T:Ord> Ord for @mut T {
    #[inline]
    fn lt(&self, other: &@mut T) -> bool { *(*self) < *(*other) }
    #[inline]
    fn le(&self, other: &@mut T) -> bool { *(*self) <= *(*other) }
    #[inline]
    fn ge(&self, other: &@mut T) -> bool { *(*self) >= *(*other) }
    #[inline]
    fn gt(&self, other: &@mut T) -> bool { *(*self) > *(*other) }
}

#[cfg(not(test))]
impl<T: TotalOrd> TotalOrd for @T {
    #[inline]
    fn cmp(&self, other: &@T) -> Ordering { (**self).cmp(*other) }
}

#[cfg(not(test))]
impl<T: TotalOrd> TotalOrd for @mut T {
    #[inline]
    fn cmp(&self, other: &@mut T) -> Ordering { (**self).cmp(*other) }
}

#[cfg(not(test))]
impl<T: TotalEq> TotalEq for @T {
    #[inline]
    fn equals(&self, other: &@T) -> bool { (**self).equals(*other) }
}

#[cfg(not(test))]
impl<T: TotalEq> TotalEq for @mut T {
    #[inline]
    fn equals(&self, other: &@mut T) -> bool { (**self).equals(*other) }
}
#[test]
fn test() {
    let x = @3;
    let y = @3;
    assert!((ptr_eq::<int>(x, x)));
    assert!((ptr_eq::<int>(y, y)));
    assert!((!ptr_eq::<int>(x, y)));
    assert!((!ptr_eq::<int>(y, x)));
}
<commit_msg>Fix an off-by-one in managed::refcount<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Operations on managed box types

use ptr::to_unsafe_ptr;

#[cfg(not(test))] use cmp::*;

pub static RC_MANAGED_UNIQUE : uint = (-2) as uint;
pub static RC_IMMORTAL : uint = 0x77777777;

/// Returns the refcount of a shared box (as just before calling this)
#[inline]
pub fn refcount<T>(t: @T) -> uint {
    use unstable::raw::Repr;
    unsafe { (*t.repr()).ref_count - 1 }
}

/// Determine if two shared boxes point to the same object
#[inline]
pub fn ptr_eq<T>(a: @T, b: @T) -> bool {
    let (a_ptr, b_ptr): (*T, *T) = (to_unsafe_ptr(&*a), to_unsafe_ptr(&*b));
    a_ptr == b_ptr
}

/// Determine if two mutable shared boxes point to the same object
#[inline]
pub fn mut_ptr_eq<T>(a: @mut T, b: @mut T) -> bool {
    let (a_ptr, b_ptr): (*T, *T) = (to_unsafe_ptr(&*a), to_unsafe_ptr(&*b));
    a_ptr == b_ptr
}

#[cfg(not(test))]
impl<T:Eq> Eq for @T {
    #[inline]
    fn eq(&self, other: &@T) -> bool { *(*self) == *(*other) }
    #[inline]
    fn ne(&self, other: &@T) -> bool { *(*self) != *(*other) }
}

#[cfg(not(test))]
impl<T:Eq> Eq for @mut T {
    #[inline]
    fn eq(&self, other: &@mut T) -> bool { *(*self) == *(*other) }
    #[inline]
    fn ne(&self, other: &@mut T) -> bool { *(*self) != *(*other) }
}

#[cfg(not(test))]
impl<T:Ord> Ord for @T {
    #[inline]
    fn lt(&self, other: &@T) -> bool { *(*self) < *(*other) }
    #[inline]
    fn le(&self, other: &@T) -> bool { *(*self) <= *(*other) }
    #[inline]
    fn ge(&self, other: &@T) -> bool { *(*self) >= *(*other) }
    #[inline]
    fn gt(&self, other: &@T) -> bool { *(*self) > *(*other) }
}

#[cfg(not(test))]
impl<T:Ord> Ord for @mut T {
    #[inline]
    fn lt(&self, other: &@mut T) -> bool { *(*self) < *(*other) }
    #[inline]
    fn le(&self, other: &@mut T) -> bool { *(*self) <= *(*other) }
    #[inline]
    fn ge(&self, other: &@mut T) -> bool { *(*self) >= *(*other) }
    #[inline]
    fn gt(&self, other: &@mut T) -> bool { *(*self) > *(*other) }
}

#[cfg(not(test))]
impl<T: TotalOrd> TotalOrd for @T {
    #[inline]
    fn cmp(&self, other: &@T) -> Ordering { (**self).cmp(*other) }
}

#[cfg(not(test))]
impl<T: TotalOrd> TotalOrd for @mut T {
    #[inline]
    fn cmp(&self, other: &@mut T) -> Ordering { (**self).cmp(*other) }
}

#[cfg(not(test))]
impl<T: TotalEq> TotalEq for @T {
    #[inline]
    fn equals(&self, other: &@T) -> bool { (**self).equals(*other) }
}

#[cfg(not(test))]
impl<T: TotalEq> TotalEq for @mut T {
    #[inline]
    fn equals(&self, other: &@mut T) -> bool { (**self).equals(*other) }
}
#[test]
fn test() {
    let x = @3;
    let y = @3;
    assert!((ptr_eq::<int>(x, x)));
    assert!((ptr_eq::<int>(y, y)));
    assert!((!ptr_eq::<int>(x, y)));
    assert!((!ptr_eq::<int>(y, x)));
}

#[test]
fn refcount_test() {
    use clone::Clone;

    let x = @3;
    assert_eq!(refcount(x), 1);
    let y = x.clone();
    assert_eq!(refcount(x), 2);
    assert_eq!(refcount(y), 2);
}
<|endoftext|>


<commit_before><commit_msg>sync: add receiver_count to watch::Sender (#3729)<commit_after><|endoftext|>