<commit_before>use std::env;
use std::fs::File;
use std::io::Read;
extern crate syn;
use syn::*;

fn has_no_mangle(attrs: &Vec<Attribute>) -> bool {
    for attr in attrs {
        if let syn::MetaItem::Word(ref ident) = attr.value {
            if ident == "no_mangle" {
                return true;
            }
        }
    }
    false
}

fn map_path(p: &Path) -> String {
    let l = p.segments[0].ident.to_string();
    match l.as_ref() {
        "usize" => "size_t".to_string(),
        "u8" => "uint8_t".to_string(),
        "u32" => "uint32_t".to_string(),
        "f32" => "float".to_string(),
        _ => l
    }
}

fn map_mut_ty(mut_ty: &MutTy) -> String {
    map_ty(&mut_ty.ty)
}

fn map_ty(ty: &Ty) -> String {
    match ty {
        &Ty::Path(_, ref p) => {
            map_path(p)
        },
        &Ty::Ptr(ref p) => {
            format!("{}*", map_ty(&p.ty))
        },
        &Ty::Rptr(_, ref mut_ty) => {
            format!("{}*", map_mut_ty(mut_ty))
        }
        _ => format!("unknown {:?}", ty)
    }

}

fn map_return_type(ret: &FunctionRetTy) -> String
{
    match ret {
        &FunctionRetTy::Default => "void".to_string(),
        &FunctionRetTy::Ty(ref ty) => {
            map_ty(ty)
        }
    }
}

fn map_pat(pat: &Pat) -> String {
    match pat {
        &Pat::Ident(_, ref ident, _) => {
            ident.to_string()
        },
        _ => { format!("unknown {:?}", pat) }
    }

}

fn map_arg(f: &FnArg) -> String {
    match f {
        &FnArg::Captured(ref pat, ref ty) => {
            format!("{} {}", map_ty(ty), map_pat(pat))
        }
        _ => { "unknown".to_string() }
    }
}

fn main() {
    let p = env::args().nth(1).unwrap();
    let mut s = String::new();
    let mut f = File::open(p).unwrap();
    f.read_to_string(&mut s).unwrap();
    let krate = syn::parse_crate(&s).unwrap();
    for item in krate.items {
        match item.node {
            ItemKind::Fn(decl, ..) => {
                if has_no_mangle(&item.attrs) {
                    println!("{} {}({})", map_return_type(&decl.output), item.ident, decl.inputs.iter().map(map_arg).collect::<Vec<_>>().join(", "));
                }
            }
            _ => {}
        }
    }

}
<commit_msg>Refactor has_no_mangle to make it easier to match repr(C) which we'll need later<commit_after>use std::env;
use std::fs::File;
use std::io::Read;
extern crate syn;
use syn::*;

fn has_attribute(target: MetaItem, attrs: &Vec<Attribute>) -> bool {
    return attrs.iter().any(|ref attr| {
        attr.style == AttrStyle::Outer &&
        attr.value == target
    });
}

fn has_no_mangle(attrs: &Vec<Attribute>) -> bool {
    has_attribute(MetaItem::Word(Ident::new("no_mangle")), attrs)
}

fn map_path(p: &Path) -> String {
    let l = p.segments[0].ident.to_string();
    match l.as_ref() {
        "usize" => "size_t".to_string(),
        "u8" => "uint8_t".to_string(),
        "u32" => "uint32_t".to_string(),
        "f32" => "float".to_string(),
        _ => l
    }
}

fn map_mut_ty(mut_ty: &MutTy) -> String {
    map_ty(&mut_ty.ty)
}

fn map_ty(ty: &Ty) -> String {
    match ty {
        &Ty::Path(_, ref p) => {
            map_path(p)
        },
        &Ty::Ptr(ref p) => {
            format!("{}*", map_ty(&p.ty))
        },
        &Ty::Rptr(_, ref mut_ty) => {
            format!("{}*", map_mut_ty(mut_ty))
        }
        _ => format!("unknown {:?}", ty)
    }

}

fn map_return_type(ret: &FunctionRetTy) -> String
{
    match ret {
        &FunctionRetTy::Default => "void".to_string(),
        &FunctionRetTy::Ty(ref ty) => {
            map_ty(ty)
        }
    }
}

fn map_pat(pat: &Pat) -> String {
    match pat {
        &Pat::Ident(_, ref ident, _) => {
            ident.to_string()
        },
        _ => { format!("unknown {:?}", pat) }
    }

}

fn map_arg(f: &FnArg) -> String {
    match f {
        &FnArg::Captured(ref pat, ref ty) => {
            format!("{} {}", map_ty(ty), map_pat(pat))
        }
        _ => { "unknown".to_string() }
    }
}

fn main() {
    let p = env::args().nth(1).unwrap();
    let mut s = String::new();
    let mut f = File::open(p).unwrap();
    f.read_to_string(&mut s).unwrap();
    let krate = syn::parse_crate(&s).unwrap();
    for item in krate.items {
        match item.node {
            ItemKind::Fn(decl, ..) => {
                if has_no_mangle(&item.attrs) {
                    println!("{} {}({})", map_return_type(&decl.output), item.ident, decl.inputs.iter().map(map_arg).collect::<Vec<_>>().join(", "));
                }
            }
            _ => {}
        }
    }

}
<|endoftext|>


<commit_before>extern crate getopts;

mod diff;
mod buffer;

use std::io;
use std::io::Write;
use std::env;
use getopts::Options;

static CurrentAddress: Address = Address::Nth(1);

#[derive(Clone)]
struct Range {
    start: Box<Address>,
    end: Box<Address>,
}

#[derive(Clone)]
enum Address {
    Current,
    Last,
    Nth(i32),
    Previous,
    NthPrevious(i32),
    Next,
    NthNext(i32),
    All,
    Range(Range),
    CurrentToEnd,
    RENext(String),
    REPrevious(String),
    Mark(String),
}

fn append_after(addr: Address, diff: &diff::Diff) -> Result<diff::Diff, String> {
    let line_num: i32 = match addr {
        Address::Nth(ln) => ln,
        _ => 0,
    };
    input()
        .map_err(|err| err.to_string())
        .map(|lines| {
            diff.add_lines(line_num, lines)
        })
}

fn undo(addr: Address, diff: &diff::Diff) -> Result<diff::Diff, String> {
    Ok(diff.undo())
}

fn quit(addr: Address, diff: &diff::Diff) -> Result<diff::Diff, String> {
    std::process::exit(0);
    Err("Should never get here".to_string())
}

fn print(addr: Address, diff: &diff::Diff) -> Result<diff::Diff, String> {
    let fb = buffer::FileBuffer::new(diff.clone(), buffer::BufferFile::NoneGiven);
    match fb.lines() {
        Ok(lines) => {
            for line in lines {
                println!("{}", line);
            }
            Ok(diff.clone())
        },
        Err(err) => Err(err.to_string()),
    }
}

struct Command {
    address: Address,
    operation: fn(Address, &diff::Diff) -> Result<diff::Diff, String>,
}

fn input() -> Result<Vec<String>, io::Error> {
    let mut lines: Vec<String> = Vec::new();
    loop {
        let mut line = String::new();
        match io::stdin().read_line(&mut line) {
            Err(error) => return Err(error),
            Ok(_) => {},
        }
        match line.trim() {
            "." => {
                break
            },
            _ => {
                lines.push(line)
            }
        }
    }
    Ok(lines)
}

fn parse_cmd(line: &String) -> Result<Command, String> {
    let mut command = Command {
        address: CurrentAddress.clone(),
        operation: match line.trim() {
            "a" => append_after,
            "q" => quit,
            "u" => undo,
            "p" => print,
            _ => {
                return Err("Uknown command".to_string())
            },
        }
    };
    Ok(command)
}

fn command(line: &String, diff: &diff::Diff) -> Result<diff::Diff, String> {
    parse_cmd(line)
        .map_err(|err| err.to_string())
        .and_then(|cmd| {
            (cmd.operation)(cmd.address, diff)
        })
}

fn cmd_line(prompt: &String) -> Result<String, String> {
    let mut line = String::new();
    print!("{}", prompt);
    io::stdout().flush()
        .map_err(|err| err.to_string())
        .and_then(|_| {
            io::stdin().read_line(&mut line)
                .map_err(|err| err.to_string())
        })
        .and_then(|_| Ok(line))
}

fn main() {
    let args: Vec<String> = env::args().collect();

    let mut opts = Options::new();
    opts.optopt("p", "prompt", "prompt to show while in command mode", "PROMPT");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(f) => panic!(f.to_string())
    };

    let prompt = matches.opt_str("p")
        .unwrap_or_else(|| "".to_string());
    let mut diff = diff::Diff::new();
    loop {
        match cmd_line(&prompt)
            .map_err(|err| err.to_string())
            .and_then(|line| command(&line, &diff)) {
                Ok(d) => diff = d,
                Err(err) => println!("{}", err),
            }
    }
}
<commit_msg>Use print instead of println because too many newlines<commit_after>extern crate getopts;

mod diff;
mod buffer;

use std::io;
use std::io::Write;
use std::env;
use getopts::Options;

static CurrentAddress: Address = Address::Nth(1);

#[derive(Clone)]
struct Range {
    start: Box<Address>,
    end: Box<Address>,
}

#[derive(Clone)]
enum Address {
    Current,
    Last,
    Nth(i32),
    Previous,
    NthPrevious(i32),
    Next,
    NthNext(i32),
    All,
    Range(Range),
    CurrentToEnd,
    RENext(String),
    REPrevious(String),
    Mark(String),
}

fn append_after(addr: Address, diff: &diff::Diff) -> Result<diff::Diff, String> {
    let line_num: i32 = match addr {
        Address::Nth(ln) => ln,
        _ => 0,
    };
    input()
        .map_err(|err| err.to_string())
        .map(|lines| {
            diff.add_lines(line_num, lines)
        })
}

fn undo(addr: Address, diff: &diff::Diff) -> Result<diff::Diff, String> {
    Ok(diff.undo())
}

fn quit(addr: Address, diff: &diff::Diff) -> Result<diff::Diff, String> {
    std::process::exit(0);
    Err("Should never get here".to_string())
}

fn print(addr: Address, diff: &diff::Diff) -> Result<diff::Diff, String> {
    let fb = buffer::FileBuffer::new(diff.clone(), buffer::BufferFile::NoneGiven);
    match fb.lines() {
        Ok(lines) => {
            for line in lines {
                print!("{}", line);
            }
            io::stdout().flush().unwrap();
            Ok(diff.clone())
        },
        Err(err) => Err(err.to_string()),
    }
}

struct Command {
    address: Address,
    operation: fn(Address, &diff::Diff) -> Result<diff::Diff, String>,
}

fn input() -> Result<Vec<String>, io::Error> {
    let mut lines: Vec<String> = Vec::new();
    loop {
        let mut line = String::new();
        match io::stdin().read_line(&mut line) {
            Err(error) => return Err(error),
            Ok(_) => {},
        }
        match line.trim() {
            "." => {
                break
            },
            _ => {
                lines.push(line)
            }
        }
    }
    Ok(lines)
}

fn parse_cmd(line: &String) -> Result<Command, String> {
    let mut command = Command {
        address: CurrentAddress.clone(),
        operation: match line.trim() {
            "a" => append_after,
            "q" => quit,
            "u" => undo,
            "p" => print,
            _ => {
                return Err("Uknown command".to_string())
            },
        }
    };
    Ok(command)
}

fn command(line: &String, diff: &diff::Diff) -> Result<diff::Diff, String> {
    parse_cmd(line)
        .map_err(|err| err.to_string())
        .and_then(|cmd| {
            (cmd.operation)(cmd.address, diff)
        })
}

