<commit_before>extern crate iron;
extern crate serde;
extern crate serde_json;

#[macro_use]
extern crate serde_derive;

extern crate router;

use router::Router;
use iron::prelude::*;
use iron::{status, headers};
use iron::method::Method;
use iron::modifiers::Header;

use std::io::Read;
use std::process::Command;

#[derive(Debug, Deserialize, Serialize)]
struct Address {
    address: String
}

#[derive(Debug, Deserialize, Serialize)]
struct TxId {
	txid: String
}

#[derive(Debug, Deserialize, Serialize)]
struct OmniTransaction {
	#[serde(rename = "type")]
	type_type: String,
	txid: String,
	fee: String,
	sendingaddress: String,
	#[serde(default="default_string")]
	referenceaddress: String,
	ismine: bool,
	version: u8,
	type_int: u8,
	propertyid: u8,
	divisible: bool,
	amount: String,
	valid: bool,
	blockhash: String,
	blocktime: u32,
	positioninblock: u32,
	block: u32,
	confirmations: u32,
}

#[derive(Debug, Deserialize, Serialize)]
struct OmniInfo {
	omnicoreversion_int: u32,
	omnicoreversion: String,
	mastercoreversion: String,
	bitcoincoreversion: String,
	block: u32,
	blocktime: u32,
	blocktransactions: u32,
	totaltrades: u32,
	alerts: Vec<String>
}

fn default_string() -> String {
	"reference".to_string()
}
#[derive(Debug, Deserialize, Serialize)]
struct RawTxn {
	rawtx: String,
}

#[derive(Debug, Deserialize, Serialize)]
struct unconfirmedTransactions {
	txid: String,
	fee: String,
	sendingaddress: String,
	referenceaddress: String,
	ismine: bool,
	version: u32,
	type_int: u32,
	#[serde(rename = "type")]
	type_type: String,
	propertyid: u32,
	divisible: bool,
	amount: String,
	confirmations: u32
}

fn main() {
	let mut router = Router::new();

	router.post("/balance", move |r: &mut Request| get_balance(r), "get_balance");
	router.post("/transactions", move |r: &mut Request| get_transactions(r), "get_transactions");
	router.post("/broadcast", move |r: &mut Request| broadcast(r), "broadcast");
	router.post("/unconfirmed", move |r: &mut Request| unconfirmed(r), "unconfirmed");
	router.get("/getfee", move |r: &mut Request| getfee(r), "getfee");
	router.get("/blockheight", get_blockheight, "get_blockheight");

	//route for get balance, accepts a public key, and a property identifier

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

		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let address: Address = serde_json::from_str(&payload).unwrap();
		let balance = Command::new("omnicore-cli").arg("omni_getbalance").arg(address.address).arg("56").output().expect("failed");

		let output = balance.stdout;
		let mut response = Response::with((status::Ok, output));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

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

		let fee = Command::new("omnicore-cli").arg("estimatefee").arg("6").output().expect("failed");

		let output = fee.stdout;
		let mut response = Response::with((status::Ok, output));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn unconfirmed(req: &mut Request) -> IronResult<Response> {
		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let address: Address = serde_json::from_str(&payload).unwrap();
		let output = Command::new("omnicore-cli").arg("omni_listpendingtransactions").arg(&address.address).output().expect("failed");
		let output = String::from_utf8(output.stdout).unwrap();
		let output: Vec<unconfirmedTransactions> = serde_json::from_str(&output).unwrap();
		let mut pending_balance = 0;
		for txn in output {
			if address.address == txn.sendingaddress {
				pending_balance -= txn.amount.parse::<i32>().unwrap();
			} else {
				pending_balance += txn.amount.parse::<i32>().unwrap();
			}
		}

		let mut response = Response::with((status::Ok, pending_balance.to_string()));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn broadcast(req: &mut Request) -> IronResult<Response> {
		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let txn: RawTxn = serde_json::from_str(&payload).unwrap();
		let output = Command::new("omnicore-cli").arg("sendrawtransaction").arg(txn.rawtx).output().expect("failed");

		let output = output.stdout;
		let mut response = Response::with((status::Ok, output));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn get_transactions(req: &mut Request) -> IronResult<Response> {
		println!("{:?}", req);
		//todo remove unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		println!("got through read to string");
		let txid: TxId = serde_json::from_str(&payload).unwrap();
		println!("didnt get through txid");

		let transaction = Command::new("omnicore-cli").arg("omni_gettransaction").arg(txid.txid).output().expect("failed");

		println!("got the command in");

		let output = transaction.stdout;

		let string_output = String::from_utf8_lossy(&output);

		let safex_tx: OmniTransaction = serde_json::from_str(&string_output).unwrap();

		if safex_tx.propertyid == 56 {

			let mut response = Response::with((status::Ok, serde_json::to_string(&safex_tx).unwrap()));
			response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
			response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));

			Ok(response)
		} else {

			Ok(Response::with((status::Ok)))
		}

	}

	fn get_blockheight(_: &mut Request) -> IronResult<Response> {
		let block_info = Command::new("omnicore-cli").arg("omni_getinfo").output().expect("failed");

		let output = block_info.stdout;

		let string_output = String::from_utf8_lossy(&output);
		let block_info: OmniInfo = serde_json::from_str(&string_output).unwrap();

		let mut response = Response::with((status::Ok, serde_json::to_string(&block_info).unwrap()));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));

		Ok(response)
	}

	Iron::new(router).http("localhost:3001").unwrap();
}
<commit_msg>adjust fee<commit_after>extern crate iron;
extern crate serde;
extern crate serde_json;

#[macro_use]
extern crate serde_derive;

extern crate router;

use router::Router;
use iron::prelude::*;
use iron::{status, headers};
use iron::method::Method;
use iron::modifiers::Header;

use std::io::Read;
use std::process::Command;

#[derive(Debug, Deserialize, Serialize)]
struct Address {
    address: String
}

#[derive(Debug, Deserialize, Serialize)]
struct TxId {
	txid: String
}

#[derive(Debug, Deserialize, Serialize)]
struct OmniTransaction {
	#[serde(rename = "type")]
	type_type: String,
	txid: String,
	fee: String,
	sendingaddress: String,
	#[serde(default="default_string")]
	referenceaddress: String,
	ismine: bool,
	version: u8,
	type_int: u8,
	propertyid: u8,
	divisible: bool,
	amount: String,
	valid: bool,
	blockhash: String,
	blocktime: u32,
	positioninblock: u32,
	block: u32,
	confirmations: u32,
}

#[derive(Debug, Deserialize, Serialize)]
struct OmniInfo {
	omnicoreversion_int: u32,
	omnicoreversion: String,
	mastercoreversion: String,
	bitcoincoreversion: String,
	block: u32,
	blocktime: u32,
	blocktransactions: u32,
	totaltrades: u32,
	alerts: Vec<String>
}

fn default_string() -> String {
	"reference".to_string()
}
#[derive(Debug, Deserialize, Serialize)]
struct RawTxn {
	rawtx: String,
}

#[derive(Debug, Deserialize, Serialize)]
struct unconfirmedTransactions {
	txid: String,
	fee: String,
	sendingaddress: String,
	referenceaddress: String,
	ismine: bool,
	version: u32,
	type_int: u32,
	#[serde(rename = "type")]
	type_type: String,
	propertyid: u32,
	divisible: bool,
	amount: String,
	confirmations: u32
}

fn main() {
	let mut router = Router::new();

	router.post("/balance", move |r: &mut Request| get_balance(r), "get_balance");
	router.post("/transactions", move |r: &mut Request| get_transactions(r), "get_transactions");
	router.post("/broadcast", move |r: &mut Request| broadcast(r), "broadcast");
	router.post("/unconfirmed", move |r: &mut Request| unconfirmed(r), "unconfirmed");
	router.get("/getfee", move |r: &mut Request| getfee(r), "getfee");
	router.get("/blockheight", get_blockheight, "get_blockheight");

	//route for get balance, accepts a public key, and a property identifier

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

		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let address: Address = serde_json::from_str(&payload).unwrap();
		let balance = Command::new("omnicore-cli").arg("omni_getbalance").arg(address.address).arg("56").output().expect("failed");

		let output = balance.stdout;
		let mut response = Response::with((status::Ok, output));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

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

		let fee = Command::new("omnicore-cli").arg("estimatefee").arg("6").output().expect("failed");

		 let mut s = String::from_utf8(fee.stdout).unwrap();
    		s.pop();
		let mut response = Response::with((status::Ok, s));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn unconfirmed(req: &mut Request) -> IronResult<Response> {
		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let address: Address = serde_json::from_str(&payload).unwrap();
		let output = Command::new("omnicore-cli").arg("omni_listpendingtransactions").arg(&address.address).output().expect("failed");
		let output = String::from_utf8(output.stdout).unwrap();
		let output: Vec<unconfirmedTransactions> = serde_json::from_str(&output).unwrap();
		let mut pending_balance = 0;
		for txn in output {
			if address.address == txn.sendingaddress {
				pending_balance -= txn.amount.parse::<i32>().unwrap();
			} else {
				pending_balance += txn.amount.parse::<i32>().unwrap();
			}
		}

		let mut response = Response::with((status::Ok, pending_balance.to_string()));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn broadcast(req: &mut Request) -> IronResult<Response> {
		//todo get rid of unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		let txn: RawTxn = serde_json::from_str(&payload).unwrap();
		let output = Command::new("omnicore-cli").arg("sendrawtransaction").arg(txn.rawtx).output().expect("failed");

		let output = output.stdout;
		let mut response = Response::with((status::Ok, output));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));
		Ok(response)
	}

	fn get_transactions(req: &mut Request) -> IronResult<Response> {
		println!("{:?}", req);
		//todo remove unwraps
		let mut payload = String::new();
		req.body.read_to_string(&mut payload).unwrap();
		println!("got through read to string");
		let txid: TxId = serde_json::from_str(&payload).unwrap();
		println!("didnt get through txid");

		let transaction = Command::new("omnicore-cli").arg("omni_gettransaction").arg(txid.txid).output().expect("failed");

		println!("got the command in");

		let output = transaction.stdout;

		let string_output = String::from_utf8_lossy(&output);

		let safex_tx: OmniTransaction = serde_json::from_str(&string_output).unwrap();

		if safex_tx.propertyid == 56 {

			let mut response = Response::with((status::Ok, serde_json::to_string(&safex_tx).unwrap()));
			response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
			response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));

			Ok(response)
		} else {

			Ok(Response::with((status::Ok)))
		}

	}

	fn get_blockheight(_: &mut Request) -> IronResult<Response> {
		let block_info = Command::new("omnicore-cli").arg("omni_getinfo").output().expect("failed");

		let output = block_info.stdout;

		let string_output = String::from_utf8_lossy(&output);
		let block_info: OmniInfo = serde_json::from_str(&string_output).unwrap();

		let mut response = Response::with((status::Ok, serde_json::to_string(&block_info).unwrap()));
		response.set_mut(Header(headers::AccessControlAllowOrigin::Any));
		response.set_mut(Header(headers::AccessControlAllowMethods(vec![Method::Post])));

		Ok(response)
	}

	Iron::new(router).http("localhost:3001").unwrap();
}
<|endoftext|>


<commit_before>extern crate regex;

static DEFAULT_ALPHABET: &'static str =  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";

static DEFAULT_SEPARATORS: &'static str = "cfhistuCFHISTU";
static SEP_DIV: f32 = 3.5;
static GUARD_DIV: u32 = 12;
static MIN_ALPHABET_LENGTH: usize = 16;

struct HashIds {
  salt: String,
  alphabet: String,
  separators: String,
  minHashLength: usize,
  guards: String
}

impl HashIds {

