<commit_before>// Copyright 2016 Victor Brekenfeld
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://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.

//! Module providing the CombinedLogger Implementation

use crate::{Config, SharedLogger};
use log::{set_boxed_logger, set_max_level, LevelFilter, Log, Metadata, Record, SetLoggerError};

/// The CombinedLogger struct. Provides a Logger implementation that proxies multiple Loggers as one.
///
/// The purpose is to allow multiple Loggers to be set globally
pub struct CombinedLogger {
    level: LevelFilter,
    logger: Vec<Box<dyn SharedLogger>>,
}

impl CombinedLogger {
    /// init function. Globally initializes the CombinedLogger as the one and only used log facility.
    ///
    /// Takes all used Loggers as a Vector argument. None of those Loggers should already be set globally.
    ///
    /// All loggers need to implement `log::Log` and `logger::SharedLogger` and need to provide a way to be
    /// initialized without calling `set_logger`. All loggers of this library provide a `new(..)`` method
    /// for that purpose.
    /// Fails if another logger is already set globally.
    ///
    /// # Examples
    /// ```
    /// # extern crate simplelog;
    /// # use simplelog::*;
    /// # use std::fs::File;
    /// # fn main() {
    /// let _ = CombinedLogger::init(
    ///             vec![
    ///                 TermLogger::new(LevelFilter::Info, Config::default(), TerminalMode::Mixed).unwrap(),
    ///                 WriteLogger::new(LevelFilter::Info, Config::default(), File::create("my_rust_bin.log").unwrap())
    ///             ]
    ///         );
    /// # }
    /// ```
    pub fn init(logger: Vec<Box<dyn SharedLogger>>) -> Result<(), SetLoggerError> {
        let comblog = CombinedLogger::new(logger);
        set_max_level(comblog.level());
        set_boxed_logger(comblog)
    }

    /// allows to create a new logger, that can be independently used, no matter whats globally set.
    ///
    /// no macros are provided for this case and you probably
    /// dont want to use this function, but `init()`, if you dont want to build a `CombinedLogger`.
    ///
    /// Takes all used loggers as a Vector argument. The log level is automatically determined by the
    /// lowest log level used by the given loggers.
    ///
    /// All loggers need to implement log::Log.
    ///
    /// # Examples
    /// ```
    /// # extern crate simplelog;
    /// # use simplelog::*;
    /// # use std::fs::File;
    /// # fn main() {
    /// let combined_logger = CombinedLogger::new(
    ///             vec![
    ///                 TermLogger::new(LevelFilter::Debug, Config::default(), TerminalMode::Mixed).unwrap(),
    ///                 WriteLogger::new(LevelFilter::Info, Config::default(), File::create("my_rust_bin.log").unwrap())
    ///             ]
    ///         );
    /// # }
    /// ```
    pub fn new(logger: Vec<Box<dyn SharedLogger>>) -> Box<CombinedLogger> {
        let mut log_level = LevelFilter::Off;
        for log in &logger {
            if log_level < log.level() {
                log_level = log.level();
            }
        }

        Box::new(CombinedLogger {
            level: log_level,
            logger: logger,
        })
    }
}

impl Log for CombinedLogger {
    fn enabled(&self, metadata: &Metadata<'_>) -> bool {
        metadata.level() <= self.level
    }

    fn log(&self, record: &Record<'_>) {
        if self.enabled(record.metadata()) {
            for log in &self.logger {
                log.log(record);
            }
        }
    }

    fn flush(&self) {
        for log in &self.logger {
            log.flush();
        }
    }
}

impl SharedLogger for CombinedLogger {
    fn level(&self) -> LevelFilter {
        self.level
    }

    fn config(&self) -> Option<&Config> {
        None
    }

    fn as_log(self: Box<Self>) -> Box<dyn Log> {
        Box::new(*self)
    }
}
<commit_msg>Fix comblog-tests to include TermLogger unconditionally<commit_after>// Copyright 2016 Victor Brekenfeld
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://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.

//! Module providing the CombinedLogger Implementation

use crate::{Config, SharedLogger};
use log::{set_boxed_logger, set_max_level, LevelFilter, Log, Metadata, Record, SetLoggerError};

/// The CombinedLogger struct. Provides a Logger implementation that proxies multiple Loggers as one.
///
/// The purpose is to allow multiple Loggers to be set globally
pub struct CombinedLogger {
    level: LevelFilter,
    logger: Vec<Box<dyn SharedLogger>>,
}

impl CombinedLogger {
    /// init function. Globally initializes the CombinedLogger as the one and only used log facility.
    ///
    /// Takes all used Loggers as a Vector argument. None of those Loggers should already be set globally.
    ///
    /// All loggers need to implement `log::Log` and `logger::SharedLogger` and need to provide a way to be
    /// initialized without calling `set_logger`. All loggers of this library provide a `new(..)`` method
    /// for that purpose.
    /// Fails if another logger is already set globally.
    ///
    /// # Examples
    /// ```
    /// # extern crate simplelog;
    /// # use simplelog::*;
    /// # use std::fs::File;
    /// # fn main() {
    /// let _ = CombinedLogger::init(
    ///             vec![
    /// #               #[cfg(feature = "term")]
    ///                 TermLogger::new(LevelFilter::Info, Config::default(), TerminalMode::Mixed).unwrap(),
    ///                 WriteLogger::new(LevelFilter::Info, Config::default(), File::create("my_rust_bin.log").unwrap())
    ///             ]
    ///         );
    /// # }
    /// ```
    pub fn init(logger: Vec<Box<dyn SharedLogger>>) -> Result<(), SetLoggerError> {
        let comblog = CombinedLogger::new(logger);
        set_max_level(comblog.level());
        set_boxed_logger(comblog)
    }

    /// allows to create a new logger, that can be independently used, no matter whats globally set.
    ///
    /// no macros are provided for this case and you probably
    /// dont want to use this function, but `init()`, if you dont want to build a `CombinedLogger`.
    ///
    /// Takes all used loggers as a Vector argument. The log level is automatically determined by the
    /// lowest log level used by the given loggers.
    ///
    /// All loggers need to implement log::Log.
    ///
    /// # Examples
    /// ```
    /// # extern crate simplelog;
    /// # use simplelog::*;
    /// # use std::fs::File;
    /// # fn main() {
    /// let combined_logger = CombinedLogger::new(
    ///             vec![
    /// #               #[cfg(feature = "term")]
    ///                 TermLogger::new(LevelFilter::Debug, Config::default(), TerminalMode::Mixed).unwrap(),
    ///                 WriteLogger::new(LevelFilter::Info, Config::default(), File::create("my_rust_bin.log").unwrap())
    ///             ]
    ///         );
    /// # }
    /// ```
    pub fn new(logger: Vec<Box<dyn SharedLogger>>) -> Box<CombinedLogger> {
        let mut log_level = LevelFilter::Off;
        for log in &logger {
            if log_level < log.level() {
                log_level = log.level();
            }
        }

        Box::new(CombinedLogger {
            level: log_level,
            logger: logger,
        })
    }
}

impl Log for CombinedLogger {
    fn enabled(&self, metadata: &Metadata<'_>) -> bool {
        metadata.level() <= self.level
    }

    fn log(&self, record: &Record<'_>) {
        if self.enabled(record.metadata()) {
            for log in &self.logger {
                log.log(record);
            }
        }
    }

    fn flush(&self) {
        for log in &self.logger {
            log.flush();
        }
    }
}

impl SharedLogger for CombinedLogger {
    fn level(&self) -> LevelFilter {
        self.level
    }

    fn config(&self) -> Option<&Config> {
        None
    }

    fn as_log(self: Box<Self>) -> Box<dyn Log> {
        Box::new(*self)
    }
}
<|endoftext|>


<commit_before>/// Rosten
/// Track Bring packages in Rust
/// For testing use "TESTPACKAGE-AT-PICKUPPOINT" as tracking number
/// https://www.mybring.com/tracking/api

extern crate rustc_serialize;
extern crate hyper;

mod json_response;

use std::io::Read;
use rustc_serialize::json;
use hyper::{Client};
use json_response::BringResponse;

pub fn main() {

    // TODO Implement http query, check hyper docu
    let url = "https://tracking.bring.com/tracking.json?q=TESTPACKAGE-AT-PICKUPPOINT";
    let client = Client::new();
    let mut response = match client.get(url).send() {
        Ok(response) => response,
        Err(_) => panic!("Failed to get http response"),
    };
    let mut buf = String::new();
    match response.read_to_string(&mut buf) {
        Ok(buf) => buf,
        Err(_) => panic!("Failed to read to buffer"),
    };
    // TODO Iterate over more fields & query local buffer
    // Wrap into separate parse function
    let deserialize :BringResponse = json::decode(&buf).unwrap();
    let sets = deserialize.consignmentSet;
    // Iterate over consignmentSet and get package status description
    for i in 0..sets.len() {
        let set = &sets[i];
        println!("Sets is {}", set.senderName);
        for x in 0..set.packageSet.len() {
            let package_set = &set.packageSet[x];
            println!("Packageset number is {}", x);
            println!("Status is: {}", package_set.statusDescription);
        }
    }
}
<commit_msg>major rewrite, wrap http request in function<commit_after>/// Rosten
/// Track Bring packages in Rust
/// For testing use "TESTPACKAGE-AT-PICKUPPOINT" as tracking number
/// https://www.mybring.com/tracking/api

extern crate rustc_serialize;
extern crate hyper;

mod json_response;

use std::io;
use std::io::Read;
use std::fmt::Display;
use rustc_serialize::json;
use hyper::{Client};
use json_response::BringResponse;

pub fn main() {

    // Read user input
    println!("Enter tracking number:");
    let mut input = String::new();
    io::stdin().read_line(&mut input);

    // TODO Implement http query, check hyper docu
    let url = format!("https://tracking.bring.com/tracking.json?q={}", input);
    let url = url.as_str(); // convert &str into a String

    fn get_content(url: &str) -> hyper::Result<String> {
        let client = Client::new();
        let mut response = try!(client.get(url).send());
        let mut buf = String::new();
        try!(response.read_to_string(&mut buf));
        Ok(buf)
    }
    // TODO Figure out how to return &str for json::decode
    let buf = get_content(url);
    let deserialize :BringResponse = json::decode(&buf).unwrap();
    let sets = deserialize.consignmentSet;
    for i in 0..sets.len() {
        let set = &sets[i];
        println!("Sets is {}", set.senderName);
        for x in 0..set.packageSet.len() {
            let package_set = &set.packageSet[x];
            println!("Packageset number is {}", x);
            println!("Status is: {}", package_set.statusDescription);

            }
        }
    }
<|endoftext|>


<commit_before>extern crate iron;
extern crate router;
extern crate mount;
extern crate staticfile;
extern crate robots;
extern crate persistent;
extern crate env_logger;

use iron::prelude::*;
use iron::status;
use router::Router;
use staticfile::Static;
use mount::Mount;
use std::path::Path;
use std::any::Any;
use std::sync::Arc;
use robots::actors::{ActorSystem,Actor,ActorCell,ActorContext,Props,ActorRef,ActorPath};
use persistent::Read;
use iron::typemap::Key;
use std::fmt::{Debug, Display,Formatter,Result};
use gpioaccess::PinProxy;

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum DirectionProxied {
    In,
    Out,
    High,
    Low,
}

#[derive(Debug)]
pub enum ProxyError {
	MonErreur,
}

impl ::std::error::Error for ProxyError {
	fn description(&self) -> &str {
		"an error"
	}
}

impl Display for ProxyError {
	fn fmt(&self, f: &mut Formatter) -> Result {
		write!(f, "an error")
	}
}

pub type ProxyResult<T> = ::std::result::Result<T, ProxyError>;

