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

//! Sane serialization & deserialization of cryptographic structs into hex

use crate::keychain::BlindingFactor;
use crate::serde::{Deserialize, Deserializer, Serializer};
use crate::util::secp::pedersen::{Commitment, RangeProof};
use crate::util::{from_hex, to_hex};

/// Serializes a secp PublicKey to and from hex
pub mod pubkey_serde {
	use crate::serde::{Deserialize, Deserializer, Serializer};
	use crate::util::secp::key::PublicKey;
	use crate::util::{from_hex, static_secp_instance, to_hex};

	///
	pub fn serialize<S>(key: &PublicKey, serializer: S) -> Result<S::Ok, S::Error>
	where
		S: Serializer,
	{
		let static_secp = static_secp_instance();
		let static_secp = static_secp.lock();
		serializer.serialize_str(&to_hex(key.serialize_vec(&static_secp, true).to_vec()))
	}

	///
	pub fn deserialize<'de, D>(deserializer: D) -> Result<PublicKey, D::Error>
	where
		D: Deserializer<'de>,
	{
		use serde::de::Error;
		let static_secp = static_secp_instance();
		let static_secp = static_secp.lock();
		String::deserialize(deserializer)
			.and_then(|string| from_hex(string).map_err(|err| Error::custom(err.to_string())))
			.and_then(|bytes: Vec<u8>| {
				PublicKey::from_slice(&static_secp, &bytes)
					.map_err(|err| Error::custom(err.to_string()))
			})
	}
}

/// Serializes an Option<secp::Signature> to and from hex
pub mod option_sig_serde {
	use crate::serde::{Deserialize, Deserializer, Serializer};
	use crate::util::secp;
	use crate::util::{from_hex, to_hex};
	use serde::de::Error;

	///
	pub fn serialize<S>(sig: &Option<secp::Signature>, serializer: S) -> Result<S::Ok, S::Error>
	where
		S: Serializer,
	{
		match sig {
			Some(sig) => serializer.serialize_str(&to_hex(sig.to_raw_data().to_vec())),
			None => serializer.serialize_none(),
		}
	}

	///
	pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<secp::Signature>, D::Error>
	where
		D: Deserializer<'de>,
	{
		Option::<&str>::deserialize(deserializer).and_then(|res| match res {
			Some(string) => from_hex(string.to_string())
				.map_err(|err| Error::custom(err.to_string()))
				.and_then(|bytes: Vec<u8>| {
					let mut b = [0u8; 64];
					b.copy_from_slice(&bytes[0..64]);
					secp::Signature::from_raw_data(&b)
						.map(|val| Some(val))
						.map_err(|err| Error::custom(err.to_string()))
				}),
			None => Ok(None),
		})
	}

}

/// Serializes a secp::Signature to and from hex
pub mod sig_serde {
	use crate::serde::{Deserialize, Deserializer, Serializer};
	use crate::util::secp;
	use crate::util::{from_hex, to_hex};
	use serde::de::Error;

	///
	pub fn serialize<S>(sig: &secp::Signature, serializer: S) -> Result<S::Ok, S::Error>
	where
		S: Serializer,
	{
		serializer.serialize_str(&to_hex(sig.to_raw_data().to_vec()))
	}

	///
	pub fn deserialize<'de, D>(deserializer: D) -> Result<secp::Signature, D::Error>
	where
		D: Deserializer<'de>,
	{
		String::deserialize(deserializer)
			.and_then(|string| from_hex(string).map_err(|err| Error::custom(err.to_string())))
			.and_then(|bytes: Vec<u8>| {
				let mut b = [0u8; 64];
				b.copy_from_slice(&bytes[0..64]);
				secp::Signature::from_raw_data(&b).map_err(|err| Error::custom(err.to_string()))
			})
	}
}

/// Creates a BlindingFactor from a hex string
pub fn blind_from_hex<'de, D>(deserializer: D) -> Result<BlindingFactor, D::Error>
where
	D: Deserializer<'de>,
{
	use serde::de::Error;
	String::deserialize(deserializer).and_then(|string| {
		BlindingFactor::from_hex(&string).map_err(|err| Error::custom(err.to_string()))
	})
}

/// Creates a RangeProof from a hex string
pub fn rangeproof_from_hex<'de, D>(deserializer: D) -> Result<RangeProof, D::Error>
where
	D: Deserializer<'de>,
{
	use serde::de::{Error, IntoDeserializer};

	let val = String::deserialize(deserializer)
		.and_then(|string| from_hex(string).map_err(|err| Error::custom(err.to_string())))?;
	RangeProof::deserialize(val.into_deserializer())
}

/// Creates a Pedersen Commitment from a hex string
pub fn commitment_from_hex<'de, D>(deserializer: D) -> Result<Commitment, D::Error>
where
	D: Deserializer<'de>,
{
	use serde::de::Error;
	String::deserialize(deserializer)
		.and_then(|string| from_hex(string).map_err(|err| Error::custom(err.to_string())))
		.and_then(|bytes: Vec<u8>| Ok(Commitment::from_vec(bytes.to_vec())))
}

/// Seralizes a byte string into hex
pub fn as_hex<T, S>(bytes: T, serializer: S) -> Result<S::Ok, S::Error>
where
	T: AsRef<[u8]>,
	S: Serializer,
{
	serializer.serialize_str(&to_hex(bytes.as_ref().to_vec()))
}

/// Used to ensure u64s are serialised in json
/// as strings by default, since it can't be guaranteed that consumers
/// will know what to do with u64 literals (e.g. Javascript). However,
/// fields using this tag can be deserialized from literals or strings.
/// From solutions on:
/// https://github.com/serde-rs/json/issues/329
pub mod string_or_u64 {
	use std::fmt;

	use serde::{de, Deserializer, Serializer};

	/// serialize into a string
	pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
	where
		T: fmt::Display,
		S: Serializer,
	{
		serializer.collect_str(value)
	}

	/// deserialize from either literal or string
	pub fn deserialize<'de, D>(deserializer: D) -> Result<u64, D::Error>
	where
		D: Deserializer<'de>,
	{
		struct Visitor;
		impl<'a> de::Visitor<'a> for Visitor {
			type Value = u64;
			fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
				write!(
					formatter,
					"a string containing digits or an int fitting into u64"
				)
			}
			fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> {
				Ok(v)
			}
			fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
			where
				E: de::Error,
			{
				s.parse().map_err(de::Error::custom)
			}
		}
		deserializer.deserialize_any(Visitor)
	}
}

/// As above, for Options
pub mod opt_string_or_u64 {
	use std::fmt;

	use serde::{de, Deserializer, Serializer};

	/// serialize into string or none
	pub fn serialize<T, S>(value: &Option<T>, serializer: S) -> Result<S::Ok, S::Error>
	where
		T: fmt::Display,
		S: Serializer,
	{
		match value {
			Some(v) => serializer.collect_str(v),
			None => serializer.serialize_none(),
		}
	}

	/// deser from 'null', literal or string
	pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<u64>, D::Error>
	where
		D: Deserializer<'de>,
	{
		struct Visitor;
		impl<'a> de::Visitor<'a> for Visitor {
			type Value = Option<u64>;
			fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
				write!(
					formatter,
					"null, a string containing digits or an int fitting into u64"
				)
			}
			fn visit_unit<E>(self) -> Result<Self::Value, E> {
				Ok(None)
			}
			fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> {
				Ok(Some(v))
			}
			fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
			where
				E: de::Error,
			{
				let val: u64 = s.parse().map_err(de::Error::custom)?;
				Ok(Some(val))
			}
		}
		deserializer.deserialize_any(Visitor)
	}
}

// Test serialization methods of components that are being used
#[cfg(test)]
mod test {
	use super::*;
	use crate::libtx::aggsig;
	use crate::util::secp::key::{PublicKey, SecretKey};
	use crate::util::secp::{Message, Signature};
	use crate::util::static_secp_instance;

	use serde_json;

	use rand::{thread_rng, Rng};

	#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
	struct SerTest {
		#[serde(with = "pubkey_serde")]
		pub pub_key: PublicKey,
		#[serde(with = "option_sig_serde")]
		pub opt_sig: Option<Signature>,
		#[serde(with = "sig_serde")]
		pub sig: Signature,
		#[serde(with = "string_or_u64")]
		pub num: u64,
		#[serde(with = "opt_string_or_u64")]
		pub opt_num: Option<u64>,
	}

	impl SerTest {
		pub fn random() -> SerTest {
			let static_secp = static_secp_instance();
			let secp = static_secp.lock();
			let sk = SecretKey::new(&secp, &mut thread_rng());
			let mut msg = [0u8; 32];
			thread_rng().fill(&mut msg);
			let msg = Message::from_slice(&msg).unwrap();
			let sig = aggsig::sign_single(&secp, &msg, &sk, None, None).unwrap();
			SerTest {
				pub_key: PublicKey::from_secret_key(&secp, &sk).unwrap(),
				opt_sig: Some(sig.clone()),
				sig: sig.clone(),
				num: 30,
				opt_num: Some(33),
			}
		}
	}