  pub fn new(salt: String, minHashLength: usize, alphabet: String) -> HashIds {
    use std::num::Float;

    let minLength = HashIds::getMinHashLength(minHashLength);
    let uniqueAlphabet = HashIds::getUniqueAlphabet(alphabet);

    if uniqueAlphabet.len() < ::MIN_ALPHABET_LENGTH {
      //Error
    }

    let (t_separators, mut t_alphabet) = HashIds::getSeps(uniqueAlphabet);
    let mut shuffledSeparators = HashIds::hashids_shuffle(t_separators.clone(), salt.clone());

    if HashIds::needManipulate(shuffledSeparators.len(), t_alphabet.len()) == true {
      let mut seps_len =  ((t_alphabet.len() as f32) / ::SEP_DIV) as usize;
      if seps_len == 1 {
        seps_len += 1;
      }

      if seps_len > shuffledSeparators.len() {
        let diff = seps_len - shuffledSeparators.len();
        shuffledSeparators.push_str(t_alphabet.slice(0,diff));
        t_alphabet = t_alphabet.slice_from(diff).to_string();
      } else {
        shuffledSeparators = shuffledSeparators.slice(0, seps_len).to_string();
      }
    }

    let mut shuffledAlphabet = HashIds::hashids_shuffle(t_alphabet.clone(), salt.clone());
    let guardCount = (shuffledAlphabet.len() as f32 / ::GUARD_DIV as f32).ceil() as usize;

    let mut t_guards;

    if guardCount < 3 {
      t_guards = shuffledSeparators.slice(0, guardCount).to_string();
      shuffledSeparators = shuffledSeparators.slice_from(guardCount).to_string();
    } else {
      t_guards = shuffledAlphabet.slice(0, guardCount).to_string();
      shuffledAlphabet = shuffledAlphabet.slice_from(guardCount).to_string();
    }

    HashIds {
      salt: salt.to_string(),
      minHashLength: minLength,
      guards: t_guards,
      separators: shuffledSeparators,
      alphabet: shuffledAlphabet
    }
  }

  pub fn newWithSaltAndMinLength(salt: String, minHashLength: usize) -> HashIds {
    HashIds::new(salt, minHashLength, DEFAULT_ALPHABET.to_string())
  }

  pub fn newWithSalt(salt: String) -> HashIds {
    HashIds::newWithSaltAndMinLength(salt, 0)
  }

  fn needManipulate(slen: usize, alen: usize) -> bool {
    if slen <= 0 && (((alen/slen) as f32)> ::SEP_DIV) {
      return true;
    }

    false
  }

  fn getMinHashLength(length: usize) -> usize {
    if length > 0 {
      return length;
    } else {
      return 0;
    }
  }

  fn getSeps(alphabet: String) -> (String, String) {
    HashIds::getNonDuplicatedString(::DEFAULT_SEPARATORS.to_string(), alphabet)
  }

  fn hashids_shuffle(alphabet: String, salt: String) -> String {
    if salt.len() <= 0 {
      return alphabet;
    }

    let salt_len = salt.len();
    let arr = salt.as_bytes();
    let len = alphabet.len();
    let mut bytes = alphabet.into_bytes();
    let mut shuffle = bytes.as_mut_slice();

    let mut i: usize = len-1;
    let mut j: usize = 0;
    let mut v: usize = 0;
    let mut p: usize = 0;
    let mut temp1: u8;
    let mut temp2: u8;
    let mut t: usize = 0;

    while i > 0 {
      v %= salt_len;
      t = arr[v] as usize;
      p += t;
      j = (t + v + p) % i;

      shuffle.swap(i,j);

      i=i-1;
      v=v+1;
    }

    let mut shuffledAlphabet = String::with_capacity(len);
    for i in (0..len) {
      shuffledAlphabet.push(shuffle[i] as char);
    }

    shuffledAlphabet
  }

  fn getNonDuplicatedString(separators: String, alphabet: String) -> (String, String) {
    use std::collections::HashMap;
    let mut checkSeparatorMap = HashMap::new();
    let mut checkAlphabetMap = HashMap::new();

    let mut modifiedSeparators = String::new();
    let mut modifiedAlphabet = String::new();

    for c in separators.chars() {
      checkSeparatorMap.insert(c, 1);
    }

    for c in alphabet.chars() {
      checkAlphabetMap.insert(c, 1);
    }

    for c in separators.chars() {
      if checkAlphabetMap.contains_key(&c) {
        modifiedSeparators.push(c);
      }
    }

    for c in alphabet.chars() {
      if !checkSeparatorMap.contains_key(&c) {
        modifiedAlphabet.push(c);
      }
    }

    (modifiedSeparators, modifiedAlphabet)
  }

  fn getUniqueAlphabet(alphabet: String) -> String {
    use std::collections::HashMap;

    let mut uniqueAlphabet: String = String::new();
    let mut checkMap = HashMap::new();

    for c in alphabet.chars() {
      if !checkMap.contains_key(&c) {
        uniqueAlphabet.push(c);
        checkMap.insert(c, 1);
      }
    }

    uniqueAlphabet
  }

  fn encrypt(&self, numbers: &Vec<i64>) -> String {
    return self.encode(numbers);
  }

  fn decrypt(&self, hash: String) -> Vec<i64> {
    return self.decode(hash);
  }

  fn encode(&self, numbers: &Vec<i64>) -> String {
    let mut ret = "".to_string();
    if numbers.len() == 0 {
      return ret;
    }

    for number in numbers.iter() {
      if *number > 9007199254740992 {
        return ret;
      }
    }

    self._encode(numbers)
  }

  fn decode(&self, hash: String) -> Vec<i64> {
    let ret : Vec<i64> = Vec::new();
    if hash.len() == 0 {
      return ret;
    }

    self._decode(hash)
  }

  fn _decode(&self, hash: String) -> Vec<i64> {
    use regex::Regex;

    let mut regexp = String::new();
    regexp.push('[');
    regexp.push_str(self.guards.as_slice());
    regexp.push(']');

    let re = Regex::new(regexp.as_slice()).unwrap();
    let t_hash = re.replace_all(hash.as_slice(), " ");

    let mut split: Vec<&str> = t_hash.as_slice().split_str(" ").collect();
    let mut i = 0;

    let len = split.len();
    if len == 3 || len == 2 {
      i = 1;
    }
    let mut hashBreakdown = split[i].to_string();

    let lottery = hashBreakdown.slice(0,1).to_string();

    hashBreakdown = hashBreakdown.slice_from(1).to_string();

    let mut regexp2 = String::new();
    regexp2.push('[');
    regexp2.push_str(self.separators.as_slice());
    regexp2.push(']');

    let re2 = Regex::new(regexp2.as_slice()).unwrap();
    hashBreakdown  = re2.replace_all(hashBreakdown.as_slice(), " ");

    split = hashBreakdown.as_slice().split_str(" ").collect();

    let mut alphabet = self.alphabet.clone();

    let mut ret: Vec<i64> = Vec::new();

    for s in split.iter() {
      let subHash = s.to_string();
      let mut buffer = String::new();
      buffer.push_str(lottery.as_slice());
      buffer.push_str(self.salt.as_slice());
      buffer.push_str(alphabet.clone().as_slice());

      let alpha_len = alphabet.len();
      alphabet = HashIds::hashids_shuffle(alphabet, buffer.slice(0, alpha_len).to_string());
      ret.push(HashIds::unhash(subHash, alphabet.clone()));
    }

    ret
  }

  fn indexOf(input :&[u8], v: u8) -> i64 {
    let mut i = 0;
    for s in input.iter() {
      if *s == v {
        return i;
      }

      i += 1;
    }

    return -1;
  }

  fn unhash(input: String, alphabet: String) -> i64 {
    use std::num::Int;

    let mut number: i64 = 0;
    let input_slice = input.as_bytes();
    let alpha_slice = alphabet.as_bytes();
    let len = input.len();
    let alpha_len = alphabet.len() as i64;
    let mut pos : usize = 0;

    let mut i: usize = 0;
    loop {
      if i >= len {
        break;
      }

      let v = input_slice[i] as usize;
      let pos = HashIds::indexOf(alpha_slice, v as u8);
      let pow_size = (len - i - 1) as usize;
      number += ((pos * alpha_len.pow(pow_size)) as i64);
      i += 1;
    }

    number
  }

  fn hash(input: i64, alphabet: String) -> String {
    let mut t_in = input;
    let mut hash = "".to_string();
    let len = alphabet.len() as i64;
    let mut idx = 0;

    loop {
      idx = (t_in % len) as usize;
      let mut t = alphabet.slice(idx, idx+1).to_string();
      t.push_str(hash.as_slice());
      hash = t;
      t_in /= len;

      if t_in <= 0 {
        break;
      }
    }

    hash
  }

  fn _encode(&self, numbers: &Vec<i64>) -> String {
    let mut numberHashInt  = 0;
    let mut count = 100;
    for number in numbers.iter() {
      numberHashInt += (*number % count);
      count += 1;
    }

    let idx = (numberHashInt % (self.alphabet.len() as i64)) as usize;
    let ret = self.alphabet.slice(idx, idx+1).to_string();
    let mut ret_str = ret.clone();

    let mut t_alphabet = self.alphabet.clone();
    for number in numbers.iter() {
      let mut buffer = ret.clone();
      buffer.push_str(self.salt.as_slice());
      buffer.push_str(t_alphabet.as_slice());
      t_alphabet = HashIds::hashids_shuffle(t_alphabet.clone(), buffer.slice(0, t_alphabet.len()).to_string());
      let last = HashIds::hash(*number, t_alphabet.clone());

      ret_str.push_str(last.as_slice());
    }

    if ret_str.len() < self.minHashLength {
      let guardIdx = (numberHashInt + ret_str.clone().into_bytes()[0] as i64) as usize % self.guards.len();
      let guard = self.guards.slice(guardIdx, guardIdx+1).to_string();
      let mut t = guard.clone();
      t.push_str(ret_str.as_slice());
      ret_str = t;

      if ret_str.len() < self.minHashLength {
        let guardIdx = (numberHashInt + ret_str.clone().into_bytes()[2] as i64) as usize % self.guards.len();
        let guard = self.guards.slice(guardIdx, guardIdx+1);
        ret_str.push_str(guard)
      }
    }

    let halfLen = t_alphabet.len() / 2;
    while ret_str.len() < self.minHashLength {
      t_alphabet = HashIds::hashids_shuffle(t_alphabet.clone(), t_alphabet.clone());
      let mut t_ret = "".to_string();
      t_ret.push_str(t_alphabet.slice_from(halfLen));
      t_ret.push_str(ret_str.as_slice());
      t_ret.push_str(t_alphabet.slice(0, halfLen));
      ret_str = t_ret;

      let excess = (ret_str.len() as i64 - self.minHashLength as i64);
      println!("excess = {}", excess);
      if (excess > 0) {
        let start_pos = (excess as i64 / 2) as usize;
        ret_str = ret_str.slice(start_pos, start_pos + self.minHashLength).to_string();
      }
    }

    ret_str
  }
}

fn main() {
//  let ids = HashIds::new("1234".to_string(), 10, DEFAULT_ALPHABET.to_string());
  let ids = HashIds::newWithSalt("this is my salt".to_string());
  println!("{}", ids.alphabet);
  println!("{}", ids.separators);
  let numbers: Vec<i64> = vec![12345];
  let encode = ids.encrypt(&numbers);
  println!("{}", encode);

  let longs = ids.decrypt(encode);
  for s in longs.iter() {
    println!("{}", s);
  }
}
<commit_msg>fix bug and add encode_hex and decode_hex<commit_after>extern crate regex;

static DEFAULT_ALPHABET: &'static str =  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
static DEFAULT_SEPARATORS: &'static str = "cfhistuCFHISTU";
static SEP_DIV: f32 = 3.5;
static GUARD_DIV: u32 = 12;
static MIN_ALPHABET_LENGTH: usize = 16;

struct HashIds {
  salt: String,
  alphabet: String,
  separators: String,
  min_hash_length: usize,
  guards: String
}

impl HashIds {

