<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,Mutex};
use std::thread;
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(()),
				_ => yProxyError::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:8080").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 pre_start(&self, context: ActorCell) {
		   context.actor_of(Props::new(Arc::new(PinActor::new), 18), "pin18".to_owned()).unwrap();
    }
    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 => {
            let pin18 : ActorRef = _context.children().get(&ActorPath::new_local("/user/gorynich/wings/pin18".to_owned())).cloned().unwrap();
						_context.tell(pin18,PinCommands::Blink(20));
						println!("Moving Wings");
				},
				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");
						},
				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) => {
              let pin = self.pinproxy.lock().unwrap();
              match pin.export() {
                  Ok(()) => {
						          println!("Pin exported");
                      let test = try!(pin.set_direction(DirectionProxied::Out));
                      let test2 = try!({
                          pin.set_direction(DirectionProxied::High);
                          thread::sleep(1);
                          pin.set_direction(DirectionProxied::Low);
                          thread::sleep(1);
                      });
                      match pin.unexport() {
                          Ok(()) => {
						                  println!("Pin unexported");
                          }
                          _ => {}
                      }
                  }
                  _ => {}
              }
          },
				PinCommands::Switch => {	}
			}
		}
	}
}

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

mod test;
<commit_msg>it wrking egen<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 std::thread;
use std::time;
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(()),
				_ => yProxyError::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:8080").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 pre_start(&self, context: ActorCell) {
		   context.actor_of(Props::new(Arc::new(PinActor::new), 18), "pin18".to_owned()).unwrap();
    }
    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 => {
            let pin18 : ActorRef = _context.children().get(&ActorPath::new_local("/user/gorynich/wings/pin18".to_owned())).cloned().unwrap();
						_context.tell(pin18,PinCommands::Blink(20));
						println!("Moving Wings");
				},
				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");
						},
				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) => {
              let pin = self.pinproxy.lock().unwrap();
              match pin.export() {
                  Ok(()) => {
						          println!("Pin exported");
                      pin.set_direction(DirectionProxied::Out);
                      pin.set_direction(DirectionProxied::High);
                      thread::sleep(time::Duration::from_millis(10));
                      pin.set_direction(DirectionProxied::Low);
                      thread::sleep(time::Duration::from_millis(10));
                      match pin.unexport() {
                          Ok(()) => {
						                  println!("Pin unexported");
                          }
                          _ => {}
                      }
                  }
                  _ => {}
              }
          },
				PinCommands::Switch => {	}
			}
		}
	}
}

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

mod test;
<|endoftext|>


<commit_before>extern crate rff;
extern crate clap;

use std::io::{self, Write, BufWriter};
use rff::{stdin, match_and_score};
use rff::interface::Interface;
use clap::{App, Arg};

fn main() {
    let status_code = run();
    std::process::exit(status_code);
}

fn run() -> i32 {
    let matches = App::new("rff").
        version(env!("CARGO_PKG_VERSION")).
        author("Andrew S. <andrew@stwrt.ca>").
        about("A fuzzy finder.").
        arg(
            Arg::with_name("query").
                short("s").
                long("search").
                value_name("QUERY").
                help("Term to search for")
        ).
        arg(
            Arg::with_name("benchmark").
                long("benchmark").
                help("Run rff in benchmark mode")
        ).
        get_matches();

    let has_query = matches.is_present("query");
    let has_benchmark = matches.is_present("benchmark");

    if has_benchmark && !has_query {
        println!("Must specifiy -s/--search with --benchmark");
        return 1
    }

    if has_query {
        let query = matches.value_of("query").unwrap();

        if has_benchmark {
            benchmark(query, stdin::slurp());
        } else {
            search(query, stdin::slurp());
        }
    } else {
        Interface::new(stdin::slurp()).run();
    }

    return 0
}

fn benchmark(needle: &str, lines: Vec<String>) {
    // in benchmark mode, we run the match/score/sort loop 100 times
    for _ in 0..100 {
        lines
            .iter()
            .filter_map(|line| match_and_score(needle, line))
            .collect::<Vec<_>>()
            .sort_by(|a, b| a.1.partial_cmp(&b.1).unwrap().reverse());
    }
}

fn search(needle: &str, lines: Vec<String>) {
    let mut lines: Vec<_> = lines
        .iter()
        .filter_map(|line| match_and_score(needle, line))
        .collect();

    lines.sort_by(|a, b| a.1.partial_cmp(&b.1).unwrap().reverse());

    let stdout = io::stdout();
    let mut stdout = BufWriter::new(stdout.lock());

    for line in &lines {
        writeln!(stdout, "{}", line.0).unwrap();
    }
}
<commit_msg>Split logic into side functions<commit_after>extern crate rff;
extern crate clap;

use std::io::{self, Write, BufWriter};
use rff::{stdin, match_and_score};
use rff::interface::Interface;
use clap::{App, Arg};

fn main() {
    let status_code = run();
    std::process::exit(status_code);
}

fn run() -> i32 {
    let matches = App::new("rff").
        version(env!("CARGO_PKG_VERSION")).
        author("Andrew S. <andrew@stwrt.ca>").
        about("A fuzzy finder.").
        arg(
            Arg::with_name("query").
                short("s").
                long("search").
                value_name("QUERY").
                help("Term to search for")
        ).
        arg(
            Arg::with_name("benchmark").
                long("benchmark").
                help("Run rff in benchmark mode")
        ).
        get_matches();

    let has_query = matches.is_present("query");
    let has_benchmark = matches.is_present("benchmark");

    if has_benchmark && !has_query {
        println!("Must specifiy -s/--search with --benchmark");
        return 1
    }

    if has_query {
        let query = matches.value_of("query").unwrap();

        if has_benchmark {
            benchmark(query);
        } else {
            search(query);
        }
    } else {
        interactive();
    }

    return 0
}

fn benchmark(needle: &str) {
    let lines = stdin::slurp();

    // in benchmark mode, we run the match/score/sort loop 100 times
    for _ in 0..100 {
        lines
            .iter()
            .filter_map(|line| match_and_score(needle, line))
            .collect::<Vec<_>>()
            .sort_by(|a, b| a.1.partial_cmp(&b.1).unwrap().reverse());
    }
}

fn search(needle: &str) {
    let lines = stdin::slurp();
    let mut lines: Vec<_> = lines
        .iter()
        .filter_map(|line| match_and_score(needle, line))
        .collect();

    lines.sort_by(|a, b| a.1.partial_cmp(&b.1).unwrap().reverse());

    let stdout = io::stdout();
    let mut stdout = BufWriter::new(stdout.lock());

    for line in &lines {
        writeln!(stdout, "{}", line.0).unwrap();
    }
}

fn interactive() {
    Interface::new(stdin::slurp()).run();
}
<|endoftext|>


<commit_before>// A terminal shell implementation in Rust
use std::io;

fn main() {

		let mut cmd = String::new();
		println!("{}::","\u{019B}");
		io::stdin().read_line(&mut cmd)
		.ok()
		.expect("Error: Command Not Found");
		let cmd_slice = &cmd;

}<commit_msg>trying echo command<commit_after>// A terminal shell implementation in Rust
use std::io;

fn main() {

	let mut cmd = String::new();
	loop {

	println!("{}::","\u{019B}");
	io::stdin().read_line(&mut cmd)
		.ok()
		.expect("Error: Command Not Found");
	let cmd_vec:Vec<&str> = cmd.split(" ").collect();
	match cmd_vec[0] {
		"echo" => println!("{}",cmd_vec[1]),
		_ => println!("Error: Command not found"),
	}

	}
}<|endoftext|>


<commit_before>extern crate iron;
extern crate staticfile;

use iron::Iron;

use staticfile::Static;

use std::env;

fn main() {
    let default_port = "8080".to_string();
    let port = env::args().nth(1).unwrap_or(default_port);
    let addr = format!("localhost:{}", port);

    match Iron::new(Static::new(".")).http(&*addr) {
        Ok(_) => {
            println!("Listening on port {}", port);
        },
        Err(_) => {
            println!("Could not start server on port {}. Do you have permission or is it already in use?", port);
        },
    }
}
<commit_msg>Style fixes<commit_after>extern crate iron;
extern crate staticfile;

use iron::Iron;
use staticfile::Static;
use std::env;

const DEFAULT_PORT: &'static str = "8080";

fn main() {
    let port = env::args().nth(1).unwrap_or(DEFAULT_PORT.into());
    let addr = format!("localhost:{}", port);

    match Iron::new(Static::new(".")).http(&*addr) {
        Ok(_) => {
            println!("Listening on port {}", port);
        },
        Err(_) => {
            println!("Could not start server on port {}. \
                      Make sure that you have the required permissions \
                      and that the port is not already in use.", port);
        },
    }
}
<|endoftext|>


<commit_before>extern crate rustc_serialize;
extern crate docopt;

use std::process;
use docopt::Docopt;

const USAGE: &'static str = "
Usage: alfred-rust-calc [--alfred2] [--] <expr>...
       alfred-rust-calc (-h | --help)