//depend on abstractions not concretions lulz
trait PinProxyContract {

	fn new(pin_num: u64) -> Self;
	//FIXME :figure out mapping overloaded Result from gpio library
	fn export(&self) -> ProxyResult<()>;

	fn unexport(&self) ->  ProxyResult<()>;

	fn set_value(&self, value: u8) -> ProxyResult<()>;

	fn set_direction(&self, dir: DirectionProxied) ->  ProxyResult<()>;
}

#[cfg(linux)]
pub mod gpioaccess{

	extern crate sysfs_gpio;
	use sysfs_gpio::{Direction, Pin};
	use super::{PinProxyContract,DirectionProxied,ProxyError,ProxyResult};

	pub struct PinProxy {
		pin : Pin,
	}

	impl PinProxyContract for PinProxy
	{
		fn new(pin_num: u64) -> PinProxy {
			PinProxy{ pin: Pin::new(pin_num) }
		}

		fn export(&self) ->  ProxyResult<()>{
			match self.pin.export()
			{
				Ok(()) => Ok(()),
				_ => ProxyError::MonErreur,

			}
		}

		fn unexport(&self) ->  ProxyResult<()> {
			match self.pin.unexport()
			{
				Ok(()) => Ok(()),
				_ => ProxyError::MonErreur,

			}
		}

		fn set_value(&self, value: u8) ->  ProxyResult<()> {
			match self.pin.set_value(value)
			{
				Ok(()) => Ok(()),
				_ => ProxyError::MonErreur,

			}
		}

		fn set_direction(&self, dir: DirectionProxied) ->  ProxyResult<()>{
			let dirmapped =  match dir {
                                           DirectionProxied::In =>  Direction::In,
                                           DirectionProxied::Out => Direction::Out,
                                           DirectionProxied::High => Direction::High,
                                           DirectionProxied::Low => Direction::Low,
                                       };
			match self.pin.set_direction(dirmapped)
			{
				Ok(()) => Ok(()),
				_ => ProxyError::MonErreur,

			}
		}

    }
}

#[cfg(not(linux))]
pub mod gpioaccess{

	use std::fmt;
	use super::{PinProxyContract,DirectionProxied,ProxyError,ProxyResult};

	pub struct PinProxy {
		pin_num: u64,
	}

	impl PinProxyContract for PinProxy
	{
		fn new(pin_num: u64) -> PinProxy {
			PinProxy{ pin_num: pin_num }
		}

		fn export(&self) -> ProxyResult<()>
		{
			Ok::<(),ProxyError>(())
		}

		fn unexport(&self) -> ProxyResult<()>
		{
			Ok::<(),ProxyError>(())
		}

		fn set_value(&self, value: u8) -> ProxyResult<()>
		{
			Ok::<(),ProxyError>(())
		}

		fn set_direction(&self, dir: DirectionProxied) -> ProxyResult<()>
		{
			Ok::<(),ProxyError>(())
		}
    }
}

#[derive(Copy, Clone)]
pub struct Sys;
impl Key for Sys { type Value = ActorSystem; }

struct Resolver;

impl Actor for Resolver {
    fn receive(&self, message: Box<Any>, context: ActorCell) {
        if let Ok(message) = Box::<Any>::downcast::<String>(message) {
            let future = context.identify_actor(*message, "resolver_request".to_owned());
            context.forward_result_to_future::<Option<ActorRef>>(future, context.sender());
			context.stop(context.actor_ref());
        }
    }
}

impl Resolver {
    fn new(_dummy: ()) -> Resolver {
        Resolver
    }
}

fn main() {
	env_logger::init().unwrap();
	let dragon_actor_system  = ActorSystem::new("dragon".to_owned());
	dragon_actor_system.spawn_threads(3);

	dragon_actor_system.actor_of(Props::new(Arc::new(Dragon::new),()), "gorynich".to_owned());

    // the router (for RESTfull actions)
	let mut router = Router::new();

	router.get("/wings", move_wings,"wings");
	router.get("/mouth", open_mouth,"mouth");
	router.get("/eyes", blink_eyes,"eyes");

	fn handle_command(req: &mut Request, dragon_command: DragonCommands, dragon_event: DragonEvents ) ->IronResult<Response> {
		let arcsys = req.get::<Read<Sys>>().unwrap();
    	let sys = arcsys.as_ref();
		let props = Props::new(Arc::new(Resolver::new), ());
    	let answerer = sys.actor_of(props.clone(), "answerer".to_owned());
        let dragon = sys.ask(answerer, "/user/gorynich".to_owned(), "future".to_owned());
    	let dragon: Option<ActorRef> = sys.extract_result(dragon);
		match dragon {
			None => {
				Ok(Response::with((status::Ok, "Dragon not found")))
			}
			Some(dragonunwrapped) => {
				let future = sys.ask(dragonunwrapped, dragon_command, "request".to_owned());
	    		let event: DragonEvents = sys.extract_result(future);
				if event == dragon_event {
					Ok(Response::with((status::Ok, dragon_event.to_string())))
				} else
				{
					Ok(Response::with((status::Ok, "Unknown event!")))
				}
			}
		}
	}

	fn move_wings(req:&mut Request)  -> IronResult<Response>  {
		handle_command(req,DragonCommands::MoveWings,DragonEvents::WingsMoved)
	}

	fn open_mouth(req: &mut Request) -> IronResult<Response> {
		handle_command(req,DragonCommands::OpenMouth,DragonEvents::MouthOpened)
	}

	fn blink_eyes(req: &mut Request) -> IronResult<Response> {
		handle_command(req,DragonCommands::BlinkEyes,DragonEvents::EyesBlinked)
	}

	let mut chain = Chain::new(router);
	chain.link(Read::<Sys>::both(dragon_actor_system));

	// the mounter for static files
	let mut mount = Mount::new();
	mount
		.mount("/",Static::new(Path::new("static")))
		.mount("/api/",chain);
	Iron::new(mount).http("0.0.0.0:3000").unwrap();
}

#[derive(Copy, Clone, PartialEq,Debug)]
enum DragonCommands {
	MoveWings,
	OpenMouth,
	BlinkEyes,
}

#[derive(Copy, Clone, PartialEq,Debug)]
enum DragonEvents {
	WingsMoved,
	MouthOpened,
	EyesBlinked,
}

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

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

struct Dragon;

impl Actor for Dragon {

	fn pre_start(&self, context: ActorCell) {
		let wings = context.actor_of(Props::new(Arc::new(Wings::new),()), "wings".to_owned()).unwrap();
		let mouth = context.actor_of(Props::new(Arc::new(Mouth::new),()), "mouth".to_owned()).unwrap();
		let eyes = context.actor_of(Props::new(Arc::new(Eyes::new),()), "eyes".to_owned()).unwrap();
		context.tell(wings,LimbCommands::Init(10));
		context.tell(mouth,LimbCommands::Init(10));
		context.tell(eyes,LimbCommands::Init(10));
	}
	fn receive(&self, _message: Box<Any>, _context: ActorCell){
		if let Ok(_message) = Box::<Any>::downcast::<DragonCommands>(_message){
			match *_message {
				DragonCommands::MoveWings => {
						let wings: ActorRef = _context.children().get(&ActorPath::new_local("/user/gorynich/wings".to_owned())).cloned().unwrap();
						_context.tell(wings,LimbCommands::Aggitate);
						_context.complete(_context.sender(),DragonEvents::WingsMoved);
						},
				DragonCommands::OpenMouth => {
						let mouth: ActorRef = _context.children().get(&ActorPath::new_local("/user/gorynich/mouth".to_owned())).cloned().unwrap();
						_context.tell(mouth,LimbCommands::Aggitate);
						_context.complete(_context.sender(),DragonEvents::MouthOpened);
						},
				DragonCommands::BlinkEyes => {
						let eyes: ActorRef = _context.children().get(&ActorPath::new_local("/user/gorynich/eyes".to_owned())).cloned().unwrap();
						_context.tell(eyes,LimbCommands::Aggitate);
						_context.complete(_context.sender(),DragonEvents::EyesBlinked);
						}
			}
		} else {
			println!("Gorynich does not understand!");
		}
	}
}

impl Dragon {
	fn new(_: ()) -> Dragon {
		Dragon
	}
}

#[derive(Copy, Clone, PartialEq,Debug)]
enum LimbCommands {
	Init(u64),
	Aggitate,
	Reset,
}

#[derive(Copy, Clone, PartialEq,Debug)]
enum LimbEvents {
	Aggitated,
	NotAggitated(u64),
}

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

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

struct Wings;

impl Actor for Wings {
    fn receive(&self, _message: Box<Any>, _context: ActorCell) {
		if let Ok(_message) = Box::<Any>::downcast::<LimbCommands>(_message){
			match *_message {
				LimbCommands::Init(max) => { println!("Initializing with maximum {}",max); },
				LimbCommands::Aggitate => {
						println!("Moving Wings");
						//_context.complete(_context.sender(),LimbEvents::Aggitated);
						},
				LimbCommands::Reset => { println!("Received reset"); }
			}
		} else {
			println!("Gorynich does not understand!");
		}
	}
}

impl Wings {
    fn new(_: ()) -> Wings {
        Wings
    }
}

struct Mouth;

impl Actor for Mouth {
    fn receive(&self, _message: Box<Any>, _context: ActorCell) {
		if let Ok(_message) = Box::<Any>::downcast::<LimbCommands>(_message){
			match *_message {
				LimbCommands::Init(max) => { println!("Initializing with maximum {}",max); },
				LimbCommands::Aggitate => {
						println!("Opening Mouth");
						//_context.complete(_context.sender(),LimbEvents::Aggitated);
						},
				LimbCommands::Reset => { println!("Received reset"); }
			}
		} else {
			println!("Gorynich does not understand!");
		}
	}
}

impl Mouth {
    fn new(_: ()) -> Mouth {
        Mouth
    }
}

struct Eyes;

impl Actor for Eyes {
    fn receive(&self, _message: Box<Any>, _context: ActorCell) {
		if let Ok(_message) = Box::<Any>::downcast::<LimbCommands>(_message){
			match *_message {
				LimbCommands::Init(max) => { println!("Initializing with maximum {}",max); },
				LimbCommands::Aggitate => {
						println!("Blinking Eyes");
						//_context.complete(_context.sender(),LimbEvents::Aggitated);
						},
				LimbCommands::Reset => { println!("Received reset"); }
			}
		} else {
			println!("Gorynich does not understand!");
		}
	}
}

impl Eyes {
    fn new(_: ()) -> Eyes {
        Eyes
    }
}

mod test;
<commit_msg>pinproxy<commit_after>extern crate iron;
extern crate router;
extern crate mount;
extern crate staticfile;
extern crate robots;
extern crate persistent;
extern crate env_logger;

use iron::prelude::*;
use iron::status;
use router::Router;
use staticfile::Static;
use mount::Mount;
use std::path::Path;
use std::any::Any;
use std::sync::{Arc,Mutex};
use robots::actors::{ActorSystem,Actor,ActorCell,ActorContext,Props,ActorRef,ActorPath};
use persistent::Read;
use iron::typemap::Key;
use std::fmt::{Debug, Display,Formatter,Result};
use gpioaccess::PinProxy;

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum DirectionProxied {
    In,
    Out,
    High,
    Low,
}

#[derive(Debug)]
pub enum ProxyError {
	MonErreur,
}

impl ::std::error::Error for ProxyError {
	fn description(&self) -> &str {
		"an error"
	}
}

impl Display for ProxyError {
	fn fmt(&self, f: &mut Formatter) -> Result {
		write!(f, "an error")
	}
}

pub type ProxyResult<T> = ::std::result::Result<T, ProxyError>;