fn cmd_line(prompt: &String) -> Result<String, String> {
    let mut line = String::new();
    print!("{}", prompt);
    io::stdout().flush()
        .map_err(|err| err.to_string())
        .and_then(|_| {
            io::stdin().read_line(&mut line)
                .map_err(|err| err.to_string())
        })
        .and_then(|_| Ok(line))
}

fn main() {
    let args: Vec<String> = env::args().collect();

    let mut opts = Options::new();
    opts.optopt("p", "prompt", "prompt to show while in command mode", "PROMPT");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(f) => panic!(f.to_string())
    };

    let prompt = matches.opt_str("p")
        .unwrap_or_else(|| "".to_string());
    let mut diff = diff::Diff::new();
    loop {
        match cmd_line(&prompt)
            .map_err(|err| err.to_string())
            .and_then(|line| command(&line, &diff)) {
                Ok(d) => diff = d,
                Err(err) => println!("{}", err),
            }
    }
}
<|endoftext|>


<commit_before>extern crate serde;
extern crate serde_json;
#[macro_use] extern crate serde_derive;
#[macro_use] extern crate exonum;
extern crate router;
extern crate bodyparser;
extern crate iron;

use exonum::blockchain::{self, Blockchain, Service, GenesisConfig, ValidatorKeys, Transaction, ApiContext};
use exonum::messages::{RawTransaction, FromRaw, Message};
use exonum::node::{Node, NodeConfig, NodeApiConfig, TransactionSend, TxSender, NodeChannel};
use exonum::storage::{Fork, MemoryDB, MapIndex};
use exonum::crypto::{PublicKey, Hash};
use exonum::encoding::{self, Field};
use exonum::api::{Api, ApiError};
use iron::prelude::*;
use iron::Handler;
use router::Router;

// // // // // // // // // // PERSISTENT DATA // // // // // // // // // //

encoding_struct! {
    struct Wallet {
        const SIZE = 48;

        field pub_key:            &PublicKey  [00 => 32]
        field name:               &str        [32 => 40]
        field balance:            u64         [40 => 48]
    }
}

impl Wallet {
    pub fn increase(&mut self, amount: u64) {
        let balance = self.balance() + amount;
        Field::write(&balance, &mut self.raw, 40, 48);
    }

    pub fn decrease(&mut self, amount: u64) {
        let balance = self.balance() - amount;
        Field::write(&balance, &mut self.raw, 40, 48);
    }
}

// // // // // // // // // // TRANSACTIONS // // // // // // // // // //

pub const TX_CREATE_WALLET_ID: u16 = 1;

message! {
    struct TxCreateWallet {
        const TYPE = SERVICE_ID;
        const ID = TX_CREATE_WALLET_ID;
        const SIZE = 40;

        field pub_key:     &PublicKey  [00 => 32]
        field name:        &str        [32 => 40]
    }
}

pub const TX_TRANSFER_ID: u16 = 2;

message! {
    struct TxTransfer {
        const TYPE = SERVICE_ID;
        const ID = TX_TRANSFER_ID;
        const SIZE = 80;

        field from:        &PublicKey  [00 => 32]
        field to:          &PublicKey  [32 => 64]
        field amount:      u64         [64 => 72]
        field seed:        u64         [72 => 80]
    }
}

// // // // // // // // // // CONTRACTS // // // // // // // // // //

const INIT_BALANCE: u64 = 100;

impl Transaction for TxCreateWallet {
    fn verify(&self) -> bool {
        self.verify_signature(self.pub_key())
    }

    fn execute(&self, view: &mut Fork) {
        let mut schema = CurrencySchema { view };
        if let None = schema.wallet(self.pub_key()) {
            let wallet = Wallet::new(self.pub_key(), self.name(), INIT_BALANCE);
            println!("Create the wallet: {:?}", wallet);
            schema.wallets().put(self.pub_key(), wallet)
        }
    }
}

impl Transaction for TxTransfer {
    fn verify(&self) -> bool {
        (*self.from() != *self.to()) && self.verify_signature(self.from())
    }

    fn execute(&self, view: &mut Fork) {
        let mut schema = CurrencySchema { view };
        let sender = schema.wallet(self.from());
        let receiver = schema.wallet(self.to());
        if let (Some(mut sender), Some(mut receiver)) = (sender, receiver) {
            let amount = self.amount();
            if sender.balance() >= amount {
                sender.decrease(amount);
                receiver.increase(amount);
                println!("Transfer between wallets: {:?} => {:?}", sender, receiver);
                let mut wallets = schema.wallets();
                wallets.put(self.from(), sender);
                wallets.put(self.to(), receiver);
            }
        }
    }
}

// // // // // // // // // // REST API // // // // // // // // // //

#[derive(Clone)]
struct CryptocurrencyApi {
    channel: TxSender<NodeChannel>,
}

impl Api for CryptocurrencyApi {
    fn wire(&self, router: &mut Router) {

        #[serde(untagged)]
        #[derive(Clone, Serialize, Deserialize)]
        enum TransactionRequest {
            CreateWallet(TxCreateWallet),
            Transfer(TxTransfer),
        }

        impl Into<Box<Transaction>> for TransactionRequest {
            fn into(self) -> Box<Transaction> {
                match self {
                    TransactionRequest::CreateWallet(trans) => Box::new(trans),
                    TransactionRequest::Transfer(trans) => Box::new(trans),
                }
            }
        }

        #[derive(Serialize, Deserialize)]
        struct TransactionResponse {
            tx_hash: Hash,
        }

        let self_ = self.clone();
        let transaction = move |req: &mut Request| -> IronResult<Response> {
            match req.get::<bodyparser::Struct<TransactionRequest>>() {
                Ok(Some(transaction)) => {
                    let transaction: Box<Transaction> = transaction.into();
                    let tx_hash = transaction.hash();
                    self_.channel.send(transaction).map_err(|e| ApiError::Events(e))?;
                    let json = TransactionResponse { tx_hash };
                    self_.ok_response(&serde_json::to_value(&json).unwrap())
                }
                Ok(None) => Err(ApiError::IncorrectRequest("Empty request body".into()))?,
                Err(e) => Err(ApiError::IncorrectRequest(Box::new(e)))?,
            }
        };
        let route_post = "/v1/wallets/transaction";
        router.post(&route_post, transaction, "transaction");
    }
}

// // // // // // // // // // STORAGE DATA LAYOUT // // // // // // // // // //

pub struct CurrencySchema<'a> {
    view: &'a mut Fork,
}

impl<'a> CurrencySchema<'a> {
    pub fn wallets(&mut self) -> MapIndex<&mut Fork, PublicKey, Wallet> {
        let prefix = blockchain::gen_prefix(SERVICE_ID, 0, &());
        MapIndex::new(prefix, self.view)
    }

    pub fn wallet(&mut self, pub_key: &PublicKey) -> Option<Wallet> {
        self.wallets().get(pub_key)
    }
}

// // // // // // // // // // SERVICE DECLARATION // // // // // // // // // //

pub const SERVICE_ID: u16 = 1;

struct CurrencyService;

impl Service for CurrencyService {
    fn service_name(&self) -> &'static str { "cryptocurrency" }

    fn service_id(&self) -> u16 { SERVICE_ID }

    fn tx_from_raw(&self, raw: RawTransaction) -> Result<Box<Transaction>, encoding::Error> {
        let trans: Box<Transaction> = match raw.message_type() {
            TX_TRANSFER_ID => Box::new(TxTransfer::from_raw(raw)?),
            TX_CREATE_WALLET_ID => Box::new(TxCreateWallet::from_raw(raw)?),
            _ => {
                return Err(encoding::Error::IncorrectMessageType { message_type: raw.message_type() });
            },
        };
        Ok(trans)
    }

    fn public_api_handler(&self, ctx: &ApiContext) -> Option<Box<Handler>> {
        let mut router = Router::new();
        let api = CryptocurrencyApi {
            channel: ctx.node_channel().clone(),
        };
        api.wire(&mut router);
        Some(Box::new(router))
    }
}

// // // // // // // // // // ENTRY POINT // // // // // // // // // //

fn main() {
    exonum::helpers::init_logger().unwrap();

    println!("Creating in-memory database...");
    let db = MemoryDB::new();
    let services: Vec<Box<Service>> = vec![
        Box::new(CurrencyService),
    ];
    let blockchain = Blockchain::new(Box::new(db), services);

    let (consensus_public_key, consensus_secret_key) = exonum::crypto::gen_keypair();
    let (service_public_key, service_secret_key) = exonum::crypto::gen_keypair();

    let peer_address = "0.0.0.0:2000".parse().unwrap();
    let api_address = "0.0.0.0:8000".parse().unwrap();

    let validator_keys = ValidatorKeys {
        consensus_key: consensus_public_key,
        service_key: service_public_key,
    };
    let genesis = GenesisConfig::new(vec![validator_keys].into_iter());

    let api_cfg = NodeApiConfig {
        enable_blockchain_explorer: true,
        public_api_address: Some(api_address),
        private_api_address: None,
    };

    let node_cfg = NodeConfig {
        listen_address: peer_address,
        peers: vec![],
        service_public_key,
        service_secret_key,
        consensus_public_key,
        consensus_secret_key,
        genesis,
        external_address: None,
        network: Default::default(),
        whitelist: Default::default(),
        api: api_cfg,
        mempool: Default::default(),
        services_configs: Default::default(),
    };

    println!("Starting a single node...");
    let mut node = Node::new(blockchain, node_cfg);

    println!("Blockchain in ready for transactions!");
    node.run().unwrap();
}
<commit_msg>Move consts to a separated section<commit_after>extern crate serde;
extern crate serde_json;
#[macro_use] extern crate serde_derive;
#[macro_use] extern crate exonum;
extern crate router;
extern crate bodyparser;
extern crate iron;

use exonum::blockchain::{self, Blockchain, Service, GenesisConfig, ValidatorKeys, Transaction, ApiContext};
use exonum::messages::{RawTransaction, FromRaw, Message};
use exonum::node::{Node, NodeConfig, NodeApiConfig, TransactionSend, TxSender, NodeChannel};
use exonum::storage::{Fork, MemoryDB, MapIndex};
use exonum::crypto::{PublicKey, Hash};
use exonum::encoding::{self, Field};
use exonum::api::{Api, ApiError};
use iron::prelude::*;
use iron::Handler;
use router::Router;

// // // // // // // // // // CONSTANTS // // // // // // // // // //

const SERVICE_ID: u16 = 1;

const TX_CREATE_WALLET_ID: u16 = 1;

const TX_TRANSFER_ID: u16 = 2;

const INIT_BALANCE: u64 = 100;

// // // // // // // // // // PERSISTENT DATA // // // // // // // // // //

encoding_struct! {
    struct Wallet {
        const SIZE = 48;

        field pub_key:            &PublicKey  [00 => 32]
        field name:               &str        [32 => 40]
        field balance:            u64         [40 => 48]
    }
}

impl Wallet {
    pub fn increase(&mut self, amount: u64) {
        let balance = self.balance() + amount;
        Field::write(&balance, &mut self.raw, 40, 48);
    }

    pub fn decrease(&mut self, amount: u64) {
        let balance = self.balance() - amount;
        Field::write(&balance, &mut self.raw, 40, 48);
    }
}

// // // // // // // // // // TRANSACTIONS // // // // // // // // // //

message! {
    struct TxCreateWallet {
        const TYPE = SERVICE_ID;
        const ID = TX_CREATE_WALLET_ID;
        const SIZE = 40;

        field pub_key:     &PublicKey  [00 => 32]
        field name:        &str        [32 => 40]
    }
}

message! {
    struct TxTransfer {
        const TYPE = SERVICE_ID;
        const ID = TX_TRANSFER_ID;
        const SIZE = 80;

        field from:        &PublicKey  [00 => 32]
        field to:          &PublicKey  [32 => 64]
        field amount:      u64         [64 => 72]
        field seed:        u64         [72 => 80]
    }
}