	#[test]
	fn ser_secp_primitives() {
		for _ in 0..10 {
			let s = SerTest::random();
			println!("Before Serialization: {:?}", s);
			let serialized = serde_json::to_string_pretty(&s).unwrap();
			println!("JSON: {}", serialized);
			let deserialized: SerTest = serde_json::from_str(&serialized).unwrap();
			println!("After Serialization: {:?}", deserialized);
			println!();
			assert_eq!(s, deserialized);
		}
	}
}
<commit_msg>fix option_sig_serde (#2699)<commit_after>// Copyright 2018 The Grin Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Sane serialization & deserialization of cryptographic structs into hex

use crate::keychain::BlindingFactor;
use crate::serde::{Deserialize, Deserializer, Serializer};
use crate::util::secp::pedersen::{Commitment, RangeProof};
use crate::util::{from_hex, to_hex};

/// Serializes a secp PublicKey to and from hex
pub mod pubkey_serde {
	use crate::serde::{Deserialize, Deserializer, Serializer};
	use crate::util::secp::key::PublicKey;
	use crate::util::{from_hex, static_secp_instance, to_hex};

	///
	pub fn serialize<S>(key: &PublicKey, serializer: S) -> Result<S::Ok, S::Error>
	where
		S: Serializer,
	{
		let static_secp = static_secp_instance();
		let static_secp = static_secp.lock();
		serializer.serialize_str(&to_hex(key.serialize_vec(&static_secp, true).to_vec()))
	}

	///
	pub fn deserialize<'de, D>(deserializer: D) -> Result<PublicKey, D::Error>
	where
		D: Deserializer<'de>,
	{
		use serde::de::Error;
		let static_secp = static_secp_instance();
		let static_secp = static_secp.lock();
		String::deserialize(deserializer)
			.and_then(|string| from_hex(string).map_err(|err| Error::custom(err.to_string())))
			.and_then(|bytes: Vec<u8>| {
				PublicKey::from_slice(&static_secp, &bytes)
					.map_err(|err| Error::custom(err.to_string()))
			})
	}
}

/// Serializes an Option<secp::Signature> to and from hex
pub mod option_sig_serde {
	use crate::serde::{Deserialize, Deserializer, Serializer};
	use crate::util::secp;
	use crate::util::{from_hex, to_hex};
	use serde::de::Error;

	///
	pub fn serialize<S>(sig: &Option<secp::Signature>, serializer: S) -> Result<S::Ok, S::Error>
	where
		S: Serializer,
	{
		match sig {
			Some(sig) => serializer.serialize_str(&to_hex(sig.to_raw_data().to_vec())),
			None => serializer.serialize_none(),
		}
	}

	///
	pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<secp::Signature>, D::Error>
	where
		D: Deserializer<'de>,
	{
		Option::<String>::deserialize(deserializer).and_then(|res| match res {
			Some(string) => from_hex(string.to_string())
				.map_err(|err| Error::custom(err.to_string()))
				.and_then(|bytes: Vec<u8>| {
					let mut b = [0u8; 64];
					b.copy_from_slice(&bytes[0..64]);
					secp::Signature::from_raw_data(&b)
						.map(|val| Some(val))
						.map_err(|err| Error::custom(err.to_string()))
				}),
			None => Ok(None),
		})
	}

}

/// Serializes a secp::Signature to and from hex
pub mod sig_serde {
	use crate::serde::{Deserialize, Deserializer, Serializer};
	use crate::util::secp;
	use crate::util::{from_hex, to_hex};
	use serde::de::Error;

	///
	pub fn serialize<S>(sig: &secp::Signature, serializer: S) -> Result<S::Ok, S::Error>
	where
		S: Serializer,
	{
		serializer.serialize_str(&to_hex(sig.to_raw_data().to_vec()))
	}

	///
	pub fn deserialize<'de, D>(deserializer: D) -> Result<secp::Signature, D::Error>
	where
		D: Deserializer<'de>,
	{
		String::deserialize(deserializer)
			.and_then(|string| from_hex(string).map_err(|err| Error::custom(err.to_string())))
			.and_then(|bytes: Vec<u8>| {
				let mut b = [0u8; 64];
				b.copy_from_slice(&bytes[0..64]);
				secp::Signature::from_raw_data(&b).map_err(|err| Error::custom(err.to_string()))
			})
	}
}

/// Creates a BlindingFactor from a hex string
pub fn blind_from_hex<'de, D>(deserializer: D) -> Result<BlindingFactor, D::Error>
where
	D: Deserializer<'de>,
{
	use serde::de::Error;
	String::deserialize(deserializer).and_then(|string| {
		BlindingFactor::from_hex(&string).map_err(|err| Error::custom(err.to_string()))
	})
}

/// Creates a RangeProof from a hex string
pub fn rangeproof_from_hex<'de, D>(deserializer: D) -> Result<RangeProof, D::Error>
where
	D: Deserializer<'de>,
{
	use serde::de::{Error, IntoDeserializer};

	let val = String::deserialize(deserializer)
		.and_then(|string| from_hex(string).map_err(|err| Error::custom(err.to_string())))?;
	RangeProof::deserialize(val.into_deserializer())
}

/// Creates a Pedersen Commitment from a hex string
pub fn commitment_from_hex<'de, D>(deserializer: D) -> Result<Commitment, D::Error>
where
	D: Deserializer<'de>,
{
	use serde::de::Error;
	String::deserialize(deserializer)
		.and_then(|string| from_hex(string).map_err(|err| Error::custom(err.to_string())))
		.and_then(|bytes: Vec<u8>| Ok(Commitment::from_vec(bytes.to_vec())))
}

/// Seralizes a byte string into hex
pub fn as_hex<T, S>(bytes: T, serializer: S) -> Result<S::Ok, S::Error>
where
	T: AsRef<[u8]>,
	S: Serializer,
{
	serializer.serialize_str(&to_hex(bytes.as_ref().to_vec()))
}

/// Used to ensure u64s are serialised in json
/// as strings by default, since it can't be guaranteed that consumers
/// will know what to do with u64 literals (e.g. Javascript). However,
/// fields using this tag can be deserialized from literals or strings.
/// From solutions on:
/// https://github.com/serde-rs/json/issues/329
pub mod string_or_u64 {
	use std::fmt;

	use serde::{de, Deserializer, Serializer};

	/// serialize into a string
	pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
	where
		T: fmt::Display,
		S: Serializer,
	{
		serializer.collect_str(value)
	}

	/// deserialize from either literal or string
	pub fn deserialize<'de, D>(deserializer: D) -> Result<u64, D::Error>
	where
		D: Deserializer<'de>,
	{
		struct Visitor;
		impl<'a> de::Visitor<'a> for Visitor {
			type Value = u64;
			fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
				write!(
					formatter,
					"a string containing digits or an int fitting into u64"
				)
			}
			fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> {
				Ok(v)
			}
			fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
			where
				E: de::Error,
			{
				s.parse().map_err(de::Error::custom)
			}
		}
		deserializer.deserialize_any(Visitor)
	}
}

/// As above, for Options
pub mod opt_string_or_u64 {
	use std::fmt;

	use serde::{de, Deserializer, Serializer};

	/// serialize into string or none
	pub fn serialize<T, S>(value: &Option<T>, serializer: S) -> Result<S::Ok, S::Error>
	where
		T: fmt::Display,
		S: Serializer,
	{
		match value {
			Some(v) => serializer.collect_str(v),
			None => serializer.serialize_none(),
		}
	}

	/// deser from 'null', literal or string
	pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<u64>, D::Error>
	where
		D: Deserializer<'de>,
	{
		struct Visitor;
		impl<'a> de::Visitor<'a> for Visitor {
			type Value = Option<u64>;
			fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
				write!(
					formatter,
					"null, a string containing digits or an int fitting into u64"
				)
			}
			fn visit_unit<E>(self) -> Result<Self::Value, E> {
				Ok(None)
			}
			fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> {
				Ok(Some(v))
			}
			fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
			where
				E: de::Error,
			{
				let val: u64 = s.parse().map_err(de::Error::custom)?;
				Ok(Some(val))
			}
		}
		deserializer.deserialize_any(Visitor)
	}
}

// Test serialization methods of components that are being used
#[cfg(test)]
mod test {
	use super::*;
	use crate::libtx::aggsig;
	use crate::util::secp::key::{PublicKey, SecretKey};
	use crate::util::secp::{Message, Signature};
	use crate::util::static_secp_instance;

	use serde_json;

	use rand::{thread_rng, Rng};

	#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
	struct SerTest {
		#[serde(with = "pubkey_serde")]
		pub pub_key: PublicKey,
		#[serde(with = "option_sig_serde")]
		pub opt_sig: Option<Signature>,
		#[serde(with = "sig_serde")]
		pub sig: Signature,
		#[serde(with = "string_or_u64")]
		pub num: u64,
		#[serde(with = "opt_string_or_u64")]
		pub opt_num: Option<u64>,
	}

	impl SerTest {
		pub fn random() -> SerTest {
			let static_secp = static_secp_instance();
			let secp = static_secp.lock();
			let sk = SecretKey::new(&secp, &mut thread_rng());
			let mut msg = [0u8; 32];
			thread_rng().fill(&mut msg);
			let msg = Message::from_slice(&msg).unwrap();
			let sig = aggsig::sign_single(&secp, &msg, &sk, None, None).unwrap();
			SerTest {
				pub_key: PublicKey::from_secret_key(&secp, &sk).unwrap(),
				opt_sig: Some(sig.clone()),
				sig: sig.clone(),
				num: 30,
				opt_num: Some(33),
			}
		}
	}

	#[test]
	fn ser_secp_primitives() {
		for _ in 0..10 {
			let s = SerTest::random();
			println!("Before Serialization: {:?}", s);
			let serialized = serde_json::to_string_pretty(&s).unwrap();
			println!("JSON: {}", serialized);
			let deserialized: SerTest = serde_json::from_str(&serialized).unwrap();
			println!("After Serialization: {:?}", deserialized);
			println!();
			assert_eq!(s, deserialized);
		}
	}
}
<|endoftext|>


<commit_before>extern crate polydraw;

use std::i64;

use polydraw::geom::point::Point;
use polydraw::{Application, Renderer, Frame};
use polydraw::raster::{Scene, Rasterizer, EdgeType, Poly, create_default_vec};

#[derive(Debug, Clone, Copy)]
pub struct Edge {
   pub edge_type: EdgeType,
   pub p1: Point,
   pub p2: Point,
}

impl Edge {
   #[inline]
   pub fn new(edge_type: EdgeType, x1: i64, y1: i64, x2: i64, y2: i64) -> Self {
      Edge {
         edge_type: edge_type,
         p1: Point::new(x1, y1),
         p2: Point::new(x2, y2),
      }
   }

   #[inline]
   pub fn vert_top(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LVT, x1, y1, x2, y2)
   }

   #[inline]
   pub fn vert_bottom(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LVB, x1, y1, x2, y2)
   }

   #[inline]
   pub fn hori_right(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LHR, x1, y1, x2, y2)
   }

   #[inline]
   pub fn hori_left(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LHL, x1, y1, x2, y2)
   }

   #[inline]
   pub fn top_right(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LTR, x1, y1, x2, y2)
   }

   #[inline]
   pub fn top_left(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LTL, x1, y1, x2, y2)
   }

   #[inline]
   pub fn bottom_right(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LBR, x1, y1, x2, y2)
   }

   #[inline]
   pub fn bottom_left(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LBL, x1, y1, x2, y2)
   }
}

struct ClipRenderer {
   rasterizer: Rasterizer,
   div_per_pixel: i64,

   edges: Vec<Edge>,
   polys: Vec<Poly>,

   edge_min_y: Vec<i64>,
   edge_max_y: Vec<i64>,
}