  pub fn new(salt: String, min_hash_length: usize, alphabet: String) -> HashIds {
    use std::num::Float;

    let min_length = HashIds::get_min_hash_length(min_hash_length);
    let unique_alphabet = HashIds::get_unique_alphabet(alphabet);

    if unique_alphabet.len() < ::MIN_ALPHABET_LENGTH {
      //Error
    }

    let (t_separators, mut t_alphabet) = HashIds::get_separators(unique_alphabet);
    let mut shuffled_separators = HashIds::hashids_shuffle(t_separators.clone(), salt.clone());

    if HashIds::need_manipulate(shuffled_separators.len(), t_alphabet.len()) == true {
      let mut seps_len =  ((t_alphabet.len() as f32) / ::SEP_DIV) as usize;
      if seps_len == 1 {
        seps_len += 1;
      }

      if seps_len > shuffled_separators.len() {
        let diff = seps_len - shuffled_separators.len();
        shuffled_separators.push_str(t_alphabet.slice(0,diff));
        t_alphabet = t_alphabet.slice_from(diff).to_string();
      } else {
        shuffled_separators = shuffled_separators.slice(0, seps_len).to_string();
      }
    }

    let mut shuffled_alphabet = HashIds::hashids_shuffle(t_alphabet.clone(), salt.clone());
    let guard_count = (shuffled_alphabet.len() as f32 / ::GUARD_DIV as f32).ceil() as usize;

    let mut t_guards;

    if guard_count < 3 {
      t_guards = shuffled_separators.slice(0, guard_count).to_string();
      shuffled_separators = shuffled_separators.slice_from(guard_count).to_string();
    } else {
      t_guards = shuffled_alphabet.slice(0, guard_count).to_string();
      shuffled_alphabet = shuffled_alphabet.slice_from(guard_count).to_string();
    }

    HashIds {
      salt: salt,
      min_hash_length: min_length,
      guards: t_guards,
      separators: shuffled_separators,
      alphabet: shuffled_alphabet
    }
  }

  pub fn new_with_salt_and_min_length(salt: String, min_hash_length: usize) -> HashIds {
    HashIds::new(salt, min_hash_length, DEFAULT_ALPHABET.to_string())
  }

  pub fn new_with_salt(salt: String) -> HashIds {
    HashIds::new_with_salt_and_min_length(salt, 0)
  }

  fn need_manipulate(slen: usize, alen: usize) -> bool {
    if slen <= 0 && (((alen/slen) as f32)> ::SEP_DIV) {
      return true;
    }

    false
  }

  fn get_min_hash_length(length: usize) -> usize {
    if length > 0 {
      return length;
    } else {
      return 0;
    }
  }

  fn get_separators(alphabet: String) -> (String, String) {
    HashIds::get_non_duplicated_string(::DEFAULT_SEPARATORS.to_string(), alphabet)
  }

  fn hashids_shuffle(alphabet: String, salt: String) -> String {
    if salt.len() <= 0 {
      return alphabet;
    }

    let salt_len = salt.len();
    let arr = salt.as_bytes();
    let len = alphabet.len();
    let mut bytes = alphabet.into_bytes();
    let mut shuffle = bytes.as_mut_slice();

    let mut i: usize = len-1;
    let mut v: usize = 0;
    let mut p: usize = 0;

    while i > 0 {
      v %= salt_len;
      let t = arr[v] as usize;
      p += t;
      let j = (t + v + p) % i;

      shuffle.swap(i,j);

      i=i-1;
      v=v+1;
    }

    let mut shuffled_alphabet = String::with_capacity(len);
    for i in (0..len) {
      shuffled_alphabet.push(shuffle[i] as char);
    }

    shuffled_alphabet
  }

  fn get_non_duplicated_string(separators: String, alphabet: String) -> (String, String) {
    use std::collections::HashMap;
    let mut check_separator_map = HashMap::new();
    let mut check_alphabet_map = HashMap::new();

    let mut modified_separators = String::new();
    let mut modified_alphabet = String::new();

    for c in separators.chars() {
      check_separator_map.insert(c, 1);
    }

    for c in alphabet.chars() {
      check_alphabet_map.insert(c, 1);
    }

    for c in separators.chars() {
      if check_alphabet_map.contains_key(&c) {
        modified_separators.push(c);
      }
    }

    for c in alphabet.chars() {
      if !check_separator_map.contains_key(&c) {
        modified_alphabet.push(c);
      }
    }

    (modified_separators, modified_alphabet)
  }

  fn get_unique_alphabet(alphabet: String) -> String {
    use std::collections::HashMap;

    let mut unique_alphabet: String = String::new();
    let mut check_map = HashMap::new();

    for c in alphabet.chars() {
      if !check_map.contains_key(&c) {
        unique_alphabet.push(c);
        check_map.insert(c, 1);
      }
    }

    unique_alphabet
  }

  fn encrypt(&self, numbers: &Vec<i64>) -> String {
    return self.encode(numbers);
  }

  fn decrypt(&self, hash: String) -> Vec<i64> {
    return self.decode(hash);
  }

  fn encode_hex(&self, hex: String) -> String {
    use regex::Regex;
    use std::num;
    let regex1 = Regex::new(r"^[0-9a-fA-F]+$").unwrap();
    if regex1.is_match(hex.as_slice()) == false {
      return String::new();
    }

    let mut numbers: Vec<i64> = Vec::new();
    let regex2 = Regex::new(r"[\w\W]{1,12}").unwrap();
    for matcher in regex2.find_iter(hex.as_slice()) {
      let mut num = String::new();
      num.push('1');
      num.push_str(hex.slice(matcher.0, matcher.1));
      let v: i64 = num::from_str_radix(num.as_slice(), 16).unwrap();
      numbers.push(v);
    }

    self.encode(&numbers)
  }

  fn decode_hex(&self, hash: String) -> String {
    use std::fmt;
    let mut ret = String::new();
    let numbers = self.decode(hash);
    for number in numbers.iter() {
      let r = format!("{:x}", number);
      ret.push_str(r.slice_from(1));
    }

    ret
  }

  fn encode(&self, numbers: &Vec<i64>) -> String {
    if numbers.len() == 0 {
      return "".to_string();
    }

    for number in numbers.iter() {
      if *number > 9007199254740992 {
        return "".to_string();
      }
    }

    self._encode(numbers)
  }

  fn decode(&self, hash: String) -> Vec<i64> {
    let ret : Vec<i64> = Vec::new();
    if hash.len() == 0 {
      return ret;
    }

    self._decode(hash)
  }

  fn _decode(&self, hash: String) -> Vec<i64> {
    use regex::Regex;

    let mut regexp = String::new();
    regexp.push('[');
    regexp.push_str(self.guards.as_slice());
    regexp.push(']');

    let re = Regex::new(regexp.as_slice()).unwrap();
    let t_hash = re.replace_all(hash.as_slice(), " ");

    let mut split: Vec<&str> = t_hash.as_slice().split_str(" ").collect();
    let mut i = 0;

    let len = split.len();
    if len == 3 || len == 2 {
      i = 1;
    }
    let mut hash_breakdown = split[i].to_string();

    let lottery = hash_breakdown.slice(0,1).to_string();

    hash_breakdown = hash_breakdown.slice_from(1).to_string();

    let mut regexp2 = String::new();
    regexp2.push('[');
    regexp2.push_str(self.separators.as_slice());
    regexp2.push(']');

    let re2 = Regex::new(regexp2.as_slice()).unwrap();
    hash_breakdown  = re2.replace_all(hash_breakdown.as_slice(), " ");

    split = hash_breakdown.as_slice().split_str(" ").collect();

    let mut alphabet = self.alphabet.clone();

    let mut ret: Vec<i64> = Vec::new();

    for s in split.iter() {
      let sub_hash = s.to_string();
      let mut buffer = String::new();
      buffer.push_str(lottery.as_slice());
      buffer.push_str(self.salt.as_slice());
      buffer.push_str(alphabet.clone().as_slice());

      let alpha_len = alphabet.len();
      alphabet = HashIds::hashids_shuffle(alphabet, buffer.slice(0, alpha_len).to_string());
      ret.push(HashIds::unhash(sub_hash, alphabet.clone()));
    }

    ret
  }

  fn index_of(input :&[u8], v: u8) -> i64 {
    let mut i = 0;
    for s in input.iter() {
      if *s == v {
        return i;
      }

      i += 1;
    }

    return -1;
  }

  fn unhash(input: String, alphabet: String) -> i64 {
    use std::num::Int;

    let mut number: i64 = 0;
    let input_slice = input.as_bytes();
    let alpha_slice = alphabet.as_bytes();
    let len = input.len();
    let alpha_len = alphabet.len() as i64;
    let mut i: usize = 0;
    loop {
      if i >= len {
        break;
      }

      let v = input_slice[i] as usize;
      let pos = HashIds::index_of(alpha_slice, v as u8);
      let pow_size = (len - i - 1) as usize;
      number += ((pos * alpha_len.pow(pow_size)) as i64);
      i += 1;
    }

    number
  }

  fn hash(input: i64, alphabet: String) -> String {
    let mut t_in = input;
    let mut hash = "".to_string();
    let len = alphabet.len() as i64;

    loop {
      let idx = (t_in % len) as usize;
      let mut t = alphabet.slice(idx, idx+1).to_string();
      t.push_str(hash.as_slice());
      hash = t;
      t_in /= len;

      if t_in <= 0 {
        break;
      }
    }

    hash
  }

  fn _encode(&self, numbers: &Vec<i64>) -> String {
    let mut number_hash_int  = 0;
    let mut count = 100;
    for number in numbers.iter() {
      number_hash_int += (*number % count);
      count += 1;
    }

    let idx = (number_hash_int % (self.alphabet.len() as i64)) as usize;
    let ret = self.alphabet.slice(idx, idx+1).to_string();
    let mut ret_str = ret.clone();

    let mut t_alphabet = self.alphabet.clone();
    let mut i = 0;
    let len = self.separators.len() as i64;
    let last_len = count - 100;
    for number in numbers.iter() {
      let mut buffer = ret.clone();
      buffer.push_str(self.salt.as_slice());
      buffer.push_str(t_alphabet.as_slice());
      t_alphabet = HashIds::hashids_shuffle(t_alphabet.clone(), buffer.slice(0, t_alphabet.len()).to_string());
      let last = HashIds::hash(*number, t_alphabet.clone());

      ret_str.push_str(last.as_slice());

      if (i + 1) < last_len {
        let mut v = *number % (last.as_bytes()[0] as i64 + i);
        v = v % len;
        ret_str.push(self.separators.as_bytes()[v as usize] as char);
      }
      i += 1;
    }

    if ret_str.len() < self.min_hash_length {
      let guard_idx = (number_hash_int + ret_str.clone().into_bytes()[0] as i64) as usize % self.guards.len();
      let guard = self.guards.slice(guard_idx, guard_idx+1).to_string();
      let mut t = guard.clone();
      t.push_str(ret_str.as_slice());
      ret_str = t;

      if ret_str.len() < self.min_hash_length {
        let guard_idx = (number_hash_int + ret_str.clone().into_bytes()[2] as i64) as usize % self.guards.len();
        let guard = self.guards.slice(guard_idx, guard_idx+1);
        ret_str.push_str(guard);
      }
    }

    let half_len = t_alphabet.len() / 2;
    while ret_str.len() < self.min_hash_length {
      t_alphabet = HashIds::hashids_shuffle(t_alphabet.clone(), t_alphabet.clone());
      let mut t_ret = "".to_string();
      t_ret.push_str(t_alphabet.slice_from(half_len));
      t_ret.push_str(ret_str.as_slice());
      t_ret.push_str(t_alphabet.slice(0, half_len));
      ret_str = t_ret;

      let excess = ret_str.len() as i64 - self.min_hash_length as i64;
      if (excess > 0) {
        let start_pos = (excess as i64 / 2) as usize;
        ret_str = ret_str.slice(start_pos, start_pos + self.min_hash_length).to_string();
      }
    }

    ret_str
  }
}