// // // // // // // // // // CONTRACTS // // // // // // // // // //

impl Transaction for TxCreateWallet {
    fn verify(&self) -> bool {
        self.verify_signature(self.pub_key())
    }

    fn execute(&self, view: &mut Fork) {
        let mut schema = CurrencySchema { view };
        if let None = schema.wallet(self.pub_key()) {
            let wallet = Wallet::new(self.pub_key(), self.name(), INIT_BALANCE);
            println!("Create the wallet: {:?}", wallet);
            schema.wallets().put(self.pub_key(), wallet)
        }
    }
}

impl Transaction for TxTransfer {
    fn verify(&self) -> bool {
        (*self.from() != *self.to()) && self.verify_signature(self.from())
    }

    fn execute(&self, view: &mut Fork) {
        let mut schema = CurrencySchema { view };
        let sender = schema.wallet(self.from());
        let receiver = schema.wallet(self.to());
        if let (Some(mut sender), Some(mut receiver)) = (sender, receiver) {
            let amount = self.amount();
            if sender.balance() >= amount {
                sender.decrease(amount);
                receiver.increase(amount);
                println!("Transfer between wallets: {:?} => {:?}", sender, receiver);
                let mut wallets = schema.wallets();
                wallets.put(self.from(), sender);
                wallets.put(self.to(), receiver);
            }
        }
    }
}

// // // // // // // // // // REST API // // // // // // // // // //

#[derive(Clone)]
struct CryptocurrencyApi {
    channel: TxSender<NodeChannel>,
}

impl Api for CryptocurrencyApi {
    fn wire(&self, router: &mut Router) {

        #[serde(untagged)]
        #[derive(Clone, Serialize, Deserialize)]
        enum TransactionRequest {
            CreateWallet(TxCreateWallet),
            Transfer(TxTransfer),
        }

        impl Into<Box<Transaction>> for TransactionRequest {
            fn into(self) -> Box<Transaction> {
                match self {
                    TransactionRequest::CreateWallet(trans) => Box::new(trans),
                    TransactionRequest::Transfer(trans) => Box::new(trans),
                }
            }
        }

        #[derive(Serialize, Deserialize)]
        struct TransactionResponse {
            tx_hash: Hash,
        }

        let self_ = self.clone();
        let transaction = move |req: &mut Request| -> IronResult<Response> {
            match req.get::<bodyparser::Struct<TransactionRequest>>() {
                Ok(Some(transaction)) => {
                    let transaction: Box<Transaction> = transaction.into();
                    let tx_hash = transaction.hash();
                    self_.channel.send(transaction).map_err(|e| ApiError::Events(e))?;
                    let json = TransactionResponse { tx_hash };
                    self_.ok_response(&serde_json::to_value(&json).unwrap())
                }
                Ok(None) => Err(ApiError::IncorrectRequest("Empty request body".into()))?,
                Err(e) => Err(ApiError::IncorrectRequest(Box::new(e)))?,
            }
        };
        let route_post = "/v1/wallets/transaction";
        router.post(&route_post, transaction, "transaction");
    }
}

// // // // // // // // // // STORAGE DATA LAYOUT // // // // // // // // // //

pub struct CurrencySchema<'a> {
    view: &'a mut Fork,
}

impl<'a> CurrencySchema<'a> {
    pub fn wallets(&mut self) -> MapIndex<&mut Fork, PublicKey, Wallet> {
        let prefix = blockchain::gen_prefix(SERVICE_ID, 0, &());
        MapIndex::new(prefix, self.view)
    }

    pub fn wallet(&mut self, pub_key: &PublicKey) -> Option<Wallet> {
        self.wallets().get(pub_key)
    }
}

// // // // // // // // // // SERVICE DECLARATION // // // // // // // // // //

struct CurrencyService;

impl Service for CurrencyService {
    fn service_name(&self) -> &'static str { "cryptocurrency" }

    fn service_id(&self) -> u16 { SERVICE_ID }

    fn tx_from_raw(&self, raw: RawTransaction) -> Result<Box<Transaction>, encoding::Error> {
        let trans: Box<Transaction> = match raw.message_type() {
            TX_TRANSFER_ID => Box::new(TxTransfer::from_raw(raw)?),
            TX_CREATE_WALLET_ID => Box::new(TxCreateWallet::from_raw(raw)?),
            _ => {
                return Err(encoding::Error::IncorrectMessageType { message_type: raw.message_type() });
            },
        };
        Ok(trans)
    }

    fn public_api_handler(&self, ctx: &ApiContext) -> Option<Box<Handler>> {
        let mut router = Router::new();
        let api = CryptocurrencyApi {
            channel: ctx.node_channel().clone(),
        };
        api.wire(&mut router);
        Some(Box::new(router))
    }
}

// // // // // // // // // // ENTRY POINT // // // // // // // // // //

fn main() {
    exonum::helpers::init_logger().unwrap();

    println!("Creating in-memory database...");
    let db = MemoryDB::new();
    let services: Vec<Box<Service>> = vec![
        Box::new(CurrencyService),
    ];
    let blockchain = Blockchain::new(Box::new(db), services);

    let (consensus_public_key, consensus_secret_key) = exonum::crypto::gen_keypair();
    let (service_public_key, service_secret_key) = exonum::crypto::gen_keypair();

    let peer_address = "0.0.0.0:2000".parse().unwrap();
    let api_address = "0.0.0.0:8000".parse().unwrap();

    let validator_keys = ValidatorKeys {
        consensus_key: consensus_public_key,
        service_key: service_public_key,
    };
    let genesis = GenesisConfig::new(vec![validator_keys].into_iter());

    let api_cfg = NodeApiConfig {
        enable_blockchain_explorer: true,
        public_api_address: Some(api_address),
        private_api_address: None,
    };

    let node_cfg = NodeConfig {
        listen_address: peer_address,
        peers: vec![],
        service_public_key,
        service_secret_key,
        consensus_public_key,
        consensus_secret_key,
        genesis,
        external_address: None,
        network: Default::default(),
        whitelist: Default::default(),
        api: api_cfg,
        mempool: Default::default(),
        services_configs: Default::default(),
    };

    println!("Starting a single node...");
    let mut node = Node::new(blockchain, node_cfg);

    println!("Blockchain in ready for transactions!");
    node.run().unwrap();
}
<|endoftext|>


<commit_before>#![feature(custom_derive)]
extern crate hyper;
extern crate rand;

use std::fmt;

use std::fs;
use std::fs::File;
use std::io::{Read, Write};
use std::collections::HashSet;
use std::borrow::Borrow;
use std::str::FromStr;

use rand::Rand;
use rand::Rng;
use rand::StdRng;

use hyper::status::StatusCode::UnsupportedMediaType;
use hyper::status::StatusCode::InternalServerError;
use hyper::status::StatusCode::NotFound;
use hyper::server::{Request, Response};
use hyper::{Get, Post};
use hyper::uri::RequestUri::AbsolutePath;
use hyper::header::ContentType;
use hyper::net::Fresh;
use hyper::server::Handler;

const SERVER_ADDRESS: &'static str = "127.0.0.1:3000";
const SERVER_URL: &'static str = SERVER_ADDRESS; // TODO: change to domain

const IMAGE_DIR: &'static str = "screenies";
const IMAGE_EXT: &'static str = ".png";

fn read_whole<T: Read>(readable: &mut T) -> std::io::Result<Vec<u8>> {
    let mut buffer = Vec::<u8>::new();

    let result = readable.read_to_end(&mut buffer);
    match result {
        Ok(_) => Ok(buffer),
        Err(e) => Err(e)
    }
}

type ImageUrlImpl = u64;

#[derive(PartialEq, Eq, Hash, Debug)]
struct ImageUrl(ImageUrlImpl);

struct Server<'a> {
    imageDir : &'a str,
    imageExt: &'a str,
    serverUrl: &'a str,
    runAddress: &'a str,
    usedUrls : HashSet<ImageUrl>,
    rng : StdRng,
}

// not sure how to make this into a constant
fn image_content_type() -> ContentType {
    ContentType::png()
}

enum ReadError {
    IoError(std::io::Error),
    NotFound
}

impl <'a> Server<'a> {
    fn new(imageDir: &'a str, imageExt: &'a str, runAddress: &'a str, serverUrl: &'a str) -> Server<'a> {
        let usedUrls = match fs::read_dir(imageDir) {
            Ok(paths) => {
                let urls = HashSet::<ImageUrl>::new();
                for path in paths {
                    match path.unwrap().file_name().into_string() {
                        Ok(s) => {
                            // TODO
                            let num = ImageUrl::from_str(s.split(".").nth(0).unwrap());
                            //urls.push(num);
                        }
                        Err(_) => { continue; }
                    }
                }

                urls
            }
            Err(_) => HashSet::<ImageUrl>::new()
        };

        Server { imageDir: imageDir,
                 imageExt: imageExt,
                 serverUrl: serverUrl,
                 runAddress: runAddress,
                 usedUrls: usedUrls, rng: panic!(StdRng::new()) }
    }

    fn run<F: Fn(&mut Server, Request, Response) + std::marker::Sync>(&mut self, callback: &F) {
        hyper::Server::http(self.runAddress).unwrap().handle(|req: Request, res: Response| { callback(self, req, res); }).unwrap();

    }

    // retrieves an image path
    // image.png => <imageDir>/image.<imageExt>
    // image => <imageDir>/image.<imageExt>
    fn get_image_path(&self, path: &str) -> String {
        // remove extension
        let base = path.split(".").nth(0).unwrap();
        self.imageDir.to_string() + base + self.imageExt
    }

    // returns ReadError if it does not exist or if there's an IO error
    // otherwise returns the data of the image
    fn retrieve_image(&mut self, path: &str) -> Result<Vec<u8>, std::io::Error> {
        let full_path = self.get_image_path(path);
        match fs::metadata(&full_path) {
            Ok(_) => {
                let mut file = File::open(&full_path).unwrap();
                return read_whole(&mut file);
            },
            Err(e) => Err(e)
        }
    }

    fn gen_image_url(&mut self) -> ImageUrl {
        ImageUrl(self.rng.gen::<ImageUrlImpl>())
    }

    fn upload_image(&mut self, data: &[u8]) -> Option<String> {
        let mut num = self.gen_image_url();
        while self.usedUrls.contains(&num) {
            num = self.gen_image_url();
        }

        let fileName = self.get_image_path(num.to_string().borrow());

        return match File::create(&fileName) {
            Ok(mut file) => {
                file.write_all(data);
                Some(self.serverUrl.to_string() + fileName.borrow())
            }
            Err(e) => None
        }
    }
}

const BASE: u64 = 62;
const IMAGE_URL_CHARS: &'static str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

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

        let mut num = self.0;
        let mut result = ['0' as u8; 6];

        for i in (0..result.len()).rev() {
            result[i] = IMAGE_URL_CHARS.as_bytes()[(num % BASE) as usize];
            num /= BASE;
        }

        match std::str::from_utf8(&result) {
            Ok(s) => write!(f, "{}", s),
            Err(_) => write!(f, "")
        }
    }
}

fn index(ch: u8) -> Option<u8> {
    match IMAGE_URL_CHARS.as_bytes().iter().position(|x| *x == ch) {
        Some(x) => Some(x as u8),
        None => None
    }
}

#[derive(Debug)]
struct OutOfRange(u8);

impl FromStr for ImageUrl {
    type Err = OutOfRange;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let mut result: u64 = 0;
        for ch in s.as_bytes().iter() {
            match index(*ch) {
                Some(x) => result = result * BASE + x as u64,
                None => return Err(OutOfRange(*ch))
            }
        }
        return Ok(ImageUrl(result));
    }
}