impl ClipRenderer {
   fn new() -> Self {
      let edges = vec![
         Edge::top_left(5, 1, 1, 6),       // 0
         Edge::top_right(1, 6, 8, 9),      // 1
         Edge::bottom_right(8, 9, 9, 6),   // 2
         Edge::bottom_left(9, 6, 5, 1),    // 3
         Edge::top_right(1, 1, 3, 8),      // 4
         Edge::bottom_right(3, 8, 10, 4),  // 5
         Edge::bottom_left(10, 4, 1, 1),   // 6
      ];

      let polys = vec![
         Poly::new(0, 4, 0),    // 0
         Poly::new(4, 7, 1),    // 1
      ];

      let edges_len = edges.len();

      let edge_min_y = create_default_vec(edges_len);
      let edge_max_y = create_default_vec(edges_len);

      ClipRenderer {
         rasterizer: Rasterizer::new(),
         div_per_pixel: 1000,

         edges: edges,
         polys: polys,

         edge_min_y: edge_min_y,
         edge_max_y: edge_max_y,
      }
   }

   fn create_scene(&self) -> Scene {
      let points = vec![];

      let segments = vec![];

      let circles = vec![];

      let edges = vec![];

      let polys = vec![];

      let colors = vec![];

      Scene {
         points: points,
         segments: segments,
         circles: circles,
         edges: edges,
         polys: polys,
         colors: colors,
      }
   }

   fn init_edge_min_max_y(&mut self) {
      for edge_index in 0..self.edges.len() {
         let ref edge = self.edges[edge_index];

         let mut min_y = i64::MAX;
         let mut max_y = i64::MIN;

         let (edge_min_y, edge_max_y) = if edge.edge_type.reversed() {
            (edge.p2.y, edge.p1.y)
         } else {
            (edge.p1.y, edge.p2.y)
         };

         if edge_min_y < min_y  {
            min_y = edge_min_y;
         }

         if edge_max_y > max_y {
            max_y = edge_max_y;
         }

         self.edge_min_y[edge_index] = min_y;
         self.edge_max_y[edge_index] = max_y;
      }

      println!("MIN Y {:?}", self.edge_min_y);
      println!("MAX Y {:?}", self.edge_max_y);

      panic!("END");
   }
}

impl Renderer for ClipRenderer {
   fn render(&mut self, frame: &mut Frame) {
      frame.clear();

      self.init_edge_min_max_y();

      let scene = self.create_scene();

      self.rasterizer.render(&scene, frame, self.div_per_pixel);
   }
}

fn main() {
   let mut renderer = ClipRenderer::new();

   Application::new()
      .renderer(&mut renderer)
      .title("Clip")
      .run();
}
<commit_msg>Ordering of edges by min y<commit_after>extern crate polydraw;

use std::cmp::Ordering;
use std::i64;

use polydraw::geom::point::Point;
use polydraw::{Application, Renderer, Frame};
use polydraw::raster::{Scene, Rasterizer, EdgeType, Poly, create_default_vec};

#[derive(Debug, Clone, Copy)]
pub struct Edge {
   pub edge_type: EdgeType,
   pub p1: Point,
   pub p2: Point,
}

impl Edge {
   #[inline]
   pub fn new(edge_type: EdgeType, x1: i64, y1: i64, x2: i64, y2: i64) -> Self {
      Edge {
         edge_type: edge_type,
         p1: Point::new(x1, y1),
         p2: Point::new(x2, y2),
      }
   }

   #[inline]
   pub fn vert_top(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LVT, x1, y1, x2, y2)
   }

   #[inline]
   pub fn vert_bottom(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LVB, x1, y1, x2, y2)
   }

   #[inline]
   pub fn hori_right(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LHR, x1, y1, x2, y2)
   }

   #[inline]
   pub fn hori_left(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LHL, x1, y1, x2, y2)
   }

   #[inline]
   pub fn top_right(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LTR, x1, y1, x2, y2)
   }

   #[inline]
   pub fn top_left(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LTL, x1, y1, x2, y2)
   }

   #[inline]
   pub fn bottom_right(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LBR, x1, y1, x2, y2)
   }

   #[inline]
   pub fn bottom_left(x1: i64, y1: i64, x2: i64, y2: i64) -> Edge {
      Edge::new(EdgeType::LBL, x1, y1, x2, y2)
   }
}

struct ClipRenderer {
   rasterizer: Rasterizer,
   div_per_pixel: i64,

   edges: Vec<Edge>,
   polys: Vec<Poly>,

   edge_min_y: Vec<i64>,
   edge_max_y: Vec<i64>,
   edge_order: Vec<usize>,
}

impl ClipRenderer {
   fn new() -> Self {
      let edges = vec![
         Edge::top_left(5, 1, 1, 6),       // 0
         Edge::top_right(1, 6, 8, 9),      // 1
         Edge::bottom_right(8, 9, 9, 6),   // 2
         Edge::bottom_left(9, 6, 5, 1),    // 3
         Edge::top_right(1, 1, 3, 8),      // 4
         Edge::bottom_right(3, 8, 10, 4),  // 5
         Edge::bottom_left(10, 4, 1, 1),   // 6
      ];

      let polys = vec![
         Poly::new(0, 4, 0),    // 0
         Poly::new(4, 7, 1),    // 1
      ];

      let edges_len = edges.len();

      let edge_min_y = create_default_vec(edges_len);
      let edge_max_y = create_default_vec(edges_len);
      let edge_order = create_default_vec(edges_len);

      ClipRenderer {
         rasterizer: Rasterizer::new(),
         div_per_pixel: 1000,

         edges: edges,
         polys: polys,

         edge_min_y: edge_min_y,
         edge_max_y: edge_max_y,
         edge_order: edge_order,
      }
   }

   fn create_scene(&self) -> Scene {
      let points = vec![];

      let segments = vec![];

      let circles = vec![];

      let edges = vec![];

      let polys = vec![];

      let colors = vec![];

      Scene {
         points: points,
         segments: segments,
         circles: circles,
         edges: edges,
         polys: polys,
         colors: colors,
      }
   }

   fn init_edge_min_max_y(&mut self) {
      for edge_index in 0..self.edges.len() {
         let ref edge = self.edges[edge_index];

         let mut min_y = i64::MAX;
         let mut max_y = i64::MIN;

         let (edge_min_y, edge_max_y) = if edge.edge_type.reversed() {
            (edge.p2.y, edge.p1.y)
         } else {
            (edge.p1.y, edge.p2.y)
         };

         if edge_min_y < min_y  {
            min_y = edge_min_y;
         }

         if edge_max_y > max_y {
            max_y = edge_max_y;
         }

         self.edge_min_y[edge_index] = min_y;
         self.edge_max_y[edge_index] = max_y;
         self.edge_order[edge_index] = edge_index;
      }

      self.sort_edge_order();

      println!("MIN Y {:?}", self.edge_min_y);
      println!("MAX Y {:?}", self.edge_max_y);
      println!("ORDER {:?}", self.edge_order);

      panic!("END");
   }

   fn sort_edge_order(&mut self) {
      let edge_order = &mut self.edge_order;
      let edge_min_y = &self.edge_min_y;
      let edge_max_y = &self.edge_max_y;

      edge_order.sort_by(|a, b| {
         match edge_min_y[*a].cmp(&edge_min_y[*b]) {
            Ordering::Less => Ordering::Less,
            Ordering::Greater => Ordering::Greater,
            Ordering::Equal => edge_max_y[*a].cmp(&edge_max_y[*b])
         }
      });
   }
}

impl Renderer for ClipRenderer {
   fn render(&mut self, frame: &mut Frame) {
      frame.clear();

      self.init_edge_min_max_y();

      let scene = self.create_scene();

      self.rasterizer.render(&scene, frame, self.div_per_pixel);
   }
}

fn main() {
   let mut renderer = ClipRenderer::new();

   Application::new()
      .renderer(&mut renderer)
      .title("Clip")
      .run();
}
<|endoftext|>


<commit_before>#![feature(type_ascription)]
#![feature(question_mark)]
#![feature(custom_derive)]
#![feature(plugin)]
#![plugin(serde_macros)]

#[macro_use]
extern crate rustless;
extern crate jsonway;
extern crate iron;
extern crate hyper;
extern crate valico;
extern crate env_logger;
extern crate clap;
extern crate serde;
extern crate time;
extern crate rand;

extern crate exonum;
extern crate blockchain_explorer;
extern crate cryptocurrency;

use std::net::SocketAddr;
use std::path::Path;
use std::thread;
use std::default::Default;

use clap::{Arg, App, SubCommand};
use rustless::json::ToJson;
use rustless::{Application, Api, Nesting, Versioning, Response};
use rustless::batteries::cookie::{Cookie, CookieExt, CookieJar};
use rustless::batteries::swagger;
use valico::json_dsl;
use hyper::status::StatusCode;
use rand::{Rng, thread_rng};

use exonum::node::{Node, Configuration, TxSender, NodeChannel};
use exonum::storage::{Database, MemoryDB, LevelDB, LevelDBOptions};
use exonum::storage::{Result as StorageResult, Error as StorageError};
use exonum::crypto::{gen_keypair, PublicKey, SecretKey, HexValue};
use exonum::messages::Message;
use exonum::config::ConfigFile;
use exonum::node::config::GenesisConfig;

use cryptocurrency::{CurrencyBlockchain, CurrencyTx, TxIssue, TxTransfer, TxCreateWallet};
use cryptocurrency::api::CurrencyApi;

pub type CurrencyTxSender<B> = TxSender<B, NodeChannel<B>>;

fn save_keypair_in_cookies(storage: &mut CookieJar,
                           public_key: &PublicKey,
                           secret_key: &SecretKey) {
    let p = storage.permanent();
    let e = p.encrypted();

    e.add(Cookie::new("public_key".to_string(), public_key.to_hex()));
    e.add(Cookie::new("secret_key".to_string(), secret_key.to_hex()));
}

fn load_hex_value_from_cookie<'a>(storage: &'a CookieJar, key: &str) -> StorageResult<Vec<u8>> {
    if let Some(cookie) = storage.find(key) {
        if let Ok(value) = HexValue::from_hex(cookie.value) {
            return Ok(value);
        }
    }
    Err(StorageError::new(format!("Unable to find value with given key {}", key)))
}

fn load_keypair_from_cookies(storage: &CookieJar) -> StorageResult<(PublicKey, SecretKey)> {
    let p = storage.permanent();
    let e = p.encrypted();

    let public_key = PublicKey::from_slice(load_hex_value_from_cookie(&e, "public_key")?.as_ref());
    let secret_key = SecretKey::from_slice(load_hex_value_from_cookie(&e, "secret_key")?.as_ref());

    let public_key = public_key.ok_or(StorageError::new("Unable to read public key"))?;
    let secret_key = secret_key.ok_or(StorageError::new("Unable to read secret key"))?;
    Ok((public_key, secret_key))
}