//depend on abstractions not concretions lulz
trait PinProxyContract {

	fn new(pin_num: u64) -> Self;
	//FIXME :figure out mapping overloaded Result from gpio library
	fn export(&self) -> ProxyResult<()>;

	fn unexport(&self) ->  ProxyResult<()>;

	fn set_value(&self, value: u8) -> ProxyResult<()>;

	fn set_direction(&self, dir: DirectionProxied) ->  ProxyResult<()>;
}

#[cfg(linux)]
pub mod gpioaccess{

	extern crate sysfs_gpio;
	use sysfs_gpio::{Direction, Pin};
	use super::{PinProxyContract,DirectionProxied,ProxyError,ProxyResult};

	pub struct PinProxy {
		pin : Pin,
	}

	impl PinProxyContract for PinProxy
	{
		fn new(pin_num: u64) -> PinProxy {
			PinProxy{ pin: Pin::new(pin_num) }
		}

		fn export(&self) ->  ProxyResult<()>{
			match self.pin.export()
			{
				Ok(()) => Ok(()),
				_ => ProxyError::MonErreur,

			}
		}

		fn unexport(&self) ->  ProxyResult<()> {
			match self.pin.unexport()
			{
				Ok(()) => Ok(()),
				_ => ProxyError::MonErreur,

			}
		}

		fn set_value(&self, value: u8) ->  ProxyResult<()> {
			match self.pin.set_value(value)
			{
				Ok(()) => Ok(()),
				_ => ProxyError::MonErreur,

			}
		}

		fn set_direction(&self, dir: DirectionProxied) ->  ProxyResult<()>{
			let dirmapped =  match dir {
                                           DirectionProxied::In =>  Direction::In,
                                           DirectionProxied::Out => Direction::Out,
                                           DirectionProxied::High => Direction::High,
                                           DirectionProxied::Low => Direction::Low,
                                       };
			match self.pin.set_direction(dirmapped)
			{
				Ok(()) => Ok(()),
				_ => ProxyError::MonErreur,

			}
		}

    }
}

#[cfg(not(linux))]
pub mod gpioaccess{

	use std::fmt;
	use super::{PinProxyContract,DirectionProxied,ProxyError,ProxyResult};

	pub struct PinProxy {
		pin_num: u64,
	}

	impl PinProxyContract for PinProxy
	{
		fn new(pin_num: u64) -> PinProxy {
			PinProxy{ pin_num: pin_num }
		}

		fn export(&self) -> ProxyResult<()>
		{
			Ok::<(),ProxyError>(())
		}

		fn unexport(&self) -> ProxyResult<()>
		{
			Ok::<(),ProxyError>(())
		}

		fn set_value(&self, value: u8) -> ProxyResult<()>
		{
			Ok::<(),ProxyError>(())
		}

		fn set_direction(&self, dir: DirectionProxied) -> ProxyResult<()>
		{
			Ok::<(),ProxyError>(())
		}
    }
}

#[derive(Copy, Clone)]
pub struct Sys;
impl Key for Sys { type Value = ActorSystem; }

struct Resolver;

impl Actor for Resolver {
    fn receive(&self, message: Box<Any>, context: ActorCell) {
        if let Ok(message) = Box::<Any>::downcast::<String>(message) {
            let future = context.identify_actor(*message, "resolver_request".to_owned());
            context.forward_result_to_future::<Option<ActorRef>>(future, context.sender());
			context.stop(context.actor_ref());
        }
    }
}

impl Resolver {
    fn new(_dummy: ()) -> Resolver {
        Resolver
    }
}

fn main() {
	env_logger::init().unwrap();
	let dragon_actor_system  = ActorSystem::new("dragon".to_owned());
	dragon_actor_system.spawn_threads(3);

	dragon_actor_system.actor_of(Props::new(Arc::new(Dragon::new),()), "gorynich".to_owned());

    // the router (for RESTfull actions)
	let mut router = Router::new();

	router.get("/wings", move_wings,"wings");
	router.get("/mouth", open_mouth,"mouth");
	router.get("/eyes", blink_eyes,"eyes");

	fn handle_command(req: &mut Request, dragon_command: DragonCommands, dragon_event: DragonEvents ) ->IronResult<Response> {
		let arcsys = req.get::<Read<Sys>>().unwrap();
    	let sys = arcsys.as_ref();
		let props = Props::new(Arc::new(Resolver::new), ());
    	let answerer = sys.actor_of(props.clone(), "answerer".to_owned());
        let dragon = sys.ask(answerer, "/user/gorynich".to_owned(), "future".to_owned());
    	let dragon: Option<ActorRef> = sys.extract_result(dragon);
		match dragon {
			None => {
				Ok(Response::with((status::Ok, "Dragon not found")))
			}
			Some(dragonunwrapped) => {
				let future = sys.ask(dragonunwrapped, dragon_command, "request".to_owned());
	    		let event: DragonEvents = sys.extract_result(future);
				if event == dragon_event {
					Ok(Response::with((status::Ok, dragon_event.to_string())))
				} else
				{
					Ok(Response::with((status::Ok, "Unknown event!")))
				}
			}
		}
	}

	fn move_wings(req:&mut Request)  -> IronResult<Response>  {
		handle_command(req,DragonCommands::MoveWings,DragonEvents::WingsMoved)
	}

	fn open_mouth(req: &mut Request) -> IronResult<Response> {
		handle_command(req,DragonCommands::OpenMouth,DragonEvents::MouthOpened)
	}

	fn blink_eyes(req: &mut Request) -> IronResult<Response> {
		handle_command(req,DragonCommands::BlinkEyes,DragonEvents::EyesBlinked)
	}

	let mut chain = Chain::new(router);
	chain.link(Read::<Sys>::both(dragon_actor_system));

	// the mounter for static files
	let mut mount = Mount::new();
	mount
		.mount("/",Static::new(Path::new("static")))
		.mount("/api/",chain);
	Iron::new(mount).http("0.0.0.0:3000").unwrap();
}

#[derive(Copy, Clone, PartialEq,Debug)]
enum DragonCommands {
	MoveWings,
	OpenMouth,
	BlinkEyes,
}

#[derive(Copy, Clone, PartialEq,Debug)]
enum DragonEvents {
	WingsMoved,
	MouthOpened,
	EyesBlinked,
}

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

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

struct Dragon;

impl Actor for Dragon {

	fn pre_start(&self, context: ActorCell) {
		let wings = context.actor_of(Props::new(Arc::new(Wings::new),()), "wings".to_owned()).unwrap();
		let mouth = context.actor_of(Props::new(Arc::new(Mouth::new),()), "mouth".to_owned()).unwrap();
		let eyes = context.actor_of(Props::new(Arc::new(Eyes::new),()), "eyes".to_owned()).unwrap();
		context.tell(wings,LimbCommands::Init(10));
		context.tell(mouth,LimbCommands::Init(10));
		context.tell(eyes,LimbCommands::Init(10));
	}
	fn receive(&self, _message: Box<Any>, _context: ActorCell){
		if let Ok(_message) = Box::<Any>::downcast::<DragonCommands>(_message){
			match *_message {
				DragonCommands::MoveWings => {
						let wings: ActorRef = _context.children().get(&ActorPath::new_local("/user/gorynich/wings".to_owned())).cloned().unwrap();
						_context.tell(wings,LimbCommands::Aggitate);
						_context.complete(_context.sender(),DragonEvents::WingsMoved);
						},
				DragonCommands::OpenMouth => {
						let mouth: ActorRef = _context.children().get(&ActorPath::new_local("/user/gorynich/mouth".to_owned())).cloned().unwrap();
						_context.tell(mouth,LimbCommands::Aggitate);
						_context.complete(_context.sender(),DragonEvents::MouthOpened);
						},
				DragonCommands::BlinkEyes => {
						let eyes: ActorRef = _context.children().get(&ActorPath::new_local("/user/gorynich/eyes".to_owned())).cloned().unwrap();
						_context.tell(eyes,LimbCommands::Aggitate);
						_context.complete(_context.sender(),DragonEvents::EyesBlinked);
						}
			}
		} else {
			println!("Gorynich does not understand!");
		}
	}
}

impl Dragon {
	fn new(_: ()) -> Dragon {
		Dragon
	}
}

#[derive(Copy, Clone, PartialEq,Debug)]
enum LimbCommands {
	Init(u64),
	Aggitate,
	Reset,
}

#[derive(Copy, Clone, PartialEq,Debug)]
enum LimbEvents {
	Aggitated,
	NotAggitated(u64),
}

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

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

struct Wings;

impl Actor for Wings {
    fn receive(&self, _message: Box<Any>, _context: ActorCell) {
		if let Ok(_message) = Box::<Any>::downcast::<LimbCommands>(_message){
			match *_message {
				LimbCommands::Init(max) => { println!("Initializing with maximum {}",max); },
				LimbCommands::Aggitate => {
						println!("Moving Wings");
						//_context.complete(_context.sender(),LimbEvents::Aggitated);
						},
				LimbCommands::Reset => { println!("Received reset"); }
			}
		} else {
			println!("Gorynich does not understand!");
		}
	}
}

impl Wings {
    fn new(_: ()) -> Wings {
        Wings
    }
}

struct Mouth;

impl Actor for Mouth {
    fn receive(&self, _message: Box<Any>, _context: ActorCell) {
		if let Ok(_message) = Box::<Any>::downcast::<LimbCommands>(_message){
			match *_message {
				LimbCommands::Init(max) => { println!("Initializing with maximum {}",max); },
				LimbCommands::Aggitate => {
						println!("Opening Mouth");
						//_context.complete(_context.sender(),LimbEvents::Aggitated);
						},
				LimbCommands::Reset => { println!("Received reset"); }
			}
		} else {
			println!("Gorynich does not understand!");
		}
	}
}

impl Mouth {
    fn new(_: ()) -> Mouth {
        Mouth
    }
}

struct Eyes;

impl Actor for Eyes {
    fn receive(&self, _message: Box<Any>, _context: ActorCell) {
		if let Ok(_message) = Box::<Any>::downcast::<LimbCommands>(_message){
			match *_message {
				LimbCommands::Init(max) => { println!("Initializing with maximum {}",max); },
				LimbCommands::Aggitate => {
						println!("Blinking Eyes");
						//_context.complete(_context.sender(),LimbEvents::Aggitated);
						},
				LimbCommands::Reset => { println!("Received reset"); }
			}
		} else {
			println!("Gorynich does not understand!");
		}
	}
}

impl Eyes {
    fn new(_: ()) -> Eyes {
        Eyes
    }
}

#[derive(Copy, Clone, PartialEq,Debug)]
enum PinCommands {
	Blink(u64),
	Switch,
}

struct PinActor {
	pinproxy :  Mutex<PinProxy>,
}

impl Actor for PinActor {
    fn receive(&self, _message: Box<Any>, _context: ActorCell) {
		if let Ok(_message) = Box::<Any>::downcast::<PinCommands>(_message){
			match *_message {
				PinCommands::Blink(times) => { },
				PinCommands::Switch => {	}
			}
		}
	}
}

impl PinActor{
	fn new(pin_number: u64) -> PinActor {
		PinActor{ pinproxy : Mutex::new(PinProxy::new(pin_number)) }
    }
}

mod test;
<|endoftext|>


<commit_before>#![cfg_attr(test, allow(dead_code))]

// TODO revisit these after 1.0.0beta
#![feature(collections)]
#![feature(core)]
#![feature(io)]
#![feature(os)]
#![feature(path)]
#![feature(rand)]

extern crate shader_version;
extern crate input;
extern crate event;
extern crate graphics;
extern crate sdl2_window;
extern crate window;
extern crate opengl_graphics;
extern crate quack;