macro_rules! try_print(
    ($e:expr) => {{
        match $e {
            Ok(v) => v,
            Err(e) => { println!("Error: {}", e); return; }
        }
    }}
);

fn retrieve_image(server: &mut Server, path: &str, mut res: Response) {
    match server.retrieve_image(path) {
        Ok(data) => {
            res.headers_mut().set(image_content_type());
            try_print!(res.send(data.borrow()));
        },
        Err(e) => {
            println!("Error: {}", e);
            *res.status_mut() = match e.kind() {
                std::io::ErrorKind::NotFound => NotFound,
                _ => InternalServerError
            }
        }
    }
}

fn on_req(server: &mut Server, req: Request, res: Response) {
    // determine what request they are making:
    // if it is a GET method, then retrieve the image
    // if it is a POST method:
    //    - then ensure it is an image (HOW?)
    //    - save it locally with a random 8 character long 62 bit number (a-zA-Z0-9)
    //    - give them the URL

    match req.method {
        Get => {
            match req.uri {
                AbsolutePath(path) => retrieve_image(server, &path[..], res),
                _ => ()
            }
        }
        Post => {
            println!("received post");
            // check to see if the request has a content type
            // and it is something that we can use. If so:
            // then we will upload it
            if !req.headers.has::<ContentType>() {
                println!("Error: Post request has no content type");
                *res.status_mut() = hyper::BadRequest;
                return;
            }

            if *req.headers.get::<ContentType>().unwrap() != image_content_type() {
                println!("UnsupportedMediaType: {}", *req.headers.get::<ContentType>().unwrap());
                println!("{}", req.headers);
                *res.status_mut() = UnsupportedMediaType;
                return;
            }

            // give back the URL to the image
            let data = try_print!(read_whole(&mut req));
            let url = server.upload_image(data.borrow());

            try_print!(res.send(url.borrow().unwrap().as_bytes()));
        },
        _ => ()
    }
}

fn main() {
    let mut server = Server::new(IMAGE_DIR, IMAGE_EXT, SERVER_URL, SERVER_ADDRESS);
    server.run(&on_req);
}
<commit_msg>init server properly<commit_after>#![feature(custom_derive)]
extern crate hyper;
extern crate rand;

use std::fmt;

use std::fs;
use std::fs::File;
use std::io::{Read, Write};
use std::collections::HashSet;
use std::borrow::Borrow;
use std::str::FromStr;

use rand::Rand;
use rand::Rng;
use rand::StdRng;

use hyper::status::StatusCode::UnsupportedMediaType;
use hyper::status::StatusCode::InternalServerError;
use hyper::status::StatusCode::NotFound;
use hyper::server::{Request, Response};
use hyper::{Get, Post};
use hyper::uri::RequestUri::AbsolutePath;
use hyper::header::ContentType;
use hyper::net::Fresh;
use hyper::server::Handler;

const SERVER_ADDRESS: &'static str = "127.0.0.1:3000";
const SERVER_URL: &'static str = SERVER_ADDRESS; // TODO: change to domain

const IMAGE_DIR: &'static str = "screenies";
const IMAGE_EXT: &'static str = ".png";

fn read_whole<T: Read>(readable: &mut T) -> std::io::Result<Vec<u8>> {
    let mut buffer = Vec::<u8>::new();

    let result = readable.read_to_end(&mut buffer);
    match result {
        Ok(_) => Ok(buffer),
        Err(e) => Err(e)
    }
}

type ImageUrlImpl = u64;

#[derive(PartialEq, Eq, Hash, Debug)]
struct ImageUrl(ImageUrlImpl);

struct Server<'a> {
    imageDir : &'a str,
    imageExt: &'a str,
    serverUrl: &'a str,
    runAddress: &'a str,
    usedUrls : HashSet<ImageUrl>,
    rng : StdRng,
}

// not sure how to make this into a constant
fn image_content_type() -> ContentType {
    ContentType::png()
}

enum ReadError {
    IoError(std::io::Error),
    NotFound
}

impl <'a> Server<'a> {
    fn new(imageDir: &'a str, imageExt: &'a str, runAddress: &'a str, serverUrl: &'a str) -> Server<'a> {
        let usedUrls = match fs::read_dir(imageDir) {
            Ok(paths) => {
                let mut urls = HashSet::<ImageUrl>::new();
                for path in paths {
                    match path.unwrap().file_name().into_string() {
                        Ok(s) => {
                            match ImageUrl::from_str(s.split(".").nth(0).unwrap()) {
                                Ok(num) => { urls.insert(num); }
                                Err(_) => { continue; }
                            }
                        },
                        Err(_) => { continue; }
                    }
                }

                urls
            }
            Err(_) => HashSet::<ImageUrl>::new()
        };

        Server { imageDir: imageDir,
                 imageExt: imageExt,
                 serverUrl: serverUrl,
                 runAddress: runAddress,
                 usedUrls: usedUrls, rng: panic!(StdRng::new()) }
    }

    fn run<F: Fn(&mut Server, Request, Response) + std::marker::Sync>(&mut self, callback: &F) {
        hyper::Server::http(self.runAddress).unwrap().handle(|req: Request, res: Response| { callback(self, req, res); }).unwrap();

    }

    // retrieves an image path
    // image.png => <imageDir>/image.<imageExt>
    // image => <imageDir>/image.<imageExt>
    fn get_image_path(&self, path: &str) -> String {
        // remove extension
        let base = path.split(".").nth(0).unwrap();
        self.imageDir.to_string() + base + self.imageExt
    }

    // returns ReadError if it does not exist or if there's an IO error
    // otherwise returns the data of the image
    fn retrieve_image(&mut self, path: &str) -> Result<Vec<u8>, std::io::Error> {
        let full_path = self.get_image_path(path);
        match fs::metadata(&full_path) {
            Ok(_) => {
                let mut file = File::open(&full_path).unwrap();
                return read_whole(&mut file);
            },
            Err(e) => Err(e)
        }
    }

    fn gen_image_url(&mut self) -> ImageUrl {
        ImageUrl(self.rng.gen::<ImageUrlImpl>())
    }

    fn upload_image(&mut self, data: &[u8]) -> Option<String> {
        let mut num = self.gen_image_url();
        while self.usedUrls.contains(&num) {
            num = self.gen_image_url();
        }

        let fileName = self.get_image_path(num.to_string().borrow());

        return match File::create(&fileName) {
            Ok(mut file) => {
                file.write_all(data);
                Some(self.serverUrl.to_string() + fileName.borrow())
            }
            Err(e) => None
        }
    }
}

const BASE: u64 = 62;
const IMAGE_URL_CHARS: &'static str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

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

        let mut num = self.0;
        let mut result = ['0' as u8; 6];

        for i in (0..result.len()).rev() {
            result[i] = IMAGE_URL_CHARS.as_bytes()[(num % BASE) as usize];
            num /= BASE;
        }

        match std::str::from_utf8(&result) {
            Ok(s) => write!(f, "{}", s),
            Err(_) => write!(f, "")
        }
    }
}

fn index(ch: u8) -> Option<u8> {
    match IMAGE_URL_CHARS.as_bytes().iter().position(|x| *x == ch) {
        Some(x) => Some(x as u8),
        None => None
    }
}

#[derive(Debug)]
struct OutOfRange(u8);

impl FromStr for ImageUrl {
    type Err = OutOfRange;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let mut result: u64 = 0;
        for ch in s.as_bytes().iter() {
            match index(*ch) {
                Some(x) => result = result * BASE + x as u64,
                None => return Err(OutOfRange(*ch))
            }
        }
        return Ok(ImageUrl(result));
    }
}

macro_rules! try_print(
    ($e:expr) => {{
        match $e {
            Ok(v) => v,
            Err(e) => { println!("Error: {}", e); return; }
        }
    }}
);

fn retrieve_image(server: &mut Server, path: &str, mut res: Response) {
    match server.retrieve_image(path) {
        Ok(data) => {
            res.headers_mut().set(image_content_type());
            try_print!(res.send(data.borrow()));
        },
        Err(e) => {
            println!("Error: {}", e);
            *res.status_mut() = match e.kind() {
                std::io::ErrorKind::NotFound => NotFound,
                _ => InternalServerError
            }
        }
    }
}

fn on_req(server: &mut Server, req: Request, res: Response) {
    // determine what request they are making:
    // if it is a GET method, then retrieve the image
    // if it is a POST method:
    //    - then ensure it is an image
    //    - save it locally with a random 6 character long 62 bit number (a-zA-Z0-9)
    //    - give them the URL

    match req.method {
        Get => {
            match req.uri {
                AbsolutePath(path) => retrieve_image(server, &path[..], res),
                _ => ()
            }
        }
        Post => {
            println!("received post");
            // check to see if the request has a content type
            // and it is something that we can use. If so:
            // then we will upload it
            if !req.headers.has::<ContentType>() {
                println!("Error: Post request has no content type");
                *res.status_mut() = hyper::BadRequest;
                return;
            }

            if *req.headers.get::<ContentType>().unwrap() != image_content_type() {
                println!("UnsupportedMediaType: {}", *req.headers.get::<ContentType>().unwrap());
                println!("{}", req.headers);
                *res.status_mut() = UnsupportedMediaType;
                return;
            }

            // give back the URL to the image
            let data = try_print!(read_whole(&mut req));
            let url = server.upload_image(data.borrow());

            try_print!(res.send(url.borrow().unwrap().as_bytes()));
        },
        _ => ()
    }
}

fn main() {
    let mut server = Server::new(IMAGE_DIR, IMAGE_EXT, SERVER_URL, SERVER_ADDRESS);
    server.run(&on_req);
}
<|endoftext|>


<commit_before>extern crate iron;
extern crate router;
extern crate rustc_serialize;
extern crate time;

use iron::prelude::*;
use iron::status;
use router::Router;
use rustc_serialize::json;
use std::io::Read;

mod lang_test;
mod user;

#[derive(RustcEncodable, RustcDecodable)]
struct SubjectTestRequestPayload {
    user: String,
    language: String,
    subject: String,
    solution: String
}

#[derive(RustcEncodable, RustcDecodable)]
struct SubjectTestResponsePayload {
    response_code: i8,
    response_message: String,
    user: String,
    subject: String,
    language: String,
    metrics: Option<lang_test::parser::ResponseMetrics>,
    timestamp: String
}

#[derive(RustcEncodable, RustcDecodable)]
struct UserRequestPayload {
    user: String
}

#[derive(RustcEncodable, RustcDecodable)]
struct UserResponsePayload {
    response_code: i8,
    response_message: String,
    timestamp: String
}