fn blockchain_explorer_api<D: Database>(api: &mut Api, b1: CurrencyBlockchain<D>) {
    blockchain_explorer::make_api::<CurrencyBlockchain<D>, CurrencyTx>(api, b1);
}

fn cryptocurrency_api<D: Database>(api: &mut Api,
                                   blockchain: CurrencyBlockchain<D>,
                                   channel: CurrencyTxSender<CurrencyBlockchain<D>>) {
    api.namespace("wallets", move |api| {
        let ch = channel.clone();
        api.post("create", move |endpoint| {
            endpoint.summary("Create a new wallet for user with given name");
            endpoint.params(|params| {
                params.req_typed("name", json_dsl::string());
            });

            endpoint.handle(move |client, params| {
                let name = params.find("name").unwrap().as_str().unwrap();
                // TODO make secure
                let (public_key, secret_key) = gen_keypair();
                {
                    let mut cookies = client.request.cookies();
                    save_keypair_in_cookies(&mut cookies, &public_key, &secret_key);
                }
                let tx = TxCreateWallet::new(&public_key, &name, &secret_key);

                let tx_hash = tx.hash().to_hex();
                ch.send(CurrencyTx::CreateWallet(tx));
                let json = &jsonway::object(|json| json.set("tx_hash", tx_hash)).unwrap();
                client.json(json)
            })
        });

        let ch = channel.clone();
        api.post("issue", move |endpoint| {
            endpoint.params(|params| {
                params.req_typed("amount", json_dsl::i64());
            });

            endpoint.handle(move |client, params| {
                let (public_key, secret_key) = {
                    let r = {
                        let cookies = client.request.cookies();
                        load_keypair_from_cookies(&cookies)
                    };
                    match r {
                        Ok((p, s)) => (p, s),
                        Err(e) => return client.error(e),
                    }
                };

                let amount = params.find("amount").unwrap().as_i64().unwrap();
                let seed = thread_rng().gen::<u64>();
                let tx = TxIssue::new(&public_key, amount, seed, &secret_key);

                let tx_hash = tx.hash().to_hex();
                ch.send(CurrencyTx::Issue(tx));
                let json = &jsonway::object(|json| json.set("tx_hash", tx_hash)).unwrap();
                client.json(json)
            })
        });

        let ch = channel.clone();
        api.post("transfer", move |endpoint| {
            endpoint.params(|params| {
                params.req_typed("amount", json_dsl::i64());
                params.req_typed("to", json_dsl::string());
            });

            endpoint.handle(move |client, params| {
                let (from_key, secret_key) = {
                    let r = {
                        let cookies = client.request.cookies();
                        load_keypair_from_cookies(&cookies)
                    };
                    match r {
                        Ok((p, s)) => (p, s),
                        Err(e) => return client.error(e),
                    }
                };
                // TODO remove unwrap
                let amount = params.find("amount").unwrap().as_i64().unwrap();
                let to = params.find("to").unwrap().as_str().unwrap();
                let seed = thread_rng().gen::<u64>();
                match PublicKey::from_hex(to) {
                    Ok(to_key) => {
                        let tx = TxTransfer::new(&from_key, &to_key, amount, seed, &secret_key);

                        let tx_hash = tx.hash().to_hex();
                        ch.send(CurrencyTx::Transfer(tx));
                        let json = &jsonway::object(|json| json.set("tx_hash", tx_hash)).unwrap();
                        client.json(json)
                    }
                    Err(e) => return client.error(e),
                }
            })
        });

        let b = blockchain.clone();
        api.get("info", move |endpoint| {
            endpoint.handle(move |client, _| {
                let (public_key, _) = {
                    let r = {
                        let cookies = client.request.cookies();
                        load_keypair_from_cookies(&cookies)
                    };
                    match r {
                        Ok((p, s)) => (p, s),
                        Err(e) => return client.error(e),
                    }
                };
                let currency_api = CurrencyApi::<D>::new(b.clone());
                match currency_api.wallet_info(&public_key) {
                    Ok(Some(info)) => client.json(&info.to_json()),
                    _ => client.error(StorageError::new("Unable to get wallet info")),
                }
            })
        })
    });
}

fn run_node<D: Database>(blockchain: CurrencyBlockchain<D>,
                         node_cfg: Configuration,
                         port: Option<u16>) {
    if let Some(port) = port {
        let mut node = Node::new(blockchain.clone(), node_cfg);
        let channel = node.channel();

        let api_thread = thread::spawn(move || {
            let channel = channel.clone();
            let blockchain = blockchain.clone();

            let api = Api::build(move |api| {
                // Specify API version
                api.version("v1", Versioning::Path);
                api.prefix("api");

                api.error_formatter(|err, _media| {
                    if let Some(e) = err.downcast::<StorageError>() {
                        let body = format!("An internal error occured: {}", e);
                        Some(Response::from(StatusCode::InternalServerError, Box::new(body)))
                    } else {
                        None
                    }
                });

                blockchain_explorer_api(api, blockchain.clone());
                cryptocurrency_api(api, blockchain.clone(), channel.clone());
                api.mount(swagger::create_api("docs"));
            });

            let listen_address: SocketAddr = format!("127.0.0.1:{}", port).parse().unwrap();
            println!("Cryptocurrency node server started on {}", listen_address);

            let mut app = Application::new(api);

            swagger::enable(&mut app,
                            swagger::Spec {
                                info: swagger::Info {
                                    title: "Cryptocurrency API".to_string(),
                                    description: Some("Simple API to demonstration".to_string()),
                                    contact: Some(swagger::Contact {
                                        name: "Aleksey Sidorov".to_string(),
                                        url: Some("aleksei.sidorov@xdev.re".to_string()),
                                        ..Default::default()
                                    }),
                                    license: Some(swagger::License {
                                        name: "Demo".to_string(),
                                        url: "http://exonum.com".to_string(),
                                    }),
                                    ..Default::default()
                                },
                                ..Default::default()
                            });

            let mut chain = iron::Chain::new(app);
            let api_key = b"abacabasecretcoinblabla23nx8Hasojd8";
            let cookie = ::rustless::batteries::cookie::new(api_key);
            chain.link(cookie);
            iron::Iron::new(chain).http(listen_address).unwrap();
        });

        node.run().unwrap();
        api_thread.join().unwrap();
    } else {
        Node::new(blockchain, node_cfg).run().unwrap();
    }
}

fn main() {
    env_logger::init().unwrap();

    let app = App::new("Simple cryptocurrency demo program")
        .version(env!("CARGO_PKG_VERSION"))
        .author("Aleksey S. <aleksei.sidorov@xdev.re>")
        .about("Demo cryptocurrency validator node")
        .arg(Arg::with_name("CONFIG")
            .short("c")
            .long("config")
            .value_name("CONFIG_PATH")
            .help("Sets a node config file")
            .required(true)
            .takes_value(true))
        .subcommand(SubCommand::with_name("generate")
            .about("Generates default configuration file")
            .version(env!("CARGO_PKG_VERSION"))
            .author("Aleksey S. <aleksei.sidorov@xdev.re>")
            .arg(Arg::with_name("START_PORT")
                .short("p")
                .long("port")
                .value_name("START_PORT")
                .help("Port for first validator")
                .takes_value(true))
            .arg(Arg::with_name("COUNT")
                .help("Validators count")
                .required(true)
                .index(1)))
        .subcommand(SubCommand::with_name("run")
            .about("Run demo node with the given validator id")
            .version(env!("CARGO_PKG_VERSION"))
            .author("Aleksey S. <aleksei.sidorov@xdev.re>")
            .arg(Arg::with_name("LEVELDB_PATH")
                .short("d")
                .long("leveldb-path")
                .value_name("LEVELDB_PATH")
                .help("Use leveldb database with the given path")
                .takes_value(true))
            .arg(Arg::with_name("HTTP_PORT")
                .short("p")
                .long("port")
                .value_name("HTTP_PORT")
                .help("Run http server on given port")
                .takes_value(true))
            .arg(Arg::with_name("PEERS")
                .long("known-peers")
                .value_name("PEERS")
                .help("Comma separated list of known validator ids")
                .takes_value(true))
            .arg(Arg::with_name("VALIDATOR")
                .help("Sets a validator id")
                .required(true)
                .index(1)));

    let matches = app.get_matches();
    let path = Path::new(matches.value_of("CONFIG").unwrap());
    match matches.subcommand() {
        ("generate", Some(matches)) => {
            let count: u8 = matches.value_of("COUNT").unwrap().parse().unwrap();
            let port: Option<u16> = matches.value_of("START_PORT").map(|x| x.parse().unwrap());
            let cfg = GenesisConfig::gen(count, port);
            ConfigFile::save(&cfg, &path).unwrap();
            println!("The configuration was successfully written to file {:?}",
                     path);
        }
        ("run", Some(matches)) => {
            let cfg: GenesisConfig = ConfigFile::load(path).unwrap();
            let idx: usize = matches.value_of("VALIDATOR").unwrap().parse().unwrap();
            let port: Option<u16> = matches.value_of("HTTP_PORT").map(|x| x.parse().unwrap());
            let peers = match matches.value_of("PEERS") {
                Some(string) => {
                    string.split(" ")
                        .map(|x| -> usize { x.parse().unwrap() })
                        .map(|x| cfg.validators[x].address)
                        .collect()
                }
                None => {
                    cfg.validators
                        .iter()
                        .map(|v| v.address)
                        .collect()
                }
            };
            let node_cfg = cfg.to_node_configuration(idx, peers);
            match matches.value_of("LEVELDB_PATH") {
                Some(ref db_path) => {
                    println!("Using levedb storage with path: {}", db_path);
                    let mut options = LevelDBOptions::new();
                    options.create_if_missing = true;
                    let leveldb = LevelDB::new(&Path::new(db_path), options).unwrap();

                    let blockchain = CurrencyBlockchain { db: leveldb };
                    run_node(blockchain, node_cfg, port);
                }
                None => {
                    println!("Using memorydb storage");

                    let blockchain = CurrencyBlockchain { db: MemoryDB::new() };
                    run_node(blockchain, node_cfg, port);
                }
            };
        }
        _ => {
            unreachable!("Wrong subcommand");
        }
    }
}
<commit_msg>Add time to logs in cryptocurrency<commit_after>#![feature(type_ascription)]
#![feature(question_mark)]
#![feature(custom_derive)]
#![feature(plugin)]
#![plugin(serde_macros)]

#[macro_use]
extern crate rustless;
extern crate jsonway;
extern crate iron;
extern crate hyper;
extern crate valico;
extern crate env_logger;
extern crate clap;
extern crate serde;
extern crate time;
extern crate rand;
extern crate log;