Options:
    -h,--help    Show this screen.
    --alfred2    Emit Alfred2-style workflow XML.
";

mod calc {
    include!(concat!(env!("OUT_DIR"), "/calc.rs"));
}

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_alfred2: bool,
    arg_expr: Vec<String>,
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());

    let expr_str = args.arg_expr.join(" ");

    if args.flag_alfred2 {
        match calc::expr(&*expr_str) {
            Ok(expr) => {
        print!("\
<?xml version=\"1.0\"?>
<items>
  <item arg=\"{0}\" valid=\"YES\" autocomplete=\"{0}\" type=\"default\">
    <title>{0}</title>
    <subtitle>(decimal)</subtitle>
  </item>
  <item arg=\"0x{0:x}\" valid=\"YES\" autocomplete=\"0x{0:x}\" type=\"default\">
    <title>0x{0:x}</title>
    <subtitle>(hexadecimal)</subtitle>
  </item>
  <item arg=\"0o{0:o}\" valid=\"YES\" autocomplete=\"0o{0:o}\" type=\"default\">
    <title>0o{0:o}</title>
    <subtitle>(octal)</subtitle>
  </item>
  <item arg=\"0b{0:b}\" valid=\"YES\" autocomplete=\"0b{0:b}\" type=\"default\">
    <title>0b{0:o}</title>
    <subtitle>(binary)</subtitle>
  </item>
</items>
", expr);
            },
            Err(err) => {
                println!("Error: {}", err);
                process::exit(1);
            }
        }
    } else {
        match calc::expr(&*expr_str) {
            Ok(expr) => {
                println!("{:}", expr);
            },
            Err(err) => {
                println!("Error: {}", err);
                process::exit(1);
            }
        }
    }

    // TODO:
    // - package the Alfred workflow properly, including icon
    // - add a README.md
    // - add unary operators:
    //   + integer negation ("-")
    //   + bitwise negation ("~")
    // - add parentheses support
    // - add "<icon>hex.png</icon>" (etc.) to xml output
    // - add tests for the binary behavior
}
<commit_msg>add comment pointing to Alfred2 docs<commit_after>extern crate rustc_serialize;
extern crate docopt;

use std::process;
use docopt::Docopt;

const USAGE: &'static str = "
Usage: alfred-rust-calc [--alfred2] [--] <expr>...
       alfred-rust-calc (-h | --help)

Options:
    -h,--help    Show this screen.
    --alfred2    Emit Alfred2-style workflow XML.
";