fn main() {

    let mut router = Router::new();

    router.get("/", ping, "ping");
    router.post("/submit", submit, "submit");
    router.post("/create/user", create_user_subjects, "create user's subject folders");

    fn ping(_: &mut Request) -> IronResult<Response> {
        let now_utc = tm2str(time::now_utc());
        let message = UserResponsePayload { response_code: 0, response_message: "pong".to_string(), timestamp: now_utc};
        let payload = json::encode(&message).unwrap();
        Ok(Response::with((status::Ok, payload)))
    }

    fn submit(req: &mut Request) -> IronResult<Response> {
        let mut body = String::new();
        req.body.read_to_string(&mut body).unwrap();

        let body: SubjectTestRequestPayload = json::decode(&body).unwrap();

        let response_msg = lang_test::run_spark_test(&body.language, &body.user, &body.subject, &body.solution);

        let now_utc = tm2str(time::now_utc());
        let message = match response_msg.error {
            // success
            0 => SubjectTestResponsePayload { response_code: 0, response_message: "pass".to_string(), user: format!("{}", &body.user), subject: format!("{}", &body.subject), language: format!("{}", &body.language), metrics: Some(response_msg), timestamp: now_utc },
            // syntax error
            127 => SubjectTestResponsePayload { response_code: 1, response_message: "syntax error".to_string(), user: format!("{}", &body.user), subject: format!("{}", &body.subject), language: format!("{}", &body.language), metrics: Some(response_msg), timestamp: now_utc },
            // test case failed
            _ => SubjectTestResponsePayload { response_code: 2, response_message: "fail".to_string(), user: format!("{}", &body.user), subject: format!("{}", &body.subject), language: format!("{}", &body.language), metrics: Some(response_msg), timestamp: now_utc }
        };
        let payload = json::encode(&message).unwrap();
        println!("{}", &payload);
        Ok(Response::with((status::Ok, payload)))
    }

    fn create_user_subjects(req: &mut Request) -> IronResult<Response> {
        let mut body = String::new();
        req.body.read_to_string(&mut body).unwrap();

        let body: UserRequestPayload = json::decode(&body).unwrap();
        let result = user::create_subjects(&body.user);
        let now_utc = tm2str(time::now_utc());
        let message = match result.stderr.len() {
            // success
            0 => UserResponsePayload {response_code: 0, response_message: format!("Create {} subjects directories successfully.", &body.user), timestamp: now_utc},
            _ => UserResponsePayload {response_code: 2, response_message: format!("{:?}", result.stderr), timestamp: now_utc}
        };
        let payload = json::encode(&message).unwrap();
        Ok(Response::with((status::Ok, payload)))
    }

    let _server = Iron::new(router).http("0.0.0.0:3000").unwrap();
    println!("On 3000");
}

fn tm2str(tm: time::Tm) -> String {
    format!("{:?}-{:?}-{:?} {:?}:{:?}:{:?}", &tm.tm_year + 1900, &tm.tm_mon + 1, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec)
}
<commit_msg>Change error string from vec to str type<commit_after>extern crate iron;
extern crate router;
extern crate rustc_serialize;
extern crate time;

use iron::prelude::*;
use iron::status;
use router::Router;
use rustc_serialize::json;
use std::io::Read;

mod lang_test;
mod user;

#[derive(RustcEncodable, RustcDecodable)]
struct SubjectTestRequestPayload {
    user: String,
    language: String,
    subject: String,
    solution: String
}

#[derive(RustcEncodable, RustcDecodable)]
struct SubjectTestResponsePayload {
    response_code: i8,
    response_message: String,
    user: String,
    subject: String,
    language: String,
    metrics: Option<lang_test::parser::ResponseMetrics>,
    timestamp: String
}

#[derive(RustcEncodable, RustcDecodable)]
struct UserRequestPayload {
    user: String
}

#[derive(RustcEncodable, RustcDecodable)]
struct UserResponsePayload {
    response_code: i8,
    response_message: String,
    timestamp: String
}

fn main() {

    let mut router = Router::new();

    router.get("/", ping, "ping");
    router.post("/submit", submit, "submit");
    router.post("/create/user", create_user_subjects, "create user's subject folders");

    fn ping(_: &mut Request) -> IronResult<Response> {
        let now_utc = tm2str(time::now_utc());
        let message = UserResponsePayload { response_code: 0, response_message: "pong".to_string(), timestamp: now_utc};
        let payload = json::encode(&message).unwrap();
        Ok(Response::with((status::Ok, payload)))
    }

    fn submit(req: &mut Request) -> IronResult<Response> {
        let mut body = String::new();
        req.body.read_to_string(&mut body).unwrap();

        let body: SubjectTestRequestPayload = json::decode(&body).unwrap();

        let response_msg = lang_test::run_spark_test(&body.language, &body.user, &body.subject, &body.solution);

        let now_utc = tm2str(time::now_utc());
        let message = match response_msg.error {
            // success
            0 => SubjectTestResponsePayload { response_code: 0, response_message: "pass".to_string(), user: format!("{}", &body.user), subject: format!("{}", &body.subject), language: format!("{}", &body.language), metrics: Some(response_msg), timestamp: now_utc },
            // syntax error
            127 => SubjectTestResponsePayload { response_code: 1, response_message: "syntax error".to_string(), user: format!("{}", &body.user), subject: format!("{}", &body.subject), language: format!("{}", &body.language), metrics: Some(response_msg), timestamp: now_utc },
            // test case failed
            _ => SubjectTestResponsePayload { response_code: 2, response_message: "fail".to_string(), user: format!("{}", &body.user), subject: format!("{}", &body.subject), language: format!("{}", &body.language), metrics: Some(response_msg), timestamp: now_utc }
        };
        let payload = json::encode(&message).unwrap();
        println!("{}", &payload);
        Ok(Response::with((status::Ok, payload)))
    }

    fn create_user_subjects(req: &mut Request) -> IronResult<Response> {
        let mut body = String::new();
        req.body.read_to_string(&mut body).unwrap();

        let body: UserRequestPayload = json::decode(&body).unwrap();
        let result = user::create_subjects(&body.user);
        let now_utc = tm2str(time::now_utc());
        let message = match result.stderr.len() {
            // success
            0 => UserResponsePayload {response_code: 0, response_message: format!("Create {} subjects directories successfully.", &body.user), timestamp: now_utc},
            _ => UserResponsePayload {response_code: 2, response_message: format!("{:?}", String::from_utf8(result.stderr).unwrap()), timestamp: now_utc},
        };
        let payload = json::encode(&message).unwrap();
        Ok(Response::with((status::Ok, payload)))
    }

    let _server = Iron::new(router).http("0.0.0.0:3000").unwrap();
    println!("On 3000");
}

fn tm2str(tm: time::Tm) -> String {
    format!("{:?}-{:?}-{:?} {:?}:{:?}:{:?}", &tm.tm_year + 1900, &tm.tm_mon + 1, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec)
}
<|endoftext|>


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

mod playlist;
mod default_ui;

use argparse::{ArgumentParser, Store, StoreTrue, List};
use default_ui::*;
use regex::Regex;
use gst::ElementT;
use std::fs;
use std::path::Path;

fn main() {
    let mut global_err = String::from("");
    {
    let mut regex = String::new();
    let mut songs : Vec<String> = vec![]; // TODO: add with capacity!
    let mut recurse = false;
    {
        let mut ap = ArgumentParser::new();
        ap.set_description("Rust Fucking Simple Music Player");
        ap.refer(&mut recurse)
            .add_option(&["-r", "--recursive"], StoreTrue, "Recurse through directories if passed them");
        ap.refer(&mut regex)
            .add_option(&["-s", "--search"], Store, "Search songs using regular expressions");
        ap.refer(&mut songs)
            .add_argument("arguments", List, "Songs to play");
        ap.parse_args_or_exit();
    }

    if songs.len() == 0 {
        println!("Usage:");
        println!("    rfsmp [OPTIONS] [SONGS ...]");
        return;
    }

    if regex != "" {
        let re = Regex::new(&regex).expect("regex invalid");
        songs.retain(|i| re.is_match(i));
    }
    let mut append : Vec<String> = vec![];

    if recurse {
        let mut temp_list = songs.clone();
        let mut append = temp_list.iter().filter(|a| fs::metadata(a).is_ok()).filter(|a| fs::metadata(a).unwrap().is_dir()).collect::<Vec<&String>>();
        for dir in append {
            let mut files = fs::read_dir(Path::new(dir)).unwrap();
            for file in files {
                let mut pass = file.unwrap().path();
                match fs::metadata(&pass).unwrap().is_dir() {
                    true => {},
                    false => songs.push(pass.as_path().to_str().unwrap_or_else(|| "invalid char type").to_string())
                }
            }
        }
    }
    let mut playlist = playlist::Playlist::new(songs);

    gst::init();
    let mut playbin = gst::PlayBin::new("audio_player")
        .expect("Couldn't create playlist");
    let mut main_loop = gst::MainLoop::new();

    let mut bus;
    let bus_receiver;

    let song = match playlist.get_next_song() {
        Some(a) => gst::filename_to_uri(a).expect("URI Error"),
        None => panic!("can't get song"),
    };

    playbin.set_uri(&song);
    bus = playbin.bus().expect("Couldn't get pipeline bus");
    bus_receiver = bus.receiver();

    let mut ui = UI::new(&playlist);

    main_loop.spawn();
    playbin.play();

    let mut song_buffered = false;

    'outer: loop {
        loop {
            match bus_receiver.try_recv() {
                Ok(message) => {
                    match message.parse(){
                        gst::Message::ErrorParsed{ref error, ..} => {
                            global_err.push_str(
                                &format!("error msg from element `{}`: {}, quit",
                                        message.src_name(), error.message()));
                            break 'outer;
                        }
                        gst::Message::Eos(ref _msg) => {
                            break 'outer;
                        }
                        gst::Message::StreamStart(ref _msg) => {
                            song_buffered = false;
                            playlist.go_to_next();
                        }
                        _ => {
                            //println!("msg of type `{}` from element `{}`",
                            //         message.type_name(), message.src_name());
                        }
                    }
                }
                Err(err) => {
                    match err {
                        std::sync::mpsc::TryRecvError::Empty => break,
                        std::sync::mpsc::TryRecvError::Disconnected => break,
                    }
                }
            }
        }
        let stream_dir = playbin.duration_s();
        let stream_pos = playbin.position_s();

        if stream_dir.is_some() && stream_pos.is_some() && !song_buffered {
            if stream_dir.unwrap() - stream_pos.unwrap() < 3.0 {
                match playlist.get_next_song() {
                    Some(a) => {
                        let song = match gst::filename_to_uri(a) {
                            Ok(a) => a,
                            Err(e) => {
                                global_err.push_str("URI Error ");
                                global_err.push_str(&e.message());
                                break 'outer;
                            }
                        };
                        playbin.set_uri(&song);
                        song_buffered = true;
                    }
                    None => {
                        //println!("All songs played");
                    }
                };
            }
        }

        let stream_dir = match stream_dir {
            Some(a) => a as i32,
            None => 0,
        };
        let stream_pos = match stream_pos {
            Some(a) => a as i32,
            None => 0,
        };

        match ui.manage_ui(&playlist, stream_pos, stream_dir) {
            UIResult::PlayPause => {
                if playbin.is_paused() {
                    playbin.play();
                }
                else {
                    playbin.pause();
                }
            }
            UIResult::Previous => {
                playbin.set_state(gst::ffi::GstState::GST_STATE_NULL);
                playlist.go_to_prev();
                playlist.go_to_prev();
                match playlist.get_next_song() {
                    Some(a) => {
                        let song = match gst::filename_to_uri(a) {
                            Ok(a) => a,
                            Err(e) => {
                                global_err.push_str("URI Error ");
                                global_err.push_str(&e.message());
                                break 'outer;
                            }
                        };
                        playbin.set_uri(&song);
                        song_buffered = true;
                    }
                    None => {
                        println!("All songs played");
                        break;
                    }
                };
                playbin.play();

            }
            UIResult::Next => {
                playbin.set_state(gst::ffi::GstState::GST_STATE_NULL);
                match playlist.get_next_song() {
                    Some(a) => {
                        let song = match gst::filename_to_uri(a) {
                            Ok(a) => a,
                            Err(e) => {
                                global_err.push_str("URI Error ");
                                global_err.push_str(&e.message());
                                break 'outer;
                            }
                        };
                        playbin.set_uri(&song);
                        song_buffered = true;
                    }
                    None => {
                        println!("All songs played");
                        break;
                    }
                };
                playbin.play();
            }
            UIResult::Exit => {
                break;
            }
            UIResult::Error(a) => {
                global_err = a;
                break 'outer;
            }
            UIResult::NA => {}
        }
        std::thread::sleep(std::time::Duration::new(0, 20000000));
    }
    main_loop.quit();
    }
    if global_err != "" {
        println!("{}", global_err);
    }
}
<commit_msg>changed up the recursive feature to be completely actually recursive, but am at a roadblock because I cannot use the file varaible twice, even though i need to. Rust is preventing me from using it wice and i DISLIKE rust right now and with i was using PYTHON<commit_after>//  Copyright 2015 Nathanael Merrill
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
extern crate rustty;
extern crate gst;
extern crate argparse;
extern crate regex;