extern crate exonum;
extern crate blockchain_explorer;
extern crate cryptocurrency;

use std::net::SocketAddr;
use std::path::Path;
use std::thread;
use std::default::Default;
use std::env;

use clap::{Arg, App, SubCommand};
use rustless::json::ToJson;
use rustless::{Application, Api, Nesting, Versioning, Response};
use rustless::batteries::cookie::{Cookie, CookieExt, CookieJar};
use rustless::batteries::swagger;
use valico::json_dsl;
use hyper::status::StatusCode;
use rand::{Rng, thread_rng};
use log::{LogRecord, LogLevelFilter};
use env_logger::LogBuilder;

use exonum::node::{Node, Configuration, TxSender, NodeChannel};
use exonum::storage::{Database, MemoryDB, LevelDB, LevelDBOptions};
use exonum::storage::{Result as StorageResult, Error as StorageError};
use exonum::crypto::{gen_keypair, PublicKey, SecretKey, HexValue};
use exonum::messages::Message;
use exonum::config::ConfigFile;
use exonum::node::config::GenesisConfig;

use cryptocurrency::{CurrencyBlockchain, CurrencyTx, TxIssue, TxTransfer, TxCreateWallet};
use cryptocurrency::api::CurrencyApi;

pub type CurrencyTxSender<B> = TxSender<B, NodeChannel<B>>;

fn save_keypair_in_cookies(storage: &mut CookieJar,
                           public_key: &PublicKey,
                           secret_key: &SecretKey) {
    let p = storage.permanent();
    let e = p.encrypted();

    e.add(Cookie::new("public_key".to_string(), public_key.to_hex()));
    e.add(Cookie::new("secret_key".to_string(), secret_key.to_hex()));
}

fn load_hex_value_from_cookie<'a>(storage: &'a CookieJar, key: &str) -> StorageResult<Vec<u8>> {
    if let Some(cookie) = storage.find(key) {
        if let Ok(value) = HexValue::from_hex(cookie.value) {
            return Ok(value);
        }
    }
    Err(StorageError::new(format!("Unable to find value with given key {}", key)))
}

fn load_keypair_from_cookies(storage: &CookieJar) -> StorageResult<(PublicKey, SecretKey)> {
    let p = storage.permanent();
    let e = p.encrypted();

    let public_key = PublicKey::from_slice(load_hex_value_from_cookie(&e, "public_key")?.as_ref());
    let secret_key = SecretKey::from_slice(load_hex_value_from_cookie(&e, "secret_key")?.as_ref());

    let public_key = public_key.ok_or(StorageError::new("Unable to read public key"))?;
    let secret_key = secret_key.ok_or(StorageError::new("Unable to read secret key"))?;
    Ok((public_key, secret_key))
}

fn blockchain_explorer_api<D: Database>(api: &mut Api, b1: CurrencyBlockchain<D>) {
    blockchain_explorer::make_api::<CurrencyBlockchain<D>, CurrencyTx>(api, b1);
}

fn cryptocurrency_api<D: Database>(api: &mut Api,
                                   blockchain: CurrencyBlockchain<D>,
                                   channel: CurrencyTxSender<CurrencyBlockchain<D>>) {
    api.namespace("wallets", move |api| {
        let ch = channel.clone();
        api.post("create", move |endpoint| {
            endpoint.summary("Create a new wallet for user with given name");
            endpoint.params(|params| {
                params.req_typed("name", json_dsl::string());
            });

            endpoint.handle(move |client, params| {
                let name = params.find("name").unwrap().as_str().unwrap();
                // TODO make secure
                let (public_key, secret_key) = gen_keypair();
                {
                    let mut cookies = client.request.cookies();
                    save_keypair_in_cookies(&mut cookies, &public_key, &secret_key);
                }
                let tx = TxCreateWallet::new(&public_key, &name, &secret_key);

                let tx_hash = tx.hash().to_hex();
                ch.send(CurrencyTx::CreateWallet(tx));
                let json = &jsonway::object(|json| json.set("tx_hash", tx_hash)).unwrap();
                client.json(json)
            })
        });

        let ch = channel.clone();
        api.post("issue", move |endpoint| {
            endpoint.params(|params| {
                params.req_typed("amount", json_dsl::i64());
            });

            endpoint.handle(move |client, params| {
                let (public_key, secret_key) = {
                    let r = {
                        let cookies = client.request.cookies();
                        load_keypair_from_cookies(&cookies)
                    };
                    match r {
                        Ok((p, s)) => (p, s),
                        Err(e) => return client.error(e),
                    }
                };

                let amount = params.find("amount").unwrap().as_i64().unwrap();
                let seed = thread_rng().gen::<u64>();
                let tx = TxIssue::new(&public_key, amount, seed, &secret_key);

                let tx_hash = tx.hash().to_hex();
                ch.send(CurrencyTx::Issue(tx));
                let json = &jsonway::object(|json| json.set("tx_hash", tx_hash)).unwrap();
                client.json(json)
            })
        });

        let ch = channel.clone();
        api.post("transfer", move |endpoint| {
            endpoint.params(|params| {
                params.req_typed("amount", json_dsl::i64());
                params.req_typed("to", json_dsl::string());
            });

            endpoint.handle(move |client, params| {
                let (from_key, secret_key) = {
                    let r = {
                        let cookies = client.request.cookies();
                        load_keypair_from_cookies(&cookies)
                    };
                    match r {
                        Ok((p, s)) => (p, s),
                        Err(e) => return client.error(e),
                    }
                };
                // TODO remove unwrap
                let amount = params.find("amount").unwrap().as_i64().unwrap();
                let to = params.find("to").unwrap().as_str().unwrap();
                let seed = thread_rng().gen::<u64>();
                match PublicKey::from_hex(to) {
                    Ok(to_key) => {
                        let tx = TxTransfer::new(&from_key, &to_key, amount, seed, &secret_key);

                        let tx_hash = tx.hash().to_hex();
                        ch.send(CurrencyTx::Transfer(tx));
                        let json = &jsonway::object(|json| json.set("tx_hash", tx_hash)).unwrap();
                        client.json(json)
                    }
                    Err(e) => return client.error(e),
                }
            })
        });

        let b = blockchain.clone();
        api.get("info", move |endpoint| {
            endpoint.handle(move |client, _| {
                let (public_key, _) = {
                    let r = {
                        let cookies = client.request.cookies();
                        load_keypair_from_cookies(&cookies)
                    };
                    match r {
                        Ok((p, s)) => (p, s),
                        Err(e) => return client.error(e),
                    }
                };
                let currency_api = CurrencyApi::<D>::new(b.clone());
                match currency_api.wallet_info(&public_key) {
                    Ok(Some(info)) => client.json(&info.to_json()),
                    _ => client.error(StorageError::new("Unable to get wallet info")),
                }
            })
        })
    });
}

fn run_node<D: Database>(blockchain: CurrencyBlockchain<D>,
                         node_cfg: Configuration,
                         port: Option<u16>) {
    if let Some(port) = port {
        let mut node = Node::new(blockchain.clone(), node_cfg);
        let channel = node.channel();

        let api_thread = thread::spawn(move || {
            let channel = channel.clone();
            let blockchain = blockchain.clone();

            let api = Api::build(move |api| {
                // Specify API version
                api.version("v1", Versioning::Path);
                api.prefix("api");

                api.error_formatter(|err, _media| {
                    if let Some(e) = err.downcast::<StorageError>() {
                        let body = format!("An internal error occured: {}", e);
                        Some(Response::from(StatusCode::InternalServerError, Box::new(body)))
                    } else {
                        None
                    }
                });

                blockchain_explorer_api(api, blockchain.clone());
                cryptocurrency_api(api, blockchain.clone(), channel.clone());
                api.mount(swagger::create_api("docs"));
            });

            let listen_address: SocketAddr = format!("127.0.0.1:{}", port).parse().unwrap();
            println!("Cryptocurrency node server started on {}", listen_address);

            let mut app = Application::new(api);

            swagger::enable(&mut app,
                            swagger::Spec {
                                info: swagger::Info {
                                    title: "Cryptocurrency API".to_string(),
                                    description: Some("Simple API to demonstration".to_string()),
                                    contact: Some(swagger::Contact {
                                        name: "Aleksey Sidorov".to_string(),
                                        url: Some("aleksei.sidorov@xdev.re".to_string()),
                                        ..Default::default()
                                    }),
                                    license: Some(swagger::License {
                                        name: "Demo".to_string(),
                                        url: "http://exonum.com".to_string(),
                                    }),
                                    ..Default::default()
                                },
                                ..Default::default()
                            });

            let mut chain = iron::Chain::new(app);
            let api_key = b"abacabasecretcoinblabla23nx8Hasojd8";
            let cookie = ::rustless::batteries::cookie::new(api_key);
            chain.link(cookie);
            iron::Iron::new(chain).http(listen_address).unwrap();
        });

        node.run().unwrap();
        api_thread.join().unwrap();
    } else {
        Node::new(blockchain, node_cfg).run().unwrap();
    }
}