fn main() {
//  let ids = HashIds::new("1234".to_string(), 10, DEFAULT_ALPHABET.to_string());
  let ids = HashIds::new_with_salt("this is my salt".to_string());
  println!("{}", ids.alphabet);
  println!("{}", ids.separators);
  let numbers: Vec<i64> = vec![12345];
  let encode = ids.encrypt(&numbers);
  println!("{}", encode);

  let longs = ids.decrypt(encode);
  for s in longs.iter() {
    println!("longs: {}", s);
  }

  let ids2 = HashIds::new_with_salt("this is my salt".to_string());
  let i = ids2.encode_hex("1234567890abcdef".to_string());
  println!("{}", i);

  let o = ids2.decode_hex(i);
  println!("{}", o);
}
<|endoftext|>


<commit_before>mod vm;
mod command;
mod parse;
mod program;

use vm::VM;
use program::Program;
use std::io::Write;
use std::env;

fn main() {
    for argument in env::args() {
        println!("{}", argument);
    }

    let vm = VM::new();
    let program = Program::new();
    match env::args().nth(1) {
        None => repl(vm, program),
        Some(_arg) => {}
    }
}

fn repl (mut vm: VM, mut program: Program) -> () {
    loop {
        print!("{}", if program.is_seeking {"... "} else {"bf> "});
        std::io::stdout().flush().unwrap();

        let mut line = String::new();
        let commands = match std::io::stdin().read_line(&mut line) {
            Ok(0) => break,
            Ok(_) => parse::parse(&line),
            Err(error) => panic!(error),
        };
        program.append(&commands);
        program.execute(&mut vm);
    }
}
<commit_msg>Add function to provide interpreter interface<commit_after>mod vm;
mod command;
mod parse;
mod program;

use vm::VM;
use program::Program;
use std::io::Write;
use std::env;
use std::path::Path;
use std::fs::File;
use std::io::prelude::*;

fn main() {
    for argument in env::args() {
        println!("{}", argument);
    }

    let vm = VM::new();
    let program = Program::new();
    match env::args().nth(1) {
        None => repl(vm, program),
        Some(_arg) => {}
    }
}

fn repl (mut vm: VM, mut program: Program) -> () {
    loop {
        print!("{}", if program.is_seeking {"... "} else {"bf> "});
        std::io::stdout().flush().unwrap();

        let mut line = String::new();
        let commands = match std::io::stdin().read_line(&mut line) {
            Ok(0) => break,
            Ok(_) => parse::parse(&line),
            Err(error) => panic!(error),
        };
        program.append(&commands);
        program.execute(&mut vm);
    }
}

fn interpreter(arg: String, mut vm: VM, mut program: Program) -> () {
    let path = Path::new(&arg);
    let mut contents = String::new();
    File::open(&path)
        .unwrap()
        .read_to_string(&mut contents)
        .unwrap();

    program.append(&parse::parse(&contents));
    program.execute(&mut vm);
}
<|endoftext|>


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

use secsp::ParseResult;

use std::io::Read;
use std::io::Write;
use std::fs::File;

mod compiler;
mod decompiler;

fn compile(input: &mut Box<Read>, output: &mut Box<Write>, print_ast: bool) {
    match secsp::parse(input) {
        ParseResult::Ok(ref statements) => {
            if print_ast {
                write!(output, "{:#?}", statements);
            } else {
                compiler::emit(output, statements);
            }
        }
        ParseResult::Err(e) => panic!("{:?}", e),
        ParseResult::Incomplete(n) => panic!("{:?}", n),
    }
}

fn decompile(input: &mut Box<Read>, output: &mut Box<Write>, print_ast: bool) {}

fn main() {
    let opts = clap_app!(cspc =>
        (@arg DECOMPILE: -d --decompile "Decompile CIL sources into equivalent CSP")
        (@arg PRINT_AST: -s --show_ast "Print the parsed AST to stdout")
        (@arg INPUT: -f --file +takes_value "Sets the input file to use")
    ).get_matches();

    let mut input: Box<Read> = match opts.value_of("INPUT") {
        Some(filename) => {
            Box::new(File::open(filename).unwrap_or_else(|e| {
                panic!("Unable to open file \"{}\": {}", filename, e)
            }))
        }
        None => Box::new(std::io::stdin()),
    };

    let mut output: Box<Write> = Box::new(std::io::stdout());
    let print_ast = opts.is_present("PRINT_AST");

    if opts.is_present("DECOMPILE") {
        decompile(&mut input, &mut output, print_ast);
    } else {
        compile(&mut input, &mut output, print_ast);
    }
}
<commit_msg>Add version and author information to clap<commit_after>#[macro_use]
extern crate clap;
extern crate secsp;

use secsp::ParseResult;

use std::io::Read;
use std::io::Write;
use std::fs::File;

mod compiler;
mod decompiler;

fn compile(input: &mut Box<Read>, output: &mut Box<Write>, print_ast: bool) {
    match secsp::parse(input) {
        ParseResult::Ok(ref statements) => {
            if print_ast {
                write!(output, "{:#?}", statements);
            } else {
                compiler::emit(output, statements);
            }
        }
        ParseResult::Err(e) => panic!("{:?}", e),
        ParseResult::Incomplete(n) => panic!("{:?}", n),
    }
}

fn decompile(input: &mut Box<Read>, output: &mut Box<Write>, print_ast: bool) {}

fn main() {
    let opts = clap_app!(cspc =>
        (version: crate_version!())
        (author: crate_authors!())
        (about: "Compiles C-style policy to CIL")
        (@arg DECOMPILE: -d --decompile "Decompile CIL sources into equivalent CSP")
        (@arg PRINT_AST: -s --show_ast "Print the parsed AST to stdout")
        (@arg INPUT: -f --file +takes_value "Sets the input file to use")
    ).get_matches();

    let mut input: Box<Read> = match opts.value_of("INPUT") {
        Some(filename) => {
            Box::new(File::open(filename).unwrap_or_else(|e| {
                panic!("Unable to open file \"{}\": {}", filename, e)
            }))
        }
        None => Box::new(std::io::stdin()),
    };

    let mut output: Box<Write> = Box::new(std::io::stdout());
    let print_ast = opts.is_present("PRINT_AST");

    if opts.is_present("DECOMPILE") {
        decompile(&mut input, &mut output, print_ast);
    } else {
        compile(&mut input, &mut output, print_ast);
    }
}
<|endoftext|>


<commit_before>#![feature(globs)]
extern crate xlib;
extern crate libc;

use xlib::{XOpenDisplay, XDisplayName, XQueryExtension, XInitExtension, XSynchronize};
use libc::{c_int};
use std::ptr;
use xtst::{XRecordCreateContext, XRecordAllClients, XRecordAllocRange, XRecordRange, XRecordQueryVersion, XRecordEnableContext, XRecordEnableContextAsync,XRecordInterceptData, XRecordProcessReplies, XRecordFreeData};
use std::mem;
mod xtst;

fn main() {
	let mut a:  i8 = 0;
	let display_control = unsafe { XOpenDisplay(&mut a)};
	let display_data = unsafe { XOpenDisplay(&mut a)};
	if display_data.is_null() || display_control.is_null() {
		fail!("XOpenDisplay() failed!");
	}

	unsafe {
		XSynchronize(display_control, 1);
	}

	let display_name = unsafe {XDisplayName(&mut a)};
	let ext_name = "RECORD";

	unsafe {
		// Check presence of Record extension
		let arg2:*mut c_int = &mut 1;
		let arg3:*mut c_int = &mut 1;
		let arg4:*mut c_int = &mut 1;
		let has_record = XQueryExtension(display_control, ext_name.to_c_str().as_ptr() as *mut i8,arg2,arg3,arg4);
		let extension = XInitExtension(display_control, ext_name.to_c_str().as_ptr() as *mut i8);
		if extension.is_null() {
			fail!("XInitExtension() failed!");
		}

		// Get version
		let mut versionMajor: c_int = 0;
		let mut versionMinor: c_int = 0;
		XRecordQueryVersion(display_control, &mut versionMajor, &mut versionMinor);
		println!("RECORD extension version {}.{}", versionMajor, versionMinor);

		// Prepare record range
		let mut recordRange: XRecordRange = *XRecordAllocRange();
		let mut recordRangePtr: *mut *mut XRecordRange = std::mem::transmute(&mut &mut recordRange);
		recordRange.device_events.first = 2; // KeyPress
		recordRange.device_events.last = 6; // MotionNotify

		// Create context
		let context = XRecordCreateContext(
			display_control,
			0,
			&mut XRecordAllClients,
			0,
			recordRangePtr,
			0
		);
		if context == 0 {
			fail!("Fail create Record context\n");
		}

		// Run
		let res = XRecordEnableContextAsync(display_data, context, Some(recordCallback), &mut 0);
		if res == 0 {
			fail!("Cound not enable the Record context!\n");
		}
		loop {
			XRecordProcessReplies(display_data);
		}
	}
}

extern "C" fn recordCallback(pointer:*mut i8, data: *mut XRecordInterceptData) {
	println!("Receive event\n");
	unsafe {
		XRecordFreeData(data);
	}
}<commit_msg>Work!<commit_after>#![feature(globs)]
extern crate xlib;
extern crate libc;

use xlib::{XOpenDisplay, XDisplayName, XQueryExtension, XInitExtension, XSynchronize};
use libc::{c_int};
use std::ptr;
use xtst::{XRecordCreateContext, XRecordAllClients, XRecordAllocRange, XRecordRange, XRecordQueryVersion, XRecordEnableContext, XRecordEnableContextAsync,XRecordInterceptData, XRecordProcessReplies, XRecordFreeData};
use std::mem;
mod xtst;

fn main() {
	let mut a:  i8 = 0;
	let display_control = unsafe { XOpenDisplay(&mut a)};
	let display_data = unsafe { XOpenDisplay(&mut a)};
	if display_data.is_null() || display_control.is_null() {
		fail!("XOpenDisplay() failed!");
	}

	unsafe {
		XSynchronize(display_control, 1);
	}

	let display_name = unsafe {XDisplayName(&mut a)};
	let ext_name = "RECORD";

	unsafe {
		// Check presence of Record extension
		let arg2:*mut c_int = &mut 1;
		let arg3:*mut c_int = &mut 1;
		let arg4:*mut c_int = &mut 1;
		let has_record = XQueryExtension(display_control, ext_name.to_c_str().as_ptr() as *mut i8,arg2,arg3,arg4);
		let extension = XInitExtension(display_control, ext_name.to_c_str().as_ptr() as *mut i8);
		if extension.is_null() {
			fail!("XInitExtension() failed!");
		}

		// Get version
		let mut versionMajor: c_int = 0;
		let mut versionMinor: c_int = 0;
		XRecordQueryVersion(display_control, &mut versionMajor, &mut versionMinor);
		println!("RECORD extension version {}.{}", versionMajor, versionMinor);

		// Prepare record range
		let mut recordRange: XRecordRange = *XRecordAllocRange();
		let mut recordRangePtr: *mut *mut XRecordRange = std::mem::transmute(&mut &mut recordRange);
		recordRange.device_events.first = 2; // KeyPress
		recordRange.device_events.last = 6; // MotionNotify

		// Create context
		let context = XRecordCreateContext(
			display_control,
			0,
			&mut XRecordAllClients,
			1,
			recordRangePtr,
			1
		);
		if context == 0 {
			fail!("Fail create Record context\n");
		}

		// Run
		let res = XRecordEnableContextAsync(display_data, context, Some(recordCallback), &mut 0);
		if res == 0 {
			fail!("Cound not enable the Record context!\n");
		}
		loop {
			XRecordProcessReplies(display_data);
		}
	}
}

extern "C" fn recordCallback(pointer:*mut i8, data: *mut XRecordInterceptData) {
	println!("Receive event\n");
	unsafe {
		XRecordFreeData(data);
	}
}<|endoftext|>


<commit_before>extern crate futures;
extern crate futures_cpupool;
extern crate time;
extern crate wikidata;