use std::cell::RefCell;
use sdl2_window::Sdl2Window;
use window::WindowSettings;
use opengl_graphics::{
    Gl,
};

use std::os;
use std::old_io::File;
use std::old_io::BufReader;
// use std::time::duration::Duration;
use quack::Set;
// use input::keyboard::Key;
use input::Button;

use vm::Vm;

mod error;
mod ops;
mod vm;

const TITLE: &'static str = "Chip8";
const BEEP_TITLE: &'static str = "♬ Chip8 ♬";

const INTRO_ROM: &'static [u8] = include_bytes!("intro/intro.ch8");

fn main() {
    let mut vm = Vm::new();

    let mut rom: Option<File> = None;

    if os::args().len() > 1 {
        if let Ok(f) = File::open(&Path::new(os::args()[1].clone())) {
            rom = Some(f);
        } else {
            println!("Could not open rom {}", os::args()[1]);
        }
    }

    let intro_reader = &mut BufReader::new(INTRO_ROM) as &mut Reader;
    let mut rom_reader = match &mut rom {
        &mut Some(ref mut r) => r as &mut Reader,
        _ => {
            println!("You can provide a path to a chip8 binary to interpret it.");
            intro_reader
        }
    };

    match vm.load_rom(rom_reader) {
        Ok(size) => println!("Loaded rom size: {}", size),
        Err(e) => {
            println!("Error loading rom: {}", e);
            return;
        }
    }

    let (width, height) = (800, 400);
    let opengl = shader_version::OpenGL::_3_2;
    let window = Sdl2Window::new(
        opengl,
        WindowSettings {
            title: TITLE.to_string(),
            size: [width, height],
            fullscreen: false,
            exit_on_esc: true,
            samples: 0,
        }
    );

    let ref mut gl = Gl::new(opengl);
    let window = RefCell::new(window);

    fn keymap(k: Option<Button>) -> Option<u8> {
        use input::Key::*;
        if let Some(Button::Keyboard(k)) = k {
            return match k {
                D1 => Some(0x1),
                D2 => Some(0x2),
                D3 => Some(0x3),

                Q  => Some(0x4),
                W  => Some(0x5),
                E  => Some(0x6),

                A  => Some(0x7),
                S  => Some(0x8),
                D  => Some(0x9),

                Z  => Some(0xA),
                X  => Some(0x0),
                C  => Some(0xB),

                D4 => Some(0xC),
                R  => Some(0xD),
                F  => Some(0xE),
                V  => Some(0xF),

                _ => None
            }
        }
        return None
    }

    for e in event::events(&window) {
        use event::{ ReleaseEvent, UpdateEvent, PressEvent, RenderEvent };

        if let Some(args) = e.update_args() {
            vm.step(args.dt as f32);
            if vm.beeping() {
                (*window.borrow_mut()).window.set_title(BEEP_TITLE);
            } else {
                (*window.borrow_mut()).window.set_title(TITLE);
            }
        }
        if let Some(args) = e.render_args() {
            use graphics::*;
            gl.draw([0, 0, args.width as i32, args.height as i32], |&mut: c, gl| {
                graphics::clear([0.0, 0.0, 0.0, 1.0], gl);
                let r = Rectangle::new([1.0, 1.0, 1.0, 1.0]);
                let off = Color([0.0, 0.0, 0.0, 1.0]);
                let on = Color([1.0, 1.0, 1.0, 1.0]);

                let w = args.width as f64 / 64.0;
                let h = args.height as f64 / 32.0;

                for (y,row) in vm.screen_rows().enumerate() {
                    for (x,byte) in row.iter().enumerate() {
                        let x = x as f64 * w;
                        let y = y as f64 * h;
                        r.set(match *byte { 0 => off, _ => on })
                        .draw([x, y, w, h], &c, gl);
                    }
                }
            });
        }
        if let Some(keynum) = keymap(e.press_args()) {
            vm.set_key(keynum);
        }
        if let Some(keynum) = keymap(e.release_args()) {
            vm.unset_key(keynum);
        }
    }
}
<commit_msg>Remove 'collections' feature gate<commit_after>#![cfg_attr(test, allow(dead_code))]

// TODO revisit these after 1.0.0beta
#![feature(core)]
#![feature(io)]
#![feature(os)]
#![feature(path)]
#![feature(rand)]

extern crate shader_version;
extern crate input;
extern crate event;
extern crate graphics;
extern crate sdl2_window;
extern crate window;
extern crate opengl_graphics;
extern crate quack;

use std::cell::RefCell;
use sdl2_window::Sdl2Window;
use window::WindowSettings;
use opengl_graphics::{
    Gl,
};

use std::os;
use std::old_io::File;
use std::old_io::BufReader;
// use std::time::duration::Duration;
use quack::Set;
// use input::keyboard::Key;
use input::Button;

use vm::Vm;

mod error;
mod ops;
mod vm;

const TITLE: &'static str = "Chip8";
const BEEP_TITLE: &'static str = "♬ Chip8 ♬";

const INTRO_ROM: &'static [u8] = include_bytes!("intro/intro.ch8");

fn main() {
    let mut vm = Vm::new();

    let mut rom: Option<File> = None;

    if os::args().len() > 1 {
        if let Ok(f) = File::open(&Path::new(os::args()[1].clone())) {
            rom = Some(f);
        } else {
            println!("Could not open rom {}", os::args()[1]);
        }
    }

    let intro_reader = &mut BufReader::new(INTRO_ROM) as &mut Reader;
    let mut rom_reader = match &mut rom {
        &mut Some(ref mut r) => r as &mut Reader,
        _ => {
            println!("You can provide a path to a chip8 binary to interpret it.");
            intro_reader
        }
    };

    match vm.load_rom(rom_reader) {
        Ok(size) => println!("Loaded rom size: {}", size),
        Err(e) => {
            println!("Error loading rom: {}", e);
            return;
        }
    }

    let (width, height) = (800, 400);
    let opengl = shader_version::OpenGL::_3_2;
    let window = Sdl2Window::new(
        opengl,
        WindowSettings {
            title: TITLE.to_string(),
            size: [width, height],
            fullscreen: false,
            exit_on_esc: true,
            samples: 0,
        }
    );

    let ref mut gl = Gl::new(opengl);
    let window = RefCell::new(window);

    fn keymap(k: Option<Button>) -> Option<u8> {
        use input::Key::*;
        if let Some(Button::Keyboard(k)) = k {
            return match k {
                D1 => Some(0x1),
                D2 => Some(0x2),
                D3 => Some(0x3),

                Q  => Some(0x4),
                W  => Some(0x5),
                E  => Some(0x6),

                A  => Some(0x7),
                S  => Some(0x8),
                D  => Some(0x9),

                Z  => Some(0xA),
                X  => Some(0x0),
                C  => Some(0xB),

                D4 => Some(0xC),
                R  => Some(0xD),
                F  => Some(0xE),
                V  => Some(0xF),

                _ => None
            }
        }
        return None
    }

    for e in event::events(&window) {
        use event::{ ReleaseEvent, UpdateEvent, PressEvent, RenderEvent };

        if let Some(args) = e.update_args() {
            vm.step(args.dt as f32);
            if vm.beeping() {
                (*window.borrow_mut()).window.set_title(BEEP_TITLE);
            } else {
                (*window.borrow_mut()).window.set_title(TITLE);
            }
        }
        if let Some(args) = e.render_args() {
            use graphics::*;
            gl.draw([0, 0, args.width as i32, args.height as i32], |&mut: c, gl| {
                graphics::clear([0.0, 0.0, 0.0, 1.0], gl);
                let r = Rectangle::new([1.0, 1.0, 1.0, 1.0]);
                let off = Color([0.0, 0.0, 0.0, 1.0]);
                let on = Color([1.0, 1.0, 1.0, 1.0]);

                let w = args.width as f64 / 64.0;
                let h = args.height as f64 / 32.0;

                for (y,row) in vm.screen_rows().enumerate() {
                    for (x,byte) in row.iter().enumerate() {
                        let x = x as f64 * w;
                        let y = y as f64 * h;
                        r.set(match *byte { 0 => off, _ => on })
                        .draw([x, y, w, h], &c, gl);
                    }
                }
            });
        }
        if let Some(keynum) = keymap(e.press_args()) {
            vm.set_key(keynum);
        }
        if let Some(keynum) = keymap(e.release_args()) {
            vm.unset_key(keynum);
        }
    }
}
<|endoftext|>


<commit_before>extern crate chrono;
extern crate nalgebra as na;
extern crate rustracer as rt;
#[macro_use]
extern crate clap;
extern crate rustc_serialize;
extern crate num_cpus;
#[macro_use(o, slog_info, slog_debug, slog_warn, slog_error, slog_trace, slog_log)]
extern crate slog;
#[macro_use]
extern crate slog_scope;
extern crate slog_stream;
extern crate thread_id;

use std::sync::Arc;
use std::num::ParseIntError;
use std::fs::OpenOptions;
use std::path::Path;
use std::io;
use std::process;

use chrono::Local;
use clap::{Arg, ArgMatches, App};
use slog::*;

use rt::bvh::BVH;
use rt::camera::Camera;
use rt::integrator::{SamplerIntegrator, Whitted, Normal, AmbientOcclusion};
use rt::light::{Light, DistantLight, DiffuseAreaLight};
use rt::material::matte::MatteMaterial;
use rt::material::metal::Metal;
use rt::material::plastic::Plastic;
use rt::primitive::{Primitive, GeometricPrimitive};
use rt::renderer;
use rt::scene::Scene;
use rt::shapes::disk::Disk;
use rt::shapes::sphere::Sphere;
use rt::spectrum::Spectrum;
use rt::transform;
use rt::{Transform, Point, Vector3f, Dim};

arg_enum! {
  #[derive(Debug)]
  enum SamplerIntegratorType {
      Whitted,
      Ao,
      Normal
  }
}

fn main() {
    // configure logger
    configure_logger();

    let matches = parse_args();
    if let Err(e) = run(matches) {
        println!("Application error: {}", e);
        process::exit(1);
    }
}

fn run(matches: ArgMatches) -> Result<(), String> {
    let parsed_dims: Result<Vec<u32>, ParseIntError> =
        matches.value_of("dim").unwrap().split('x').map(|s| s.parse::<u32>()).collect();
    let dims = parsed_dims.expect("Invalid dimensions");
    if dims.len() != 2 {
        panic!("Error: invalid dimension specification");
    }
    let dim = (dims[0], dims[1]);

    let integrator: Box<SamplerIntegrator + Send + Sync> =
        match value_t!(matches.value_of("integrator"), SamplerIntegratorType)
            .unwrap_or(SamplerIntegratorType::Whitted) {
            SamplerIntegratorType::Whitted => {
                info!("Using Whitted integrator with max ray depth of {}", 8);
                // Box::new(Whitted::new(args.flag_whitted_max_ray_depth))
                Box::new(Whitted::new(8))
            }
            SamplerIntegratorType::Ao => {
                info!("Using Ambient Occlusion integrator with {} samples", 32);
                Box::new(AmbientOcclusion::new(32))
            }
            SamplerIntegratorType::Normal => {
                info!("Using normal facing ratio integrator");
                Box::new(Normal {})
            }
        };

    let scene = build_scene(dim, integrator);

    let start_time = std::time::Instant::now();
    let stats =
        renderer::render(scene,
                         dim,
                         matches.value_of("output").unwrap(),
                         matches.value_of("threads")
                             .and_then(|s| s.parse::<usize>().ok())
                             .unwrap_or_else(num_cpus::get),
                         matches.value_of("spp").and_then(|s| s.parse::<usize>().ok()).unwrap(),
                         32);
    // args.flag_block_size);
    let duration = start_time.elapsed();
    println!("Render time                : {}", duration.human_display());
    println!("Primary rays               : {}", stats.primary_rays);
    println!("Secondary rays             : {}", stats.secondary_rays);
    println!("Num triangles              : {}", stats.triangles);
    println!("Ray-triangle tests         : {}", stats.ray_triangle_tests);
    println!("Ray-triangle intersections : {}\t({}%)",
             stats.ray_triangle_isect,
             stats.ray_triangle_isect as f32 / stats.ray_triangle_tests as f32 * 100.0);
    println!("Fast bounding-box test     : {}", stats.fast_bbox_isect);

    Ok(())
}