fn main() {
    let format = |record: &LogRecord| {
        let now = time::now_utc();
        format!("{}  [{}]  {}", now.asctime(), record.level(), record.args())
    };

    let mut builder = LogBuilder::new();
    builder.format(format).filter(None, LogLevelFilter::Info);

    if env::var("RUST_LOG").is_ok() {
       builder.parse(&env::var("RUST_LOG").unwrap());
    }

    builder.init().unwrap();

    let app = App::new("Simple cryptocurrency demo program")
        .version(env!("CARGO_PKG_VERSION"))
        .author("Aleksey S. <aleksei.sidorov@xdev.re>")
        .about("Demo cryptocurrency validator node")
        .arg(Arg::with_name("CONFIG")
            .short("c")
            .long("config")
            .value_name("CONFIG_PATH")
            .help("Sets a node config file")
            .required(true)
            .takes_value(true))
        .subcommand(SubCommand::with_name("generate")
            .about("Generates default configuration file")
            .version(env!("CARGO_PKG_VERSION"))
            .author("Aleksey S. <aleksei.sidorov@xdev.re>")
            .arg(Arg::with_name("START_PORT")
                .short("p")
                .long("port")
                .value_name("START_PORT")
                .help("Port for first validator")
                .takes_value(true))
            .arg(Arg::with_name("COUNT")
                .help("Validators count")
                .required(true)
                .index(1)))
        .subcommand(SubCommand::with_name("run")
            .about("Run demo node with the given validator id")
            .version(env!("CARGO_PKG_VERSION"))
            .author("Aleksey S. <aleksei.sidorov@xdev.re>")
            .arg(Arg::with_name("LEVELDB_PATH")
                .short("d")
                .long("leveldb-path")
                .value_name("LEVELDB_PATH")
                .help("Use leveldb database with the given path")
                .takes_value(true))
            .arg(Arg::with_name("HTTP_PORT")
                .short("p")
                .long("port")
                .value_name("HTTP_PORT")
                .help("Run http server on given port")
                .takes_value(true))
            .arg(Arg::with_name("PEERS")
                .long("known-peers")
                .value_name("PEERS")
                .help("Comma separated list of known validator ids")
                .takes_value(true))
            .arg(Arg::with_name("VALIDATOR")
                .help("Sets a validator id")
                .required(true)
                .index(1)));

    let matches = app.get_matches();
    let path = Path::new(matches.value_of("CONFIG").unwrap());
    match matches.subcommand() {
        ("generate", Some(matches)) => {
            let count: u8 = matches.value_of("COUNT").unwrap().parse().unwrap();
            let port: Option<u16> = matches.value_of("START_PORT").map(|x| x.parse().unwrap());
            let cfg = GenesisConfig::gen(count, port);
            ConfigFile::save(&cfg, &path).unwrap();
            println!("The configuration was successfully written to file {:?}",
                     path);
        }
        ("run", Some(matches)) => {
            let cfg: GenesisConfig = ConfigFile::load(path).unwrap();
            let idx: usize = matches.value_of("VALIDATOR").unwrap().parse().unwrap();
            let port: Option<u16> = matches.value_of("HTTP_PORT").map(|x| x.parse().unwrap());
            let peers = match matches.value_of("PEERS") {
                Some(string) => {
                    string.split(" ")
                        .map(|x| -> usize { x.parse().unwrap() })
                        .map(|x| cfg.validators[x].address)
                        .collect()
                }
                None => {
                    cfg.validators
                        .iter()
                        .map(|v| v.address)
                        .collect()
                }
            };
            let node_cfg = cfg.to_node_configuration(idx, peers);
            match matches.value_of("LEVELDB_PATH") {
                Some(ref db_path) => {
                    println!("Using levedb storage with path: {}", db_path);
                    let mut options = LevelDBOptions::new();
                    options.create_if_missing = true;
                    let leveldb = LevelDB::new(&Path::new(db_path), options).unwrap();

                    let blockchain = CurrencyBlockchain { db: leveldb };
                    run_node(blockchain, node_cfg, port);
                }
                None => {
                    println!("Using memorydb storage");

                    let blockchain = CurrencyBlockchain { db: MemoryDB::new() };
                    run_node(blockchain, node_cfg, port);
                }
            };
        }
        _ => {
            unreachable!("Wrong subcommand");
        }
    }
}
<|endoftext|>


<commit_before>use regex::Regex;
use std::env;
use std::fs::File;
use std::io::BufReader;
use std::collections::HashMap;

#[macro_use]
extern crate lazy_static;
extern crate regex;

//Maybe do not need regex
lazy_static! {
    static ref line_re: Regex = Regex::new(r"^\d ").unwrap();
    static ref symbols_re: Regex = Regex::new(r"").unwrap();
    static ref addres_re: Regex = Regex::new(r"").unwrap();
}

#[derive(Debug)]
pub enum Content {
    DefSym(Vec<String>),
    Symbols(Vec<String>),
    Addrs(Vec<String>),
}

#[derive(Debug)]
pub struct SingleLine {
    pub num: i32,
    pub content: Option<Content>,
}

impl Content {
    pub fn num_change(&mut self) -> Vec<(String, i32)> {
        let mut result: Vec<(String, i32)> = vec![];
        match self {
            Content::DefSym(l) | Content::Addrs(l) => {
                let (_, l2) = l.split_at(1);
                for (i, (x, y)) in l.iter().zip(l2.iter()).enumerate() {
                    if i % 2 == 0 {
                        result.push((x.clone(), y.parse::<i32>().unwrap()));
                    }
                }
            }
            _ => (),
        }
        return result;
    }
}

pub fn read_linker_line(li: String) -> SingleLine {
    let mut cut_str: Vec<&str> = li.split_whitespace().collect();
    let num = cut_str[0].parse::<i32>().unwrap();

    if cut_str.len() == 1 {
        return SingleLine {
            num: num,
            content: None,
        };
    }

    if cut_str[1] != "A" && cut_str[1] != "E" && cut_str[1] != "R" && cut_str[1] != "I" {
        if let Ok(_) = cut_str[2].parse::<i32>() {
            return SingleLine {
                num: num,
                content: Some(Content::DefSym(
                    cut_str.split_off(1).iter().map(|s| s.to_string()).collect(),
                )),
            };
        }
        return SingleLine {
            num: num,
            content: Some(Content::Symbols(
                cut_str.split_off(1).iter().map(|s| s.to_string()).collect(),
            )),
        };
    } else {
        return SingleLine {
            num: num,
            content: Some(Content::Addrs(
                cut_str.split_off(1).iter().map(|s| s.to_string()).collect(),
            )),
        };
    }
}

pub fn add_line_vec(ve: &mut Vec<SingleLine>, l: SingleLine) {
    ve.push(l);
}

fn iter_all_lines() -> (HashMap, Vec<(String,i32)>) {
    return HashMap::new(), vec![("a",1)];
}
<commit_msg>a bit<commit_after>use regex::Regex;
use std::collections::HashMap;
use std::env;
use std::fs::File;
use std::io::BufReader;

#[macro_use]
extern crate lazy_static;
extern crate regex;

//Maybe do not need regex
lazy_static! {
    static ref line_re: Regex = Regex::new(r"^\d ").unwrap();
    static ref symbols_re: Regex = Regex::new(r"").unwrap();
    static ref addres_re: Regex = Regex::new(r"").unwrap();
}

#[derive(Debug, Clone)]
pub enum Content {
    DefSym(Vec<String>),
    Symbols(Vec<String>),
    Addrs(Vec<String>),
}

#[derive(Debug)]
pub struct SingleLine {
    pub num: i32,
    pub content: Option<Content>,
}

impl Content {
    pub fn num_change(&self) -> Result<Vec<(String, i32)>, ()> {
        let mut result: Vec<(String, i32)> = vec![];
        match self {
            Content::DefSym(l) | Content::Addrs(l) => {
                let (_, l2) = l.split_at(1);
                for (i, (x, y)) in l.iter().zip(l2.iter()).enumerate() {
                    if i % 2 == 0 {
                        result.push((x.clone(), y.parse::<i32>().unwrap()));
                    }
                }
                return Ok(result);
            }
            _ => return Err(()),
        }
    }
}

pub fn read_linker_line(li: String) -> SingleLine {
    let mut cut_str: Vec<&str> = li.split_whitespace().collect();
    let num = cut_str[0].parse::<i32>().unwrap();

    if cut_str.len() == 1 {
        return SingleLine {
            num: num,
            content: None,
        };
    }

    if cut_str[1] != "A" && cut_str[1] != "E" && cut_str[1] != "R" && cut_str[1] != "I" {
        if let Ok(_) = cut_str[2].parse::<i32>() {
            return SingleLine {
                num: num,
                content: Some(Content::DefSym(
                    cut_str.split_off(1).iter().map(|s| s.to_string()).collect(),
                )),
            };
        }
        return SingleLine {
            num: num,
            content: Some(Content::Symbols(
                cut_str.split_off(1).iter().map(|s| s.to_string()).collect(),
            )),
        };
    } else {
        return SingleLine {
            num: num,
            content: Some(Content::Addrs(
                cut_str.split_off(1).iter().map(|s| s.to_string()).collect(),
            )),
        };
    }
}

pub fn add_line_vec(ve: &mut Vec<SingleLine>, l: SingleLine) {
    ve.push(l);
}