use std::sync::mpsc::channel;

use futures::Future;
use futures_cpupool::CpuPool;
use time::precise_time_ns;

use wikidata::parse::parse_item;
use wikidata::read::Streamer;
use wikidata::param::{Parameters,read_params};

fn main() {
    let t0 = precise_time_ns();

    let Parameters{input_file, languages, threads} = read_params();
    println!("Input file: {}", input_file);
    println!("Languages: {:?}", languages);
    println!("Number of threads: {}", threads);

    let pool = CpuPool::new(threads);
    let mut futs = Vec::new();
    let (tx, rx) = channel();
    if let Ok(streamer) = Streamer::new(&input_file) {
        let t00 = precise_time_ns();
        for line in streamer {
            let l = line.clone();
            let langs = languages.clone();
            let tx = tx.clone();
            let t = pool.spawn_fn(move || {
                parse_item(&l, &langs)
                    .ok()
                    .and_then(|l| l)
                    .map(|e| {
                        let _ = tx.send(e);
                    });
                Ok::<(), ()>(())
            });
            futs.push(t);
        }
        let t10 = precise_time_ns();
        println!("Main loop: {} us", (t10 - t00) / 1000 );
    }

    let t000 = precise_time_ns();
    let mut same = 0;
    let mut different = 0;
    drop(tx); // Close the original sender, since we won't be sending anything from it
    for e in rx {
        if e[&languages[0]] == e[&languages[1]] {
            same += 1
        } else {
            different += 1
        }
    }
    for f in futs {
        let _ = f.wait();
    }
    let t100 = precise_time_ns();
    println!("Counting: {} us", (t100 - t000) / 1000 );

    let t1 = precise_time_ns();
    println!("Results - Same: {}, Different: {}", same, different);
    println!("Time: {} us", (t1 - t0) / 1000 )
}
<commit_msg>Simplify use of futures<commit_after>extern crate futures;
extern crate futures_cpupool;
extern crate time;
extern crate wikidata;

use futures::Future;
use futures_cpupool::CpuPool;
use time::precise_time_ns;

use wikidata::parse::parse_item;
use wikidata::read::Streamer;
use wikidata::param::{Parameters, read_params};

fn main() {
    let t0 = precise_time_ns();

    let Parameters { input_file, languages, threads } = read_params();
    println!("Input file: {}", input_file);
    println!("Languages: {:?}", languages);
    println!("Number of threads: {}", threads);

    let pool = CpuPool::new(threads);
    let mut futs = Vec::new();
    if let Ok(streamer) = Streamer::new(&input_file) {
        let t00 = precise_time_ns();
        for line in streamer {
            let l = line.clone();
            let langs = languages.clone();
            futs.push(pool.spawn_fn(move || parse_item(&l, &langs)));
        }
        let t10 = precise_time_ns();
        println!("Main loop: {} us", (t10 - t00) / 1000);
    }

    let t000 = precise_time_ns();
    let mut same = 0;
    let mut different = 0;
    for f in futs {
        f.wait().ok().and_then(|v| v).map(|v| {
            if v[&languages[0]] == v[&languages[1]] {
                same += 1
            } else {
                different += 1
            };
        });
    }
    let t100 = precise_time_ns();
    println!("Counting: {} us", (t100 - t000) / 1000);

    let t1 = precise_time_ns();
    println!("Results - Same: {}, Different: {}", same, different);
    println!("Time: {} us", (t1 - t0) / 1000)
}
<|endoftext|>


<commit_before>/// A genetic algorithm in Rust
/// Copyright (C) 2015  Andrew Schwartzmeyer

extern crate rand;
extern crate time;

use rand::Rng;
use rand::distributions;
use time::precise_time_s;
use std::thread;
use individual::Individual;

mod individual;

/// Tournament selection from 4 random individuals
fn select<R: Rng>(population: &Vec<Individual>, rng: &mut R)
                  -> Individual {
    if let Some(selected) = (0..4).map(|_| rng.choose(population)).min() {
        selected.unwrap().clone()
    } else {
        unimplemented!();
    }
}

/// Setup and run algorithm to search for solution
fn main() {
    let mut rng = rand::thread_rng();
    let range = distributions::Range::new(-500_f64, 500_f64);

    // initialize population of 512 individuals
    let mut population: Vec<_> = (0..512).map(|_| {
        Individual::new(&range, &mut rng)
    }).collect();

    let start_time = precise_time_s();
    // search through at most 10,000 generations
    for i in 0..10000 {
        // select, mutate, and recombine individuals for next generation
        let mut offspring: Vec<Individual> = Vec::with_capacity(population.len());
        for _ in 0..population.len()/2 {
            let (mut x, mut y) = (select(&population, &mut rng),
                                  select(&population, &mut rng));
            x.mutate(&range, &mut rng);
            y.mutate(&range, &mut rng);
            Individual::combine(&mut x, &mut y, &mut rng);
            offspring.push(x);
            offspring.push(y);
        }
        assert!(offspring.len() == population.len());

        // replace 2 random individuals with elite of prior generation
        for _ in 0..2 {
            if let Some(x) = population.iter().min() {
                offspring[rng.gen_range(0, population.len())] = x.clone();
            }
        }

        // replace population with next generation
        population = offspring;

        // examine best individual for convergence
        if let Some(x) = population.iter().min() {
            if i % 10 == 0 {
                let fitness = x.fitness;
                thread::spawn(move || {
                    println!("{}th fitness {}", i, fitness)
                });
            }
            if x.fitness < 0.05_f64 {
                let duration = precise_time_s() - start_time;
                println!("{}th solution converged at {} in {} seconds: {:?}",
                         i, x.fitness, duration, x.solution);
                return;
            }
        } else { unimplemented!() }
    }
    println!("Failed to converge.");
}
<commit_msg>Pass a slice not a Vec<commit_after>/// A genetic algorithm in Rust
/// Copyright (C) 2015  Andrew Schwartzmeyer

extern crate rand;
extern crate time;

use rand::Rng;
use rand::distributions;
use time::precise_time_s;
use std::thread;
use individual::Individual;

mod individual;

/// Tournament selection from 4 random individuals
fn select<R: Rng>(population: &[Individual], rng: &mut R) -> Individual {
    if let Some(selected) = (0..4).map(|_| rng.choose(population)).min() {
        selected.unwrap().clone()
    } else {
        unimplemented!();
    }
}

/// Setup and run algorithm to search for solution
fn main() {
    let mut rng = rand::thread_rng();
    let range = distributions::Range::new(-500_f64, 500_f64);

    // initialize population of 512 individuals
    let mut population: Vec<_> = (0..512).map(|_| {
        Individual::new(&range, &mut rng)
    }).collect();

    let start_time = precise_time_s();
    // search through at most 10,000 generations
    for i in 0..10000 {
        // select, mutate, and recombine individuals for next generation
        let mut offspring: Vec<Individual> = Vec::with_capacity(population.len());
        for _ in 0..population.len()/2 {
            let (mut x, mut y) = (select(&population, &mut rng),
                                  select(&population, &mut rng));
            x.mutate(&range, &mut rng);
            y.mutate(&range, &mut rng);
            Individual::combine(&mut x, &mut y, &mut rng);
            offspring.push(x);
            offspring.push(y);
        }
        assert!(offspring.len() == population.len());

        // replace 2 random individuals with elite of prior generation
        for _ in 0..2 {
            if let Some(x) = population.iter().min() {
                offspring[rng.gen_range(0, population.len())] = x.clone();
            }
        }

        // replace population with next generation
        population = offspring;

        // examine best individual for convergence
        if let Some(x) = population.iter().min() {
            if i % 10 == 0 {
                let fitness = x.fitness;
                thread::spawn(move || {
                    println!("{}th fitness {}", i, fitness)
                });
            }
            if x.fitness < 0.05_f64 {
                let duration = precise_time_s() - start_time;
                println!("{}th solution converged at {} in {} seconds: {:?}",
                         i, x.fitness, duration, x.solution);
                return;
            }
        } else { unimplemented!() }
    }
    println!("Failed to converge.");
}
<|endoftext|>


<commit_before>extern crate discord;
extern crate serde_json;

use serde_json::de;
use std::fs::File;
use std::io::Read;
use discord::{Discord, State};
use discord::model::{Event, LiveServer, Member};

fn main() {
    // Read and set config vars
    let mut file = File::open("config.json").unwrap();
    let mut config = String::new();
    file.read_to_string(&mut config).unwrap();

    let json: serde_json::Value = serde_json::from_str(&config).unwrap();
    let botTokens = json.find_path(&["bot-token"]).unwrap();
    let welcomeMessage = json.find_path(&["welcome-message"]).unwrap();

    //    println!("bot-token has been set to {} from config", botTokens);
    //    println!("welcome-message has been set to {} from the config", welcomeMessage);

    // Login to the API
    let discord = Discord::from_bot_token(botTokens.as_string().unwrap()).expect("Login Fail");

    // establish websocket and voice connection
    let (mut connection, ready) = discord.connect().expect("connect failed");
    println!("[Ready] {} is serving {} servers",
             ready.user.username,
             ready.servers.len());
    let mut state = State::new(ready);

    // receive events forever
    loop {
        let event = match connection.recv_event() {
            Ok(event) => event,
            Err(err) => {
                println!("[Warning] Receive error: {:?}", err);
                if let discord::Error::WebSocket(..) = err {
                    // Handle the websocket connection being dropped
                    let (new_connection, ready) = discord.connect().expect("connect failed");
                    connection = new_connection;
                    state = State::new(ready);
                    println!("[Ready] Reconnected successfully.");
                }
                if let discord::Error::Closed(..) = err {
                    break;
                }
                continue;
            }
        };
        state.update(&event);

        match event {
            Event::MessageCreate(message) => {
                use std::ascii::AsciiExt;
                // safeguard: stop if the message is from us
                if message.author.id == state.user().id {
                    continue;
                }

                // reply to a command if there was one
                let mut split = message.content.split(" ");
                let first_word = split.next().unwrap_or("");
                let argument = split.next().unwrap_or("");

                if first_word.eq_ignore_ascii_case("!dj") {
                    let vchan = state.find_voice_user(message.author.id);
                    if argument.eq_ignore_ascii_case("stop") {
                        vchan.map(|(sid, _)| connection.voice(sid).stop());
                    } else if argument.eq_ignore_ascii_case("quit") {
                        vchan.map(|(sid, _)| connection.drop_voice(sid));
                    } else {
                        let output = if let Some((server_id, channel_id)) = vchan {
                            match discord::voice::open_ytdl_stream(&argument) {
                                Ok(stream) => {
                                    let voice = connection.voice(server_id);
                                    voice.set_deaf(true);
                                    voice.connect(channel_id);
                                    voice.play(stream);
                                    String::new()
                                }
                                Err(error) => format!("Error: {}", error),
                            }
                        } else {
                            "You must be in a voice channel to DJ".to_owned()
                        };
                        if output.len() > 0 {
                            warn(discord.send_message(&message.channel_id, &output, "", false));
                        }
                    }
                }
            }
            Event::VoiceStateUpdate(server_id, _) => {
                // If someone moves/hangs up, and we are in a voice channel,
                if let Some(cur_channel) = connection.voice(server_id).current_channel() {
                    // and our current voice channel is empty, disconnect from voice
                    if let Some(srv) = state.servers().iter().find(|srv| srv.id == server_id) {
                        if srv.voice_states
                            .iter()
                            .filter(|vs| vs.channel_id == Some(cur_channel))
                            .count() <= 1 {
                            connection.voice(server_id).disconnect();
                        }
                    }
                }
            }
            _ => {} // discard other events
        }
    }
}

fn warn<T, E: ::std::fmt::Debug>(result: Result<T, E>) {
    match result {
        Ok(_) => {}
        Err(err) => println!("[Warning] {:?}", err),
    }
}
<commit_msg>Version 0.1.0<commit_after>extern crate discord;
extern crate serde_json;