mod playlist;
mod default_ui;

use argparse::{ArgumentParser, Store, StoreTrue, List};
use default_ui::*;
use regex::Regex;
use gst::ElementT;
use std::fs;
use std::path::Path;
use std::io;

fn main() {
    let mut global_err = String::from("");
    {
    let mut regex = String::new();
    let mut songs : Vec<String> = vec![]; // TODO: add with capacity!
    let mut recurse = false;
    {
        let mut ap = ArgumentParser::new();
        ap.set_description("Rust Fucking Simple Music Player");
        ap.refer(&mut recurse)
            .add_option(&["-r", "--recursive"], StoreTrue, "Recurse through directories if passed them");
        ap.refer(&mut regex)
            .add_option(&["-s", "--search"], Store, "Search songs using regular expressions");
        ap.refer(&mut songs)
            .add_argument("arguments", List, "Songs to play");
        ap.parse_args_or_exit();
    }

    if songs.len() == 0 {
        println!("Usage:");
        println!("    rfsmp [OPTIONS] [SONGS ...]");
        return;
    }

    if regex != "" {
        let  re = Regex::new(&regex).expect("regex invalid");
        songs.retain(|i| re.is_match(i));
    }

    if recurse {
        let mut append : Vec<String> = vec![];
        for song in songs.clone() {
            if fs::metadata(&song).unwrap().is_dir() {
                append.append(&mut recurse_songs(&song).unwrap());
            } else {
                append.push(song);
            }
        }
        songs = append;
    }
    let mut playlist = playlist::Playlist::new(songs);

    gst::init();
    let mut playbin = gst::PlayBin::new("audio_player")
        .expect("Couldn't create playlist");
    let mut main_loop = gst::MainLoop::new();

    let mut bus;
    let bus_receiver;

    let song = match playlist.get_next_song() {
        Some(a) => gst::filename_to_uri(a).expect("URI Error"),
        None => panic!("can't get song"),
    };

    playbin.set_uri(&song);
    bus = playbin.bus().expect("Couldn't get pipeline bus");
    bus_receiver = bus.receiver();

    let mut ui = UI::new(&playlist);

    main_loop.spawn();
    playbin.play();

    let mut song_buffered = false;

    'outer: loop {
        loop {
            match bus_receiver.try_recv() {
                Ok(message) => {
                    match message.parse(){
                        gst::Message::ErrorParsed{ref error, ..} => {
                            global_err.push_str(
                                &format!("error msg from element `{}`: {}, quit",
                                        message.src_name(), error.message()));
                            break 'outer;
                        }
                        gst::Message::Eos(ref _msg) => {
                            break 'outer;
                        }
                        gst::Message::StreamStart(ref _msg) => {
                            song_buffered = false;
                            playlist.go_to_next();
                        }
                        _ => {
                            //println!("msg of type `{}` from element `{}`",
                            //         message.type_name(), message.src_name());
                        }
                    }
                }
                Err(err) => {
                    match err {
                        std::sync::mpsc::TryRecvError::Empty => break,
                        std::sync::mpsc::TryRecvError::Disconnected => break,
                    }
                }
            }
        }
        let stream_dir = playbin.duration_s();
        let stream_pos = playbin.position_s();

        if stream_dir.is_some() && stream_pos.is_some() && !song_buffered {
            if stream_dir.unwrap() - stream_pos.unwrap() < 3.0 {
                match playlist.get_next_song() {
                    Some(a) => {
                        let song = match gst::filename_to_uri(a) {
                            Ok(a) => a,
                            Err(e) => {
                                global_err.push_str("URI Error ");
                                global_err.push_str(&e.message());
                                break 'outer;
                            }
                        };
                        playbin.set_uri(&song);
                        song_buffered = true;
                    }
                    None => {
                        //println!("All songs played");
                    }
                };
            }
        }

        let stream_dir = match stream_dir {
            Some(a) => a as i32,
            None => 0,
        };
        let stream_pos = match stream_pos {
            Some(a) => a as i32,
            None => 0,
        };

        match ui.manage_ui(&playlist, stream_pos, stream_dir) {
            UIResult::PlayPause => {
                if playbin.is_paused() {
                    playbin.play();
                }
                else {
                    playbin.pause();
                }
            }
            UIResult::Previous => {
                playbin.set_state(gst::ffi::GstState::GST_STATE_NULL);
                playlist.go_to_prev();
                playlist.go_to_prev();
                match playlist.get_next_song() {
                    Some(a) => {
                        let song = match gst::filename_to_uri(a) {
                            Ok(a) => a,
                            Err(e) => {
                                global_err.push_str("URI Error ");
                                global_err.push_str(&e.message());
                                break 'outer;
                            }
                        };
                        playbin.set_uri(&song);
                        song_buffered = true;
                    }
                    None => {
                        println!("All songs played");
                        break;
                    }
                };
                playbin.play();

            }
            UIResult::Next => {
                playbin.set_state(gst::ffi::GstState::GST_STATE_NULL);
                match playlist.get_next_song() {
                    Some(a) => {
                        let song = match gst::filename_to_uri(a) {
                            Ok(a) => a,
                            Err(e) => {
                                global_err.push_str("URI Error ");
                                global_err.push_str(&e.message());
                                break 'outer;
                            }
                        };
                        playbin.set_uri(&song);
                        song_buffered = true;
                    }
                    None => {
                        println!("All songs played");
                        break;
                    }
                };
                playbin.play();
            }
            UIResult::Exit => {
                break;
            }
            UIResult::Error(a) => {
                global_err = a;
                break 'outer;
            }
            UIResult::NA => {}
        }
        std::thread::sleep(std::time::Duration::new(0, 20000000));
    }
    main_loop.quit();
    }
    if global_err != "" {
        println!("{}", global_err);
    }
}

fn recurse_songs(dir : &String) -> Result<Vec<String>, io::Error>{
    let mut toAppend : Vec<String> = vec![];
    if try!(fs::metadata(&dir)).is_dir() {
        for entry in try!(fs::read_dir(dir)) {
            match try!(fs::metadata(entry.unwrap().path())).is_dir() {
                false => toAppend.push(second.unwrap().path().to_str().unwrap().to_string()),
                true => {},
            };
         }
    }
    Ok(toAppend)
}

<|endoftext|>


<commit_before>extern crate piston_window;
extern crate graphics;
extern crate itertools;
extern crate opengl_graphics;
extern crate piston;
extern crate rand;
extern crate sdl2_window;

mod drawing;
mod game;
mod models;
mod traits;

use piston_window::*;
use opengl_graphics::GlGraphics;
use sdl2_window::Sdl2Window;

use game::Game;

// Use this typedef to make type of window prettier.
// Need to use Sdl2Window as backend in order to get joystick events currently.
pub type SDL2GameWindow = PistonWindow<(), Sdl2Window>;

// Returns a result containing a GlutinWindow or an error if the window
// settings are not supported
fn main() {

    let opengl = OpenGL::V3_2;

    let mut game = Game::new(drawing::Size::new(1024.0, 600.0));

    let mut window: SDL2GameWindow = WindowSettings::new("Rocket!", [1024, 600])
        .opengl(opengl).samples(8).exit_on_esc(true).build().unwrap();

    window.set_ups(60);
    window.set_max_fps(60);

    let mut gl = GlGraphics::new(opengl);

    let mut events = window.events();

    while let Some(e) = events.next(&mut window) {
    // Event handling
        match e {
            Event::Input(Input::Press(Button::Keyboard(key))) => {
                game.key_press(key);
            }

            Event::Input(Input::Release(Button::Keyboard(key))) => {
                game.key_release(key);
            }

            Event::Input(Input::Press(Button::Joystick(button))) => {
                game.button_press(button);
            }

            Event::Input(Input::Release(Button::Joystick(button))) => {
                game.button_release(button);
            }

            // Joystick Axis are Move Input types
            Event::Input(Input::Move(Motion::JoystickAxis(axis))) => {
                game.handle_axis(axis);
            }

            Event::Render(args) => {
                gl.draw(args.viewport(), |c, g| game.render(c, g));
            }

            Event::Update(args) => {
                game.update(args.dt);
            }

            _ => {}
        }
    }

}
<commit_msg>Update main.rs<commit_after>extern crate piston_window;
extern crate graphics;
extern crate itertools;
extern crate opengl_graphics;
extern crate piston;
extern crate rand;
extern crate sdl2_window;

mod drawing;
mod game;
mod models;
mod traits;

use piston_window::*;
use opengl_graphics::GlGraphics;
use sdl2_window::Sdl2Window;

use game::Game;

// Use this typedef to make type of window prettier.
// Need to use Sdl2Window as backend in order to get controller/joystick events currently.
pub type SDL2GameWindow = PistonWindow<Sdl2Window>;

// Returns a result containing a GlutinWindow or an error if the window
// settings are not supported
fn main() {

    let opengl = OpenGL::V3_2;

    let mut game = Game::new(drawing::Size::new(1024.0, 600.0));

    let mut window: SDL2GameWindow = WindowSettings::new("Rocket!", [1024, 600])
        .opengl(opengl).samples(8).exit_on_esc(true).build().unwrap();

    window.set_ups(60);
    window.set_max_fps(60);

    let mut gl = GlGraphics::new(opengl);

    let mut events = window.events();

    while let Some(e) = events.next(&mut window) {
    // Event handling
        match e {
            Event::Input(Input::Press(Button::Keyboard(key))) => {
                game.key_press(key);
            }

            Event::Input(Input::Release(Button::Keyboard(key))) => {
                game.key_release(key);
            }

            Event::Input(Input::Press(Button::Controller(button))) => {
                game.button_press(button);
            }

            Event::Input(Input::Release(Button::Controller(button))) => {
                game.button_release(button);
            }

            // Controller Axis are Move Input types
            Event::Input(Input::Move(Motion::ControllerAxis(axis))) => {
                game.handle_axis(axis);
            }

            Event::Render(args) => {
                gl.draw(args.viewport(), |c, g| game.render(c, g));
            }

            Event::Update(args) => {
                game.update(args.dt);
            }

            _ => {}
        }
    }

}
<|endoftext|>


<commit_before>#[macro_use]
extern crate imgui;
extern crate mush;
use mush::interface::Interface;
use imgui::{Ui,ImStr,ImString};

use std::fs;
//use std::path::Path;

use std::time::{Duration,Instant};
use std::thread;

const CLEAR_COLOR: (f32, f32, f32, f32) = (0.006, 0.006, 0.006, 1.0);

/// represents 15ms as nanos
static FPS_60: u32 = 15000000;

fn main() {
    let mut ifc = Interface::init();
    let mut state = State::default();
    let mut filestate = FileState::default();

    loop {
        let start_time = Instant::now();

        let r = ifc.render(CLEAR_COLOR, |ui| {
            menu(ui, &mut state);
            open_file(ui, &mut state, &mut filestate);
        });
        if !r | state.exit{ break }

        maybe_sleep(start_time); // we must manage sleep if we run too fast
    }
}

fn maybe_sleep(start_time: Instant) {
    let duration = Duration::new(0,FPS_60);
    if start_time.elapsed() < duration {
        let delay = duration - start_time.elapsed();
        thread::sleep(delay);
    }
}

struct State {
    exit: bool,
    open_file: bool,
}
impl Default for State {
    fn default() -> Self {
        State {
            exit: false,
            open_file: true,
        }
    }
}

struct FileState {
    /// MAX_PATH set to 260 chars
    cd: ImString,
    idx: i32,
    files: Vec<String>,
}