//:= need clean mind, I forget requirments actually.
pub fn create_sym_table(line_vec: &Vec<SingleLine>) -> HashMap<String, i32> {
    let mut result: HashMap<String, i32> = HashMap::new();
    let mut mem_jump = 0;

    for l in line_vec {
        if let Some(ref c) = l.content {
            match c {
                Content::DefSym(_) => if let Ok(cc) = c.num_change() {
                    result.insert(cc[0].0.to_string(), mem_jump);
                },
                _ => (),
            }
        }
    }

    result
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2017 Boucher, Antoni <bouanto@zoho.com>
 *
 * 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.
 */

#![feature(proc_macro)]

extern crate gtk;
#[macro_use]
extern crate relm;
extern crate relm_attributes;
#[macro_use]
extern crate relm_derive;

use gtk::{
    ButtonExt,
    Inhibit,
    LabelExt,
    NotebookExt,
    WidgetExt,
};
use relm::Widget;
use relm_attributes::widget;

use self::Msg::*;

#[derive(Msg)]
pub enum Msg {
    Quit,
}

#[widget]
impl Widget for Win {
    fn model() -> () {
        ()
    }

    fn update(&mut self, event: Msg) {
        match event {
            Quit => gtk::main_quit(),
        }
    }

    view! {
        gtk::Window {
            gtk::Notebook {
                gtk::Button {
                    child: {
                        tab_label: Some("First Button"),
                    },
                    label: "+",
                },
                gtk::Label {
                    tab: {
                        label: &gtk::Label::new("Second page"),
                    },
                    text: "0",
                },
                gtk::Button {
                    label: "-",
                },
            },
            delete_event(_, _) => (Quit, Inhibit(false)),
        }
    }
}

fn main() {
    Win::run(()).unwrap();
}
<commit_msg>Uses relm_widget macro in tabs example<commit_after>/*
 * Copyright (c) 2017 Boucher, Antoni <bouanto@zoho.com>
 *
 * 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.
 */

extern crate gtk;
#[macro_use]
extern crate relm;
#[macro_use]
extern crate relm_derive;

use gtk::{
    ButtonExt,
    Inhibit,
    LabelExt,
    NotebookExt,
    WidgetExt,
};
use relm::Widget;

use self::Msg::*;

#[derive(Msg)]
pub enum Msg {
    Quit,
}

relm_widget! {
    impl ::relm::Widget for Win {
        fn model() -> () {
            ()
        }

        fn update(&mut self, event: Msg) {
            match event {
                Quit => gtk::main_quit(),
            }
        }

        view! {
            gtk::Window {
                gtk::Notebook {
                    gtk::Button {
                        child: {
                            tab_label: Some("First Button"),
                        },
                        label: "+",
                    },
                    gtk::Label {
                        tab: {
                            label: &gtk::Label::new("Second page"),
                        },
                        text: "0",
                    },
                    gtk::Button {
                        label: "-",
                    },
                },
                delete_event(_, _) => (Quit, Inhibit(false)),
            }
        }
    }
}

fn main() {
    Win::run(()).unwrap();
}
<|endoftext|>


<commit_before>//!
//! An example of using dsp-chain to create a simple Synthesiser with 3 sine wave oscillators.
//!

extern crate dsp;

use dsp::{
    Event,
    Node,
    SoundStream,
    Settings,
};

/// The number of frames processed per second.
const SAMPLE_HZ: u32 = 44100;
/// The number of channels to use for output. We'll use two for stereo.
const CHANNELS: u16 = 2;
/// This value is equal to (fixed-size buffer length / CHANNELS).
const FRAMES: u16 = 256;

const SETTINGS: Settings = Settings { sample_hz: SAMPLE_HZ, frames: FRAMES, channels: CHANNELS };

const BUFFER_SIZE: uint = (FRAMES * CHANNELS) as uint;

type Input = f32;
type Output = f32;
type OutputBuffer = [f32, ..BUFFER_SIZE];

type Phase = f64;
type Frequency = f64;
type Volume = f64;

const A5_HZ: Frequency = 440.0;
const D5_HZ: Frequency = 587.33;
const F5_HZ: Frequency = 698.46;

fn main() {

    // Construct the stream and handle any errors that may have occurred.
    let mut stream = match SoundStream::<OutputBuffer, Input, Output>::new(SETTINGS) {
        Ok(stream) => { println!("It begins!"); stream },
        Err(err) => panic!("An error occurred while constructing SoundStream: {}", err),
    };

    // Construct our fancy Synth!
    let mut synth = Synth([
            Oscillator(0.0, A5_HZ, 0.2),
            Oscillator(0.0, D5_HZ, 0.1),
            Oscillator(0.0, F5_HZ, 0.15)
        ]);

    // We'll use this to count down from three seconds and then break from the loop.
    let mut timer: f64 = 3.0;

    // The SoundStream iterator will automatically return these events in this order.
    for event in stream {
        match event {
            Event::Out(buffer) => synth.audio_requested(buffer, SETTINGS),
            Event::Update(dt) => {
                timer -= dt as f64;
                if timer <= 0.0 { break }
            }
            _ => (),
        }
    }

    // Close the stream and shut down PortAudio.
    match stream.close() {
        Ok(()) => println!("Great success!"),
        Err(err) => println!("An error occurred while closing SoundStream: {}", err),
    }

}

/// Synth will be our demonstration of a parent DspNode where the Oscillators
/// that it owns are it's children.
struct Synth([Oscillator, ..3]);

impl Node<OutputBuffer, Output> for Synth {
    /// Here we return a reference to each of our Oscillators as our `inputs`.
    /// This allows the default `audio_requested` method to draw input from
    /// each of our oscillators automatically.
    fn inputs(&mut self) -> Vec<&mut Node<OutputBuffer, Output>> {
        let Synth(ref mut oscillators) = *self;
        oscillators.iter_mut().map(|osc| osc as &mut Node<OutputBuffer, Output>).collect()
    }
}

/// Oscillator will be our generator type of node, meaning that we will override
/// the way it provides audio via its `audio_requested` method.
struct Oscillator(Phase, Frequency, Volume);

impl Node<OutputBuffer, Output> for Oscillator {
    /// Here we'll override the audio_requested method and generate a sine wave.
    fn audio_requested(&mut self, buffer: &mut OutputBuffer, settings: Settings) {
        let (frames, channels) = (settings.frames as uint, settings.channels as uint);
        let Oscillator(ref mut phase, frequency, volume) = *self;
        // For every frame in the buffer.
        for i in range(0u, frames) {
            *phase += frequency / settings.sample_hz as f64;
            let val = sine_wave(*phase, volume);
            // For each channel in the frame.
            for j in range(0u, channels) {
                let idx = i * channels + j;
                buffer[idx] = val;
            }
        }
    }
}

/// Return a sine wave for the given phase.
fn sine_wave(phase: Phase, volume: Volume) -> Output {
    use std::f64::consts::PI_2;
    use std::num::FloatMath;
    ((phase * PI_2).sin() * volume) as Output
}

<commit_msg>Made decrement-timer-else-break a one liner in example<commit_after>//!
//! An example of using dsp-chain to create a simple Synthesiser with 3 sine wave oscillators.
//!

extern crate dsp;

use dsp::{
    Event,
    Node,
    SoundStream,
    Settings,
};

/// The number of frames processed per second.
const SAMPLE_HZ: u32 = 44100;
/// The number of channels to use for output. We'll use two for stereo.
const CHANNELS: u16 = 2;
/// This value is equal to (fixed-size buffer length / CHANNELS).
const FRAMES: u16 = 256;

const SETTINGS: Settings = Settings { sample_hz: SAMPLE_HZ, frames: FRAMES, channels: CHANNELS };

const BUFFER_SIZE: uint = (FRAMES * CHANNELS) as uint;

type Input = f32;
type Output = f32;
type OutputBuffer = [f32, ..BUFFER_SIZE];

type Phase = f64;
type Frequency = f64;
type Volume = f64;

const A5_HZ: Frequency = 440.0;
const D5_HZ: Frequency = 587.33;
const F5_HZ: Frequency = 698.46;

fn main() {

    // Construct the stream and handle any errors that may have occurred.
    let mut stream = match SoundStream::<OutputBuffer, Input, Output>::new(SETTINGS) {
        Ok(stream) => { println!("It begins!"); stream },
        Err(err) => panic!("An error occurred while constructing SoundStream: {}", err),
    };

    // Construct our fancy Synth!
    let mut synth = Synth([
            Oscillator(0.0, A5_HZ, 0.2),
            Oscillator(0.0, D5_HZ, 0.1),
            Oscillator(0.0, F5_HZ, 0.15)
        ]);

    // We'll use this to count down from three seconds and then break from the loop.
    let mut timer: f64 = 3.0;

    // The SoundStream iterator will automatically return these events in this order.
    for event in stream {
        match event {
            Event::Out(buffer) => synth.audio_requested(buffer, SETTINGS),
            Event::Update(dt) => if timer > 0.0 { timer -= dt } else { break },
            _ => (),
        }
    }

    // Close the stream and shut down PortAudio.
    match stream.close() {
        Ok(()) => println!("Great success!"),
        Err(err) => println!("An error occurred while closing SoundStream: {}", err),
    }

}

/// Synth will be our demonstration of a parent DspNode where the Oscillators
/// that it owns are it's children.
struct Synth([Oscillator, ..3]);

impl Node<OutputBuffer, Output> for Synth {
    /// Here we return a reference to each of our Oscillators as our `inputs`.
    /// This allows the default `audio_requested` method to draw input from
    /// each of our oscillators automatically.
    fn inputs(&mut self) -> Vec<&mut Node<OutputBuffer, Output>> {
        let Synth(ref mut oscillators) = *self;
        oscillators.iter_mut().map(|osc| osc as &mut Node<OutputBuffer, Output>).collect()
    }
}

/// Oscillator will be our generator type of node, meaning that we will override
/// the way it provides audio via its `audio_requested` method.
struct Oscillator(Phase, Frequency, Volume);

impl Node<OutputBuffer, Output> for Oscillator {
    /// Here we'll override the audio_requested method and generate a sine wave.
    fn audio_requested(&mut self, buffer: &mut OutputBuffer, settings: Settings) {
        let (frames, channels) = (settings.frames as uint, settings.channels as uint);
        let Oscillator(ref mut phase, frequency, volume) = *self;
        // For every frame in the buffer.
        for i in range(0u, frames) {
            *phase += frequency / settings.sample_hz as f64;
            let val = sine_wave(*phase, volume);
            // For each channel in the frame.
            for j in range(0u, channels) {
                let idx = i * channels + j;
                buffer[idx] = val;
            }
        }
    }
}

/// Return a sine wave for the given phase.
fn sine_wave(phase: Phase, volume: Volume) -> Output {
    use std::f64::consts::PI_2;
    use std::num::FloatMath;
    ((phase * PI_2).sin() * volume) as Output
}

<|endoftext|>


<commit_before>#[macro_use]
extern crate tini;
use tini::Ini;

static INPUT: &'static str = "./example.ini";
static OUTPUT: &'static str = "./test.ini";
static SPLIT: &'static str = "=----------------------------------------------------------=";

fn main() {
    let config = Ini::from_file(INPUT).unwrap();
    println!(">> readed `{}` config file\n{}\n{}\n{}",
             INPUT,
             SPLIT,
             config,
             SPLIT);
    let n1: u32 = get_or!(config, "section_one", "name1", 0);
    println!(">> entry `name1` from `section_one` = {}", n1);
    let n2: Vec<bool> = get_vec_or!(config, "section_three", "frst4", vec![false]);
    println!(">> entry `frst4` from `section_three` = {:?}", n2);
    let test = Ini::new()
                   .section("section_one")
                   .item("a", "1")
                   .item("b", "2")
                   .section("section_two")
                   .item("c", "3")
                   .item("d", "4")
                   .append();
    println!(">> builded `{}` config\n{}\n{}\n{}",
             OUTPUT,
             SPLIT,
             test,
             SPLIT);
    test.to_file(OUTPUT).unwrap();
}
<commit_msg>[fix] irregular verbs<commit_after>#[macro_use]
extern crate tini;
use tini::Ini;

static INPUT: &'static str = "./example.ini";
static OUTPUT: &'static str = "./test.ini";
static SPLIT: &'static str = "=----------------------------------------------------------=";

fn main() {
    let config = Ini::from_file(INPUT).unwrap();
    println!(">> read `{}` config file\n{}\n{}\n{}",
             INPUT,
             SPLIT,
             config,
             SPLIT);
    let n1: u32 = get_or!(config, "section_one", "name1", 0);
    println!(">> entry `name1` from `section_one` = {}", n1);
    let n2: Vec<bool> = get_vec_or!(config, "section_three", "frst4", vec![false]);
    println!(">> entry `frst4` from `section_three` = {:?}", n2);
    let test = Ini::new()
                   .section("section_one")
                   .item("a", "1")
                   .item("b", "2")
                   .section("section_two")
                   .item("c", "3")
                   .item("d", "4")
                   .append();
    println!(">> built `{}` config\n{}\n{}\n{}",
             OUTPUT,
             SPLIT,
             test,
             SPLIT);
    test.to_file(OUTPUT).unwrap();
}
<|endoftext|>


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

use itertools::Itertools;
use syn::Type;

use crate::types::TypeName;
use std::collections::HashSet;

/// Central registry of all information known about types.
/// At present this is very minimal; in future we should roll
/// known_types.rs into this and possibly other things as well.
#[derive(Default)]
pub(crate) struct TypeDatabase {
    pod_requests: HashSet<TypeName>,
    allowlist: HashSet<String>, // not TypeName as it may be funcs not types.
    blocklist: HashSet<String>, // not TypeName as it may be funcs not types.
}

impl TypeDatabase {
    pub(crate) fn new() -> Self {
        Self::default()
    }

    pub(crate) fn note_pod_request(&mut self, tn: TypeName) {
        self.pod_requests.insert(tn);
    }

    pub(crate) fn add_to_allowlist(&mut self, item: String) {
        self.allowlist.insert(item);
    }

    pub(crate) fn add_to_blocklist(&mut self, item: String) {
        self.blocklist.insert(item);
    }

    pub(crate) fn get_pod_requests(&self) -> &HashSet<TypeName> {
        &self.pod_requests
    }

    pub(crate) fn allowlist(&self) -> impl Iterator<Item = &String> {
        self.allowlist.iter()
    }

    pub(crate) fn allowlist_is_empty(&self) -> bool {
        self.allowlist.is_empty()
    }

    /// Whether this type is on the allowlist specified by the user.
    ///
    /// A note on the allowlist handling in general. It's used in two places:
    /// 1) As directives to bindgen
    /// 2) After bindgen has generated code, to filter the APIs which
    ///    we pass to cxx.
    /// This second pass may seem redundant. But sometimes bindgen generates
    /// unnecessary stuff.
    pub(crate) fn is_on_allowlist(&self, tn: &TypeName) -> bool {
        self.allowlist.contains(&tn.to_cpp_name())
    }

    pub(crate) fn is_on_blocklist(&self, tn: &TypeName) -> bool {
        self.blocklist.contains(&tn.to_cpp_name())
    }

    pub(crate) fn type_to_cpp(&self, ty: &Type) -> String {
        match ty {
            Type::Path(typ) => {
                // If this is a std::unique_ptr we do need to pass
                // its argument through.
                let root = TypeName::from_type_path(typ);
                let root = root.to_cpp_name();
                if root == "Pin" {
                    // Strip all Pins from type names when describing them in C++.
                    let inner_type = &typ.path.segments.last().unwrap().arguments;
                    if let syn::PathArguments::AngleBracketed(ab) = inner_type {
                        let inner_type = ab.args.iter().next().unwrap();
                        if let syn::GenericArgument::Type(gat) = inner_type {
                            return self.type_to_cpp(gat);
                        }
                    }
                    panic!("Pin<...> didn't contain the inner types we expected");
                }
                let suffix = match &typ.path.segments.last().unwrap().arguments {
                    syn::PathArguments::AngleBracketed(ab) => Some(
                        ab.args
                            .iter()
                            .map(|x| match x {
                                syn::GenericArgument::Type(gat) => self.type_to_cpp(gat),
                                _ => "".to_string(),
                            })
                            .join(", "),
                    ),
                    syn::PathArguments::None | syn::PathArguments::Parenthesized(_) => None,
                };
                match suffix {
                    None => root,
                    Some(suffix) => format!("{}<{}>", root, suffix),
                }
            }
            Type::Reference(typr) => {
                let const_bit = match typr.mutability {
                    None => "const ",
                    Some(_) => "",
                };
                format!("{}{}&", const_bit, self.type_to_cpp(typr.elem.as_ref()))
            }
            Type::Array(_)
            | Type::BareFn(_)
            | Type::Group(_)
            | Type::ImplTrait(_)
            | Type::Infer(_)
            | Type::Macro(_)
            | Type::Never(_)
            | Type::Paren(_)
            | Type::Ptr(_)
            | Type::Slice(_)
            | Type::TraitObject(_)
            | Type::Tuple(_)
            | Type::Verbatim(_) => panic!("Unsupported type"),
            _ => panic!("Unknown type"),
        }
    }
}
<commit_msg>Make type database hashable.<commit_after>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use itertools::Itertools;
use syn::Type;

use crate::types::TypeName;

/// Central registry of all information known about types.
/// At present this is very minimal; in future we should roll
/// known_types.rs into this and possibly other things as well.
#[derive(Default, Hash)]
pub(crate) struct TypeDatabase {
    pod_requests: Vec<TypeName>,
    allowlist: Vec<String>, // not TypeName as it may be funcs not types.
    blocklist: Vec<String>, // not TypeName as it may be funcs not types.
}

impl TypeDatabase {
    pub(crate) fn new() -> Self {
        Self::default()
    }

    pub(crate) fn note_pod_request(&mut self, tn: TypeName) {
        self.pod_requests.push(tn);
    }

    pub(crate) fn add_to_allowlist(&mut self, item: String) {
        self.allowlist.push(item);
    }

    pub(crate) fn add_to_blocklist(&mut self, item: String) {
        self.blocklist.push(item);
    }

    pub(crate) fn get_pod_requests(&self) -> &[TypeName] {
        &self.pod_requests
    }

    pub(crate) fn allowlist(&self) -> impl Iterator<Item = &String> {
        self.allowlist.iter()
    }

    pub(crate) fn allowlist_is_empty(&self) -> bool {
        self.allowlist.is_empty()
    }

    /// Whether this type is on the allowlist specified by the user.
    ///
    /// A note on the allowlist handling in general. It's used in two places:
    /// 1) As directives to bindgen
    /// 2) After bindgen has generated code, to filter the APIs which
    ///    we pass to cxx.
    /// This second pass may seem redundant. But sometimes bindgen generates
    /// unnecessary stuff.
    pub(crate) fn is_on_allowlist(&self, tn: &TypeName) -> bool {
        self.allowlist.contains(&tn.to_cpp_name())
    }

    pub(crate) fn is_on_blocklist(&self, tn: &TypeName) -> bool {
        self.blocklist.contains(&tn.to_cpp_name())
    }

    pub(crate) fn type_to_cpp(&self, ty: &Type) -> String {
        match ty {
            Type::Path(typ) => {
                // If this is a std::unique_ptr we do need to pass
                // its argument through.
                let root = TypeName::from_type_path(typ);
                let root = root.to_cpp_name();
                if root == "Pin" {
                    // Strip all Pins from type names when describing them in C++.
                    let inner_type = &typ.path.segments.last().unwrap().arguments;
                    if let syn::PathArguments::AngleBracketed(ab) = inner_type {
                        let inner_type = ab.args.iter().next().unwrap();
                        if let syn::GenericArgument::Type(gat) = inner_type {
                            return self.type_to_cpp(gat);
                        }
                    }
                    panic!("Pin<...> didn't contain the inner types we expected");
                }
                let suffix = match &typ.path.segments.last().unwrap().arguments {
                    syn::PathArguments::AngleBracketed(ab) => Some(
                        ab.args
                            .iter()
                            .map(|x| match x {
                                syn::GenericArgument::Type(gat) => self.type_to_cpp(gat),
                                _ => "".to_string(),
                            })
                            .join(", "),
                    ),
                    syn::PathArguments::None | syn::PathArguments::Parenthesized(_) => None,
                };
                match suffix {
                    None => root,
                    Some(suffix) => format!("{}<{}>", root, suffix),
                }
            }
            Type::Reference(typr) => {
                let const_bit = match typr.mutability {
                    None => "const ",
                    Some(_) => "",
                };
                format!("{}{}&", const_bit, self.type_to_cpp(typr.elem.as_ref()))
            }
            Type::Array(_)
            | Type::BareFn(_)
            | Type::Group(_)
            | Type::ImplTrait(_)
            | Type::Infer(_)
            | Type::Macro(_)
            | Type::Never(_)
            | Type::Paren(_)
            | Type::Ptr(_)
            | Type::Slice(_)
            | Type::TraitObject(_)
            | Type::Tuple(_)
            | Type::Verbatim(_) => panic!("Unsupported type"),
            _ => panic!("Unknown type"),
        }
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;

use metric::Metric;

pub trait Registry<'a> {
    fn get(&'a self, name: &'a str) -> &'a Metric;

    fn insert<T: Metric + 'a>(&mut self, name: &'a str, metric: T);
}

pub struct StdRegistry<'a> {
    metrics: HashMap<&'a str, Box<Metric + 'a>>,
}