fn build_scene(dim: Dim, integrator: Box<SamplerIntegrator + Send + Sync>) -> Scene {
    info!("Building scene");
    let camera = Camera::new(Point::new(0.0, 0.0, 5.0), dim, 50.0);
    let mut lights: Vec<Arc<Light + Send + Sync>> = Vec::new();

    let disk = Arc::new(Disk::new(-2.0, 0.8, 0.0, 360.0, transform::rot_x(90.0)));
    let area_light =
        Arc::new(DiffuseAreaLight::new(Spectrum::rgb(3.0, 3.0, 3.0), disk.clone(), 16));
    let area_light_prim = Box::new(GeometricPrimitive {
        shape: disk.clone(),
        area_light: Some(area_light.clone()),
        material: Some(Arc::new(MatteMaterial::default())),
    });

    let bronze = Arc::new(Metal::new());
    let gold = Arc::new(Metal::gold());
    let plastic = Arc::new(Plastic::new(Spectrum::rgb(0.3, 0.3, 1.0), Spectrum::white()));
    let plastic_lines = Arc::new(Plastic::new_tex("lines.png", Spectrum::white()));
    let sphere = Box::new(GeometricPrimitive {
        shape: Arc::new(Sphere::new().radius(0.7).transform(transform::translate_y(-0.3))),
        area_light: None,
        // material: Some(Arc::new(Plastic::new(Spectrum::red(), Spectrum::white()))),
        // material: Some(Arc::new(Plastic::new_tex("lines.png", Spectrum::white()))),
        material: Some(bronze.clone()),
    });
    let bunny =
        Box::new(BVH::<GeometricPrimitive>::from_mesh_file(Path::new("models/bunny.obj"),
                                                           "bunny",
                                                           plastic.clone(),
                                                           &Transform::new(
                                                             Vector3f::new(2.0, -0.8, 0.0),
                                                             Vector3f::new(0.0, 20.0f32.to_radians(), 0.0),
                                                             0.5
                                                             ))) as Box<Primitive + Send + Sync>;
    let buddha =
        Box::new(BVH::<GeometricPrimitive>::from_mesh_file(Path::new("models/buddha.obj"),
                                                           "buddha",
                                                           gold.clone(),
                                                           &Transform::new(
                                                             Vector3f::new(-2.0, 0.0, 0.0),
                                                             Vector3f::new(0.0, 200.0f32.to_radians(), 0.0),
                                                             3.0
                                                             ))) as Box<Primitive + Send + Sync>;
    let floor = Box::new(GeometricPrimitive {
        shape: Arc::new(Disk::new(-1.0, 20.0, 0.0, 360.0, transform::rot_x(-90.0))),
        area_light: None,
        // material: Some(Arc::new(MatteMaterial::checkerboard(0.0))),
        // material: Some(Arc::new(MatteMaterial::new(Spectrum::red(), 0.0))),
        material: Some(plastic_lines.clone()),
    });

    let primitives: Vec<Box<Primitive + Sync + Send>> =
        vec![buddha, sphere, bunny, floor, area_light_prim];
    // Light
    lights.push(area_light);
    lights.push(Arc::new(DistantLight::new(Vector3f::new(0.0, -1.0, -5.0),
                                           Spectrum::rgb(0.5, 0.5, 0.5))));

    Scene::new(camera, integrator, primitives, lights)
}

fn parse_args<'a>() -> ArgMatches<'a> {
    // TODO add block-size and ao-samples and whitted-max-ray? Or maybe not since eventually it
    // will be read from the scene file...
    App::new("rustracer")
        .version("0.1")
        .author("Antoine Bűsch")
        .about("Toy raytracer in Rust based on PBRTv3")
        .arg(Arg::with_name("output")
            .long("output")
            .short("o")
            .help("Output file name")
            .default_value("image.png"))
        .arg(Arg::with_name("threads")
            .long("threads")
            .short("t")
            .help("Number of worker threads"))
        .arg(Arg::with_name("dim")
            .long("dim")
            .short("d")
            .help("Dimension of the output image")
            .default_value("800x600"))
        .arg(Arg::with_name("integrator")
            .long("integrator")
            .short("i")
            .help("SamplerIntegrator to use")
            .possible_values(&SamplerIntegratorType::variants()))
        .arg(Arg::with_name("spp")
            .long("spp")
            .help("Sample per pixels")
            .default_value("4"))
        .get_matches()
}

fn configure_logger() {
    let log_path = "/tmp/rustracer.log";
    let file = OpenOptions::new()
        .create(true)
        .write(true)
        .truncate(true)
        .open(log_path)
        .unwrap();

    let drain = slog_stream::stream(file, MyFormat).fuse();
    let log = Logger::root(drain, o!());
    slog_scope::set_global_logger(log);

}

trait HumanDisplay {
    fn human_display(&self) -> String;
}
impl HumanDisplay for std::time::Duration {
    fn human_display(&self) -> String {
        let mut hours = 0;
        let mut minutes = 0;
        let mut seconds = self.as_secs();
        if seconds >= 60 {
            seconds %= 60;
            minutes = seconds / 60;
        }
        if minutes >= 60 {
            minutes %= 60;
            hours = minutes / 60;
        }
        let millis = self.subsec_nanos() / 1000000;
        format!("{}:{}:{}.{}", hours, minutes, seconds, millis)
    }
}

macro_rules! now {
    () => ( Local::now().format("%m-%d %H:%M:%S%.3f") )
}

struct MyFormat;

impl slog_stream::Format for MyFormat {
    fn format(&self,
              io: &mut io::Write,
              rinfo: &slog::Record,
              _logger_values: &slog::OwnedKeyValueList)
              -> io::Result<()> {
        let msg = format!("{} [{}][{:x}][{}:{} {}] - {}\n",
                          now!(),
                          rinfo.level(),
                          thread_id::get(),
                          rinfo.file(),
                          rinfo.line(),
                          rinfo.module(),
                          rinfo.msg());
        try!(io.write_all(msg.as_bytes()));
        Ok(())
    }
}
<commit_msg>Change test scene to use infinite light<commit_after>extern crate chrono;
extern crate nalgebra as na;
extern crate rustracer as rt;
#[macro_use]
extern crate clap;
extern crate rustc_serialize;
extern crate num_cpus;
#[macro_use(o, slog_info, slog_debug, slog_warn, slog_error, slog_trace, slog_log)]
extern crate slog;
#[macro_use]
extern crate slog_scope;
extern crate slog_stream;
extern crate thread_id;

use std::sync::Arc;
use std::num::ParseIntError;
use std::fs::OpenOptions;
use std::path::Path;
use std::io;
use std::process;

use chrono::Local;
use clap::{Arg, ArgMatches, App};
use slog::*;

use rt::bvh::BVH;
use rt::camera::Camera;
use rt::integrator::{SamplerIntegrator, Whitted, Normal, AmbientOcclusion};
use rt::light::{Light, DistantLight, DiffuseAreaLight, InfiniteAreaLight};
use rt::material::matte::MatteMaterial;
use rt::material::metal::Metal;
use rt::material::plastic::Plastic;
use rt::primitive::{Primitive, GeometricPrimitive};
use rt::renderer;
use rt::scene::Scene;
use rt::shapes::disk::Disk;
use rt::shapes::sphere::Sphere;
use rt::spectrum::Spectrum;
use rt::transform;
use rt::{Transform, Point, Vector3f, Dim};

arg_enum! {
  #[derive(Debug)]
  enum SamplerIntegratorType {
      Whitted,
      Ao,
      Normal
  }
}

fn main() {
    // configure logger
    configure_logger();

    let matches = parse_args();
    if let Err(e) = run(matches) {
        println!("Application error: {}", e);
        process::exit(1);
    }
}

fn run(matches: ArgMatches) -> Result<(), String> {
    let parsed_dims: Result<Vec<u32>, ParseIntError> =
        matches.value_of("dim").unwrap().split('x').map(|s| s.parse::<u32>()).collect();
    let dims = parsed_dims.expect("Invalid dimensions");
    if dims.len() != 2 {
        panic!("Error: invalid dimension specification");
    }
    let dim = (dims[0], dims[1]);

    let integrator: Box<SamplerIntegrator + Send + Sync> =
        match value_t!(matches.value_of("integrator"), SamplerIntegratorType)
            .unwrap_or(SamplerIntegratorType::Whitted) {
            SamplerIntegratorType::Whitted => {
                info!("Using Whitted integrator with max ray depth of {}", 8);
                // Box::new(Whitted::new(args.flag_whitted_max_ray_depth))
                Box::new(Whitted::new(8))
            }
            SamplerIntegratorType::Ao => {
                info!("Using Ambient Occlusion integrator with {} samples", 32);
                Box::new(AmbientOcclusion::new(32))
            }
            SamplerIntegratorType::Normal => {
                info!("Using normal facing ratio integrator");
                Box::new(Normal {})
            }
        };

    let scene = build_scene(dim, integrator);

    let start_time = std::time::Instant::now();
    let stats =
        renderer::render(scene,
                         dim,
                         matches.value_of("output").unwrap(),
                         matches.value_of("threads")
                             .and_then(|s| s.parse::<usize>().ok())
                             .unwrap_or_else(num_cpus::get),
                         matches.value_of("spp").and_then(|s| s.parse::<usize>().ok()).unwrap(),
                         32);
    // args.flag_block_size);
    let duration = start_time.elapsed();
    println!("Render time                : {}", duration.human_display());
    println!("Primary rays               : {}", stats.primary_rays);
    println!("Secondary rays             : {}", stats.secondary_rays);
    println!("Num triangles              : {}", stats.triangles);
    println!("Ray-triangle tests         : {}", stats.ray_triangle_tests);
    println!("Ray-triangle intersections : {}\t({}%)",
             stats.ray_triangle_isect,
             stats.ray_triangle_isect as f32 / stats.ray_triangle_tests as f32 * 100.0);
    println!("Fast bounding-box test     : {}", stats.fast_bbox_isect);

    Ok(())
}