impl Default for FileState {
    fn default() -> Self {
        let mut cd = ImString::from(im_str!("./"));
        cd.reserve(261); //arbitrary max path size

        FileState {
            cd: cd,
            idx: 0,
            files: vec![],
        }
    }
}

impl FileState {
    fn update(&mut self) {
        if let Ok(paths) = fs::read_dir(&self.cd.to_string()) {
            self.files = paths
                .filter(|p| p.is_ok())
                .map(|p| {
                    p.unwrap().path().as_path().to_str().unwrap().to_owned()
                })
                .collect();
        }
    }
}

fn menu (ui: &Ui, state: &mut State) {
    ui.main_menu_bar(|| {
        ui.menu(im_str!("File"))
            .build(|| {
                ui.menu_item(im_str!("Open"))
                    .selected(&mut state.open_file)
                    .build();

                ui.menu_item(im_str!("Exit"))
                    .selected(&mut state.exit)
                    .build();
            });
    });
}

fn open_file (ui: &Ui, state: &mut State, filestate: &mut FileState) {
    if !state.open_file { return }

    ui.window(im_str!("Select source"))
        .always_auto_resize(true)
        .movable(true)
        .show_borders(true)
        .opened(&mut state.open_file)
        .build(||{
            ui.text(im_str!("Select a source file to be parsed and evaluated.\nSource files must be parsable through the lichen crate."));
            ui.separator();
            ui.input_text(im_str!("Current Directory"), &mut filestate.cd)
                .enter_returns_true(true)
                .build();
            ui.separator();

            filestate.update();

            // NOTE: to appease the borrow checker and have the proper argument for list_box
            // we must do build the list in two steps
            let paths: Vec<ImString> = filestate.files.iter().map(|p| {
                    im_str!("{:}", p).to_owned()
                })
                .collect();

            let paths: Vec<&ImStr> = paths.iter().map(|p|p.as_ref()).collect();

            ui.list_box(im_str!("Files"),
                        &mut filestate.idx,
                        &paths[..],
                        paths.len() as i32);
        })
}
<commit_msg>listbox selection of folders to traverse<commit_after>#[macro_use]
extern crate imgui;
extern crate mush;
use mush::interface::Interface;
use imgui::{Ui,ImStr,ImString};

use std::fs;
//use std::path::Path;

use std::time::{Duration,Instant};
use std::thread;

const CLEAR_COLOR: (f32, f32, f32, f32) = (0.006, 0.006, 0.006, 1.0);

/// represents 15ms as nanos
static FPS_60: u32 = 15000000;

fn main() {
    let mut ifc = Interface::init();
    let mut state = State::default();
    let mut filestate = FileState::default();

    loop {
        let start_time = Instant::now();

        let r = ifc.render(CLEAR_COLOR, |ui| {
            menu(ui, &mut state);
            open_file(ui, &mut state, &mut filestate);
        });
        if !r | state.exit{ break }

        maybe_sleep(start_time); // we must manage sleep if we run too fast
    }
}

fn maybe_sleep(start_time: Instant) {
    let duration = Duration::new(0,FPS_60);
    if start_time.elapsed() < duration {
        let delay = duration - start_time.elapsed();
        thread::sleep(delay);
    }
}

struct State {
    exit: bool,
    open_file: bool,
}
impl Default for State {
    fn default() -> Self {
        State {
            exit: false,
            open_file: true,
        }
    }
}

struct FileState {
    /// MAX_PATH set to 260 chars
    cd: ImString,
    idx: i32,
    files: Vec<String>,
}

impl Default for FileState {
    fn default() -> Self {
        let mut cd = ImString::from(im_str!("./"));
        cd.reserve(261); //arbitrary max path size

        FileState {
            cd: cd,
            idx: 1,
            files: vec![],
        }
    }
}

impl FileState {
    fn update(&mut self) {
        if self.idx != 1 {
            if let Some(file) = self.files.get(self.idx as usize) {
                self.cd.clear();
                self.cd.push_str(file);
                self.idx = 1;
            }
        }

        if let Ok(paths) = fs::read_dir(&self.cd.to_string()) {
            self.files = paths
                .filter(|p| p.is_ok())
                .map(|p| {
                    p.unwrap().path().as_path().to_str().unwrap().to_owned()
                })
                .collect();
        }
        else { self.idx = 0; }

        self.files.insert(0,"./".to_owned());
        self.files.insert(0,"..".to_owned());
    }
}

fn menu (ui: &Ui, state: &mut State) {
    ui.main_menu_bar(|| {
        ui.menu(im_str!("File"))
            .build(|| {
                ui.menu_item(im_str!("Open"))
                    .selected(&mut state.open_file)
                    .build();

                ui.menu_item(im_str!("Exit"))
                    .selected(&mut state.exit)
                    .build();
            });
    });
}

fn open_file (ui: &Ui, state: &mut State, filestate: &mut FileState) {
    if !state.open_file { return }

    ui.window(im_str!("Select source"))
        .always_auto_resize(true)
        .movable(true)
        .show_borders(true)
        .opened(&mut state.open_file)
        .build(||{
            ui.text(im_str!("Select a source file to be parsed and evaluated.\nSource files must be parsable through the lichen crate."));
            ui.separator();
            ui.input_text(im_str!("Current Directory"), &mut filestate.cd)
                .enter_returns_true(true)
                .build();
            ui.separator();

            filestate.update();

            // NOTE: to appease the borrow checker and have the proper argument for list_box
            // we must do build the list in two steps
            let paths: Vec<ImString> = filestate.files.iter().map(|p| {
                    im_str!("{:}", p).to_owned()
                })
                .collect();

            let paths: Vec<&ImStr> = paths.iter().map(|p|p.as_ref()).collect();

            ui.list_box(im_str!("Files"),
                        &mut filestate.idx,
                        &paths[..],
                        paths.len() as i32);
        })
}
<|endoftext|>


<commit_before>extern crate hkg;
extern crate termion;
extern crate rustc_serialize;
extern crate kuchiki;
extern crate chrono;
extern crate cancellation;

#[macro_use]
extern crate log;
extern crate log4rs;

use std::io::{stdout, stdin, Write};
use std::sync::mpsc::channel;
use std::sync::mpsc::Sender;
use std::sync::{Arc, Mutex};
use rustc_serialize::json;
use termion::input::TermRead;
use termion::raw::IntoRawMode;
use hkg::status::*;
use hkg::model::IconItem;
use hkg::state_manager::*;
use hkg::screen_manager::*;
use hkg::resources::*;
use hkg::web::*;
use hkg::responser::*;

fn main() {

    // Initialize
    log4rs::init_file("config/log4rs.yaml", Default::default()).expect("fail to init log4rs");

    // Clear the screen.
    hkg::screen::common::clear_screen();

    let _stdout = stdout();

    // web background services
    let (tx_req, rx_req) = channel::<ChannelItem>();
    let (tx_res, rx_res) = channel::<ChannelItem>();

    let mut app = {

        let stdout = {
            Box::new(_stdout.lock().into_raw_mode().expect("fail to lock stdout"))
        };

        let icon_collection: Box<Vec<IconItem>> = {
            let icon_manifest_string = hkg::utility::readfile(String::from("data/icon.manifest.json"));
            Box::new(json::decode(&icon_manifest_string).expect("fail to lock stdout"))
        };

        hkg::App {
            builder: hkg::builder::Builder::new(),
            state_manager: StateManager::new(),
            screen_manager: ScreenManager::new(),

            // initialize empty page
            list_topic_items: vec![],
            show_item: hkg::builder::Builder::new().default_show_item(),

            status_bar: hkg::screen::status_bar::StatusBar::new(),
            index: hkg::screen::index::Index::new(),
            show: hkg::screen::show::Show::new(icon_collection),

            image_request_count_lock: Arc::new(Mutex::new(0)),
            tx_req: &tx_req,
            rx_res: &rx_res,

            stdout: stdout
        }
    };

    Requester::new(rx_req, tx_res);

    let respsoner = Responser::new();

    let mut index_control = hkg::control::index::Index::new();
    let mut show_control = hkg::control::show::Show::new();

    // topics request
    let status_message = list_page(&mut app.state_manager, &tx_req);
    app.status_bar.append(&app.screen_manager, &status_message);

    loop {

        respsoner.try_recv(&mut app);

        print_screen(&mut app);

        app.status_bar.print(&app.screen_manager);

        app.stdout.flush().expect("fail to flush the stdout");

        if !app.state_manager.is_web_request() {

            let stdin = stdin();

            for c in stdin.keys() {

                if app.screen_manager.is_width_changed() {
                    hkg::screen::common::clear_screen();
                }

                match app.state_manager.get_state() {
                    Status::Startup => {}
                    Status::List => {
                        match index_control.handle(c.ok().expect("fail to get stdin keys"), &mut app) {
                            Some(i) => return if i == 0 { return } else { break },
                            None => {}
                        }
                    }
                    Status::Show => {
                        match show_control.handle(c.ok().expect("fail to get stdin keys"), &mut app) {
                            Some(i) => return if i == 0 { return } else { break },
                            None => {}
                        }
                    }
                }

            }
        }
    }
}

fn list_page(state_manager: &mut StateManager, tx_req: &Sender<ChannelItem>) -> String {

    let ci = ChannelItem {
        extra: ChannelItemType::Index(ChannelIndexItem {}),
        result: String::from(""),
    };

    let status_message = match tx_req.send(ci) {
        Ok(()) => {
            state_manager.set_web_request(true);    // *is_web_requesting = true;
            "SOK".to_string()
        }
        Err(e) => format!("{}:{}", "SFAIL", e).to_string(),
    };

    status_message
}

fn show_page(postid: &String, page: usize, state_manager: &mut StateManager, tx_req: &Sender<ChannelItem>) -> String {

    let ci = ChannelItem {
        extra: ChannelItemType::Show(ChannelShowItem {
                                         postid: postid.clone(),
                                         page: page,
                                     }),
        result: String::from(""),
    };

    let status_message = match tx_req.send(ci) {
        Ok(()) => {
            state_manager.setWebRequest(true); // *is_web_requesting = true;
            "SOK".to_string()
        }
        Err(e) => format!("{}:{}", "SFAIL", e).to_string(),
    };

    status_message
}

fn get_show_page_status_message(postid: &String, page: usize, status_message: &String) -> String {
    format!("[{}-{}:{}]", postid, page, status_message)
}

fn print_screen(app: &mut hkg::App) {
    match app.state_manager.get_state() {
        Status::Startup => {}
        Status::List => {
            app.index.print(&mut app.stdout, &app.list_topic_items);
        }
        Status::Show => {
            app.show.print(&mut app.stdout, &app.show_item);
        }
    }
}
<commit_msg>clean unused methods<commit_after>extern crate hkg;
extern crate termion;
extern crate rustc_serialize;
extern crate kuchiki;
extern crate chrono;
extern crate cancellation;

#[macro_use]
extern crate log;
extern crate log4rs;

use std::io::{stdout, stdin, Write};
use std::sync::mpsc::channel;
use std::sync::mpsc::Sender;
use std::sync::{Arc, Mutex};
use rustc_serialize::json;
use termion::input::TermRead;
use termion::raw::IntoRawMode;
use hkg::status::*;
use hkg::model::IconItem;
use hkg::state_manager::*;
use hkg::screen_manager::*;
use hkg::resources::*;
use hkg::web::*;
use hkg::responser::*;