use std::fs::File;
use std::io::Read;
use discord::{Discord, State};
use discord::model::{Event, LiveServer, Member};

fn main() {
    // Read and set config vars
    let mut file = File::open("config.json").unwrap();
    let mut config = String::new();
    file.read_to_string(&mut config).unwrap();

    let json: serde_json::Value = serde_json::from_str(&config).unwrap();
    let bot_tokens = json.find_path(&["bot-token"]).unwrap();
    let welcome_message = json.find_path(&["welcome-message"]).unwrap();

    println!("bot-token has been set to {} from config", bot_tokens);
    println!("welcome-message has been set to {} from the config",
             welcome_message);

    // Login to the API
    let discord = Discord::from_bot_token(bot_tokens.as_string().unwrap()).expect("Login Fail");

    // establish websocket and voice connection
    let (mut connection, ready) = discord.connect().expect("connect failed");
    println!("[Ready] {} is serving {} servers",
             ready.user.username,
             ready.servers.len());
    let mut state = State::new(ready);

    // receive events forever
    loop {
        let event = match connection.recv_event() {
            Ok(event) => event,
            Err(err) => {
                println!("[Warning] Receive error: {:?}", err);
                if let discord::Error::WebSocket(..) = err {
                    // Handle the websocket connection being dropped
                    let (new_connection, ready) = discord.connect().expect("connect failed");
                    connection = new_connection;
                    state = State::new(ready);
                    println!("[Ready] Reconnected successfully.");
                }
                if let discord::Error::Closed(..) = err {
                    break;
                }
                continue;
            }
        };
        state.update(&event);

        match event {
            Event::MessageCreate(message) => {
                use std::ascii::AsciiExt;
                // safeguard: stop if the message is from us
                if message.author.id == state.user().id {
                    continue;
                }

                // reply to a command if there was one
                let mut split = message.content.split(" ");
                let first_word = split.next().unwrap_or("");
                let argument = split.next().unwrap_or("");

                if first_word.eq_ignore_ascii_case("!dj") {
                    let vchan = state.find_voice_user(message.author.id);
                    if argument.eq_ignore_ascii_case("stop") {
                        vchan.map(|(sid, _)| connection.voice(sid).stop());
                    } else if argument.eq_ignore_ascii_case("quit") {
                        vchan.map(|(sid, _)| connection.drop_voice(sid));
                    } else {
                        let output = if let Some((server_id, channel_id)) = vchan {
                            match discord::voice::open_ytdl_stream(&argument) {
                                Ok(stream) => {
                                    let voice = connection.voice(server_id);
                                    voice.set_deaf(true);
                                    voice.connect(channel_id);
                                    voice.play(stream);
                                    String::new()
                                }
                                Err(error) => format!("Error: {}", error),
                            }
                        } else {
                            "You must be in a voice channel to DJ".to_owned()
                        };
                        if output.len() > 0 {
                            warn(discord.send_message(&message.channel_id, &output, "", false));
                        }
                    }
                }
            }
            Event::VoiceStateUpdate(server_id, _) => {
                // If someone moves/hangs up, and we are in a voice channel,
                if let Some(cur_channel) = connection.voice(server_id).current_channel() {
                    // and our current voice channel is empty, disconnect from voice
                    if let Some(srv) = state.servers().iter().find(|srv| srv.id == server_id) {
                        if srv.voice_states
                            .iter()
                            .filter(|vs| vs.channel_id == Some(cur_channel))
                            .count() <= 1 {
                            connection.voice(server_id).disconnect();
                        }
                    }
                }
            }
            _ => {} // discard other events
        }
    }
}

fn warn<T, E: ::std::fmt::Debug>(result: Result<T, E>) {
    match result {
        Ok(_) => {}
        Err(err) => println!("[Warning] {:?}", err),
    }
}
<|endoftext|>


<commit_before>extern crate little_rust_tcp;
extern crate lib;
use std::string::String;
use little_rust_tcp::tcpserver::ServerFunction;
use lib::server_data::ServerDataConstructor;
use lib::server_data::DataAnalyzer;
use std::sync::{Arc, Mutex};
use std::collections::ring_buf::RingBuf;

fn main()
{
    let shared_ring_buf = Arc::new(Mutex::new(RingBuf::new()));
    let server_data = ServerDataConstructor::new(shared_ring_buf.clone());
    let mut data_analyzer = DataAnalyzer::new(shared_ring_buf.clone());
    let server = ServerFunction::new(String::from_str("8000"));
    spawn(proc(){
        server.start_server(server_data);
    });
    loop
    {
        data_analyzer.interpret_data();
    }
}
<commit_msg>Update main.rs<commit_after>extern crate little_rust_tcp;
extern crate lib;
use little_rust_tcp::tcpserver::ServerFunction;
use lib::server_data::ServerDataConstructor;
use lib::server_data::DataAnalyzer;
use std::string::String;
use std::sync::{Arc, Mutex};
use std::collections::ring_buf::RingBuf;

fn main()
{
    let shared_ring_buf = Arc::new(Mutex::new(RingBuf::new()));
    let server_data = ServerDataConstructor::new(shared_ring_buf.clone());
    let mut data_analyzer = DataAnalyzer::new(shared_ring_buf.clone());
    let server = ServerFunction::new(String::from_str("8000"));
    spawn(proc(){
        server.start_server(server_data);
    });
    loop
    {
        data_analyzer.interpret_data();
    }
}
<|endoftext|>


<commit_before>#![feature(rustc_private)] // TODO Migrate to crates.io variant (json)
#![feature(core)]

extern crate hyper;
extern crate regex;
extern crate serialize;
extern crate websocket;
extern crate rustc_serialize;

mod authentication;
mod messages_stream;
mod user_view;

mod user;
mod message;
mod channel;
mod current_state;

#[allow(dead_code)]
fn main() {
    let (token,_guard) = authentication::get_oauth_token_or_panic();

    let slack_stream = messages_stream::establish_stream(&token);
    // let view = user_view::new();
    // interface.update_state(slack_stream.initial_state);
    // TODO Clear screen here

    // println!("Connection established!");

    // for message in slack_stream.into_iter() {
    //     view.print_message(message);
    // }

    // println!("Server closed!")
}
<commit_msg>Add stub code for printing mapped messages<commit_after>#![feature(rustc_private)] // TODO Migrate to crates.io variant (json)
#![feature(core)]

extern crate hyper;
extern crate regex;
extern crate serialize;
extern crate websocket;
extern crate rustc_serialize;

mod authentication;
mod messages_stream;
mod user_view;
mod user;
mod message;
mod channel;
mod current_state;

use current_state::new_current_state_from_json;
use message::new_message_from_str;

#[allow(dead_code)]
fn main() {
    let (token,_guard) = authentication::get_oauth_token_or_panic();

    // let slack_stream = messages_stream::establish_stream(&token);
    // let current_state = new_current_state_from_json(&slack_stream.initial_state);
    // for message in slack_stream.iter() {
    //     match new_message_from_str(message.as_slice()) {
    //         Ok(message) => {
    //             match current_state.user_id_to_user(message.user.as_slice()) {
    //                 Some(user) => {
    //                     println!("{} - {}: {}", message.channel, user.name, message.text)
    //                 },
    //                 None => {
    //                     println!("{} - {}: {}", message.channel, "UnknownUser", message.text)
    //                 }

    //             }
    //         },
    //         Err(e) => println!("{}", e)
    //     }
    // }
}
<|endoftext|>


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

//! Rust and Scheme inspired implementation of LISP
//!
//! # Envisioned syntax
//! ```ignore
//! (extern crate num)
//!
//! ; Types are static and can be specified with `: <TYPE>` or inferred, like in Rust.
//!
//! ; `define` translates to `const` and `fn` in Rust.
//!
//! ; Define a constant C_FOO with value 1_000 of type U32
//! {define C_FOO 1_000: U16} ; == const C_FOO = 1_000_u16;
//!
//! ; Define a constant C_BAR of type U64, with value 337 of type num::BigInt coerced to U64.
//! ; Number types can only be coerced upwards, to higher precision
//! {define: U64 C_BAR 337: num::BigInt} ; == const C_BAR: u64 = 337_u32;
//!
//! ; Define a constant C_BAZ of inferred type num::BigInt
//! {define C_BAZ (+ C_FOO C_BAR)}
//!
//! ; Define a function of inferred type. Only specify type of argument `a`, and infer the rest
//! {define (f_foo a: U32) a} ; == fn f_foo(a: u32) -> u32 { a }
//!
//! ; Try to define a function of inferred type. Don't specify any types. Won't work.
//! {define (f_bar a) a} ; == fn f_foo(a: _) -> _ { a }
//!
//! ; Define a function of type Fn<(F32), F64>.
//! ; Infer argument type and return value coersion type from function type
//! {define (f_baz: Fn<(F32) F64> a) a} ; == fn tmp(a: _) -> _ {a}; const f_foo: fn(f32) -> f64 = tmp;
//!
//! The `main` function entry, same as Rust `fn main() { ...`
//! {define (main) (block
//! 	(println! "c_foo: {}, c_bar: {}, c_baz: {}" C_FOO C_BAR C_BAZ)
//! 	(println! "f_foo: {}" (f_baz (as C_BAZ F32))))}
//! ```

// TODO: Compile time execution. By marking functions as pure,
// enable calculation of constants from these functions at compile time.

// TODO: Higher Kinded Types. Like Functor which would provide map for a generic container

// TODO: Find errors in code. When lexing, produce a map of token indices =>
// line and col in source. When parsing, pass along token index.

// TODO: In cases like:
//     map f [] = []
//     map f (first:rest) = f first : map f rest
// do not try to infer type, instead, leave types of f, first, and rest as type variables

// TODO: Implement something like
// [Damas-Hindley-Miller](http://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system)
// for type inference

// Per default, expect that all functions are pure, but make it possible to explicitly mark them as
// unpure. Similar to unsafe in Rust.

#![feature(non_ascii_idents, box_patterns, rustc_private, collections, collections_drain)]

#[macro_use]
extern crate lazy_static;
extern crate getopts;
#[macro_use]
extern crate bitflags;

use getopts::Options;
use std::env;
use std::io::{ Read };
use std::fs::File;
use std::path::PathBuf;

use lib::{ tokenize_string, compile };
use lib::front::parse;

mod lib;

#[cfg(unix)]
const BIN_EXTENSION: &'static str = "bin";
#[cfg(windows)]
const BIN_EXTENSION: &'static str = "exe";

bitflags! {
	flags Emit: u16 {
		const EMIT_RUST = 1,
	}
}

fn print_usage(program: &str, opts: Options) {
	let brief = format!("Usage: {} [options] SOURCE-FILE", program);
	print!("{}", opts.usage(&brief));
}