fn build_scene(dim: Dim, integrator: Box<SamplerIntegrator + Send + Sync>) -> Scene {
    info!("Building scene");
    let camera = Camera::new(Point::new(0.0, 0.0, 5.0), dim, 50.0);
    let mut lights: Vec<Arc<Light + Send + Sync>> = Vec::new();

    let disk = Arc::new(Disk::new(-2.0, 0.8, 0.0, 360.0, transform::rot_x(90.0)));
    let area_light =
        Arc::new(DiffuseAreaLight::new(Spectrum::rgb(3.0, 3.0, 3.0), disk.clone(), 16));
    let area_light_prim = Box::new(GeometricPrimitive {
        shape: disk.clone(),
        area_light: Some(area_light.clone()),
        material: Some(Arc::new(MatteMaterial::default())),
    });

    let bronze = Arc::new(Metal::new());
    let gold = Arc::new(Metal::gold());
    let plastic = Arc::new(Plastic::new(Spectrum::rgb(0.3, 0.3, 1.0), Spectrum::white()));
    let plastic_lines = Arc::new(Plastic::new_tex("lines.png", Spectrum::white()));
    let sphere = Box::new(GeometricPrimitive {
        shape: Arc::new(Sphere::new().radius(0.7).transform(transform::translate_y(-0.3))),
        area_light: None,
        // material: Some(Arc::new(Plastic::new(Spectrum::red(), Spectrum::white()))),
        // material: Some(Arc::new(Plastic::new_tex("lines.png", Spectrum::white()))),
        material: Some(bronze.clone()),
    });
    let bunny =
        Box::new(BVH::<GeometricPrimitive>::from_mesh_file(Path::new("models/bunny.obj"),
                                                           "bunny",
                                                           plastic.clone(),
                                                           &Transform::new(
                                                             Vector3f::new(2.0, -0.8, 0.0),
                                                             Vector3f::new(0.0, 20.0f32.to_radians(), 0.0),
                                                             0.5
                                                             ))) as Box<Primitive + Send + Sync>;
    let buddha =
        Box::new(BVH::<GeometricPrimitive>::from_mesh_file(Path::new("models/buddha.obj"),
                                                           "buddha",
                                                           gold.clone(),
                                                           &Transform::new(
                                                             Vector3f::new(-2.0, 0.0, 0.0),
                                                             Vector3f::new(0.0, 200.0f32.to_radians(), 0.0),
                                                             3.0
                                                             ))) as Box<Primitive + Send + Sync>;
    let floor = Box::new(GeometricPrimitive {
        shape: Arc::new(Disk::new(-1.0, 20.0, 0.0, 360.0, transform::rot_x(-90.0))),
        area_light: None,
        // material: Some(Arc::new(MatteMaterial::checkerboard(0.0))),
        // material: Some(Arc::new(MatteMaterial::new(Spectrum::red(), 0.0))),
        material: Some(plastic_lines.clone()),
    });

    let primitives: Vec<Box<Primitive + Sync + Send>> =
        vec![buddha, sphere, bunny, floor, area_light_prim];
    // Light
    // lights.push(area_light);
    // lights.push(Arc::new(DistantLight::new(Vector3f::new(0.0, -1.0, -5.0),
    //                                        Spectrum::rgb(0.5, 0.5, 0.5))));
    lights.push(Arc::new(InfiniteAreaLight::new(na::one(),
                                                16,
                                                Spectrum::grey(0.5),
                                                Path::new("foo"))));

    Scene::new(camera, integrator, primitives, lights)
}

fn parse_args<'a>() -> ArgMatches<'a> {
    // TODO add block-size and ao-samples and whitted-max-ray? Or maybe not since eventually it
    // will be read from the scene file...
    App::new("rustracer")
        .version("0.1")
        .author("Antoine Bűsch")
        .about("Toy raytracer in Rust based on PBRTv3")
        .arg(Arg::with_name("output")
            .long("output")
            .short("o")
            .help("Output file name")
            .default_value("image.png"))
        .arg(Arg::with_name("threads")
            .long("threads")
            .short("t")
            .help("Number of worker threads"))
        .arg(Arg::with_name("dim")
            .long("dim")
            .short("d")
            .help("Dimension of the output image")
            .default_value("800x600"))
        .arg(Arg::with_name("integrator")
            .long("integrator")
            .short("i")
            .help("SamplerIntegrator to use")
            .possible_values(&SamplerIntegratorType::variants()))
        .arg(Arg::with_name("spp")
            .long("spp")
            .help("Sample per pixels")
            .default_value("4"))
        .get_matches()
}

fn configure_logger() {
    let log_path = "/tmp/rustracer.log";
    let file = OpenOptions::new()
        .create(true)
        .write(true)
        .truncate(true)
        .open(log_path)
        .unwrap();

    let drain = slog_stream::stream(file, MyFormat).fuse();
    let log = Logger::root(drain, o!());
    slog_scope::set_global_logger(log);

}

trait HumanDisplay {
    fn human_display(&self) -> String;
}
impl HumanDisplay for std::time::Duration {
    fn human_display(&self) -> String {
        let mut hours = 0;
        let mut minutes = 0;
        let mut seconds = self.as_secs();
        if seconds >= 60 {
            seconds %= 60;
            minutes = seconds / 60;
        }
        if minutes >= 60 {
            minutes %= 60;
            hours = minutes / 60;
        }
        let millis = self.subsec_nanos() / 1000000;
        format!("{}:{}:{}.{}", hours, minutes, seconds, millis)
    }
}

macro_rules! now {
    () => ( Local::now().format("%m-%d %H:%M:%S%.3f") )
}

struct MyFormat;

impl slog_stream::Format for MyFormat {
    fn format(&self,
              io: &mut io::Write,
              rinfo: &slog::Record,
              _logger_values: &slog::OwnedKeyValueList)
              -> io::Result<()> {
        let msg = format!("{} [{}][{:x}][{}:{} {}] - {}\n",
                          now!(),
                          rinfo.level(),
                          thread_id::get(),
                          rinfo.file(),
                          rinfo.line(),
                          rinfo.module(),
                          rinfo.msg());
        try!(io.write_all(msg.as_bytes()));
        Ok(())
    }
}
<|endoftext|>


<commit_before>#![feature(phase)]
extern crate cargo;
extern crate docopt;
#[phase(plugin)] extern crate docopt_macros;
extern crate graphviz;
extern crate serialize;

use cargo::core::{Resolve, SourceId, PackageId};
use docopt::{Error, FlagParser};
use graphviz as dot;
use std::io::File;
use std::str;

docopt!(Flags, "
Generate a graph of package dependencies in graphviz format

Usage: cargo dot [options]
       cargo dot --help

Options:
    -h, --help         Show this message
    -V, --version      Print version info and exit
    --lock-file=FILE   Specify location of input file, default \"Cargo.lock\"
    --dot-file=FILE    Output to file, default prints to stdout
    --source-labels    Use sources for the label instead of package names
")

fn main() {
    let config = docopt::Config { version: Some("0.1.0".to_string()) , ..docopt::DEFAULT_CONFIG };
    let flags: Flags = FlagParser::parse_conf(config).unwrap_or_else(|e| e.exit());
    let lock_file  = unless_empty(flags.flag_lock_file, "Cargo.lock");
    let dot_f_flag = if flags.flag_dot_file.is_empty() { None } else { Some(flags.flag_dot_file) };
    let source_labels = flags.flag_source_labels;

    let lock_file = Path::new(lock_file);
    let project_dir = Path::new(lock_file.dirname());
    let project_dir = std::os::make_absolute(&project_dir);
    let src_id = SourceId::for_path(&project_dir).unwrap();
    let resolved = cargo::ops::load_lockfile(&lock_file, &src_id)
                     .unwrap_or_else(|e| exit_with(e.description().as_slice()))
                     .unwrap_or_else(||  exit_with("Lock file not found."));

    let mut graph = Graph::with_root(resolved.root(), source_labels);
    graph.add_dependencies(&resolved);

    match dot_f_flag {
        None           => graph.render_to(&mut std::io::stdio::stdout()),
        Some(dot_file) => graph.render_to(&mut File::create(&Path::new(dot_file)))
    };

}

fn exit_with(s: &str) -> ! {
    fail!("Error parsing lockfile: {}", s)
}

fn unless_empty(s: String, default: &str) -> String {
    if s.is_empty() {
        default.to_string()
    } else {
        s
    }
}

pub type Nd = uint;
pub type Ed = (uint, uint);
pub struct Graph<'a> {
    nodes: Vec<&'a PackageId>,
    edges: Vec<Ed>,
    source_labels: bool
}

impl<'a> Graph<'a> {
    pub fn with_root(root: &PackageId, source_labels: bool) -> Graph {
        Graph { nodes: vec![root], edges: vec![], source_labels: source_labels }
    }

    pub fn add_dependencies(&mut self, resolved: &'a Resolve) {
        for crat in resolved.iter() {
            match resolved.deps(crat) {
                Some(mut crate_deps) => {
                    let idl = self.find_or_add(crat);
                    for dep in crate_deps {
                        let idr = self.find_or_add(dep);
                        self.edges.push((idl, idr));
                    };
                },
                None => { }
            }
        }
    }

    fn find_or_add(&mut self, new: &'a PackageId) -> uint {
        for (i, id) in self.nodes.iter().enumerate() {
            if *id == new {
                return i
            }
        }
        self.nodes.push(new);
        self.nodes.len() - 1
    }

    pub fn render_to<W:Writer>(&'a self, output: &mut W) {
        dot::render(self, output).unwrap()
    }
}

impl<'a> dot::Labeller<'a, Nd, Ed> for Graph<'a> {
    fn graph_id(&self) -> dot::Id<'a> {
        dot::Id::new("dependencies")
    }
    fn node_id(&self, n: &Nd) -> dot::Id {
        dot::Id::new(format!("N{:u}", *n))
    }
    fn node_label<'a>(&'a self, i: &Nd) -> dot::LabelText<'a> {
        if !self.source_labels {
            dot::LabelStr(str::Slice(self.nodes[*i].get_name()))
        } else {
            dot::LabelStr(str::Owned(self.nodes[*i].get_source_id().get_url().to_string()))
        }
    }
}

impl<'a> dot::GraphWalk<'a, Nd, Ed> for Graph<'a> {
    fn nodes(&self) -> dot::Nodes<'a,Nd> {
        range(0, self.nodes.len()).collect()
    }
    fn edges(&'a self) -> dot::Edges<'a,Ed> {
        dot::maybe_owned_vec::Borrowed(self.edges.as_slice())
    }
    fn source(&self, &(s, _): &Ed) -> Nd { s }
    fn target(&self, &(_, t): &Ed) -> Nd { t }
}
<commit_msg>Better error message when rendering fails<commit_after>#![feature(phase)]
extern crate cargo;
extern crate docopt;
#[phase(plugin)] extern crate docopt_macros;
extern crate graphviz;
extern crate serialize;

use cargo::core::{Resolve, SourceId, PackageId};
use docopt::{Error, FlagParser};
use graphviz as dot;
use std::io::File;
use std::str;

docopt!(Flags, "
Generate a graph of package dependencies in graphviz format

Usage: cargo dot [options]
       cargo dot --help

Options:
    -h, --help         Show this message
    -V, --version      Print version info and exit
    --lock-file=FILE   Specify location of input file, default \"Cargo.lock\"
    --dot-file=FILE    Output to file, default prints to stdout
    --source-labels    Use sources for the label instead of package names
")

fn main() {
    let config = docopt::Config { version: Some("0.1.0".to_string()) , ..docopt::DEFAULT_CONFIG };
    let flags: Flags = FlagParser::parse_conf(config).unwrap_or_else(|e| e.exit());
    let lock_file  = unless_empty(flags.flag_lock_file, "Cargo.lock");
    let dot_f_flag = if flags.flag_dot_file.is_empty() { None } else { Some(flags.flag_dot_file) };
    let source_labels = flags.flag_source_labels;

    let lock_file = Path::new(lock_file);
    let project_dir = Path::new(lock_file.dirname());
    let project_dir = std::os::make_absolute(&project_dir);
    let src_id = SourceId::for_path(&project_dir).unwrap();
    let resolved = cargo::ops::load_lockfile(&lock_file, &src_id)
                     .unwrap_or_else(|e| exit_with(e.description().as_slice()))
                     .unwrap_or_else(||  exit_with("Lock file not found."));

    let mut graph = Graph::with_root(resolved.root(), source_labels);
    graph.add_dependencies(&resolved);

    match dot_f_flag {
        None           => graph.render_to(&mut std::io::stdio::stdout()),
        Some(dot_file) => graph.render_to(&mut File::create(&Path::new(dot_file)))
    };

}

fn exit_with(s: &str) -> ! {
    fail!("Error parsing lockfile: {}", s)
}

fn unless_empty(s: String, default: &str) -> String {
    if s.is_empty() {
        default.to_string()
    } else {
        s
    }
}

pub type Nd = uint;
pub type Ed = (uint, uint);
pub struct Graph<'a> {
    nodes: Vec<&'a PackageId>,
    edges: Vec<Ed>,
    source_labels: bool
}