mod calc {
    include!(concat!(env!("OUT_DIR"), "/calc.rs"));
}

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_alfred2: bool,
    arg_expr: Vec<String>,
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());

    let expr_str = args.arg_expr.join(" ");

    if args.flag_alfred2 {
        match calc::expr(&*expr_str) {
            Ok(expr) => {
                // the Alfred2 Script Filter XML output format is documented here:
                // https://www.alfredapp.com/help/workflows/inputs/script-filter/xml/
        print!("\
<?xml version=\"1.0\"?>
<items>
  <item arg=\"{0}\" valid=\"YES\" autocomplete=\"{0}\" type=\"default\">
    <title>{0}</title>
    <subtitle>(decimal)</subtitle>
  </item>
  <item arg=\"0x{0:x}\" valid=\"YES\" autocomplete=\"0x{0:x}\" type=\"default\">
    <title>0x{0:x}</title>
    <subtitle>(hexadecimal)</subtitle>
  </item>
  <item arg=\"0o{0:o}\" valid=\"YES\" autocomplete=\"0o{0:o}\" type=\"default\">
    <title>0o{0:o}</title>
    <subtitle>(octal)</subtitle>
  </item>
  <item arg=\"0b{0:b}\" valid=\"YES\" autocomplete=\"0b{0:b}\" type=\"default\">
    <title>0b{0:o}</title>
    <subtitle>(binary)</subtitle>
  </item>
</items>
", expr);
            },
            Err(err) => {
                println!("Error: {}", err);
                process::exit(1);
            }
        }
    } else {
        match calc::expr(&*expr_str) {
            Ok(expr) => {
                println!("{:}", expr);
            },
            Err(err) => {
                println!("Error: {}", err);
                process::exit(1);
            }
        }
    }

    // TODO:
    // - package the Alfred workflow properly, including icon
    // - add a README.md
    // - add unary operators:
    //   + integer negation ("-")
    //   + bitwise negation ("~")
    // - add parentheses support
    // - add "<icon>hex.png</icon>" (etc.) to xml output
    // - add tests for the binary behavior
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate nom;
extern crate combine;
extern crate linenoise;

mod list;
mod parsercombine;
mod parser;

use nom::IResult;

use list::{Sym, Node, List};
use list::Sym::*;

fn main() {
    println!("lisp-rs");
    while let Some(input) = linenoise::input("> ") {
        linenoise::history_add(&input);

        match &input as &str {
            "clear" => linenoise::clear_screen(),
            "exit"  => break,
            _ => {
                let parsed = parser::list(input.as_bytes());
                match parsed {
                    IResult::Done(_, result) => println!("{}", result),
                    IResult::Error(_)        => println!("error: something exploded"),
                    IResult::Incomplete(_)   => println!("error: incomplete")
                }
            }
        };
    }
}
<commit_msg>Remove unused imports from main<commit_after>#[macro_use]
extern crate nom;
extern crate combine;
extern crate linenoise;

mod list;
mod parsercombine;
mod parser;

use nom::IResult;

fn main() {
    println!("lisp-rs");
    while let Some(input) = linenoise::input("> ") {
        linenoise::history_add(&input);

        match &input as &str {
            "clear" => linenoise::clear_screen(),
            "exit"  => break,
            _ => {
                let parsed = parser::list(input.as_bytes());
                match parsed {
                    IResult::Done(_, result) => println!("{}", result),
                    IResult::Error(_)        => println!("error: something exploded"),
                    IResult::Incomplete(_)   => println!("error: incomplete")
                }
            }
        };
    }
}
<|endoftext|>


<commit_before>//! A Rust snippet runner.
//!
//! Please see [readme](https://github.com/stevedonovan/runner/blob/master/readme.md)
extern crate easy_shortcuts as es;
extern crate lapp;
use es::traits::*;
use std::process;
use std::env;
use std::fs;
use std::path::PathBuf;
use std::collections::HashMap;
use std::io::Write;

mod crate_utils;
mod platform;

use platform::{open,edit,EXE};

fn rustup_lib() -> String {
    es::shell("rustc --print sysroot") + "/lib"
}

// this will be initially written to ~/.cargo/.runner/prelude and
// can then be edited.
const PRELUDE: &'static str = "
#![allow(unused_imports)]
#![allow(dead_code)]
use std::fs;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::env;
use std::path::{PathBuf,Path};
#[allow(unused_macros)]
macro_rules! debug {
    ($x:expr) => {
        println!(\"{} = {:?}\",stringify!($x),$x);
    }
}

";

fn runner_directory() -> PathBuf {
    let mut home = env::home_dir().or_die("no home!");
    home.push(".cargo");
    home.push(".runner");
    home
}

fn cargo(args: &[&str]) {
    let res = process::Command::new("cargo")
        .args(args)
        .status()
        .or_die("can't run cargo");
    if ! res.success() {
        es::quit("cargo failed");
    }
}

const STATIC_CACHE: &str = "static-cache";
const DYNAMIC_CACHE: &str = "dy-cache";

fn static_cache_dir() -> PathBuf {
    runner_directory().join(STATIC_CACHE)
}

fn static_cache_dir_check(args: &lapp::Args) -> PathBuf {
    let static_cache = static_cache_dir();
    if ! static_cache.exists() {
        args.quit("please build static cache with --create first");
    }
    static_cache
}

fn build_static_cache() {
    cargo(&["build"]);
    cargo(&["build","--release"]);
    cargo(&["doc"]);
}

fn create_static_cache(crates: &[String], create: bool) {
    use std::io::prelude::*;
    let mut home = runner_directory();
    env::set_current_dir(&home).or_die("cannot change to home directory");
    if create {
        cargo(&["new","--bin",STATIC_CACHE]);
    }
    home.push(STATIC_CACHE);
    env::set_current_dir(&home).or_die("could not create static cache");
    {
        let mut deps = fs::OpenOptions::new().append(true)
            .open("Cargo.toml").or_die("could not append to cargo.toml");
        for c in crates {
            write!(deps,"{}=\"*\"\n",c).or_die("could not modify cargo.toml");
        }
    }
    build_static_cache();
}

// this is always called first and has the important role to ensure that
// runner's directory structure is created properly.
fn get_prelude() -> String {
    let home = runner_directory();
    let pristine = ! home.is_dir();
    if pristine {
        fs::create_dir(&home).or_die("cannot create runner directory");
    }
    let prelude = home.join("prelude");
    let bin = home.join("bin");
    if pristine {
        es::write_all(&prelude,PRELUDE);
        fs::create_dir(&home.join(DYNAMIC_CACHE)).or_die("cannot create dynamic cache");
    }
    if pristine || ! bin.is_dir() {
        fs::create_dir(&bin).or_die("cannot create output directory");
    }
    es::read_to_string(&prelude)
}

fn get_cache(build_static: bool, optimize: bool) -> PathBuf {
    let mut home = runner_directory();
    let scache;
    let cache = if build_static {
        let dir = if optimize {"release"} else {"debug"};
        scache = format!("{}/target/{}/deps",STATIC_CACHE,dir);
        &scache
    } else {DYNAMIC_CACHE};
    home.push(cache);
    home
}

fn add_aliases(aliases: Vec<String>) {
    if aliases.len() == 0 { return; }
    let alias_file = runner_directory().join("alias");
    let mut f = if alias_file.is_file() {
        fs::OpenOptions::new().append(true).open(&alias_file)
    } else {
        fs::File::create(&alias_file)
    }.or_die("cannot open runner alias file");

    for crate_alias in aliases {
        write!(f,"{}\n",crate_alias).or_die("cannot write to runner alias file");
    }
}

fn get_aliases() -> HashMap<String,String> {
    let alias_file = runner_directory().join("alias");
    if ! alias_file.is_file() { return HashMap::new(); }
	es::lines(es::open(&alias_file))
      .filter_map(|s| s.split_at_delim('=').trim()) // split into (String,String)
	  .to_map()
}

fn massage_snippet(code: String, prelude: String, extern_crates: Vec<String>, wild_crates: Vec<String>) -> String {
    fn indent_line(line: &str) -> String {
        format!("    {}\n",line)
    }
    let mut prefix = prelude;
    let mut body = String::new();
    {
        if extern_crates.len() > 0 {
            let aliases = get_aliases();
            for c in extern_crates {
                prefix += &if let Some(aliased) = aliases.get(&c) {
                    format!("extern crate {} as {};",aliased,c)
                } else {
                    format!("extern crate {};",c)
                };
            }
            for c in wild_crates {
                prefix += &format!("use {}::*;",c);
            }
        }
        let mut lines = code.lines();
        let mut first = true;
        for line in lines.by_ref() {
            let line = line.trim_left();
            if first { // files may start with #! shebang...
                if line.starts_with("#!") {
                    continue;
                }
                first = false;
            }
            if line.starts_with("//") || line.starts_with("#[macro_use") ||
                line.starts_with("extern ") || line.starts_with("use ") {
                prefix += line;
                prefix.push('\n');
            } else
            if line.len() > 0 {
                body += &indent_line(line);
                break;
            }
        }
        // and indent the rest!
        body.extend(lines.map(indent_line));
    }

    format!("{}
use std::error::Error;
fn run() -> Result<(),Box<Error>> {{
{}    Ok(())
}}
fn main() {{
    run().unwrap();
}}
        ",prefix,body)

}

const USAGE: &str = "
Compile and run small Rust snippets
  -s, --static build statically (default is dynamic)
  -O, --optimize optimized static build
  -e, --expression evaluate an expression
  -i, --iterator evaluate an iterator
  -n, --lines evaluate expression over stdin; 'line' is defined
  -x, --extern... (string) add an extern crate to the snippet
  -X, --wild... (string) like -x but implies wildcard use

  Cache Management:
  --create (string...) initialize the static cache with crates
  --add  (string...) add new crates to the cache (after --create)
  --edit  edit the static cache Cargo.toml
  --build rebuild the static cache
  --doc  display documentation
  --edit-prelude edit the default prelude for snippets
  --alias (string...) crate aliases in form alias=crate_name (used with -x)

  Dynamic compilation:
  -P, --crate-path show path of crate source in Cargo cache
  -C, --compile  compile crate dynamically (limited)
  --cfg... (string) pass configuration variables to rustc

  <program> (string) Rust program, snippet or expression
  <args> (string...) arguments to pass to program
";

fn main() {
    let args = lapp::parse_args(USAGE);
    let prelude = get_prelude();

    let aliases = args.get_strings("alias");
    if aliases.len() > 0 {
        add_aliases(aliases);
        return;
    }

    if args.get_bool("edit-prelude") {
        let rdir = runner_directory().join("prelude");
        edit(&rdir);
        return;
    }

    // Static Cache Management
    let crates = args.get_strings("create");
    if crates.len() > 0 {
        create_static_cache(&crates,true);
        return;
    }
    let crates = args.get_strings("add");
    if crates.len() > 0 {
        static_cache_dir_check(&args);
        create_static_cache(&crates,false);
        return;
    }

    if args.get_bool("edit") || args.get_bool("build") || args.get_bool("doc") {
        let static_cache = static_cache_dir_check(&args);
        if args.get_bool("build") {
            env::set_current_dir(&static_cache).or_die("static cache wasn't a directory?");
            build_static_cache();
        } else
        if args.get_bool("doc") {
            let docs = static_cache.join("target/doc/static_cache/index.html");
            open(&docs);
        } else {
            let toml = static_cache.join("Cargo.toml");
            edit(&toml);
        }
        return;
    }

    let first_arg = args.get_string("program");
    let file = PathBuf::from(&first_arg);

    // Dynamically linking crates (experimental!)
    if args.get_bool("crate-path") || args.get_bool("compile") {
        let (crate_path,crate_name) = if file.exists() {
            let filename = crate_utils::path_file_name(&file);
            if file.is_dir() { // assumed to be Cargo directory
                if ! file.join("Cargo.toml").exists() {
                    args.quit("not a Cargo project directory");
                }
                (file.join("src/lib.rs"), filename)
            } else { // should be just a Rust source file
                if file.extension().or_die("expecting extension") != "rs" {
                    args.quit("expecting Rust source file");
                }
                let name = crate_utils::path_file_name(&file.with_extension(""));
                (file, name)
            }
        } else {
            (crate_utils::cache_path(&first_arg).join("src/lib.rs"), first_arg)
        };
        if args.get_bool("crate-path") {
            println!("{}",crate_utils::cache_path(&crate_name).display());
        } else {
            let valid_crate_name = crate_name.replace('-',"_");
            let cache = get_cache(false, false);
            let mut builder = process::Command::new("rustc");
                builder.args(&["-C","prefer-dynamic"]).args(&["-C","debuginfo=0"])
                .arg("-L").arg(&cache)
                .args(&["--crate-type","dylib"])
                .arg("--out-dir").arg(&cache)
                .arg("--crate-name").arg(&valid_crate_name)
                .arg(crate_path);
           for c in args.get_strings("cfg") {
                builder.arg("--cfg").arg(&c);
           }
           builder.status().or_die("can't run rustc");
        }
        return;
    }

    let build_static = args.get_bool("static");
    let optimize = args.get_bool("optimize");

    // we'll pass rest of arguments to program
    let program_args = args.get_strings("args");

    let cache = get_cache(build_static, optimize);

    let mut snippet = false;
    let mut code = if args.get_bool("expression") {
        // Evaluating an expression: just print it out.
        format!("println!(\"{{:?}}\",{});", first_arg)
    } else
    if args.get_bool("iterator") {
        // The expression is anything that implements IntoIterator
        format!("let iter = {};\n for val in iter {{ println!(\"{{:?}}\",val);}}", first_arg)
    } else
    if args.get_bool("lines") {
        // The variable 'line' is available to an expression, evaluated for each line in stdin
        format!("
            let stdin = io::stdin();
            for line in stdin.lock().lines() {{
                let line = line?;
                let val = {};
                println!(\"{{:?}}\",val);
            }}
            ", first_arg)
    } else { // otherwise, just a file
        snippet = true;
        es::read_to_string(&file)
    };

    // proper Rust programs are accepted (this is a bit rough)
    if code.find("fn main").is_none() {
        let mut extern_crates = args.get_strings("extern");
        let wild_crates = args.get_strings("wild");
        if wild_crates.len() > 0 {
            extern_crates.extend(wild_crates.iter().cloned());
        }
        code = massage_snippet(code,prelude, extern_crates, wild_crates);
    }

    // we are going to put the expanded source and resulting exe in the runner bin dir
    let mut out_file = runner_directory().join("bin");
    if snippet {
        out_file.push(&file);
        out_file.set_extension("rs");
    } else {
        out_file.push("tmp.rs");
    }
    let mut program = out_file.clone();
    program.set_extension(EXE);

    es::write_all(&out_file,&code);

    let mut builder = process::Command::new("rustc");
    if ! build_static {
        builder.args(&["-C","prefer-dynamic"]).args(&["-C","debuginfo=0"]);
    } else {
        builder.arg(if optimize {"-O"} else {"-g"});
    }
    builder.arg("-L").arg(&cache);
    let status = builder.arg("-o").arg(&program)
        .arg(&out_file)
        .status().or_die("can't run rustc");
    if ! status.success() {
        return;
    }

    let mut builder = process::Command::new(&program);
    if ! build_static {
        builder.env("LD_LIBRARY_PATH",format!("{}:{}",rustup_lib(),cache.display()));
    }
    builder.args(&program_args)
        .status()
        .or_die(&format!("can't run program {:?}",program));

}

<commit_msg>special case: dynamic linking against libc<commit_after>//! A Rust snippet runner.
//!
//! Please see [readme](https://github.com/stevedonovan/runner/blob/master/readme.md)
extern crate easy_shortcuts as es;
extern crate lapp;
use es::traits::*;
use std::process;
use std::env;
use std::fs;
use std::path::PathBuf;
use std::collections::HashMap;
use std::io::Write;

mod crate_utils;
mod platform;

use platform::{open,edit,EXE};

fn rustup_lib() -> String {
    es::shell("rustc --print sysroot") + "/lib"
}

// this will be initially written to ~/.cargo/.runner/prelude and
// can then be edited.
const PRELUDE: &'static str = "
#![allow(unused_imports)]
#![allow(dead_code)]
use std::fs;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::env;
use std::path::{PathBuf,Path};
#[allow(unused_macros)]
macro_rules! debug {
    ($x:expr) => {
        println!(\"{} = {:?}\",stringify!($x),$x);
    }
}

";

fn runner_directory() -> PathBuf {
    let mut home = env::home_dir().or_die("no home!");
    home.push(".cargo");
    home.push(".runner");
    home
}

fn cargo(args: &[&str]) {
    let res = process::Command::new("cargo")
        .args(args)
        .status()
        .or_die("can't run cargo");
    if ! res.success() {
        es::quit("cargo failed");
    }
}

const STATIC_CACHE: &str = "static-cache";
const DYNAMIC_CACHE: &str = "dy-cache";

fn static_cache_dir() -> PathBuf {
    runner_directory().join(STATIC_CACHE)
}

fn static_cache_dir_check(args: &lapp::Args) -> PathBuf {
    let static_cache = static_cache_dir();
    if ! static_cache.exists() {
        args.quit("please build static cache with --create first");
    }
    static_cache
}

fn build_static_cache() {
    cargo(&["build"]);
    cargo(&["build","--release"]);
    cargo(&["doc"]);
}

fn create_static_cache(crates: &[String], create: bool) {
    use std::io::prelude::*;
    let mut home = runner_directory();
    env::set_current_dir(&home).or_die("cannot change to home directory");
    if create {
        cargo(&["new","--bin",STATIC_CACHE]);
    }
    home.push(STATIC_CACHE);
    env::set_current_dir(&home).or_die("could not create static cache");
    {
        let mut deps = fs::OpenOptions::new().append(true)
            .open("Cargo.toml").or_die("could not append to cargo.toml");
        for c in crates {
            write!(deps,"{}=\"*\"\n",c).or_die("could not modify cargo.toml");
        }
    }
    build_static_cache();
}

// this is always called first and has the important role to ensure that
// runner's directory structure is created properly.
fn get_prelude() -> String {
    let home = runner_directory();
    let pristine = ! home.is_dir();
    if pristine {
        fs::create_dir(&home).or_die("cannot create runner directory");
    }
    let prelude = home.join("prelude");
    let bin = home.join("bin");
    if pristine {
        es::write_all(&prelude,PRELUDE);
        fs::create_dir(&home.join(DYNAMIC_CACHE)).or_die("cannot create dynamic cache");
    }
    if pristine || ! bin.is_dir() {
        fs::create_dir(&bin).or_die("cannot create output directory");
    }
    es::read_to_string(&prelude)
}

fn get_cache(build_static: bool, optimize: bool) -> PathBuf {
    let mut home = runner_directory();
    let scache;
    let cache = if build_static {
        let dir = if optimize {"release"} else {"debug"};
        scache = format!("{}/target/{}/deps",STATIC_CACHE,dir);
        &scache
    } else {DYNAMIC_CACHE};
    home.push(cache);
    home
}

fn add_aliases(aliases: Vec<String>) {
    if aliases.len() == 0 { return; }
    let alias_file = runner_directory().join("alias");
    let mut f = if alias_file.is_file() {
        fs::OpenOptions::new().append(true).open(&alias_file)
    } else {
        fs::File::create(&alias_file)
    }.or_die("cannot open runner alias file");

    for crate_alias in aliases {
        write!(f,"{}\n",crate_alias).or_die("cannot write to runner alias file");
    }
}

fn get_aliases() -> HashMap<String,String> {
    let alias_file = runner_directory().join("alias");
    if ! alias_file.is_file() { return HashMap::new(); }
	es::lines(es::open(&alias_file))
      .filter_map(|s| s.split_at_delim('=').trim()) // split into (String,String)
	  .to_map()
}

fn massage_snippet(code: String, prelude: String, extern_crates: Vec<String>, wild_crates: Vec<String>) -> String {
    fn indent_line(line: &str) -> String {
        format!("    {}\n",line)
    }
    let mut prefix = prelude;
    let mut body = String::new();
    {
        if extern_crates.len() > 0 {
            let aliases = get_aliases();
            for c in extern_crates {
                prefix += &if let Some(aliased) = aliases.get(&c) {
                    format!("extern crate {} as {};",aliased,c)
                } else {
                    format!("extern crate {};",c)
                };
            }
            for c in wild_crates {
                prefix += &format!("use {}::*;",c);
            }
        }
        let mut lines = code.lines();
        let mut first = true;
        for line in lines.by_ref() {
            let line = line.trim_left();
            if first { // files may start with #! shebang...
                if line.starts_with("#!") {
                    continue;
                }
                first = false;
            }
            if line.starts_with("//") || line.starts_with("#[macro_use") ||
                line.starts_with("extern ") || line.starts_with("use ") {
                prefix += line;
                prefix.push('\n');
            } else
            if line.len() > 0 {
                body += &indent_line(line);
                break;
            }
        }
        // and indent the rest!
        body.extend(lines.map(indent_line));
    }

    format!("{}
use std::error::Error;
fn run() -> Result<(),Box<Error>> {{
{}    Ok(())
}}
fn main() {{
    run().unwrap();
}}
        ",prefix,body)

}

const USAGE: &str = "
Compile and run small Rust snippets
  -s, --static build statically (default is dynamic)
  -O, --optimize optimized static build
  -e, --expression evaluate an expression
  -i, --iterator evaluate an iterator
  -n, --lines evaluate expression over stdin; 'line' is defined
  -x, --extern... (string) add an extern crate to the snippet
  -X, --wild... (string) like -x but implies wildcard use

  Cache Management:
  --create (string...) initialize the static cache with crates
  --add  (string...) add new crates to the cache (after --create)
  --edit  edit the static cache Cargo.toml
  --build rebuild the static cache
  --doc  display documentation
  --edit-prelude edit the default prelude for snippets
  --alias (string...) crate aliases in form alias=crate_name (used with -x)

  Dynamic compilation:
  -P, --crate-path show path of crate source in Cargo cache
  -C, --compile  compile crate dynamically (limited)
  --cfg... (string) pass configuration variables to rustc
  --libc  link dynamically against libc (special case)

  <program> (string) Rust program, snippet or expression
  <args> (string...) arguments to pass to program
";

fn main() {
    let args = lapp::parse_args(USAGE);
    let prelude = get_prelude();

    let aliases = args.get_strings("alias");
    if aliases.len() > 0 {
        add_aliases(aliases);
        return;
    }

    if args.get_bool("edit-prelude") {
        let rdir = runner_directory().join("prelude");
        edit(&rdir);
        return;
    }

    // Static Cache Management
    let crates = args.get_strings("create");
    if crates.len() > 0 {
        create_static_cache(&crates,true);
        return;
    }
    let crates = args.get_strings("add");
    if crates.len() > 0 {
        static_cache_dir_check(&args);
        create_static_cache(&crates,false);
        return;
    }

    if args.get_bool("edit") || args.get_bool("build") || args.get_bool("doc") {
        let static_cache = static_cache_dir_check(&args);
        if args.get_bool("build") {
            env::set_current_dir(&static_cache).or_die("static cache wasn't a directory?");
            build_static_cache();
        } else
        if args.get_bool("doc") {
            let docs = static_cache.join("target/doc/static_cache/index.html");
            open(&docs);
        } else {
            let toml = static_cache.join("Cargo.toml");
            edit(&toml);
        }
        return;
    }

    let first_arg = args.get_string("program");
    let file = PathBuf::from(&first_arg);

    // Dynamically linking crates (experimental!)
    if args.get_bool("crate-path") || args.get_bool("compile") {
        let (crate_path,crate_name) = if file.exists() {
            let filename = crate_utils::path_file_name(&file);
            if file.is_dir() { // assumed to be Cargo directory
                if ! file.join("Cargo.toml").exists() {
                    args.quit("not a Cargo project directory");
                }
                (file.join("src/lib.rs"), filename)
            } else { // should be just a Rust source file
                if file.extension().or_die("expecting extension") != "rs" {
                    args.quit("expecting Rust source file");
                }
                let name = crate_utils::path_file_name(&file.with_extension(""));
                (file, name)
            }
        } else {
            (crate_utils::cache_path(&first_arg).join("src/lib.rs"), first_arg)
        };
        if args.get_bool("crate-path") {
            println!("{}",crate_utils::cache_path(&crate_name).display());
        } else {
            let valid_crate_name = crate_name.replace('-',"_");
            let cache = get_cache(false, false);
            let mut builder = process::Command::new("rustc");
                builder.args(&["-C","prefer-dynamic"]).args(&["-C","debuginfo=0"])
                .arg("-L").arg(&cache)
                .args(&["--crate-type","dylib"])
                .arg("--out-dir").arg(&cache)
                .arg("--crate-name").arg(&valid_crate_name)
                .arg(crate_path);
           for c in args.get_strings("cfg") {
                builder.arg("--cfg").arg(&c);
           }
           if args.get_bool("libc") {
                builder.arg("--extern").arg(&format!("libc={}/liblibc.so",cache.display()));
           }
           builder.status().or_die("can't run rustc");
        }
        return;
    }

    let build_static = args.get_bool("static");
    let optimize = args.get_bool("optimize");

    // we'll pass rest of arguments to program
    let program_args = args.get_strings("args");

    let cache = get_cache(build_static, optimize);

    let mut snippet = false;
    let mut code = if args.get_bool("expression") {
        // Evaluating an expression: just print it out.
        format!("println!(\"{{:?}}\",{});", first_arg)
    } else
    if args.get_bool("iterator") {
        // The expression is anything that implements IntoIterator
        format!("let iter = {};\n for val in iter {{ println!(\"{{:?}}\",val);}}", first_arg)
    } else
    if args.get_bool("lines") {
        // The variable 'line' is available to an expression, evaluated for each line in stdin
        format!("
            let stdin = io::stdin();
            for line in stdin.lock().lines() {{
                let line = line?;
                let val = {};
                println!(\"{{:?}}\",val);
            }}
            ", first_arg)
    } else { // otherwise, just a file
        snippet = true;
        es::read_to_string(&file)
    };

    // proper Rust programs are accepted (this is a bit rough)
    if code.find("fn main").is_none() {
        let mut extern_crates = args.get_strings("extern");
        let wild_crates = args.get_strings("wild");
        if wild_crates.len() > 0 {
            extern_crates.extend(wild_crates.iter().cloned());
        }
        code = massage_snippet(code,prelude, extern_crates, wild_crates);
    }

    // we are going to put the expanded source and resulting exe in the runner bin dir
    let mut out_file = runner_directory().join("bin");
    if snippet {
        out_file.push(&file);
        out_file.set_extension("rs");
    } else {
        out_file.push("tmp.rs");
    }
    let mut program = out_file.clone();
    program.set_extension(EXE);

    es::write_all(&out_file,&code);

    let mut builder = process::Command::new("rustc");
    if ! build_static {
        builder.args(&["-C","prefer-dynamic"]).args(&["-C","debuginfo=0"]);
    } else {
        builder.arg(if optimize {"-O"} else {"-g"});
    }
    builder.arg("-L").arg(&cache);
    let status = builder.arg("-o").arg(&program)
        .arg(&out_file)
        .status().or_die("can't run rustc");
    if ! status.success() {
        return;
    }

    let mut builder = process::Command::new(&program);
    if ! build_static {
        builder.env("LD_LIBRARY_PATH",format!("{}:{}",rustup_lib(),cache.display()));
    }
    builder.args(&program_args)
        .status()
        .or_die(&format!("can't run program {:?}",program));

}

<|endoftext|>


<commit_before>extern crate rustc_serialize;
extern crate regex;

// use std::path::Path;

// use std::io::Write;
use std::str;
// use std::vec::Drain;

mod image_base64 {
    use std::fs::File;
    use rustc_serialize::base64::{ToBase64, MIME};
    use rustc_serialize::hex::{ToHex};
    use regex::Regex;
    use std::io::Read;
    use std::string::String;

    pub fn to_base64(path: &str) -> String {
        let mut file = File::open(path).unwrap();
        let mut v = Vec::new();
        let _ = file.read_to_end(&mut v);
        let b64 = v.to_base64(MIME);
        let hex = v.to_hex();
        return format!("data:image/{};base64,{}", get_type(&hex), b64);
    }

    fn get_type(hex: &str) -> &str {
        if Regex::new(r"^ffd8ffe0").unwrap().is_match(hex) { "jpg" }
        else if Regex::new(r"^89504e47").unwrap().is_match(hex){ "png" }
        else if Regex::new(r"^47494638").unwrap().is_match(hex){ "gif" }
        else { panic!("invalid file") }
    }
}

fn main() {

    // ------------------------------------------------------

    let fmt_base64 = image_base64::to_base64("res/test.jpg");
    let offset = fmt_base64.find(',').unwrap_or(fmt_base64.len())+1;
    let mut header = fmt_base64;
    let value: String = header.drain(..offset).collect();
    // let ggg = fmt_base64.drain(..header).collect();

     println!("{}", header);
     println!("{}", value);

    // let a = fmt_base64.find("data:image/");
    // println!("{}", None < a);

    // let a = fmt_base64.find("data:image/");
    // println!("{}", None < a);

	// let img = b64.from_base64().unwrap();
    // let mut file = File::create(&Path::new("test.jpg")).unwrap();
    // file.write_all(img.as_slice());
}<commit_msg>rename variables to be more proper name<commit_after>extern crate rustc_serialize;
extern crate regex;

// use std::path::Path;

// use std::io::Write;
use std::str;
// use std::vec::Drain;

mod image_base64 {
    use std::fs::File;
    use rustc_serialize::base64::{ToBase64, MIME};
    use rustc_serialize::hex::{ToHex};
    use regex::Regex;
    use std::io::Read;
    use std::string::String;

    pub fn to_base64(path: &str) -> String {
        let mut file = File::open(path).unwrap();
        let mut vec = Vec::new();
        let _ = file.read_to_end(&mut vec);
        let base64 = vec.to_base64(MIME);
        let hex = vec.to_hex();
        return format!("data:image/{};base64,{}", get_file_type(&hex), base64);
    }

    fn get_file_type(hex: &str) -> &str {
        if Regex::new(r"^ffd8ffe0").unwrap().is_match(hex) { "jpg" }
        else if Regex::new(r"^89504e47").unwrap().is_match(hex){ "png" }
        else if Regex::new(r"^47494638").unwrap().is_match(hex){ "gif" }
        else { panic!("invalid file") }
    }
}

fn main() {

    // ------------------------------------------------------

    let base64 = image_base64::to_base64("res/test.jpg");
    let offset = base64.find(',').unwrap_or(base64.len())+1;
    let mut header = base64; // todo: base64 should be immutable
    let value:String = header.drain(..offset).collect();

    //  println!("{}", base64);
    //  println!("--------------------------------------");
     println!("{}", header);
     println!("--------------------------------------");
     println!("{}", value);

    // let a = fmt_base64.find("data:image/");
    // println!("{}", None < a);

    // let a = fmt_base64.find("data:image/");
    // println!("{}", None < a);

	// let img = b64.from_base64().unwrap();
    // let mut file = File::create(&Path::new("test.jpg")).unwrap();
    // file.write_all(img.as_slice());
}<|endoftext|>


<commit_before>use std::io;
use std::io::Write;

#[derive(Debug, PartialEq, Clone)]
enum Token {
    Unknown(String), // Invalid test (basically non-ascii)
    Literal(String), // Numeric literal number
    Func(Function), // Pre-defined function (like cos() )
    Const(Constant), // Constant like pi or e
    Var(String), // str arbitrary single char variable name
    Op(Operator), // Any of the 4 operators (+-*/)
    Open, // Open parens '('
    Close, // Closing parens ')'
    Set(Vec<Token>), // [ (, tokens..., ) ]
    Fake,
}

#[derive(Debug, PartialEq, Clone)]
enum Function {
    Sqrt(Vec<Token>),
    Ln(Vec<Token>),
    Log(f64, Vec<Token>),
    Sin(Vec<Token>),
    Cos(Vec<Token>),
    Tan(Vec<Token>),
    Asin(Vec<Token>),
    Acos(Vec<Token>),
    Atan(Vec<Token>),
    Sinh(Vec<Token>),
    Cosh(Vec<Token>),
    Tanh(Vec<Token>),
    Asinh(Vec<Token>),
    Acosh(Vec<Token>),
    Atanh(Vec<Token>),
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
enum Constant {
	Pi,
	E,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
enum Operator {
    Add,
    Sub,
    Div,
    Mul,
    Pow,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[repr(u32)]
enum Assoc {
    Left,
    Right,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[repr(u32)]
enum Order {
    AddSub = 1,
    MulDiv = 2,
    IMul = 3, // Implicit multiplication
    Pow = 4,
    Paren = 5,
}

#[derive(Debug, PartialEq, Clone)]
struct Expression {
    tokens: Vec<Token>,
    constant: f64,
}

impl Expression {
	fn new(tokens: Vec<Token>, constant: f64) -> Self {
		Expression {tokens: tokens, constant: constant}
	}

	fn push(&mut self, token: Token) {
		self.tokens.push(token);
	}

	fn update_constant(&mut self, constant: &f64) {
		self.constant += *constant;
	}

	fn get_constant(&self) -> f64 {
		self.constant
	}

	fn get_tokens(&self) -> &[Token] {
		self.tokens.as_slice()
	}

	fn get_mut_tokens(&mut self) -> &mut [Token] {
		self.tokens.as_mut_slice()
	}

	fn replace_token(&mut self, index: usize, newToken: Token) {
		self.tokens.remove(index);
		self.tokens.insert(index, newToken);
	}

	fn replace_all_tokens(&mut self, newTokens: Vec<Token>) {
		self.tokens = newTokens
	}

	fn find_first(&self, token: &Token) -> Option<usize> {
		for i in 0..self.tokens.len() {
			if self.tokens.get(i).unwrap() == token {
				return Some(i);
			}
		}
		None
	}

	fn find_last(&self, token: &Token) -> Option<usize> {
		for i in (0..self.tokens.len()).rev() {
			if self.tokens.get(i).unwrap() == token {
				return Some(i);
			}
		}
		None
	}

	fn split_at(&self, index: usize) -> (&[Token], &[Token]) {
		self.tokens.split_at(index)
	}

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

fn main() {
    println!("Welcome to Rust-Calculus!");
    println!("To evaluate an expression, simply type one in and hit RETURN.");
    println!("To set a variable, simply type VAR_NAME=EXPRESSION and hit RETURN.");
    println!("Valid commands are: sym_int, int, sym_def, and def.");
    println!("Type 'quit' to exit.");
    let mut input = String::new();
    let stdin = io::stdin();
    let mut stdout = io::stdout();
    loop {
    	input.clear();
    	print!(">>>> ");
    	stdout.flush().ok();
        stdin.read_line(&mut input).unwrap();
        input = strip_white_space(&input);
        input = input.to_lowercase();
        if input == "quit" {
        	print!("Exiting...");
        	break;
        }
        let mut expr = parse_input(&input).unwrap();
        println!("{:?}", &expr);
    }
}

fn strip_white_space(input: &String) -> String {
	input.split_whitespace().collect::<Vec<&str>>().join("")
}

fn parse_input(input: &String) -> Result<Expression, ()> {
	let mut expr: Expression = Expression::new(Vec::new(), 0.0);
	for c in input.chars() {
		match c {
			'-' => {
				expr.push(Token::Op(Operator::Sub));
			},
			'+' => {
				expr.push(Token::Op(Operator::Add));
			},
			'/' => {
				expr.push(Token::Op(Operator::Div));
			},
			'*' => {
				expr.push(Token::Op(Operator::Mul));
			},
			'^' => {
				expr.push(Token::Op(Operator::Pow));
			},
			'(' => {
				expr.push(Token::Open);
			},
			')' => {
				expr.push(Token::Close);
			},
			_ => continue,
		}
	}
	if let Some(index) = expr.find_first(&Token::Open) { // If we find an index of an Open
		let endSet: usize = expr.find_last(&Token::Close).unwrap();
		let mut lhs: Vec<Token> = Vec::new();
		let mut rhs: Vec<Token> = Vec::new();
		{
			let (temp_lhs, temp_rhs) = expr.split_at(index); // [0, where set should be placed)
			lhs = temp_lhs.to_vec();
			rhs = temp_rhs.to_vec(); // [where set should be placed, len)
			rhs.remove(0);
			// split rhs at endset - 2
			// Left part gets pushed as a Set to lhs
			// Remove index 0 of right part (this is the close we split on) and add that as a vector to lhs
			let (mut left_rhs, mut right_rhs) = rhs.split_at(endSet-2);
			let (mut left_rhs, mut right_rhs) = (left_rhs.to_vec(), right_rhs.to_vec());
			right_rhs.remove(0);
			//rhs.remove(endSet-2); // Sub one because we removed the first element, need to split at endSet -2
			lhs.push(Token::Set(left_rhs));
			lhs.append(&mut right_rhs);
		}
		for i in (0..lhs.len()).rev() {
			if lhs.get(i).unwrap() == &Token::Close {
				lhs.remove(i);
				break;
			}
		}
		expr.replace_all_tokens(lhs);
	}
	Ok(expr)
}<commit_msg>Fixed lake of snake_case<commit_after>use std::io;
use std::io::Write;

#[derive(Debug, PartialEq, Clone)]
enum Token {
    Unknown(String), // Invalid test (basically non-ascii)
    Literal(String), // Numeric literal number
    Func(Function), // Pre-defined function (like cos() )
    Const(Constant), // Constant like pi or e
    Var(String), // str arbitrary single char variable name
    Op(Operator), // Any of the 4 operators (+-*/)
    Open, // Open parens '('
    Close, // Closing parens ')'
    Set(Vec<Token>), // [ (, tokens..., ) ]
    Fake,
}

#[derive(Debug, PartialEq, Clone)]
enum Function {
    Sqrt(Vec<Token>),
    Ln(Vec<Token>),
    Log(f64, Vec<Token>),
    Sin(Vec<Token>),
    Cos(Vec<Token>),
    Tan(Vec<Token>),
    Asin(Vec<Token>),
    Acos(Vec<Token>),
    Atan(Vec<Token>),
    Sinh(Vec<Token>),
    Cosh(Vec<Token>),
    Tanh(Vec<Token>),
    Asinh(Vec<Token>),
    Acosh(Vec<Token>),
    Atanh(Vec<Token>),
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
enum Constant {
	Pi,
	E,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
enum Operator {
    Add,
    Sub,
    Div,
    Mul,
    Pow,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[repr(u32)]
enum Assoc {
    Left,
    Right,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[repr(u32)]
enum Order {
    AddSub = 1,
    MulDiv = 2,
    IMul = 3, // Implicit multiplication
    Pow = 4,
    Paren = 5,
}

#[derive(Debug, PartialEq, Clone)]
struct Expression {
    tokens: Vec<Token>,
    constant: f64,
}

impl Expression {
	fn new(tokens: Vec<Token>, constant: f64) -> Self {
		Expression {tokens: tokens, constant: constant}
	}

	fn push(&mut self, token: Token) {
		self.tokens.push(token);
	}

	fn update_constant(&mut self, constant: &f64) {
		self.constant += *constant;
	}

	fn get_constant(&self) -> f64 {
		self.constant
	}

	fn get_tokens(&self) -> &[Token] {
		self.tokens.as_slice()
	}

	fn get_mut_tokens(&mut self) -> &mut [Token] {
		self.tokens.as_mut_slice()
	}

	fn replace_token(&mut self, index: usize, new_token: Token) {
		self.tokens.remove(index);
		self.tokens.insert(index, new_token);
	}

	fn replace_all_tokens(&mut self, new_token: Vec<Token>) {
		self.tokens = new_token
	}

	fn find_first(&self, token: &Token) -> Option<usize> {
		for i in 0..self.tokens.len() {
			if self.tokens.get(i).unwrap() == token {
				return Some(i);
			}
		}
		None
	}

	fn find_last(&self, token: &Token) -> Option<usize> {
		for i in (0..self.tokens.len()).rev() {
			if self.tokens.get(i).unwrap() == token {
				return Some(i);
			}
		}
		None
	}

	fn split_at(&self, index: usize) -> (&[Token], &[Token]) {
		self.tokens.split_at(index)
	}

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

fn main() {
    println!("Welcome to Rust-Calculus!");
    println!("To evaluate an expression, simply type one in and hit RETURN.");
    println!("To set a variable, simply type VAR_NAME=EXPRESSION and hit RETURN.");
    println!("Valid commands are: sym_int, int, sym_def, and def.");
    println!("Type 'quit' to exit.");
    let mut input = String::new();
    let stdin = io::stdin();
    let mut stdout = io::stdout();
    loop {
    	input.clear();
    	print!(">>>> ");
    	stdout.flush().ok();
        stdin.read_line(&mut input).unwrap();
        input = strip_white_space(&input);
        input = input.to_lowercase();
        if input == "quit" {
        	print!("Exiting...");
        	break;
        }
        let mut expr = parse_input(&input).unwrap();
        println!("{:?}", &expr);
    }
}

fn strip_white_space(input: &String) -> String {
	input.split_whitespace().collect::<Vec<&str>>().join("")
}

fn parse_input(input: &String) -> Result<Expression, ()> {
	let mut expr: Expression = Expression::new(Vec::new(), 0.0);
	for c in input.chars() {
		match c {
			'-' => {
				expr.push(Token::Op(Operator::Sub));
			},
			'+' => {
				expr.push(Token::Op(Operator::Add));
			},
			'/' => {
				expr.push(Token::Op(Operator::Div));
			},
			'*' => {
				expr.push(Token::Op(Operator::Mul));
			},
			'^' => {
				expr.push(Token::Op(Operator::Pow));
			},
			'(' => {
				expr.push(Token::Open);
			},
			')' => {
				expr.push(Token::Close);
			},
			_ => continue,
		}
	}
	if let Some(index) = expr.find_first(&Token::Open) { // If we find an index of an Open
		let end_set: usize = expr.find_last(&Token::Close).unwrap();
		let mut lhs: Vec<Token> = Vec::new();
		let mut rhs: Vec<Token> = Vec::new();
		{
			let (temp_lhs, temp_rhs) = expr.split_at(index); // [0, where set should be placed)
			lhs = temp_lhs.to_vec();
			rhs = temp_rhs.to_vec(); // [where set should be placed, len)
			rhs.remove(0);
			let (mut left_rhs, mut right_rhs) = rhs.split_at(end_set-2);
			let (mut left_rhs, mut right_rhs) = (left_rhs.to_vec(), right_rhs.to_vec());
			right_rhs.remove(0);
			lhs.push(Token::Set(left_rhs));
			lhs.append(&mut right_rhs);
		}
		for i in (0..lhs.len()).rev() {
			if lhs.get(i).unwrap() == &Token::Close {
				lhs.remove(i);
				break;
			}
		}
		expr.replace_all_tokens(lhs);
	}
	Ok(expr)
}<|endoftext|>


<commit_before>#[macro_use]
extern crate glium;
extern crate image;

use std::io::Cursor;
use std::collections::HashMap;
use glium::{DisplayBuild, Surface};

mod atlas;

#[derive(Copy, Clone)]
struct Vertex {
    position: [f32; 2],
    tex_coords: [f32; 2],
}

implement_vertex!(Vertex, position, tex_coords);

/// insert all atlas textures into vertices
/// returns attachment (name, index) defining 4 consecutive vertices
fn load_atlas(atlas_src: &str, width: u16, height: u16, vertices: &mut Vec<Vertex>)
    -> HashMap<String, u32>
{
    let (width, height) = (width as f32, height as f32);

    // helper closure to convert atlas texture coordinates into vertex texture's
    let to_tex_coords = |x: u16, y: u16| {
        let (x, y) = (x as f32, y as f32);
        [2.0 * x / width - 1.0, 1.0 - 2.0 * y / height]
    };

    // iterates over atlas textures and convert it to centered rectangle (4 vertices)
    let mut textures = HashMap::new();
    let mut n = shapes.len() as u32;
    for (name, t) in atlas::Atlas::from_file(atlas_src).into_iter() {
        let tex0 = to_tex_coords(t.xy.0,            t.xy.1 + t.size.1);
        let tex1 = to_tex_coords(t.xy.0 + t.size.0, t.xy.1 + t.size.1);
        let tex2 = to_tex_coords(t.xy.0 + t.size.0, t.xy.1);
        let tex3 = to_tex_coords(t.xy.0,            t.xy.1);
        // get 4 vertices defining rectangle texture, centered per default
        vertices.push(Vertex { pos: [0; 2], tex_coords: tex0 });
        vertices.push(Vertex { pos: [0; 2], tex_coords: tex1 });
        vertices.push(Vertex { pos: [0; 2], tex_coords: tex2 });
        vertices.push(Vertex { pos: [0; 2], tex_coords: tex3 });
        textures.insert(name, n);
        n += 4;
    }
    textures
}

fn draw_identity(texture_names: &HashMap<String, u32>, vertices: &mut Vec<Vertex>) -> Vec<u32> {

    let tex_to_pos = |t: &[f32; 2]| {
        [2.0 * t[0] - 1.0, 2.0 * t[1] - 1.0]
    };

    // Change all default position to texture position
    for &mut v in vertices {
        let pos = tex_to_pos(v.tex_coords);
        v.position = pos;
    }

    // build shapes by manipulating indices
    // show all shapes for now
    let mut indices = Vec::with_capacity(texture_names.len() * 6);
    for n in texture_names.values() {
        indices.extend([n, n + 1, n + 2, n + 2, n + 3, n].iter());
    }

    indices

}

fn main() {

    // TODO: parse program arguments
    let atlas_src = "/home/johann/projects/spine_render/spineboy.atlas";
    let atlas_img = "../spineboy.png";

    // prepare glium objects
    let image = image::load(Cursor::new(&include_bytes!(atlas_img)[..]), image::PNG).unwrap();
    let (width, height) = image.dimensions().expect("couldn't read texture dimension");
    let display = glium::glutin::WindowBuilder::new().build_glium().unwrap();
    let texture = glium::texture::Texture2d::new(&display, image).unwrap();

    // load textures
    let mut vertices: Vec<Vertex> = Vec::new();
    let texture_names = load_atlas(atlas_src, width, height, &mut vertices);

    // draw identity (for test)
    let indices = draw_identity(&texture_names, &mut vertices);

    let vertex_buffer = glium::VertexBuffer::new(&display, &vertices).unwrap();
    let indices = glium::IndexBuffer::new(&display,
                                          glium::index::PrimitiveType::TrianglesList,
                                          &indices).unwrap();

    // opengl vertex program
    let vertex_shader_src = r#"
        #version 140

        in vec2 position;
        in vec2 tex_coords;
        out vec2 v_tex_coords;
        uniform mat4 matrix;

        void main() {
            v_tex_coords = tex_coords;
            gl_Position = matrix * vec4(position, 0.0, 1.0);
        }
    "#;

    // opengl fragment program
    let fragment_shader_src = r#"
        #version 140

        in vec2 v_tex_coords;
        out vec4 color;
        uniform sampler2D tex;

        void main() {
            color = texture(tex, v_tex_coords);
        }
    "#;

    let program = glium::Program::from_source(&display,
                                              vertex_shader_src,
                                              fragment_shader_src,
                                              None).unwrap();

    let mut t = -0.5;

    loop {
        // we update `t`
        // t += 0.002;
        // if t > 0.5 {
        //     t = -0.5;
        // }

        let mut target = display.draw();
        target.clear_color(0.0, 0.0, 1.0, 0.0);

        let uniforms = uniform! {
            matrix: [
                [1.0, 0.0, 0.0, 0.0],
                [0.0, 1.0, 0.0, 0.0],
                [0.0, 0.0, 1.0, 0.0],
                [ t , 0.0, 0.0, 1.0f32],
            ],
            tex: &texture,
        };

        target.draw(&vertex_buffer, &indices, &program, &uniforms,
                    &Default::default()).unwrap();
        target.finish().unwrap();

        for ev in display.poll_events() {
            match ev {
                glium::glutin::Event::Closed => return,
                _ => ()
            }
        }
    }
}
<commit_msg>use run::start_loop<commit_after>#[macro_use]
extern crate glium;
extern crate image;

use std::io::Cursor;
use std::collections::HashMap;
use glium::{DisplayBuild, Surface};

mod atlas;
mod run; // loop.rs

#[derive(Copy, Clone)]
struct Vertex {
    position: [f32; 2],
    tex_coords: [f32; 2],
}

implement_vertex!(Vertex, position, tex_coords);

/// insert all atlas textures into vertices
/// returns attachment (name, index) defining 4 consecutive vertices
fn load_atlas(atlas_src: &str, width: u16, height: u16, vertices: &mut Vec<Vertex>)
    -> HashMap<String, u32>
{
    let (width, height) = (width as f32, height as f32);

    // helper closure to convert atlas texture coordinates into vertex texture's
    let to_tex_coords = |x: u16, y: u16| {
        let (x, y) = (x as f32, y as f32);
        [2.0 * x / width - 1.0, 1.0 - 2.0 * y / height]
    };

    // iterates over atlas textures and convert it to centered rectangle (4 vertices)
    let mut textures = HashMap::new();
    let mut n = shapes.len() as u32;
    for (name, t) in atlas::Atlas::from_file(atlas_src).into_iter() {
        let tex0 = to_tex_coords(t.xy.0,            t.xy.1 + t.size.1);
        let tex1 = to_tex_coords(t.xy.0 + t.size.0, t.xy.1 + t.size.1);
        let tex2 = to_tex_coords(t.xy.0 + t.size.0, t.xy.1);
        let tex3 = to_tex_coords(t.xy.0,            t.xy.1);
        // get 4 vertices defining rectangle texture, centered per default
        vertices.push(Vertex { pos: [0; 2], tex_coords: tex0 });
        vertices.push(Vertex { pos: [0; 2], tex_coords: tex1 });
        vertices.push(Vertex { pos: [0; 2], tex_coords: tex2 });
        vertices.push(Vertex { pos: [0; 2], tex_coords: tex3 });
        textures.insert(name, n);
        n += 4;
    }
    textures
}

fn draw_identity(texture_names: &HashMap<String, u32>, vertices: &mut Vec<Vertex>) -> Vec<u32> {

    let tex_to_pos = |t: &[f32; 2]| {
        [2.0 * t[0] - 1.0, 2.0 * t[1] - 1.0]
    };

    // Change all default position to texture position
    for &mut v in vertices {
        let pos = tex_to_pos(v.tex_coords);
        v.position = pos;
    }

    // build shapes by manipulating indices
    // show all shapes for now
    let mut indices = Vec::with_capacity(texture_names.len() * 6);
    for n in texture_names.values() {
        indices.extend([n, n + 1, n + 2, n + 2, n + 3, n].iter());
    }

    indices

}

fn main() {

    // TODO: parse program arguments
    let atlas_src = "/home/johann/projects/spine_render/spineboy.atlas";
    let atlas_img = "../spineboy.png";

    // prepare glium objects
    let image = image::load(Cursor::new(&include_bytes!(atlas_img)[..]), image::PNG).unwrap();
    let (width, height) = image.dimensions().expect("couldn't read texture dimension");
    let display = glium::glutin::WindowBuilder::new().build_glium().unwrap();
    let texture = glium::texture::Texture2d::new(&display, image).unwrap();

    // load textures
    let mut vertices: Vec<Vertex> = Vec::new();
    let texture_names = load_atlas(atlas_src, width, height, &mut vertices);

    // draw identity (for test)
    let indices = draw_identity(&texture_names, &mut vertices);

    let vertex_buffer = glium::VertexBuffer::new(&display, &vertices).unwrap();
    let indices = glium::IndexBuffer::new(&display,
                                          glium::index::PrimitiveType::TrianglesList,
                                          &indices).unwrap();

    // opengl vertex program
    let vertex_shader_src = r#"
        #version 140

        in vec2 position;
        in vec2 tex_coords;
        out vec2 v_tex_coords;
        uniform mat4 matrix;

        void main() {
            v_tex_coords = tex_coords;
            gl_Position = matrix * vec4(position, 0.0, 1.0);
        }
    "#;

    // opengl fragment program
    let fragment_shader_src = r#"
        #version 140

        in vec2 v_tex_coords;
        out vec4 color;
        uniform sampler2D tex;

        void main() {
            color = texture(tex, v_tex_coords);
        }
    "#;

    let program = glium::Program::from_source(&display,
                                              vertex_shader_src,
                                              fragment_shader_src,
                                              None).unwrap();

    let mut t = -0.5;

    // the main loop, supposed to run with a constant FPS
    run::start_loop(|| {

        // we update `t`
        // t += 0.002;
        // if t > 0.5 {
        //     t = -0.5;
        // }

        let mut target = display.draw();
        target.clear_color(0.0, 0.0, 1.0, 0.0);

        let uniforms = uniform! {
            matrix: [
                [1.0, 0.0, 0.0, 0.0],
                [0.0, 1.0, 0.0, 0.0],
                [0.0, 0.0, 1.0, 0.0],
                [ t , 0.0, 0.0, 1.0f32],
            ],
            tex: &texture,
        };

        target.draw(&vertex_buffer, &indices, &program, &uniforms,
                    &Default::default()).unwrap();
        target.finish().unwrap();

        for ev in display.poll_events() {
            match ev {
                glium::glutin::Event::Closed => return,
                _ => ()
            }
        }

        support::Action::Continue
    });
}
<|endoftext|>


<commit_before>#![feature(conservative_impl_trait)]

extern crate cgmath;
extern crate png;

use std::fs::File;

use cgmath::prelude::*;
use cgmath::vec3;
use png::HasParameters;

use camera::Camera;
use light::Light;
use material::Material;
use math::*;
use primitive::Primitive;
use raytracer::Raytracer;
use scene::Scene;
use texture::checkerboard;

mod camera;
mod color;
mod intersection;
mod light;
mod material;
#[macro_use] mod math;
mod primitive;
mod ray;
mod raytracer;
mod scene;
mod texture;

fn main() {
    let raytracer = Raytracer {
        scene: example_scene(),
        camera: Camera::new(Point::zero(), Vector::unit_z(), 90.0f32.to_radians()),
    };

    let (w, h) = (512, 512);
    let mut output_data = Vec::with_capacity(w * h);
    for y in 0 .. h {
        for x in 0 .. w {
            let screen_coords = (x as f32 / w as f32, y as f32 / h as f32);
            let ray = raytracer.camera.primary_ray(screen_coords);
            let result = raytracer.trace(ray, 1);

            let (r, g, b) = result.color.as_bytes();
            output_data.push(r);
            output_data.push(g);
            output_data.push(b);
        }
    }

    // TODO: add command line options to configure this.
    let mut output = File::create("output.png").expect("Couldn't create output file.");

    let mut encoder = png::Encoder::new(output, w as u32, h as u32);
    encoder.set(png::ColorType::RGB).set(png::BitDepth::Eight);
    encoder.write_header()
        .unwrap()
        .write_image_data(&output_data)
        .unwrap();
}

fn example_scene() -> Scene {
    let mut scene = Scene::new(vec3(0.05, 0.05, 0.10).into());

    scene.add_primitive(
        Primitive::plane(
            Material::solid(
                checkerboard(color!(1.0), color!(0.0), (0.5, 0.5)),
                1.0,
            ),
            vec3(0.0, -1.0, 0.0),
            Vector::unit_y(),
        )
    );

    scene.add_primitive(
        Primitive::sphere(
            Material::solid(color!(1.0, 0.0, 0.0), 1.0),
            vec3(0.0, 0.0, 2.0),
            1.0,
        )
    );

    scene.add_light(
        Light::point(vec3(1.5, 1.5, 1.5).into(), vec3(0.0, 1.0, 0.5)),
    );

    scene
}
<commit_msg>Remove an unnecessary `mut`<commit_after>#![feature(conservative_impl_trait)]

extern crate cgmath;
extern crate png;

use std::fs::File;

use cgmath::prelude::*;
use cgmath::vec3;
use png::HasParameters;

use camera::Camera;
use light::Light;
use material::Material;
use math::*;
use primitive::Primitive;
use raytracer::Raytracer;
use scene::Scene;
use texture::checkerboard;

mod camera;
mod color;
mod intersection;
mod light;
mod material;
#[macro_use] mod math;
mod primitive;
mod ray;
mod raytracer;
mod scene;
mod texture;

fn main() {
    let raytracer = Raytracer {
        scene: example_scene(),
        camera: Camera::new(Point::zero(), Vector::unit_z(), 90.0f32.to_radians()),
    };

    let (w, h) = (512, 512);
    let mut output_data = Vec::with_capacity(w * h);
    for y in 0 .. h {
        for x in 0 .. w {
            let screen_coords = (x as f32 / w as f32, y as f32 / h as f32);
            let ray = raytracer.camera.primary_ray(screen_coords);
            let result = raytracer.trace(ray, 1);

            let (r, g, b) = result.color.as_bytes();
            output_data.push(r);
            output_data.push(g);
            output_data.push(b);
        }
    }

    // TODO: add command line options to configure this.
    let output = File::create("output.png").expect("Couldn't create output file.");

    let mut encoder = png::Encoder::new(output, w as u32, h as u32);
    encoder.set(png::ColorType::RGB).set(png::BitDepth::Eight);
    encoder.write_header()
        .unwrap()
        .write_image_data(&output_data)
        .unwrap();
}

fn example_scene() -> Scene {
    let mut scene = Scene::new(vec3(0.05, 0.05, 0.10).into());

    scene.add_primitive(
        Primitive::plane(
            Material::solid(
                checkerboard(color!(1.0), color!(0.0), (0.5, 0.5)),
                1.0,
            ),
            vec3(0.0, -1.0, 0.0),
            Vector::unit_y(),
        )
    );

    scene.add_primitive(
        Primitive::sphere(
            Material::solid(color!(1.0, 0.0, 0.0), 1.0),
            vec3(0.0, 0.0, 2.0),
            1.0,
        )
    );

    scene.add_light(
        Light::point(vec3(1.5, 1.5, 1.5).into(), vec3(0.0, 1.0, 0.5)),
    );

    scene
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! # Cap'n Proto Schema Compiler Plugin Executable
//!
//! [See this.](http://kentonv.github.io/capnproto/otherlang.html#how-to-write-compiler-plugins)
//!
//!

#![crate_name="capnpc-rust"]
#![crate_type = "bin"]
#![feature(io, os)]

extern crate capnp;
extern crate capnpc;

pub fn main() {
    //! Generate Rust code according to a `schema_capnp::code_generator_request` read from stdin.

    match ::capnpc::codegen::main(&mut ::std::old_io::stdin()) {
        Ok(()) => {}
        Err(e) => {
            std::os::set_exit_status(1);
            println!("error: {}", e)
        }
    }
}
<commit_msg>one more os -> env<commit_after>// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! # Cap'n Proto Schema Compiler Plugin Executable
//!
//! [See this.](http://kentonv.github.io/capnproto/otherlang.html#how-to-write-compiler-plugins)
//!
//!

#![crate_name="capnpc-rust"]
#![crate_type = "bin"]
#![feature(io, env)]

extern crate capnp;
extern crate capnpc;

pub fn main() {
    //! Generate Rust code according to a `schema_capnp::code_generator_request` read from stdin.

    match ::capnpc::codegen::main(&mut ::std::old_io::stdin()) {
        Ok(()) => {}
        Err(e) => {
            std::env::set_exit_status(1);
            println!("error: {}", e)
        }
    }
}
<|endoftext|>