fn main() {
	let args: Vec<_> = env::args().collect();
	let bin_name = args[0].clone();

	let mut opts = Options::new();
	opts.optopt("o", "out-file", "Set output file name", "NAME");
	opts.optopt("", "sysroot", "Specify sysroot for when looking for rust libs, \
		e.g. /usr/local/ or C:/Program Files/Rust/. \
		Do this when rustc complains about missing crates", "DIR");
	opts.optflag("", "emit-rust", "Emit transpiled rust code");
	opts.optflag("h", "help", "Print this help menu");

	let matches = match opts.parse(&args[1..]) {
		Ok(m) => m,
		Err(e) => panic!(e)
	};

	if matches.opt_present("h") {
		print_usage(&bin_name, opts);
		return;
	}

	let inp_file_name = if !matches.free.is_empty() {
		PathBuf::from(matches.free[0].clone())
	} else {
		print_usage(&bin_name, opts);
		return;
	};

	let out_file_name = match matches.opt_str("o") {
		Some(o) => PathBuf::from(o),
		None => {
			let mut o = inp_file_name.clone();
			o.set_extension(BIN_EXTENSION);
			o
		}
	};
	let sysroot = matches.opt_str("sysroot").map(|s| PathBuf::from(s));

	let mut emissions = Emit::empty();
	for emission in [(EMIT_RUST, matches.opt_present("emit-rust"))].iter()
		.filter_map(|&(e, b)| if b { Some(e) } else { None })
	{
		emissions.insert(emission);
	}

	let mut scr_code = String::with_capacity(4_000);
	File::open(inp_file_name).unwrap().read_to_string(&mut scr_code).unwrap();

	let tokens = tokenize_string(&scr_code).unwrap();

	let ast = parse::AST::parse(&tokens).unwrap();

	let mut ast: lib::AST = ast.into();
	println!("AST PARSED:\n{:?}\n", ast);

	ast.remove_unused_consts();
	println!("AST REMOVED UNUSED:\n{:?}\n", ast);

	ast.infer_types();
	println!("AST INFERED:\n{:?}\n", ast);

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

//! Rust and Scheme inspired implementation of LISP
//!
//! # Envisioned syntax⊢
//! ```scheme
//! ; Types are static and can be annotated with `(:TYPE EXPR)` or inferred, similar to Rust.
//!
//! ; Define a constant C_FOO with value 1_000 of type U32
//! > (def-const C_FOO (:U16 1_000))
//! C_FOO :: U16
//!
//! ; Define a constant C_BAR of type U64, with value of C_FOO of type U16 coerced to U64.
//! ; Number types can only be coerced upwards, to higher precision
//! > (def-const C_BAR (:U64 C_FOO))
//! C_BAR :: U64
//!
//! ; Define a constant C_BAZ of inferred type U64. The result from adding numbers with different
//! ; precision gets the type of the highest precision type of the two
//! > (def-const C_BAZ (+ C_FOO C_BAR))
//! C_BAZ :: U64
//!
//! ; Define a function of inferred polymorphic type.
//! > (def-func (f_foo a) a)
//! ; which is equivalent to
//! > (def-const f_foo (λ (a) a))
//! f_foo :: ∀__Polya . __Polya → __Polya
//!
//! ; Define a function of inferred constrained type.
//! ; add : Num → Num → Num ⇒ α : Num, β : Num in add α β ⇒ λ1.λβ.add 1 β : Num → Num → Num
//! > (def-func (inc n) (+ 1 n))
//! inc :: Num → Num
//!
//! The `main` function entry, same as Rust `fn main() { ...`
//! (def-func (main) (block
//! 	(println! "c_foo: {}, c_bar: {}, c_baz: {}" C_FOO C_BAR C_BAZ)
//! 	(println! "f_foo: {}" (f_baz (as C_BAZ F32)))))
//! ```

// TODO: Compile time execution. By marking functions as pure,
// enable calculation of constants from these functions at compile time.

// TODO: Higher Kinded Types. Like Functor which would provide map for a generic container

// TODO: Find errors in code. When lexing, produce a map of token indices =>
// line and col in source. When parsing, pass along token index.

// TODO: In cases like:
//     map f [] = []
//     map f (first:rest) = f first : map f rest
// do not try to infer type, instead, leave types of f, first, and rest as type variables

// TODO: Formally prove that all type inference is correct using
// [Damas-Hindley-Miller](http://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system).
// [Good explanation](http://stackoverflow.com/questions/12532552/what-part-of-milner-hindley-do-you-not-understand)

// Per default, expect that all functions are pure, but make it possible to explicitly mark them as
// unpure. Similar to unsafe in Rust.

#![feature(non_ascii_idents, box_patterns, rustc_private, collections, collections_drain)]

#[macro_use]
extern crate lazy_static;
extern crate getopts;
#[macro_use]
extern crate bitflags;

use getopts::Options;
use std::env;
use std::io::{ Read };
use std::fs::File;
use std::path::PathBuf;

use lib::{ tokenize_string, compile };
use lib::front::parse;

mod lib;

#[cfg(unix)]
const BIN_EXTENSION: &'static str = "bin";
#[cfg(windows)]
const BIN_EXTENSION: &'static str = "exe";

bitflags! {
	flags Emit: u16 {
		const EMIT_RUST = 1,
	}
}

fn print_usage(program: &str, opts: Options) {
	let brief = format!("Usage: {} [options] SOURCE-FILE", program);
	print!("{}", opts.usage(&brief));
}

fn main() {
	let args: Vec<_> = env::args().collect();
	let bin_name = args[0].clone();

	let mut opts = Options::new();
	opts.optopt("o", "out-file", "Set output file name", "NAME");
	opts.optopt("", "sysroot", "Specify sysroot for when looking for rust libs, \
		e.g. /usr/local/ or C:/Program Files/Rust/. \
		Do this when rustc complains about missing crates", "DIR");
	opts.optflag("", "emit-rust", "Emit transpiled rust code");
	opts.optflag("h", "help", "Print this help menu");

	let matches = match opts.parse(&args[1..]) {
		Ok(m) => m,
		Err(e) => panic!(e)
	};

	if matches.opt_present("h") {
		print_usage(&bin_name, opts);
		return;
	}

	let inp_file_name = if !matches.free.is_empty() {
		PathBuf::from(matches.free[0].clone())
	} else {
		print_usage(&bin_name, opts);
		return;
	};

	let out_file_name = match matches.opt_str("o") {
		Some(o) => PathBuf::from(o),
		None => {
			let mut o = inp_file_name.clone();
			o.set_extension(BIN_EXTENSION);
			o
		}
	};
	let sysroot = matches.opt_str("sysroot").map(|s| PathBuf::from(s));

	let mut emissions = Emit::empty();
	for emission in [(EMIT_RUST, matches.opt_present("emit-rust"))].iter()
		.filter_map(|&(e, b)| if b { Some(e) } else { None })
	{
		emissions.insert(emission);
	}

	let mut scr_code = String::with_capacity(4_000);
	File::open(inp_file_name).unwrap().read_to_string(&mut scr_code).unwrap();

	let tokens = tokenize_string(&scr_code).unwrap();

	let ast = parse::AST::parse(&tokens).unwrap();

	let mut ast: lib::AST = ast.into();
	println!("AST PARSED:\n{:?}\n", ast);

	ast.remove_unused_consts();
	println!("AST REMOVED UNUSED:\n{:?}\n", ast);

	ast.infer_types();
	println!("AST INFERED:\n{:?}\n", ast);

	compile(&ast, out_file_name, sysroot, emissions);
}
<|endoftext|>


<commit_before>extern crate env_logger;
extern crate mio;
#[macro_use] extern crate mioco;
extern crate trust_dns;
extern crate rand;
#[macro_use] extern crate quick_error;
#[macro_use] extern crate log;
extern crate byteorder;

mod utils;
mod transport;

use std::net::{SocketAddr, SocketAddrV4, IpAddr};
use std::cmp::max;

use mioco::JoinHandle;
use mioco::udp::UdpSocket;
use mioco::tcp::{TcpListener, TcpStream};
use mioco::mio::Ipv4Addr;
use mioco::sync::mpsc::{channel};
use trust_dns::op::{Message, MessageType, ResponseCode, Query, OpCode, Edns};

use utils::{Result, Error, CloneExt, MessageExt, WithTimeout, Future};
use utils::with_timeout::TcpStreamExt;
use transport::{DnsTransport, BoundDnsTransport};

const QUERY_TIMEOUT: i64 = 5000;
const EDNS_VER: u8 = 0;
const EDNS_MAX_PAYLOAD: u16 = 1200;

// Idea: Use DNSSEC to check whether a domain is poisoned by GFW

fn query_core<T: DnsTransport>(q: Query, mut transport: BoundDnsTransport<T>, enable_edns: bool) -> Result<Message> {
    let mut msg : Message = Message::new();
    msg.message_type(MessageType::Query);
    msg.id(rand::random());
    msg.op_code(OpCode::Query);
    msg.recursion_desired(true);
    if enable_edns {
        let mut edns = Edns::new();
        edns.set_version(EDNS_VER);
        edns.set_dnssec_ok(false); // TODO
        edns.set_max_payload(EDNS_MAX_PAYLOAD);
        msg.set_edns(edns);
    }
    debug!("Q[{}][{}] {} {:?} {:?}",
           transport, msg.get_id(), q.get_name(), q.get_query_type(), q.get_query_class());
    msg.add_query(q);
    try!(transport.send_msg(&msg));
    loop {
        let (resp, _) = try!(transport.recv_msg());
        if ! resp.is_resp_for(&msg) {
            warn!("Q[{}][{}] Invalid response: {:?}",
                  transport, msg.get_id(), resp);
            continue;
        }
        if resp.get_response_code() == ResponseCode::FormErr && enable_edns {
            // Maybe the server doesn't implement EDNS?
            return query_core(msg.get_queries()[0].clone(), transport, false);
        }
        // TODO: Validate response, handle truncated message
        debug!("A[{}][{}] {:?} {} answer(s)",
           transport, resp.get_id(), resp.get_response_code(), resp.get_answers().len());
        return Ok(resp);
    }
}
fn query(q: Query, addr: Ipv4Addr, enable_edns: bool) -> Result<Message> {
    let target = SocketAddr::new(IpAddr::V4(addr), 53);
    let mut transport = try!(UdpSocket::v4()).with_timeout(QUERY_TIMEOUT);
    match query_core(q, transport.bound(Some(&target)), enable_edns) {
        Ok(msg) => {
            if msg.is_truncated() {
                // Try TCP
                let tcp_result = TcpStream::connect_with_timeout(&target, QUERY_TIMEOUT)
                .map_err(|e| e.into())
                .and_then(|stream| query_core(
                    msg.get_queries()[0].clone(),
                    stream.with_timeout(QUERY_TIMEOUT).bound(Some(&target)),
                    enable_edns,
                ));
                Ok(tcp_result.unwrap_or(msg))
            } else {
                Ok(msg)
            }
        },
        Err(e) => Err(e),
    }
}
fn query_multiple(q: &Query, servers: &[Ipv4Addr]) -> Result<Message> {
    let mut futures = servers.iter()
        .cloned()
        .map(move |server| {
            let qc = q.clone();
            Future::from_fn(move || query(qc, server, true))
        })
        .collect::<Vec<Future<Result<Message>>>>();
    loop {
        let result_index = Future::wait_any(&mut futures);
        let result = futures.remove(result_index).consume();
        let mut should_return = futures.len() == 0;
        match result {
            Ok(ref msg) => {
                match msg.get_response_code() {
                    ResponseCode::ServFail |
                    ResponseCode::NotImp |
                    ResponseCode::Refused => {
                        // Fall below to wait for remaining servers, if any
                    },
                    _ => { should_return = true; },
                }
            },
            Err(Error::Io(ref err)) if err.kind() == std::io::ErrorKind::TimedOut => {
                debug!("{:?} timed out", q);
            },
            Err(ref err) => {
                debug!("{:?} returned error {:?}", q, err);
            },
        };
        if should_return {
            return result;
        }
    }
}

/// This function should never fail, otherwise we have a panic
fn handle_request(msg: Message, should_truncate: bool) -> Result<Vec<u8>> {
    let mut ret : Message = msg.new_resp();
    ret.recursion_available(true);
    if let Some(req_edns) = msg.get_edns() {
        let mut resp_edns = Edns::new();
        resp_edns.set_version(EDNS_VER);
        resp_edns.set_dnssec_ok(false); // TODO
        resp_edns.set_max_payload(max(512, req_edns.get_max_payload()));
        ret.set_edns(resp_edns);
        if req_edns.get_version() > EDNS_VER {
            warn!("Got EDNS version {}", req_edns.get_version());
            ret.response_code(ResponseCode::BADVERS);
            return ret.to_bytes();
        }
    }
    if msg.get_queries().len() != 1 {
        // For simplicity, only support one question
        ret.response_code(ResponseCode::Refused);
        return ret.to_bytes();
    }
    match query_multiple(&msg.get_queries()[0], &[Ipv4Addr::new(8, 8, 8, 8), Ipv4Addr::new(8, 8, 4, 4)]) {
        Ok(resp) => { ret.copy_resp_from(&resp); },
        Err(_)   => { ret.response_code(ResponseCode::ServFail); },
    };
    let bytes = try!(ret.to_bytes());
    if should_truncate && bytes.len() > (msg.get_max_payload() as usize) {
        return ret.truncate().to_bytes();
    }
    Ok(bytes)
}
fn serve_transport_async<TRecv, TSend, F>(mut recv: TRecv, mut send: TSend, on_error: F) -> JoinHandle<()>
    where TRecv: DnsTransport + Send + 'static,
          TSend: DnsTransport + Send + 'static,
          F: FnOnce(Error) + Send + 'static,
{
    let (sch, rch) = channel::<(Vec<u8>, Option<SocketAddr>)>();
    mioco::spawn(move || {
        loop {
            match rch.recv() {
                Ok((buf, addr)) => {
                    match send.send_msg_bytes(&buf, addr.as_ref()) {
                        Ok(_) => { },
                        Err(e) => { warn!("Failed to respond to DNS request: {:?}", e); },
                    };
                },
                Err(_) => {
                    trace!("Channel is broken");
                    return;
                },
            };
        }
    });
    mioco::spawn(move || {
        loop {
            let (msg, addr) = match recv.recv_msg(None) {
                Ok(x) => x,
                Err(e) => {
                    on_error(e);
                    return;
                },
            };
            let sch_req = sch.clone();
            mioco::spawn(move || {
                let resp = handle_request(msg, TSend::should_truncate()).expect("handle_request should not return error");
                sch_req.send((resp, addr)).expect("Result pipe should not break here");
            });
        }
    })
}
fn serve_tcp(addr: &SocketAddr) -> Result<JoinHandle<()>> {
    let listener = try!(TcpListener::bind(addr));
    Ok(mioco::spawn(move || {
        loop {
            let sock = listener.accept().expect("Failed to accept TCP socket");
            let sock_clone = sock.try_clone().expect("Failed to clone TCP socket");
            serve_transport_async(
                sock.with_resetting_timeout(QUERY_TIMEOUT),
                sock_clone.with_resetting_timeout(QUERY_TIMEOUT),
                |e| trace!("Client TCP connection is broken: {:?}", e)
            );
        }
    }))
}
fn serve_udp(addr: &SocketAddr) -> Result<JoinHandle<()>> {
    let sock : UdpSocket = try!(UdpSocket::v4());
    try!(sock.bind(addr));
    let sock_clone = try!(sock.try_clone());
    Ok(serve_transport_async(
        sock, sock_clone, |e| panic!("UDP listener is broken: {:?}", e)
    ))
}

fn main() {
    env_logger::init().unwrap();
    println!("Hello, world!");

    mioco::start(move || {
        let ip = Ipv4Addr::new(0, 0, 0, 0);
        let port = 5354;
        let addr = SocketAddr::V4(SocketAddrV4::new(ip, port));

        serve_tcp(&addr).expect("Failed to initialize TCP listener");
        serve_udp(&addr).expect("Failed to initialize UDP listener");
    }).expect("Unexpected error from mioco::start");
}
<commit_msg>Enable TCP_NODELAY<commit_after>extern crate env_logger;
extern crate mio;
#[macro_use] extern crate mioco;
extern crate trust_dns;
extern crate rand;
#[macro_use] extern crate quick_error;
#[macro_use] extern crate log;
extern crate byteorder;

mod utils;
mod transport;

use std::net::{SocketAddr, SocketAddrV4, IpAddr};
use std::cmp::max;

use mioco::JoinHandle;
use mioco::udp::UdpSocket;
use mioco::tcp::{TcpListener, TcpStream};
use mioco::mio::Ipv4Addr;
use mioco::sync::mpsc::{channel};
use trust_dns::op::{Message, MessageType, ResponseCode, Query, OpCode, Edns};

use utils::{Result, Error, CloneExt, MessageExt, WithTimeout, Future};
use utils::with_timeout::TcpStreamExt;
use transport::{DnsTransport, BoundDnsTransport};

const QUERY_TIMEOUT: i64 = 5000;
const EDNS_VER: u8 = 0;
const EDNS_MAX_PAYLOAD: u16 = 1200;

// Idea: Use DNSSEC to check whether a domain is poisoned by GFW

fn query_core<T: DnsTransport>(q: Query, mut transport: BoundDnsTransport<T>, enable_edns: bool) -> Result<Message> {
    let mut msg : Message = Message::new();
    msg.message_type(MessageType::Query);
    msg.id(rand::random());
    msg.op_code(OpCode::Query);
    msg.recursion_desired(true);
    if enable_edns {
        let mut edns = Edns::new();
        edns.set_version(EDNS_VER);
        edns.set_dnssec_ok(false); // TODO
        edns.set_max_payload(EDNS_MAX_PAYLOAD);
        msg.set_edns(edns);
    }
    debug!("Q[{}][{}] {} {:?} {:?}",
           transport, msg.get_id(), q.get_name(), q.get_query_type(), q.get_query_class());
    msg.add_query(q);
    try!(transport.send_msg(&msg));
    loop {
        let (resp, _) = try!(transport.recv_msg());
        if ! resp.is_resp_for(&msg) {
            warn!("Q[{}][{}] Invalid response: {:?}",
                  transport, msg.get_id(), resp);
            continue;
        }
        if resp.get_response_code() == ResponseCode::FormErr && enable_edns {
            // Maybe the server doesn't implement EDNS?
            return query_core(msg.get_queries()[0].clone(), transport, false);
        }
        // TODO: Validate response, handle truncated message
        debug!("A[{}][{}] {:?} {} answer(s)",
           transport, resp.get_id(), resp.get_response_code(), resp.get_answers().len());
        return Ok(resp);
    }
}
fn query(q: Query, addr: Ipv4Addr, enable_edns: bool) -> Result<Message> {
    let target = SocketAddr::new(IpAddr::V4(addr), 53);
    let mut transport = try!(UdpSocket::v4()).with_timeout(QUERY_TIMEOUT);
    match query_core(q, transport.bound(Some(&target)), enable_edns) {
        Ok(msg) => {
            if msg.is_truncated() {
                // Try TCP
                let tcp_result = TcpStream::connect_with_timeout(&target, QUERY_TIMEOUT)
                .map_err(|e| e.into())
                .and_then(|stream| stream.set_nodelay(true).or(Ok(())).map(|_| stream))
                .and_then(|stream| query_core(
                    msg.get_queries()[0].clone(),
                    stream.with_timeout(QUERY_TIMEOUT).bound(Some(&target)),
                    enable_edns,
                ));
                Ok(tcp_result.unwrap_or(msg))
            } else {
                Ok(msg)
            }
        },
        Err(e) => Err(e),
    }
}
fn query_multiple(q: &Query, servers: &[Ipv4Addr]) -> Result<Message> {
    let mut futures = servers.iter()
        .cloned()
        .map(move |server| {
            let qc = q.clone();
            Future::from_fn(move || query(qc, server, true))
        })
        .collect::<Vec<Future<Result<Message>>>>();
    loop {
        let result_index = Future::wait_any(&mut futures);
        let result = futures.remove(result_index).consume();
        let mut should_return = futures.len() == 0;
        match result {
            Ok(ref msg) => {
                match msg.get_response_code() {
                    ResponseCode::ServFail |
                    ResponseCode::NotImp |
                    ResponseCode::Refused => {
                        // Fall below to wait for remaining servers, if any
                    },
                    _ => { should_return = true; },
                }
            },
            Err(Error::Io(ref err)) if err.kind() == std::io::ErrorKind::TimedOut => {
                debug!("{:?} timed out", q);
            },
            Err(ref err) => {
                debug!("{:?} returned error {:?}", q, err);
            },
        };
        if should_return {
            return result;
        }
    }
}

/// This function should never fail, otherwise we have a panic
fn handle_request(msg: Message, should_truncate: bool) -> Result<Vec<u8>> {
    let mut ret : Message = msg.new_resp();
    ret.recursion_available(true);
    if let Some(req_edns) = msg.get_edns() {
        let mut resp_edns = Edns::new();
        resp_edns.set_version(EDNS_VER);
        resp_edns.set_dnssec_ok(false); // TODO
        resp_edns.set_max_payload(max(512, req_edns.get_max_payload()));
        ret.set_edns(resp_edns);
        if req_edns.get_version() > EDNS_VER {
            warn!("Got EDNS version {}", req_edns.get_version());
            ret.response_code(ResponseCode::BADVERS);
            return ret.to_bytes();
        }
    }
    if msg.get_queries().len() != 1 {
        // For simplicity, only support one question
        ret.response_code(ResponseCode::Refused);
        return ret.to_bytes();
    }
    match query_multiple(&msg.get_queries()[0], &[Ipv4Addr::new(8, 8, 8, 8), Ipv4Addr::new(8, 8, 4, 4)]) {
        Ok(resp) => { ret.copy_resp_from(&resp); },
        Err(_)   => { ret.response_code(ResponseCode::ServFail); },
    };
    let bytes = try!(ret.to_bytes());
    if should_truncate && bytes.len() > (msg.get_max_payload() as usize) {
        return ret.truncate().to_bytes();
    }
    Ok(bytes)
}
fn serve_transport_async<TRecv, TSend, F>(mut recv: TRecv, mut send: TSend, on_error: F) -> JoinHandle<()>
    where TRecv: DnsTransport + Send + 'static,
          TSend: DnsTransport + Send + 'static,
          F: FnOnce(Error) + Send + 'static,
{
    let (sch, rch) = channel::<(Vec<u8>, Option<SocketAddr>)>();
    mioco::spawn(move || {
        loop {
            match rch.recv() {
                Ok((buf, addr)) => {
                    match send.send_msg_bytes(&buf, addr.as_ref()) {
                        Ok(_) => { },
                        Err(e) => { warn!("Failed to respond to DNS request: {:?}", e); },
                    };
                },
                Err(_) => {
                    trace!("Channel is broken");
                    return;
                },
            };
        }
    });
    mioco::spawn(move || {
        loop {
            let (msg, addr) = match recv.recv_msg(None) {
                Ok(x) => x,
                Err(e) => {
                    on_error(e);
                    return;
                },
            };
            let sch_req = sch.clone();
            mioco::spawn(move || {
                let resp = handle_request(msg, TSend::should_truncate()).expect("handle_request should not return error");
                sch_req.send((resp, addr)).expect("Result pipe should not break here");
            });
        }
    })
}
fn serve_tcp(addr: &SocketAddr) -> Result<JoinHandle<()>> {
    let listener = try!(TcpListener::bind(addr));
    Ok(mioco::spawn(move || {
        loop {
            let sock = listener.accept().expect("Failed to accept TCP socket");
            sock.set_nodelay(true).unwrap_or(());
            let sock_clone = sock.try_clone().expect("Failed to clone TCP socket");
            serve_transport_async(
                sock.with_resetting_timeout(QUERY_TIMEOUT),
                sock_clone.with_resetting_timeout(QUERY_TIMEOUT),
                |e| trace!("Client TCP connection is broken: {:?}", e)
            );
        }
    }))
}
fn serve_udp(addr: &SocketAddr) -> Result<JoinHandle<()>> {
    let sock : UdpSocket = try!(UdpSocket::v4());
    try!(sock.bind(addr));
    let sock_clone = try!(sock.try_clone());
    Ok(serve_transport_async(
        sock, sock_clone, |e| panic!("UDP listener is broken: {:?}", e)
    ))
}

fn main() {
    env_logger::init().unwrap();
    println!("Hello, world!");

    mioco::start(move || {
        let ip = Ipv4Addr::new(0, 0, 0, 0);
        let port = 5354;
        let addr = SocketAddr::V4(SocketAddrV4::new(ip, port));

        serve_tcp(&addr).expect("Failed to initialize TCP listener");
        serve_udp(&addr).expect("Failed to initialize UDP listener");
    }).expect("Unexpected error from mioco::start");
}
<|endoftext|>