impl<'a> Graph<'a> {
    pub fn with_root(root: &PackageId, source_labels: bool) -> Graph {
        Graph { nodes: vec![root], edges: vec![], source_labels: source_labels }
    }

    pub fn add_dependencies(&mut self, resolved: &'a Resolve) {
        for crat in resolved.iter() {
            match resolved.deps(crat) {
                Some(mut crate_deps) => {
                    let idl = self.find_or_add(crat);
                    for dep in crate_deps {
                        let idr = self.find_or_add(dep);
                        self.edges.push((idl, idr));
                    };
                },
                None => { }
            }
        }
    }

    fn find_or_add(&mut self, new: &'a PackageId) -> uint {
        for (i, id) in self.nodes.iter().enumerate() {
            if *id == new {
                return i
            }
        }
        self.nodes.push(new);
        self.nodes.len() - 1
    }

    pub fn render_to<W:Writer>(&'a self, output: &mut W) {
        match dot::render(self, output) {
            Ok(_) => {},
            Err(e) => fail!("error rendering graph: {}", e)
        }
    }
}

impl<'a> dot::Labeller<'a, Nd, Ed> for Graph<'a> {
    fn graph_id(&self) -> dot::Id<'a> {
        if self.nodes.is_empty() || !self.nodes[0].get_name().chars().all(is_valid) {
            return dot::Id::new("dependencies")
        } else {
            return dot::Id::new(self.nodes[0].get_name())
        }
        fn is_valid(c: char) -> bool {
            in_range('a',c,'z') || in_range('A', c, 'Z') || in_range('0', c, '9') || c == '_'
        }
        fn in_range(low: char, mid: char, hi: char) -> bool {
            low as uint <= mid as uint && mid as uint <= hi as uint
        }
    }
    fn node_id(&self, n: &Nd) -> dot::Id {
        dot::Id::new(format!("N{:u}", *n))
    }
    fn node_label<'a>(&'a self, i: &Nd) -> dot::LabelText<'a> {
        if !self.source_labels {
            dot::LabelStr(str::Slice(self.nodes[*i].get_name()))
        } else {
            dot::LabelStr(str::Owned(self.nodes[*i].get_source_id().get_url().to_string()))
        }
    }
}

impl<'a> dot::GraphWalk<'a, Nd, Ed> for Graph<'a> {
    fn nodes(&self) -> dot::Nodes<'a,Nd> {
        range(0, self.nodes.len()).collect()
    }
    fn edges(&'a self) -> dot::Edges<'a,Ed> {
        dot::maybe_owned_vec::Borrowed(self.edges.as_slice())
    }
    fn source(&self, &(s, _): &Ed) -> Nd { s }
    fn target(&self, &(_, t): &Ed) -> Nd { t }
}
<|endoftext|>


<commit_before>#![crate_name = "clog"]
#![comment = "A conventional changelog generator"]
#![license = "MIT"]
#![feature(macro_rules, phase)]

extern crate regex;
#[phase(plugin)]
extern crate regex_macros;
extern crate serialize;
#[phase(plugin)] extern crate docopt_macros;
extern crate docopt;
extern crate time;

use git::{ LogReaderConfig, get_commits, get_latest_tag };
use log_writer::{ LogWriter, LogWriterOptions };
use section_builder::build_sections;
use std::io::{File, Open, Write};
use docopt::FlagParser;

mod common;
mod git;
mod log_writer;
mod section_builder;

docopt!(Args, "clog

Usage:
  clog [--repository=<link> --setversion=<version> --subtitle=<subtitle>
        --from=<from> --to=<to> --from-latest-tag]

Options:
  -h --help               Show this screen.
  --version               Show version
  -r --repository=<link>  e.g https://github.com/thoughtram/clog
  --setversion=<version>  e.g. 0.1.0
  --subtitle=<subtitle>   e.g. crazy-release-name
  --from=<from>           e.g. 12a8546
  --to=<to>               e.g. 8057684
  --from-latest-tag       uses the latest tag as starting point. Ignores other --from parameter")

fn main () {

    let args: Args = FlagParser::parse().unwrap_or_else(|e| e.exit());

    let log_reader_config = LogReaderConfig {
        grep: "^feat|^fix|BREAKING'".to_string(),
        format: "%H%n%s%n%b%n==END==".to_string(),
        from: if args.flag_from_latest_tag { get_latest_tag() } else { args.flag_from },
        to: args.flag_to
    };

    let commits = get_commits(log_reader_config);

    let sections = build_sections(commits.clone());
    let mut file = File::open_mode(&Path::new("changelog.md"), Open, Write).ok().unwrap();
    let mut writer = LogWriter::new(&mut file, LogWriterOptions {
        repository_link: args.flag_repository,
        version: args.flag_setversion,
        subtitle: args.flag_subtitle
    });

    writer.write_header();
    writer.write_section("Bug Fixes", &sections.fixes);
    writer.write_section("Features", &sections.features);
}
<commit_msg>feat(main): always append to file<commit_after>#![crate_name = "clog"]
#![comment = "A conventional changelog generator"]
#![license = "MIT"]
#![feature(macro_rules, phase)]

extern crate regex;
#[phase(plugin)]
extern crate regex_macros;
extern crate serialize;
#[phase(plugin)] extern crate docopt_macros;
extern crate docopt;
extern crate time;

use git::{ LogReaderConfig, get_commits, get_latest_tag };
use log_writer::{ LogWriter, LogWriterOptions };
use section_builder::build_sections;
use std::io::{File, Append, Write};
use docopt::FlagParser;

mod common;
mod git;
mod log_writer;
mod section_builder;

docopt!(Args, "clog

Usage:
  clog [--repository=<link> --setversion=<version> --subtitle=<subtitle>
        --from=<from> --to=<to> --from-latest-tag]

Options:
  -h --help               Show this screen.
  --version               Show version
  -r --repository=<link>  e.g https://github.com/thoughtram/clog
  --setversion=<version>  e.g. 0.1.0
  --subtitle=<subtitle>   e.g. crazy-release-name
  --from=<from>           e.g. 12a8546
  --to=<to>               e.g. 8057684
  --from-latest-tag       uses the latest tag as starting point. Ignores other --from parameter")

fn main () {

    let args: Args = FlagParser::parse().unwrap_or_else(|e| e.exit());

    let log_reader_config = LogReaderConfig {
        grep: "^feat|^fix|BREAKING'".to_string(),
        format: "%H%n%s%n%b%n==END==".to_string(),
        from: if args.flag_from_latest_tag { get_latest_tag() } else { args.flag_from },
        to: args.flag_to
    };

    let commits = get_commits(log_reader_config);

    let sections = build_sections(commits.clone());
    let mut file = File::open_mode(&Path::new("changelog.md"), Append, Write).ok().unwrap();
    let mut writer = LogWriter::new(&mut file, LogWriterOptions {
        repository_link: args.flag_repository,
        version: args.flag_setversion,
        subtitle: args.flag_subtitle
    });

    writer.write_header();
    writer.write_section("Bug Fixes", &sections.fixes);
    writer.write_section("Features", &sections.features);
}
<|endoftext|>


<commit_before>use std::env;
use std::io;
use std::process;
use std::process::Command;
use std::io::Write;
use std::os::unix::process::CommandExt;

mod auth;
use auth::authenticate_current_user_n;
use auth::get_username;

mod settings;
use settings::Settings;

extern crate getopts;
use getopts::Options;
use getopts::ParsingStyle;

extern crate users;
use users::get_user_by_name;
use users::get_group_by_name;

#[macro_use]
extern crate serde_derive;
extern crate serde_json;

// Global config
static CONFIG_PATH: &'static str = "/etc/rudo.json";
static DEFAULT_PROMPT: &'static str = "Password: ";

fn print_help(program_name: &str, opts: Options) {
    let brief = format!("Usage: {} [flags] [command]", program_name);
    writeln!(&mut io::stderr(), "{}", opts.usage(&brief))
        .expect("Failed to write to stderr!");
}

fn generate_empty_config() {
    // Create a new settings object
    let new_settings = Settings::new();

    // Get a serialized string representation of the object
    let settings_str = new_settings.to_string()
        .expect("Unable to generate empty settings file!");

    // Output the new settings string to stdout
    println!("{}", settings_str);
}

/**
 * Handles listing of current user's permissions to STDOUT
 */
fn list_permissions() {
    // Load the settings file
    let settings = Settings::from_file(CONFIG_PATH)
        .expect("Unable to read configuration file! Run --genconfig.");

    // Get this user's User struct
    let username = get_username();
    let user = settings.get_user(&username).unwrap_or_else(|_| {
        writeln!(&mut io::stderr(), "You are not in the rudo.json file! This incident won't be reported.")
            .expect("Failed to write to stderr!");
        process::exit(1);
    });

    // Create a string of all commands the user can run
    let mut all_commands: String = String::new();
    for cmd in &user.permissions.allowed_commands {
        all_commands += cmd;
        all_commands += " ";
    }

    println!("You are allowed to run the following commands: {}", all_commands);
    process::exit(0);
}

/**
 * Handles default behavior of program - Authenticate and run a command
 * @param user user to run command as
 * @param command program to launch
 * @param args arguments to launch the program with
 */
fn run_command(user: Option<String>, group: Option<String>,  command: &str, args: &Vec<String>) {
    // Load the settings file
    let settings = Settings::from_file(CONFIG_PATH)
    .expect("Unable to read configuration file! Run --genconfig.");

    // Give the user 3 tries to authenticate
    let auth_res = authenticate_current_user_n(&settings, 3);
    if !auth_res {
        process::exit(1);
    }

    // Confirm that user is in the settings file and has permission
    let username: String = get_username();
    let can_run = settings.can_run_command(&username, command).unwrap_or_else(|_| {
        writeln!(&mut io::stderr(), "You are not in the rudo.json file! This incident won't be reported.")
            .expect("Failed to write to stderr!");
        process::exit(1);
    });

    if !can_run {
        writeln!(&mut io::stderr(), "You don't have permission to run that! This incident won't be reported.")
            .expect("Failed to write to stderr!");
        process::exit(1);
    }

    // Determine the uid of the user to impersonate
    let mut uid: u32 = 0;
    let mut gid: u32 = 0;
    if let Some(username) = user {
        let u = get_user_by_name(&username).unwrap_or_else(|| {
            writeln!(&mut io::stderr(), "Invalid username! See --help for more information.")
                .expect("Failed to write to stderr!");
            process::exit(1);
        });
        uid = u.uid();
        gid = u.primary_group_id();
    }

    // If the user provided a group, set that
    if let Some(groupname) = group {
    	let g = get_group_by_name(&groupname).unwrap_or_else(|| {
    		writeln!(&mut io::stderr(), "Invalid group name! See --help for more information.")
    			.expect("Failed to write to stderr!");
    		process::exit(1);
    	});
    	gid = g.gid();
    }

    // Now that the user is authenticated, run the provided command
    Command::new(command).args(args).uid(uid).gid(gid).exec();

    // If we got here, it means the command failed
    writeln!(&mut io::stderr(), "rudo: {}: command not found", &command)
        .expect("Failed to write to stderr!");
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let program_name = args[0].clone();
    let mut opts = Options::new();
    opts.parsing_style(ParsingStyle::StopAtFirstFree);

    let mut user: Option<String> = None;
    let mut group: Option<String> = None;

    // Set up arguments
    opts.optflag("h", "help", "print this help menu");
    opts.optflag("l", "list", "list all permissions for current user");
    opts.optopt("u", "user", "run as the specified user", "<user>");
    opts.optopt("g", "group", "run as the specified group", "<group>");
    opts.optflag("", "genconfig", "Generate an empty config and output to STDOUT");

    // Create a vec of up to 2 arguments to parse
    // We ignore all arguments past the first
    let mut matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(_) => { print_help(&program_name, opts); process::exit(1); }
    };

    // Handle help
    if matches.opt_present("h") {
        print_help(&program_name, opts);
        process::exit(0);
    }

    // Handle --list
    if matches.opt_present("l") {
        list_permissions();
        process::exit(0);
    }

    if matches.free.len() < 1 {
        print_help(&program_name, opts);
        process::exit(1);
    }

    // Handle --user
    if matches.opt_present("u") {
        // Set the user to the provided user
        user = match matches.opt_str("u") {
            Some(x) => Some(x),
            None => { print_help(&program_name, opts); process::exit(1); }
        };
    }

    // Handle --group
    if matches.opt_present("g") {
    	// Set the group to the provided group
    	group = match matches.opt_str("g") {
    		Some(x) => Some(x),
    		None => { print_help(&program_name, opts); process::exit(1) }
    	};
    }

    // Handle --genconfig
    if matches.opt_present("genconfig") {
        generate_empty_config();
        process::exit(0);
    }

    // Handle default behavior (run command)
    let command = matches.free[0].clone();
    matches.free.remove(0);
    run_command(user, group, &command, &matches.free);
}
<commit_msg>Require authentication to list permissions (-l)<commit_after>use std::env;
use std::io;
use std::process;
use std::process::Command;
use std::io::Write;
use std::os::unix::process::CommandExt;

mod auth;
use auth::authenticate_current_user_n;
use auth::get_username;

mod settings;
use settings::Settings;

extern crate getopts;
use getopts::Options;
use getopts::ParsingStyle;

extern crate users;
use users::get_user_by_name;
use users::get_group_by_name;

#[macro_use]
extern crate serde_derive;
extern crate serde_json;

// Global config
static CONFIG_PATH: &'static str = "/etc/rudo.json";
static DEFAULT_PROMPT: &'static str = "Password: ";

fn print_help(program_name: &str, opts: Options) {
    let brief = format!("Usage: {} [flags] [command]", program_name);
    writeln!(&mut io::stderr(), "{}", opts.usage(&brief))
        .expect("Failed to write to stderr!");
}

fn generate_empty_config() {
    // Create a new settings object
    let new_settings = Settings::new();

    // Get a serialized string representation of the object
    let settings_str = new_settings.to_string()
        .expect("Unable to generate empty settings file!");

    // Output the new settings string to stdout
    println!("{}", settings_str);
}

/**
 * Handles listing of current user's permissions to STDOUT
 */
fn list_permissions() {
    // Load the settings file
    let settings = Settings::from_file(CONFIG_PATH)
        .expect("Unable to read configuration file! Run --genconfig.");

    // Give the user 3 tries to authenticate
    let auth_res = authenticate_current_user_n(&settings, 3);
    if !auth_res {
        process::exit(1);
    }

    // Get this user's User struct
    let username = get_username();
    let user = settings.get_user(&username).unwrap_or_else(|_| {
        writeln!(&mut io::stderr(), "You are not in the rudo.json file! This incident won't be reported.")
            .expect("Failed to write to stderr!");
        process::exit(1);
    });

    // Create a string of all commands the user can run
    let mut all_commands: String = String::new();
    for cmd in &user.permissions.allowed_commands {
        all_commands += cmd;
        all_commands += " ";
    }

    println!("You are allowed to run the following commands: {}", all_commands);
    process::exit(0);
}

/**
 * Handles default behavior of program - Authenticate and run a command
 * @param user user to run command as
 * @param command program to launch
 * @param args arguments to launch the program with
 */
fn run_command(user: Option<String>, group: Option<String>,  command: &str, args: &Vec<String>) {
    // Load the settings file
    let settings = Settings::from_file(CONFIG_PATH)
    .expect("Unable to read configuration file! Run --genconfig.");

    // Give the user 3 tries to authenticate
    let auth_res = authenticate_current_user_n(&settings, 3);
    if !auth_res {
        process::exit(1);
    }

    // Confirm that user is in the settings file and has permission
    let username: String = get_username();
    let can_run = settings.can_run_command(&username, command).unwrap_or_else(|_| {
        writeln!(&mut io::stderr(), "You are not in the rudo.json file! This incident won't be reported.")
            .expect("Failed to write to stderr!");
        process::exit(1);
    });

    if !can_run {
        writeln!(&mut io::stderr(), "You don't have permission to run that! This incident won't be reported.")
            .expect("Failed to write to stderr!");
        process::exit(1);
    }

    // Determine the uid of the user to impersonate
    let mut uid: u32 = 0;
    let mut gid: u32 = 0;
    if let Some(username) = user {
        let u = get_user_by_name(&username).unwrap_or_else(|| {
            writeln!(&mut io::stderr(), "Invalid username! See --help for more information.")
                .expect("Failed to write to stderr!");
            process::exit(1);
        });
        uid = u.uid();
        gid = u.primary_group_id();
    }

    // If the user provided a group, set that
    if let Some(groupname) = group {
    	let g = get_group_by_name(&groupname).unwrap_or_else(|| {
    		writeln!(&mut io::stderr(), "Invalid group name! See --help for more information.")
    			.expect("Failed to write to stderr!");
    		process::exit(1);
    	});
    	gid = g.gid();
    }

    // Now that the user is authenticated, run the provided command
    Command::new(command).args(args).uid(uid).gid(gid).exec();

    // If we got here, it means the command failed
    writeln!(&mut io::stderr(), "rudo: {}: command not found", &command)
        .expect("Failed to write to stderr!");
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let program_name = args[0].clone();
    let mut opts = Options::new();
    opts.parsing_style(ParsingStyle::StopAtFirstFree);

    let mut user: Option<String> = None;
    let mut group: Option<String> = None;

    // Set up arguments
    opts.optflag("h", "help", "print this help menu");
    opts.optflag("l", "list", "list all permissions for current user");
    opts.optopt("u", "user", "run as the specified user", "<user>");
    opts.optopt("g", "group", "run as the specified group", "<group>");
    opts.optflag("", "genconfig", "Generate an empty config and output to STDOUT");

    // Create a vec of up to 2 arguments to parse
    // We ignore all arguments past the first
    let mut matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(_) => { print_help(&program_name, opts); process::exit(1); }
    };

    // Handle help
    if matches.opt_present("h") {
        print_help(&program_name, opts);
        process::exit(0);
    }

    // Handle --list
    if matches.opt_present("l") {
        list_permissions();
        process::exit(0);
    }

    if matches.free.len() < 1 {
        print_help(&program_name, opts);
        process::exit(1);
    }

    // Handle --user
    if matches.opt_present("u") {
        // Set the user to the provided user
        user = match matches.opt_str("u") {
            Some(x) => Some(x),
            None => { print_help(&program_name, opts); process::exit(1); }
        };
    }

    // Handle --group
    if matches.opt_present("g") {
    	// Set the group to the provided group
    	group = match matches.opt_str("g") {
    		Some(x) => Some(x),
    		None => { print_help(&program_name, opts); process::exit(1) }
    	};
    }

    // Handle --genconfig
    if matches.opt_present("genconfig") {
        generate_empty_config();
        process::exit(0);
    }

    // Handle default behavior (run command)
    let command = matches.free[0].clone();
    matches.free.remove(0);
    run_command(user, group, &command, &matches.free);
}
<|endoftext|>