// Specific stuff for registry goes here
impl<'a> Registry<'a> for StdRegistry<'a> {
    fn get(&'a self, name: &'a str) -> &'a Metric {
        &*self.metrics[name]
    }

    fn insert<T: Metric + 'a>(&mut self, name: &'a str, metric: T) {
        let boxed = Box::new(metric);

        self.metrics.insert(name, boxed);
    }
}

// General StdRegistry
impl<'a> StdRegistry<'a> {
    fn new() -> StdRegistry<'a> {
        StdRegistry{
            metrics: HashMap::new()
        }
    }
}

#[cfg(test)]
mod test {
    use metric::Metric;
    use meter::StdMeter;
    use registry::{Registry, StdRegistry};

    #[test]
    fn meter() {
        let mut r: StdRegistry = StdRegistry::new();
        let mut m: StdMeter = StdMeter::new();

        r.insert("foo", m);
        r.get("foo");
    }
}
<commit_msg>quiet warnings<commit_after>use std::collections::HashMap;

use metric::Metric;

pub trait Registry<'a> {
    fn get(&'a self, name: &'a str) -> &'a Metric;

    fn insert<T: Metric + 'a>(&mut self, name: &'a str, metric: T);
}

pub struct StdRegistry<'a> {
    metrics: HashMap<&'a str, Box<Metric + 'a>>,
}

// Specific stuff for registry goes here
impl<'a> Registry<'a> for StdRegistry<'a> {
    fn get(&'a self, name: &'a str) -> &'a Metric {
        &*self.metrics[name]
    }

    fn insert<T: Metric + 'a>(&mut self, name: &'a str, metric: T) {
        let boxed = Box::new(metric);

        self.metrics.insert(name, boxed);
    }
}

// General StdRegistry
impl<'a> StdRegistry<'a> {
    #[allow(dead_code)]
    fn new() -> StdRegistry<'a> {
        StdRegistry{
            metrics: HashMap::new()
        }
    }
}

#[cfg(test)]
mod test {
    use meter::StdMeter;
    use registry::{Registry, StdRegistry};

    #[test]
    fn meter() {
        let mut r: StdRegistry = StdRegistry::new();
        let m: StdMeter = StdMeter::new();

        r.insert("foo", m);
        r.get("foo");
    }
}
<|endoftext|>