fn main() {

    // Initialize
    log4rs::init_file("config/log4rs.yaml", Default::default()).expect("fail to init log4rs");

    // Clear the screen.
    hkg::screen::common::clear_screen();

    let _stdout = stdout();

    // web background services
    let (tx_req, rx_req) = channel::<ChannelItem>();
    let (tx_res, rx_res) = channel::<ChannelItem>();

    let mut app = {

        let stdout = {
            Box::new(_stdout.lock().into_raw_mode().expect("fail to lock stdout"))
        };

        let icon_collection: Box<Vec<IconItem>> = {
            let icon_manifest_string = hkg::utility::readfile(String::from("data/icon.manifest.json"));
            Box::new(json::decode(&icon_manifest_string).expect("fail to lock stdout"))
        };

        hkg::App {
            builder: hkg::builder::Builder::new(),
            state_manager: StateManager::new(),
            screen_manager: ScreenManager::new(),

            // initialize empty page
            list_topic_items: vec![],
            show_item: hkg::builder::Builder::new().default_show_item(),

            status_bar: hkg::screen::status_bar::StatusBar::new(),
            index: hkg::screen::index::Index::new(),
            show: hkg::screen::show::Show::new(icon_collection),

            image_request_count_lock: Arc::new(Mutex::new(0)),
            tx_req: &tx_req,
            rx_res: &rx_res,

            stdout: stdout
        }
    };

    Requester::new(rx_req, tx_res);

    let respsoner = Responser::new();

    let mut index_control = hkg::control::index::Index::new();
    let mut show_control = hkg::control::show::Show::new();

    // topics request
    let status_message = list_page(&mut app.state_manager, &tx_req);
    app.status_bar.append(&app.screen_manager, &status_message);

    loop {

        respsoner.try_recv(&mut app);

        print_screen(&mut app);

        app.status_bar.print(&app.screen_manager);

        app.stdout.flush().expect("fail to flush the stdout");

        if !app.state_manager.is_web_request() {

            let stdin = stdin();

            for c in stdin.keys() {

                if app.screen_manager.is_width_changed() {
                    hkg::screen::common::clear_screen();
                }

                match app.state_manager.get_state() {
                    Status::Startup => {}
                    Status::List => {
                        match index_control.handle(c.ok().expect("fail to get stdin keys"), &mut app) {
                            Some(i) => return if i == 0 { return } else { break },
                            None => {}
                        }
                    }
                    Status::Show => {
                        match show_control.handle(c.ok().expect("fail to get stdin keys"), &mut app) {
                            Some(i) => return if i == 0 { return } else { break },
                            None => {}
                        }
                    }
                }

            }
        }
    }
}

fn list_page(state_manager: &mut StateManager, tx_req: &Sender<ChannelItem>) -> String {

    let ci = ChannelItem {
        extra: ChannelItemType::Index(ChannelIndexItem {}),
        result: String::from(""),
    };

    let status_message = match tx_req.send(ci) {
        Ok(()) => {
            state_manager.set_web_request(true);    // *is_web_requesting = true;
            "SOK".to_string()
        }
        Err(e) => format!("{}:{}", "SFAIL", e).to_string(),
    };

    status_message
}

fn print_screen(app: &mut hkg::App) {
    match app.state_manager.get_state() {
        Status::Startup => {}
        Status::List => {
            app.index.print(&mut app.stdout, &app.list_topic_items);
        }
        Status::Show => {
            app.show.print(&mut app.stdout, &app.show_item);
        }
    }
}
<|endoftext|>


<commit_before>#![feature(globs)]
#![feature(phase)]
#![feature(unboxed_closures)]
#![feature(macro_rules)]
extern crate regex;
#[phase(plugin)] extern crate peruse;
extern crate peruse;

use std::collections::HashMap;
use peruse::parsers::*;
use grammar::*;
use parser::block;
use lexer::token;
use std::os;
use std::io::File;

pub mod lexer;
pub mod grammar;
pub mod parser;

fn main() {

  let args = os::args();

  let file = &args[1];

  let contents = File::open(&Path::new(file.as_slice())).read_to_string();

  match contents {
    Ok(raw) => {
      let lexer = token();
      match lexer.parse(raw.as_slice()) {
        Ok((tokens, rest)) => {
          if rest != "" {
            println!("Parser error at: {}", rest)
          } else {
            let parser = block();
            match parser.parse(tokens.as_slice()) {
              Ok((Block(stmts), rest)) => {
                if rest.len() > 0 {
                  println!("Error: unexpected token {}", rest[0]);
                } else {
                  run(&stmts);
                }
              }
              Err(err) => {println!("Parse Error: {}", err);}
            };
          }
        },
        Err(err) => {
          println!("Lexer error: {}", err);
        }
      }
    }
    Err(err) => {println!("Error Reading File: {}", err);}
  }

}

type Environment = HashMap<String, int>;

fn run(prog: &Vec<Statement>) {
  fn run_internal(prog: &Vec<Statement>, env: &mut Environment) {
    for s in prog.iter() {
      match *s {
        Assign(ref var, ref expr) => {
          match eval(expr, env) {
            Ok(res)   => {env.insert(var.clone(), res);}
            Err(err)  => {
              println!("ERROR: {}", err);
              return;
            }
          }
        },
        Output(ref expr) => match eval(expr, env) {
          Ok(val) => {println!("{}", val)}
          Err(err) => {
            println!("ERROR: {}", err)
            return;
          }
        },
        If(ref lhs, ref cmp, ref rhs, ref then_block, ref else_block) => {
          let is_true = compare(lhs, cmp, rhs, env);
          if (is_true) {
            let &Block(ref p) = then_block;
            run_internal(p, env);
          } else {
            match else_block {
              &Some(Block(ref p)) => {run_internal(p, env);}
              &None => {}
            }
          }
        }
        While(ref lhs, ref cmp, ref rhs, ref block) => {
          let &Block(ref stmts) = block;
          while(compare(lhs, cmp, rhs, env)) {
            run_internal(stmts, env);
          }
        }
      }
    }
  }
  let mut env: HashMap<String, int> = HashMap::new();
  run_internal(prog, &mut env);
}

fn compare(lhs: &Expr, cmp: &Comparator, rhs: &Expr, env: &Environment) -> bool {
  let l = eval(lhs, env);
  let r = eval(rhs, env);
  match *cmp {
    CEq   => l == r,
    CNeq  => l != r,
    CLt   => l < r,
    CGt   => l > r,
    CLeq  => l <= r,
    CGeq  => l >= r,
  }
}

fn eval(expr: &Expr, env: &HashMap<String, int>) -> Result<int, String> {
  match *expr {
    Variable(ref var) => match env.find(var) {
      Some(val) => Ok(*val),
      None => Err(format!("Undefined var {}", var)),
    },
    Num(val) => Ok(val),
    AddSub(ref ops) => {
      let mut sum = 0i;
      for &AddTerm(ref sign, ref op) in ops.iter() {
        match eval(op, env) {
          Ok(value) => match *sign {
            Add => {sum += value;}
            Subtract => {sum -= value;}
          },
          Err(err) => {
            return Err(err);
          }
        }
      }
      Ok(sum)
    },
    MultDiv(ref ops) => {
      let mut total = 1i;
      for &MultTerm(ref sign,ref op) in ops.iter() {
        match eval(op, env) {
          Ok(value) => match *sign{
            Multiply  => {total *= value;}
            Divide    => {total /= value;}
            Modulo    => {total %= value;}
          },
          Err(err) => {
            return Err(err);
          }
        }
      }
      Ok(total)
    }
  }
}

<commit_msg>adding benchmark<commit_after>#![feature(globs)]
#![feature(phase)]
#![feature(unboxed_closures)]
#![feature(macro_rules)]
extern crate regex;
#[phase(plugin)] extern crate peruse;
extern crate peruse;
extern crate test;

use std::mem::replace;
use test::Bencher;

use std::collections::HashMap;
use peruse::parsers::*;
use grammar::*;
use parser::block;
use lexer::token;
use std::os;
use std::io::File;

pub mod lexer;
pub mod grammar;
pub mod parser;

fn main() {

  let args = os::args();

  let file = &args[1];

  let contents = File::open(&Path::new(file.as_slice())).read_to_string();

  match contents {
    Ok(raw) => {
      interp(raw.as_slice());
    }
    Err(err) => {println!("Error Reading File: {}", err);}
  }

}

type Environment = HashMap<String, int>;

fn interp<'a>(raw: &'a str) {
  let lexer = token();
  match lexer.parse(raw) {
    Ok((tokens, rest)) => {
      if rest != "" {
        println!("Parser error at: {}", rest)
      } else {
        let parser = block();
        match parser.parse(tokens.as_slice()) {
          Ok((Block(stmts), rest)) => {
            if rest.len() > 0 {
              println!("Error: unexpected token {}", rest[0]);
            } else {
              run(&stmts);
            }
          }
          Err(err) => {println!("Parse Error: {}", err);}
        };
      }
    },
    Err(err) => {
      println!("Lexer error: {}", err);
    }
  }

}

fn run(prog: &Vec<Statement>) {
  fn run_internal(prog: &Vec<Statement>, env: &mut Environment) {
    for s in prog.iter() {
      match *s {
        Assign(ref var, ref expr) => {
          match eval(expr, env) {
            Ok(res)   => {env.insert(var.clone(), res);}
            Err(err)  => {
              println!("ERROR: {}", err);
              return;
            }
          }
        },
        Output(ref expr) => match eval(expr, env) {
          Ok(val) => {println!("{}", val)}
          Err(err) => {
            println!("ERROR: {}", err)
            return;
          }
        },
        If(ref lhs, ref cmp, ref rhs, ref then_block, ref else_block) => {
          let is_true = compare(lhs, cmp, rhs, env);
          if (is_true) {
            let &Block(ref p) = then_block;
            run_internal(p, env);
          } else {
            match else_block {
              &Some(Block(ref p)) => {run_internal(p, env);}
              &None => {}
            }
          }
        }
        While(ref lhs, ref cmp, ref rhs, ref block) => {
          let &Block(ref stmts) = block;
          while(compare(lhs, cmp, rhs, env)) {
            run_internal(stmts, env);
          }
        }
      }
    }
  }
  let mut env: HashMap<String, int> = HashMap::new();
  run_internal(prog, &mut env);
}

fn compare(lhs: &Expr, cmp: &Comparator, rhs: &Expr, env: &Environment) -> bool {
  let l = eval(lhs, env);
  let r = eval(rhs, env);
  match *cmp {
    CEq   => l == r,
    CNeq  => l != r,
    CLt   => l < r,
    CGt   => l > r,
    CLeq  => l <= r,
    CGeq  => l >= r,
  }
}

fn eval(expr: &Expr, env: &HashMap<String, int>) -> Result<int, String> {
  match *expr {
    Variable(ref var) => match env.find(var) {
      Some(val) => Ok(*val),
      None => Err(format!("Undefined var {}", var)),
    },
    Num(val) => Ok(val),
    AddSub(ref ops) => {
      let mut sum = 0i;
      for &AddTerm(ref sign, ref op) in ops.iter() {
        match eval(op, env) {
          Ok(value) => match *sign {
            Add => {sum += value;}
            Subtract => {sum -= value;}
          },
          Err(err) => {
            return Err(err);
          }
        }
      }
      Ok(sum)
    },
    MultDiv(ref ops) => {
      let mut total = 1i;
      for &MultTerm(ref sign,ref op) in ops.iter() {
        match eval(op, env) {
          Ok(value) => match *sign{
            Multiply  => {total *= value;}
            Divide    => {total /= value;}
            Modulo    => {total %= value;}
          },
          Err(err) => {
            return Err(err);
          }
        }
      }
      Ok(total)
    }
  }
}

#[bench]
fn bench_run(b: &mut Bencher) {
    let prog = "n1 = 1
n2 = 1
n = n1 + n2
i = 0

while i < 30 {
  n2 = n1
  n1 = n
  n = n1 + n2
  i = i + 1
}
";
  let lexer = token();
  let (tokens, rest) = lexer.parse(prog).unwrap();
  let parser = block();
  b.iter(|| {
    parser.parse(tokens.as_slice());
  })
}

<|endoftext|>