<commit_before>extern crate rustyline;
use rustyline::Editor;
use rustyline::error::ReadlineError;
use std::env::args;
use std::process::Command;

fn main() {
    // TODO use a real arg parser
    let program = args().nth(1).expect("no program specified");
    let mut line_editor = Editor::<()>::new();
    loop {
        let line_result = line_editor.readline(format!(">{} ", program.clone()).as_str());
        match line_result {
            Ok(line) => {
                let mut process_result = Command::new(&program)
                    // TODO deal with quoted strings
                    .args(line.split(" ").collect::<Vec<&str>>())
                    .spawn();
                match process_result {
                    Ok(mut process) => {
                        let _ = process.wait();
                    },
                    Err(err) => println!("error while trying to run command: {:?}", err),
                }
            },
            Err(ReadlineError::Interrupted) => {
                return;
            },
            Err(ReadlineError::Eof) => {
                return;
            },
            Err(err) => {
                eprintln!("{:?}", err);
                return;
            }
        }
    }
}
<commit_msg>add comment for return code<commit_after>extern crate rustyline;
use rustyline::Editor;
use rustyline::error::ReadlineError;
use std::env::args;
use std::process::Command;

fn main() {
    // TODO use a real arg parser
    let program = args().nth(1).expect("no program specified");
    let mut line_editor = Editor::<()>::new();
    loop {
        let line_result = line_editor.readline(format!(">{} ", program.clone()).as_str());
        match line_result {
            Ok(line) => {
                let mut process_result = Command::new(&program)
                    // TODO deal with quoted strings
                    .args(line.split(" ").collect::<Vec<&str>>())
                    .spawn();
                match process_result {
                    Ok(mut process) => {
                        // TODO maybe display return code?
                        let _ = process.wait();
                    },
                    Err(err) => println!("error while trying to run command: {:?}", err),
                }
            },
            Err(ReadlineError::Interrupted) => {
                return;
            },
            Err(ReadlineError::Eof) => {
                return;
            },
            Err(err) => {
                eprintln!("{:?}", err);
                return;
            }
        }
    }
}
<|endoftext|>


<commit_before>#![feature(io)]
#![feature(rand)]
#![allow(deprecated)]

use game::{Game};

use std::old_io;

mod game;

fn main() {
    println!("Guess the word game");
    let mut game = Game::new(get_words());
    game_loop(&mut game);
    println!("\n'{}' - You won!", game.intended_word());
}

fn game_loop(game : &mut Game) {
    loop {
        print!(" {}, {} letters left, ", game.current_progress(), game.letters_left());
        let input = old_io::stdin().read_line().ok().expect("Failed to read line");
        let input_trimed = &input[].trim();
        game.guess(input_trimed);
        if game.letters_left() == 0 {
            break;
        }
    }
}

fn get_words() -> Vec<String> {
    let words = vec![
        "rust",
        "is",
        "the",
        "best",
        "programming",
        "language",
    ];
    words.iter().map(|x| x.to_string()).collect()
}
<commit_msg>Загрузка слова из словаря<commit_after>#![feature(io)]
#![feature(rand)]
#![feature(path)]
#![allow(deprecated)]

use game::{Game};

use std::old_io;
use std::old_io::BufferedReader;
use std::old_io::File;

mod game;

fn main() {
    println!("Guess the word game");
    let mut game = Game::new(get_words());
    game_loop(&mut game);
    println!("\n'{}' - You won!", game.intended_word());
}

fn game_loop(game : &mut Game) {
    loop {
        print!(" {}, {} letters left, ", game.current_progress(), game.letters_left());
        let input = old_io::stdin().read_line().ok().expect("Failed to read line");
        let input_trimed = &input[].trim();
        game.guess(input_trimed);
        if game.letters_left() == 0 {
            break;
        }
    }
}

fn get_words() -> Vec<String> {
    let path = Path::new("words.txt");
    let mut file = BufferedReader::new(File::open(&path));
    file.lines().map(|x| x.unwrap().trim().to_string()).collect()
}
<|endoftext|>