Giant collection of fixes ... we are into lifetime errors now :)

This commit is contained in:
Andrew Poelstra 2015-04-05 19:10:37 -05:00
parent 7b89c15ed5
commit 811df8a713
21 changed files with 399 additions and 316 deletions

View File

@ -97,7 +97,7 @@ impl BlockHeader {
/// Performs an SPV validation of a block, which confirms that the proof-of-work /// Performs an SPV validation of a block, which confirms that the proof-of-work
/// is correct, but does not verify that the transactions are valid or encoded /// is correct, but does not verify that the transactions are valid or encoded
/// correctly. /// correctly.
pub fn spv_validate(&self, required_target: &Uint256) -> error::Result<()> { pub fn spv_validate(&self, required_target: &Uint256) -> Result<(), error::Error> {
let ref target = self.target(); let ref target = self.target();
if target != required_target { if target != required_target {
return Err(SpvBadTarget); return Err(SpvBadTarget);
@ -132,7 +132,6 @@ impl BitcoinHash for Block {
} }
impl_consensus_encoding!(BlockHeader, version, prev_blockhash, merkle_root, time, bits, nonce); impl_consensus_encoding!(BlockHeader, version, prev_blockhash, merkle_root, time, bits, nonce);
impl_json!(BlockHeader, version, prev_blockhash, merkle_root, time, bits, nonce);
impl_consensus_encoding!(Block, header, txdata); impl_consensus_encoding!(Block, header, txdata);
impl_consensus_encoding!(LoneBlockHeader, header, tx_count); impl_consensus_encoding!(LoneBlockHeader, header, tx_count);

View File

@ -80,9 +80,9 @@ impl BlockchainNode {
} }
} }
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for BlockchainNode { impl<S: SimpleEncoder> ConsensusEncodable<S> for BlockchainNode {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
try!(self.block.consensus_encode(s)); try!(self.block.consensus_encode(s));
try!(self.total_work.consensus_encode(s)); try!(self.total_work.consensus_encode(s));
try!(self.required_difficulty.consensus_encode(s)); try!(self.required_difficulty.consensus_encode(s));
@ -93,9 +93,9 @@ impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for BlockchainNode {
} }
} }
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for BlockchainNode { impl<D: SimpleDecoder> ConsensusDecodable<D> for BlockchainNode {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<BlockchainNode, E> { fn consensus_decode(d: &mut D) -> Result<BlockchainNode, D::Error> {
Ok(BlockchainNode { Ok(BlockchainNode {
block: try!(ConsensusDecodable::consensus_decode(d)), block: try!(ConsensusDecodable::consensus_decode(d)),
total_work: try!(ConsensusDecodable::consensus_decode(d)), total_work: try!(ConsensusDecodable::consensus_decode(d)),
@ -123,9 +123,9 @@ pub struct Blockchain {
genesis_hash: Sha256dHash genesis_hash: Sha256dHash
} }
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Blockchain { impl<S: SimpleEncoder> ConsensusEncodable<S> for Blockchain {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
try!(self.network.consensus_encode(s)); try!(self.network.consensus_encode(s));
try!(self.tree.consensus_encode(s)); try!(self.tree.consensus_encode(s));
try!(self.best_hash.consensus_encode(s)); try!(self.best_hash.consensus_encode(s));
@ -134,8 +134,8 @@ impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Blockchain {
} }
} }
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for Blockchain { impl<D: SimpleDecoder> ConsensusDecodable<D> for Blockchain {
fn consensus_decode(d: &mut D) -> Result<Blockchain, E> { fn consensus_decode(d: &mut D) -> Result<Blockchain, D::Error> {
let network: Network = try!(ConsensusDecodable::consensus_decode(d)); let network: Network = try!(ConsensusDecodable::consensus_decode(d));
let mut tree: BlockTree = try!(ConsensusDecodable::consensus_decode(d)); let mut tree: BlockTree = try!(ConsensusDecodable::consensus_decode(d));
let best_hash: Sha256dHash = try!(ConsensusDecodable::consensus_decode(d)); let best_hash: Sha256dHash = try!(ConsensusDecodable::consensus_decode(d));
@ -204,7 +204,9 @@ impl LocatorHashIter {
} }
} }
impl Iterator<Sha256dHash> for LocatorHashIter { impl Iterator for LocatorHashIter {
type Item = Sha256dHash;
fn next(&mut self) -> Option<Sha256dHash> { fn next(&mut self) -> Option<Sha256dHash> {
if self.index.is_null() { if self.index.is_null() {
return None; return None;
@ -274,7 +276,9 @@ pub struct RevStaleBlockIter<'tree> {
chain: &'tree Blockchain chain: &'tree Blockchain
} }
impl<'tree> Iterator<&'tree BlockchainNode> for BlockIter<'tree> { impl<'tree> Iterator for BlockIter<'tree> {
type Item = &'tree BlockchainNode;
fn next(&mut self) -> Option<&'tree BlockchainNode> { fn next(&mut self) -> Option<&'tree BlockchainNode> {
if self.index.is_null() { if self.index.is_null() {
return None; return None;
@ -287,7 +291,9 @@ impl<'tree> Iterator<&'tree BlockchainNode> for BlockIter<'tree> {
} }
} }
impl<'tree> Iterator<&'tree BlockchainNode> for RevBlockIter<'tree> { impl<'tree> Iterator for RevBlockIter<'tree> {
type Item = &'tree BlockchainNode;
fn next(&mut self) -> Option<&'tree BlockchainNode> { fn next(&mut self) -> Option<&'tree BlockchainNode> {
if self.index.is_null() { if self.index.is_null() {
return None; return None;
@ -300,7 +306,9 @@ impl<'tree> Iterator<&'tree BlockchainNode> for RevBlockIter<'tree> {
} }
} }
impl<'tree> Iterator<&'tree Block> for RevStaleBlockIter<'tree> { impl<'tree> Iterator for RevStaleBlockIter<'tree> {
type Item = &'tree Block;
fn next(&mut self) -> Option<&'tree Block> { fn next(&mut self) -> Option<&'tree Block> {
if self.index.is_null() { if self.index.is_null() {
return None; return None;
@ -365,7 +373,7 @@ impl Blockchain {
} }
} }
fn replace_txdata(&mut self, hash: &Uint256, txdata: Vec<Transaction>, has_txdata: bool) -> error::Result<()> { fn replace_txdata(&mut self, hash: &Uint256, txdata: Vec<Transaction>, has_txdata: bool) -> Result<(), error::Error> {
match self.tree.lookup_mut(hash, 256) { match self.tree.lookup_mut(hash, 256) {
Some(existing_block) => { Some(existing_block) => {
unsafe { unsafe {
@ -405,26 +413,26 @@ impl Blockchain {
} }
/// Locates a block in the chain and overwrites its txdata /// Locates a block in the chain and overwrites its txdata
pub fn add_txdata(&mut self, block: Block) -> error::Result<()> { pub fn add_txdata(&mut self, block: Block) -> Result<(), error::Error> {
self.replace_txdata(&block.header.bitcoin_hash().into_le(), block.txdata, true) self.replace_txdata(&block.header.bitcoin_hash().into_le(), block.txdata, true)
} }
/// Locates a block in the chain and removes its txdata /// Locates a block in the chain and removes its txdata
pub fn remove_txdata(&mut self, hash: Sha256dHash) -> error::Result<()> { pub fn remove_txdata(&mut self, hash: Sha256dHash) -> Result<(), error::Error> {
self.replace_txdata(&hash.into_le(), vec![], false) self.replace_txdata(&hash.into_le(), vec![], false)
} }
/// Adds a block header to the chain /// Adds a block header to the chain
pub fn add_header(&mut self, header: BlockHeader) -> error::Result<()> { pub fn add_header(&mut self, header: BlockHeader) -> Result<(), error::Error> {
self.real_add_block(Block { header: header, txdata: vec![] }, false) self.real_add_block(Block { header: header, txdata: vec![] }, false)
} }
/// Adds a block to the chain /// Adds a block to the chain
pub fn add_block(&mut self, block: Block) -> error::Result<()> { pub fn add_block(&mut self, block: Block) -> Result<(), error::Error> {
self.real_add_block(block, true) self.real_add_block(block, true)
} }
fn real_add_block(&mut self, block: Block, has_txdata: bool) -> error::Result<()> { fn real_add_block(&mut self, block: Block, has_txdata: bool) -> Result<(), error::Error> {
// get_prev optimizes the common case where we are extending the best tip // get_prev optimizes the common case where we are extending the best tip
#[inline] #[inline]
fn get_prev<'a>(chain: &'a Blockchain, hash: Sha256dHash) -> Option<NodePtr> { fn get_prev<'a>(chain: &'a Blockchain, hash: Sha256dHash) -> Option<NodePtr> {

View File

@ -20,7 +20,7 @@
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
use serialize::json; use serde;
// Heavy stick to translate between opcode types // Heavy stick to translate between opcode types
use std::mem::transmute; use std::mem::transmute;
@ -602,23 +602,25 @@ impl All {
} }
} }
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for All { impl<D: SimpleDecoder> ConsensusDecodable<D> for All {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<All, E> { fn consensus_decode(d: &mut D) -> Result<All, D::Error> {
Ok(All::from_u8(try!(d.read_u8()))) Ok(All::from_u8(try!(d.read_u8())))
} }
} }
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for All { impl<S: SimpleEncoder> ConsensusEncodable<S> for All {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_u8(*self as u8) s.emit_u8(*self as u8)
} }
} }
impl json::ToJson for All { impl serde::Serialize for All {
fn to_json(&self) -> json::Json { fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
json::String(self.to_string()) where S: serde::Serializer,
{
serializer.visit_str(&self.to_string())
} }
} }
@ -644,9 +646,11 @@ pub enum Class {
Ordinary(Ordinary) Ordinary(Ordinary)
} }
impl json::ToJson for Class { impl serde::Serialize for Class {
fn to_json(&self) -> json::Json { fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
json::String(self.to_string()) where S: serde::Serializer,
{
serializer.visit_str(&self.to_string())
} }
} }

View File

@ -35,9 +35,9 @@ use crypto::digest::Digest;
use crypto::ripemd160::Ripemd160; use crypto::ripemd160::Ripemd160;
use crypto::sha1::Sha1; use crypto::sha1::Sha1;
use crypto::sha2::Sha256; use crypto::sha2::Sha256;
use secp256k1::Secp256k1; use secp256k1::Secp256k1;
use secp256k1::key::PublicKey; use secp256k1::key::PublicKey;
use serde;
use blockdata::opcodes; use blockdata::opcodes;
use blockdata::transaction::{Transaction, TxIn}; use blockdata::transaction::{Transaction, TxIn};
@ -1207,9 +1207,11 @@ impl AbstractStack {
} }
} }
impl json::ToJson for Error { impl serde::Serialize for Error {
fn to_json(&self) -> json::Json { fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
json::String(self.to_string()) where S: serde::Serializer,
{
serializer.visit_str(&self.to_string())
} }
} }
@ -1238,8 +1240,6 @@ pub struct ScriptTrace {
pub error: Option<Error> pub error: Option<Error>
} }
impl_json!(TraceIteration, index, opcode, op_count, executed, errored, effect, stack);
/// Hashtype of a transaction, encoded in the last byte of a signature, /// Hashtype of a transaction, encoded in the last byte of a signature,
/// specifically in the last 5 bits `byte & 31` /// specifically in the last 5 bits `byte & 31`
#[derive(PartialEq, Eq, Debug, Clone)] #[derive(PartialEq, Eq, Debug, Clone)]
@ -1337,11 +1337,11 @@ impl<'a> ops::Index<ops::RangeFrom<usize>> for MaybeOwned<'a> {
} }
} }
impl<'a> ops::Index<ops::RangeFull<usize>> for MaybeOwned<'a> { impl<'a> ops::Index<ops::RangeFull> for MaybeOwned<'a> {
type Output = [u8]; type Output = [u8];
#[inline] #[inline]
fn index(&self, _: ops::RangeFull<usize>) -> &[u8] { fn index(&self, _: ops::RangeFull) -> &[u8] {
match *self { match *self {
MaybeOwned::Owned(ref v) => &v[..], MaybeOwned::Owned(ref v) => &v[..],
MaybeOwned::Borrowed(ref s) => &s[..] MaybeOwned::Borrowed(ref s) => &s[..]
@ -1427,16 +1427,16 @@ pub fn read_scriptbool(v: &[u8]) -> bool {
} }
/// Read a script-encoded unsigned integer /// Read a script-encoded unsigned integer
pub fn read_uint<'a, I:Iterator<&'a u8>>(mut iter: I, size: usize) pub fn read_uint(data: &[u8], size: usize) -> Result<usize, Error> {
-> Result<usize, Error> { if data.len() < size {
Err(Error::EarlyEndOfScript)
} else {
let mut ret = 0; let mut ret = 0;
for i in 0..size { for i in 0..size {
match iter.next() { ret += (data[i] as usize) << (i * 8);
Some(&n) => ret += (n as usize) << (i * 8),
None => { return Err(Error::EarlyEndOfScript); }
}
} }
Ok(ret) Ok(ret)
}
} }
/// Check a signature -- returns an error that is currently just translated /// Check a signature -- returns an error that is currently just translated
@ -2477,31 +2477,30 @@ impl Default for Script {
} }
// User-facing serialization // User-facing serialization
impl json::ToJson for Script { impl serde::Serialize for Script {
// TODO: put this in a struct alongside an opcode decode fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
fn to_json(&self) -> json::Json { where S: serde::Serializer,
{
let &Script(ref raw) = self; let &Script(ref raw) = self;
let mut ret = String::new();
for dat in raw.iter() { for dat in raw.iter() {
ret.push_char(from_digit((dat / 0x10) as usize, 16).unwrap()); serializer.visit_char(from_digit((dat / 0x10) as usize, 16).unwrap());
ret.push_char(from_digit((dat & 0x0f) as usize, 16).unwrap()); serializer.visit_char(from_digit((dat & 0x0f) as usize, 16).unwrap());
} }
json::String(ret)
} }
} }
// Network serialization // Network serialization
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Script { impl<S: SimpleEncoder> ConsensusEncodable<S> for Script {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
let &Script(ref data) = self; let &Script(ref data) = self;
data.consensus_encode(s) data.consensus_encode(s)
} }
} }
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for Script { impl<D: SimpleDecoder> ConsensusDecodable<D> for Script {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<Script, E> { fn consensus_decode(d: &mut D) -> Result<Script, D::Error> {
Ok(Script(try!(ConsensusDecodable::consensus_decode(d)))) Ok(Script(try!(ConsensusDecodable::consensus_decode(d))))
} }
} }

View File

@ -24,7 +24,7 @@
//! //!
use std::default::Default; use std::default::Default;
use serialize::json; use serde;
use util::hash::Sha256dHash; use util::hash::Sha256dHash;
use blockdata::script::{self, Script, ScriptTrace, read_scriptbool}; use blockdata::script::{self, Script, ScriptTrace, read_scriptbool};
@ -123,9 +123,11 @@ pub enum Error {
InputNotFound(Sha256dHash, u32), InputNotFound(Sha256dHash, u32),
} }
impl json::ToJson for Error { impl serde::Serialize for Error {
fn to_json(&self) -> json::Json { fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
json::String(self.to_string()) where S: serde::Serializer,
{
serializer.visit_str(&self.to_string())
} }
} }
@ -140,10 +142,6 @@ pub struct InputTrace {
error: Option<Error> error: Option<Error>
} }
impl_json!(ScriptTrace, script, initial_stack, iterations, error);
impl_json!(InputTrace, input_txid, input_vout, sig_trace,
pubkey_trace, p2sh_trace, error);
/// A trace of a transaction's execution /// A trace of a transaction's execution
#[derive(PartialEq, Eq, Clone, Debug)] #[derive(PartialEq, Eq, Clone, Debug)]
pub struct TransactionTrace { pub struct TransactionTrace {
@ -151,8 +149,6 @@ pub struct TransactionTrace {
inputs: Vec<InputTrace> inputs: Vec<InputTrace>
} }
impl_json!(TransactionTrace, txid, inputs);
impl TxIn { impl TxIn {
/// Check an input's script for validity /// Check an input's script for validity
pub fn validate(&self, pub fn validate(&self,
@ -304,12 +300,8 @@ impl BitcoinHash for Transaction {
} }
impl_consensus_encoding!(TxIn, prev_hash, prev_index, script_sig, sequence); impl_consensus_encoding!(TxIn, prev_hash, prev_index, script_sig, sequence);
impl_json!(TxIn, prev_hash, prev_index, script_sig, sequence);
impl_consensus_encoding!(TxOut, value, script_pubkey); impl_consensus_encoding!(TxOut, value, script_pubkey);
impl_json!(TxOut, value, script_pubkey);
impl_consensus_encoding!(Transaction, version, input, output, lock_time); impl_consensus_encoding!(Transaction, version, input, output, lock_time);
impl_json!(Transaction, version, input, output, lock_time);
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

View File

@ -74,7 +74,9 @@ pub struct UtxoIterator<'a> {
tx_index: u32 tx_index: u32
} }
impl<'a> Iterator<(Sha256dHash, u32, &'a TxOut, u32)> for UtxoIterator<'a> { impl<'a> Iterator for UtxoIterator<'a> {
type Item = (Sha256dHash, u32, &'a TxOut, u32);
fn next(&mut self) -> Option<(Sha256dHash, u32, &'a TxOut, u32)> { fn next(&mut self) -> Option<(Sha256dHash, u32, &'a TxOut, u32)> {
while self.current.is_some() { while self.current.is_some() {
let current = &self.current.unwrap().outputs; let current = &self.current.unwrap().outputs;

View File

@ -14,17 +14,17 @@
macro_rules! impl_consensus_encoding { macro_rules! impl_consensus_encoding {
($thing:ident, $($field:ident),+) => ( ($thing:ident, $($field:ident),+) => (
impl<S: ::network::serialize::SimpleEncoder<E>, E> ::network::encodable::ConsensusEncodable<S, E> for $thing { impl<S: ::network::serialize::SimpleEncoder> ::network::encodable::ConsensusEncodable<S> for $thing {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
$( try!(self.$field.consensus_encode(s)); )+ $( try!(self.$field.consensus_encode(s)); )+
Ok(()) Ok(())
} }
} }
impl<D: ::network::serialize::SimpleDecoder<E>, E> ::network::encodable::ConsensusDecodable<D, E> for $thing { impl<D: ::network::serialize::SimpleDecoder> ::network::encodable::ConsensusDecodable<D> for $thing {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<$thing, E> { fn consensus_decode(d: &mut D) -> Result<$thing, D::Error> {
use network::encodable::ConsensusDecodable; use network::encodable::ConsensusDecodable;
Ok($thing { Ok($thing {
$( $field: try!(ConsensusDecodable::consensus_decode(d)), )+ $( $field: try!(ConsensusDecodable::consensus_decode(d)), )+
@ -36,37 +36,23 @@ macro_rules! impl_consensus_encoding {
macro_rules! impl_newtype_consensus_encoding { macro_rules! impl_newtype_consensus_encoding {
($thing:ident) => ( ($thing:ident) => (
impl<S: ::network::serialize::SimpleEncoder<E>, E> ::network::encodable::ConsensusEncodable<S, E> for $thing { impl<S: ::network::serialize::SimpleEncoder> ::network::encodable::ConsensusEncodable<S> for $thing {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
let &$thing(ref data) = self; let &$thing(ref data) = self;
data.consensus_encode(s) data.consensus_encode(s)
} }
} }
impl<D: ::network::serialize::SimpleDecoder<E>, E> ::network::encodable::ConsensusDecodable<D, E> for $thing { impl<D: ::network::serialize::SimpleDecoder> ::network::encodable::ConsensusDecodable<D> for $thing {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<$thing, E> { fn consensus_decode(d: &mut D) -> Result<$thing, D::Error> {
Ok($thing(try!(ConsensusDecodable::consensus_decode(d)))) Ok($thing(try!(ConsensusDecodable::consensus_decode(d))))
} }
} }
); );
} }
macro_rules! impl_json {
($thing:ident, $($field:ident),+) => (
impl ::serialize::json::ToJson for $thing {
fn to_json(&self) -> ::serialize::json::Json {
use std::collections::BTreeMap;
use serialize::json::{ToJson, Object};
let mut ret = BTreeMap::new();
$( ret.insert(stringify!($field).to_string(), self.$field.to_json()); )+
Object(ret)
}
}
);
}
macro_rules! impl_array_newtype { macro_rules! impl_array_newtype {
($thing:ident, $ty:ty, $len:expr) => { ($thing:ident, $ty:ty, $len:expr) => {
impl $thing { impl $thing {
@ -201,32 +187,46 @@ macro_rules! impl_array_newtype {
macro_rules! impl_array_newtype_encodable { macro_rules! impl_array_newtype_encodable {
($thing:ident, $ty:ty, $len:expr) => { ($thing:ident, $ty:ty, $len:expr) => {
impl<D: ::serialize::Decoder<E>, E> ::serialize::Decodable<D, E> for $thing {
fn decode(d: &mut D) -> Result<$thing, E> {
use serialize::Decodable;
::assert_type_is_copy::<$ty>(); impl ::serde::Deserialize for $thing {
fn deserialize<D>(d: &mut D) -> Result<$thing, D::Error>
where D: ::serde::Deserializer
{
// We have to define the Visitor struct inside the function
// to make it local ... what we really need is that it's
// local to the macro, but this is Close Enough.
struct Visitor {
marker: ::std::marker::PhantomData<$thing>,
}
impl ::serde::de::Visitor for Visitor {
type Value = $thing;
d.read_seq(|d, len| { #[inline]
if len != $len { fn visit_seq<V>(&mut self, mut v: V) -> Result<$thing, V::Error>
Err(d.error("Invalid length")) where V: ::serde::de::SeqVisitor
} else { {
unsafe { unsafe {
use std::mem; use std::mem;
let mut ret: [$ty; $len] = mem::uninitialized(); let mut ret: [$ty; $len] = mem::uninitialized();
for i in 0..len { for i in 0..$len {
ret[i] = try!(d.read_seq_elt(i, |d| Decodable::decode(d))); ret[i] = try!(v.visit());
} }
Ok($thing(ret)) Ok($thing(ret))
} }
} }
}) }
// Begin actual function
d.visit(Visitor { marker: ::std::marker::PhantomData })
} }
} }
impl<E: ::serialize::Encoder<S>, S> ::serialize::Encodable<E, S> for $thing { impl ::serde::Serialize for $thing {
fn encode(&self, e: &mut E) -> Result<(), S> { fn serialize<S>(&self, s: &mut S) -> Result<(), S::Error>
self.as_slice().encode(e) where S: ::serde::Serializer
{
let &$thing(ref dat) = self;
(&dat[..]).serialize(s)
} }
} }
} }

View File

@ -98,17 +98,38 @@ macro_rules! user_enum {
} }
} }
impl<S: ::serialize::Encoder<E>, E> ::serialize::Encodable<S, E> for $name { impl ::serde::Deserialize for $name {
fn encode(&self, s: &mut S) -> Result<(), E> { #[inline]
s.emit_str(self.to_string().as_slice()) fn deserialize<D>(d: &mut D) -> Result<$name, D::Error>
where D: ::serde::Deserializer
{
struct Visitor;
impl ::serde::de::Visitor for Visitor {
type Value = $name;
fn visit_string<E>(&mut self, v: String) -> Result<$name, E>
where E: ::serde::de::Error
{
self.visit_str(&v)
}
fn visit_str<E>(&mut self, s: &str) -> Result<$name, E>
where E: ::serde::de::Error
{
$( if s == $txt { Ok($name::$elem) } )else*
else { Err(::serde::de::Error::syntax_error()) }
} }
} }
impl <D: ::serialize::Decoder<E>, E> ::serialize::Decodable<D, E> for $name { d.visit(Visitor)
fn decode(d: &mut D) -> Result<$name, E> { }
let s = try!(d.read_str()); }
$( if s.as_slice() == $txt { Ok($name::$elem) } )else*
else { Err(d.error(format!("unknown `{}`", s).as_slice())) } impl ::serde::Serialize for $name {
fn serialize<S>(&self, s: &mut S) -> Result<(), S::Error>
where S: ::serde::Serializer
{
s.visit_str(&self.to_string())
} }
} }
); );

View File

@ -33,9 +33,9 @@ pub struct Address {
pub port: u16 pub port: u16
} }
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Address { impl<S: SimpleEncoder> ConsensusEncodable<S> for Address {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
try!(self.services.consensus_encode(s)); try!(self.services.consensus_encode(s));
try!(self.address.consensus_encode(s)); try!(self.address.consensus_encode(s));
// Explicitly code the port since it needs to be big-endian // Explicitly code the port since it needs to be big-endian
@ -45,9 +45,9 @@ impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Address {
} }
} }
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for Address { impl<D: SimpleDecoder> ConsensusDecodable<D> for Address {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<Address, E> { fn consensus_decode(d: &mut D) -> Result<Address, D::Error> {
Ok(Address { Ok(Address {
services: try!(ConsensusDecodable::consensus_decode(d)), services: try!(ConsensusDecodable::consensus_decode(d)),
address: try!(ConsensusDecodable::consensus_decode(d)), address: try!(ConsensusDecodable::consensus_decode(d)),

View File

@ -46,16 +46,16 @@ pub fn magic(network: Network) -> u32 {
} }
} }
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Network { impl<S: SimpleEncoder> ConsensusEncodable<S> for Network {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
magic(*self).consensus_encode(s) magic(*self).consensus_encode(s)
} }
} }
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for Network { impl<D: SimpleDecoder> ConsensusDecodable<D> for Network {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<Network, E> { fn consensus_decode(d: &mut D) -> Result<Network, D::Error> {
let magic: u32 = try!(ConsensusDecodable::consensus_decode(d)); let magic: u32 = try!(ConsensusDecodable::consensus_decode(d));
match magic { match magic {
0xD9B4BEF9 => Ok(Network::Bitcoin), 0xD9B4BEF9 => Ok(Network::Bitcoin),

View File

@ -38,15 +38,15 @@ use util::hash::Sha256dHash;
use network::serialize::{SimpleDecoder, SimpleEncoder}; use network::serialize::{SimpleDecoder, SimpleEncoder};
/// Data which can be encoded in a consensus-consistent way /// Data which can be encoded in a consensus-consistent way
pub trait ConsensusEncodable<S:SimpleEncoder<E>, E> { pub trait ConsensusEncodable<S: SimpleEncoder> {
/// Encode an object with a well-defined format /// Encode an object with a well-defined format
fn consensus_encode(&self, e: &mut S) -> Result<(), E>; fn consensus_encode(&self, e: &mut S) -> Result<(), S::Error>;
} }
/// Data which can be encoded in a consensus-consistent way /// Data which can be encoded in a consensus-consistent way
pub trait ConsensusDecodable<D:SimpleDecoder<E>, E> { pub trait ConsensusDecodable<D: SimpleDecoder> {
/// Decode an object with a well-defined format /// Decode an object with a well-defined format
fn consensus_decode(d: &mut D) -> Result<Self, E>; fn consensus_decode(d: &mut D) -> Result<Self, D::Error>;
} }
/// A variable-length unsigned integer /// A variable-length unsigned integer
@ -58,39 +58,39 @@ pub struct VarInt(pub u64);
pub struct CheckedData(pub Vec<u8>); pub struct CheckedData(pub Vec<u8>);
// Primitive types // Primitive types
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for u8 { impl<S: SimpleEncoder> ConsensusEncodable<S> for u8 {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { s.emit_u8(*self) } fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u8(*self) }
} }
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for u16 { impl<S: SimpleEncoder> ConsensusEncodable<S> for u16 {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { s.emit_u16(self.to_le()) } fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u16(self.to_le()) }
} }
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for u32 { impl<S: SimpleEncoder> ConsensusEncodable<S> for u32 {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { s.emit_u32(self.to_le()) } fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u32(self.to_le()) }
} }
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for u64 { impl<S: SimpleEncoder> ConsensusEncodable<S> for u64 {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { s.emit_u64(self.to_le()) } fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u64(self.to_le()) }
} }
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for i32 { impl<S: SimpleEncoder> ConsensusEncodable<S> for i32 {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { s.emit_i32(self.to_le()) } fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_i32(self.to_le()) }
} }
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for i64 { impl<S: SimpleEncoder> ConsensusEncodable<S> for i64 {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { s.emit_i64(self.to_le()) } fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_i64(self.to_le()) }
} }
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for VarInt { impl<S: SimpleEncoder> ConsensusEncodable<S> for VarInt {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
let &VarInt(n) = self; let &VarInt(n) = self;
match n { match n {
0...0xFC => { (n as u8).consensus_encode(s) } 0...0xFC => { (n as u8).consensus_encode(s) }
@ -101,39 +101,39 @@ impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for VarInt {
} }
} }
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for u8 { impl<D: SimpleDecoder> ConsensusDecodable<D> for u8 {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<u8, E> { d.read_u8() } fn consensus_decode(d: &mut D) -> Result<u8, D::Error> { d.read_u8() }
} }
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for u16 { impl<D: SimpleDecoder> ConsensusDecodable<D> for u16 {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<u16, E> { d.read_u16().map(|n| u16::from_le(n)) } fn consensus_decode(d: &mut D) -> Result<u16, D::Error> { d.read_u16().map(|n| u16::from_le(n)) }
} }
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for u32 { impl<D: SimpleDecoder> ConsensusDecodable<D> for u32 {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<u32, E> { d.read_u32().map(|n| u32::from_le(n)) } fn consensus_decode(d: &mut D) -> Result<u32, D::Error> { d.read_u32().map(|n| u32::from_le(n)) }
} }
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for u64 { impl<D: SimpleDecoder> ConsensusDecodable<D> for u64 {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<u64, E> { d.read_u64().map(|n| u64::from_le(n)) } fn consensus_decode(d: &mut D) -> Result<u64, D::Error> { d.read_u64().map(|n| u64::from_le(n)) }
} }
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for i32 { impl<D: SimpleDecoder> ConsensusDecodable<D> for i32 {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<i32, E> { d.read_i32().map(|n| i32::from_le(n)) } fn consensus_decode(d: &mut D) -> Result<i32, D::Error> { d.read_i32().map(|n| i32::from_le(n)) }
} }
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for i64 { impl<D: SimpleDecoder> ConsensusDecodable<D> for i64 {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<i64, E> { d.read_i64().map(|n| i64::from_le(n)) } fn consensus_decode(d: &mut D) -> Result<i64, D::Error> { d.read_i64().map(|n| i64::from_le(n)) }
} }
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for VarInt { impl<D: SimpleDecoder> ConsensusDecodable<D> for VarInt {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<VarInt, E> { fn consensus_decode(d: &mut D) -> Result<VarInt, D::Error> {
let n = try!(d.read_u8()); let n = try!(d.read_u8());
match n { match n {
0xFF => d.read_u64().map(|n| VarInt(u64::from_le(n))), 0xFF => d.read_u64().map(|n| VarInt(u64::from_le(n))),
@ -145,27 +145,27 @@ impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for VarInt {
} }
// Booleans // Booleans
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for bool { impl<S: SimpleEncoder> ConsensusEncodable<S> for bool {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { s.emit_u8(if *self {1} else {0}) } fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u8(if *self {1} else {0}) }
} }
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for bool { impl<D: SimpleDecoder> ConsensusDecodable<D> for bool {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<bool, E> { d.read_u8().map(|n| n != 0) } fn consensus_decode(d: &mut D) -> Result<bool, D::Error> { d.read_u8().map(|n| n != 0) }
} }
// Strings // Strings
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for String { impl<S: SimpleEncoder> ConsensusEncodable<S> for String {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
self.as_bytes().consensus_encode(s) self.as_bytes().consensus_encode(s)
} }
} }
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for String { impl<D: SimpleDecoder> ConsensusDecodable<D> for String {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<String, E> { fn consensus_decode(d: &mut D) -> Result<String, D::Error> {
String::from_utf8(try!(ConsensusDecodable::consensus_decode(d))).map_err(|_| d.error("String was not valid UTF8")) String::from_utf8(try!(ConsensusDecodable::consensus_decode(d))).map_err(|_| d.error("String was not valid UTF8"))
} }
} }
@ -174,17 +174,17 @@ impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for String {
// Arrays // Arrays
macro_rules! impl_array { macro_rules! impl_array {
( $size:expr ) => ( ( $size:expr ) => (
impl<S:SimpleEncoder<E>, E, T:ConsensusEncodable<S, E>> ConsensusEncodable<S, E> for [T; $size] { impl<S: SimpleEncoder, T: ConsensusEncodable<S>> ConsensusEncodable<S> for [T; $size] {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
for i in self.iter() { try!(i.consensus_encode(s)); } for i in self.iter() { try!(i.consensus_encode(s)); }
Ok(()) Ok(())
} }
} }
impl<D:SimpleDecoder<E>, E, T:ConsensusDecodable<D, E>+Copy> ConsensusDecodable<D, E> for [T; $size] { impl<D: SimpleDecoder, T:ConsensusDecodable<D> + Copy> ConsensusDecodable<D> for [T; $size] {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<[T; $size], E> { fn consensus_decode(d: &mut D) -> Result<[T; $size], D::Error> {
// Set everything to the first decode // Set everything to the first decode
let mut ret = [try!(ConsensusDecodable::consensus_decode(d)); $size]; let mut ret = [try!(ConsensusDecodable::consensus_decode(d)); $size];
// Set the rest // Set the rest
@ -202,9 +202,9 @@ impl_array!(12);
impl_array!(16); impl_array!(16);
impl_array!(32); impl_array!(32);
impl<'a, S:SimpleEncoder<E>, E, T:ConsensusEncodable<S, E>> ConsensusEncodable<S, E> for &'a [T] { impl<'a, S: SimpleEncoder, T: ConsensusEncodable<S>> ConsensusEncodable<S> for &'a [T] {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
try!(VarInt(self.len() as u64).consensus_encode(s)); try!(VarInt(self.len() as u64).consensus_encode(s));
for c in self.iter() { try!(c.consensus_encode(s)); } for c in self.iter() { try!(c.consensus_encode(s)); }
Ok(()) Ok(())
@ -214,14 +214,14 @@ impl<'a, S:SimpleEncoder<E>, E, T:ConsensusEncodable<S, E>> ConsensusEncodable<S
// Cannot decode a slice // Cannot decode a slice
// Vectors // Vectors
impl<S:SimpleEncoder<E>, E, T:ConsensusEncodable<S, E>> ConsensusEncodable<S, E> for Vec<T> { impl<S: SimpleEncoder, T: ConsensusEncodable<S>> ConsensusEncodable<S> for Vec<T> {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { self.as_slice().consensus_encode(s) } fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { self.as_slice().consensus_encode(s) }
} }
impl<D:SimpleDecoder<E>, E, T:ConsensusDecodable<D, E>> ConsensusDecodable<D, E> for Vec<T> { impl<D: SimpleDecoder, T: ConsensusDecodable<D>> ConsensusDecodable<D> for Vec<T> {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<Vec<T>, E> { fn consensus_decode(d: &mut D) -> Result<Vec<T>, D::Error> {
let VarInt(len): VarInt = try!(ConsensusDecodable::consensus_decode(d)); let VarInt(len): VarInt = try!(ConsensusDecodable::consensus_decode(d));
let mut ret = Vec::with_capacity(len as usize); let mut ret = Vec::with_capacity(len as usize);
for _ in 0..len { ret.push(try!(ConsensusDecodable::consensus_decode(d))); } for _ in 0..len { ret.push(try!(ConsensusDecodable::consensus_decode(d))); }
@ -229,14 +229,14 @@ impl<D:SimpleDecoder<E>, E, T:ConsensusDecodable<D, E>> ConsensusDecodable<D, E>
} }
} }
impl<S:SimpleEncoder<E>, E, T:ConsensusEncodable<S, E>> ConsensusEncodable<S, E> for Box<[T]> { impl<S: SimpleEncoder, T: ConsensusEncodable<S>> ConsensusEncodable<S> for Box<[T]> {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { (&self[..]).consensus_encode(s) } fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { (&self[..]).consensus_encode(s) }
} }
impl<D:SimpleDecoder<E>, E, T:ConsensusDecodable<D, E>> ConsensusDecodable<D, E> for Box<[T]> { impl<D: SimpleDecoder, T: ConsensusDecodable<D>> ConsensusDecodable<D> for Box<[T]> {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<Box<[T]>, E> { fn consensus_decode(d: &mut D) -> Result<Box<[T]>, D::Error> {
let VarInt(len): VarInt = try!(ConsensusDecodable::consensus_decode(d)); let VarInt(len): VarInt = try!(ConsensusDecodable::consensus_decode(d));
unsafe { unsafe {
let len = len as usize; let len = len as usize;
@ -248,9 +248,9 @@ impl<D:SimpleDecoder<E>, E, T:ConsensusDecodable<D, E>> ConsensusDecodable<D, E>
} }
// Options (encoded as vectors of length 0 or 1) // Options (encoded as vectors of length 0 or 1)
impl<S:SimpleEncoder<E>, E, T:ConsensusEncodable<S, E>> ConsensusEncodable<S, E> for Option<T> { impl<S: SimpleEncoder, T: ConsensusEncodable<S>> ConsensusEncodable<S> for Option<T> {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
match *self { match *self {
Some(ref data) => { Some(ref data) => {
try!(1u8.consensus_encode(s)); try!(1u8.consensus_encode(s));
@ -262,9 +262,9 @@ impl<S:SimpleEncoder<E>, E, T:ConsensusEncodable<S, E>> ConsensusEncodable<S, E>
} }
} }
impl<D:SimpleDecoder<E>, E, T:ConsensusDecodable<D, E>> ConsensusDecodable<D, E> for Option<T> { impl<D: SimpleDecoder, T:ConsensusDecodable<D>> ConsensusDecodable<D> for Option<T> {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<Option<T>, E> { fn consensus_decode(d: &mut D) -> Result<Option<T>, D::Error> {
let bit: u8 = try!(ConsensusDecodable::consensus_decode(d)); let bit: u8 = try!(ConsensusDecodable::consensus_decode(d));
Ok(if bit != 0 { Ok(if bit != 0 {
Some(try!(ConsensusDecodable::consensus_decode(d))) Some(try!(ConsensusDecodable::consensus_decode(d)))
@ -282,9 +282,9 @@ fn sha2_checksum(data: &[u8]) -> [u8; 4] {
} }
// Checked data // Checked data
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for CheckedData { impl<S: SimpleEncoder> ConsensusEncodable<S> for CheckedData {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
let &CheckedData(ref data) = self; let &CheckedData(ref data) = self;
try!((data.len() as u32).consensus_encode(s)); try!((data.len() as u32).consensus_encode(s));
try!(sha2_checksum(data.as_slice()).consensus_encode(s)); try!(sha2_checksum(data.as_slice()).consensus_encode(s));
@ -296,9 +296,9 @@ impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for CheckedData {
} }
} }
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for CheckedData { impl<D: SimpleDecoder> ConsensusDecodable<D> for CheckedData {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<CheckedData, E> { fn consensus_decode(d: &mut D) -> Result<CheckedData, D::Error> {
let len: u32 = try!(ConsensusDecodable::consensus_decode(d)); let len: u32 = try!(ConsensusDecodable::consensus_decode(d));
let checksum: [u8; 4] = try!(ConsensusDecodable::consensus_decode(d)); let checksum: [u8; 4] = try!(ConsensusDecodable::consensus_decode(d));
let mut ret = Vec::with_capacity(len as usize); let mut ret = Vec::with_capacity(len as usize);
@ -315,53 +315,53 @@ impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for CheckedData {
// Tuples // Tuples
macro_rules! tuple_encode { macro_rules! tuple_encode {
($($x:ident),*) => ( ($($x:ident),*) => (
impl <SS:SimpleEncoder<EE>, EE, $($x: ConsensusEncodable<SS, EE>),*> ConsensusEncodable<SS, EE> for ($($x),*) { impl <S: SimpleEncoder, $($x: ConsensusEncodable<S>),*> ConsensusEncodable<S> for ($($x),*) {
#[inline] #[inline]
#[allow(non_snake_case)] #[allow(non_snake_case)]
fn consensus_encode(&self, s: &mut SS) -> Result<(), EE> { fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
let &($(ref $x),*) = self; let &($(ref $x),*) = self;
$( try!($x.consensus_encode(s)); )* $( try!($x.consensus_encode(s)); )*
Ok(()) Ok(())
} }
} }
impl<DD:SimpleDecoder<EE>, EE, $($x: ConsensusDecodable<DD, EE>),*> ConsensusDecodable<DD, EE> for ($($x),*) { impl<D: SimpleDecoder, $($x: ConsensusDecodable<D>),*> ConsensusDecodable<D> for ($($x),*) {
#[inline] #[inline]
#[allow(non_snake_case)] #[allow(non_snake_case)]
fn consensus_decode(d: &mut DD) -> Result<($($x),*), EE> { fn consensus_decode(d: &mut D) -> Result<($($x),*), D::Error> {
Ok(($(try!({let $x = ConsensusDecodable::consensus_decode(d); $x })),*)) Ok(($(try!({let $x = ConsensusDecodable::consensus_decode(d); $x })),*))
} }
} }
); );
} }
tuple_encode!(A, B); tuple_encode!(T0, T1);
tuple_encode!(A, B, C, D); tuple_encode!(T0, T1, T2, T3);
tuple_encode!(A, B, C, D, E, F); tuple_encode!(T0, T1, T2, T3, T4, T5);
tuple_encode!(A, B, C, D, E, F, G, H); tuple_encode!(T0, T1, T2, T3, T4, T5, T6, T7);
// References // References
impl<S:SimpleEncoder<E>, E, T: ConsensusEncodable<S, E>> ConsensusEncodable<S, E> for Box<T> { impl<S: SimpleEncoder, T: ConsensusEncodable<S>> ConsensusEncodable<S> for Box<T> {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { (**self).consensus_encode(s) } fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> { (**self).consensus_encode(s) }
} }
impl<D:SimpleDecoder<E>, E, T: ConsensusDecodable<D, E>> ConsensusDecodable<D, E> for Box<T> { impl<D: SimpleDecoder, T: ConsensusDecodable<D>> ConsensusDecodable<D> for Box<T> {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<Box<T>, E> { fn consensus_decode(d: &mut D) -> Result<Box<T>, D::Error> {
ConsensusDecodable::consensus_decode(d).map(|res| Box::new(res)) ConsensusDecodable::consensus_decode(d).map(|res| Box::new(res))
} }
} }
// HashMap // HashMap
impl<S:SimpleEncoder<E>, E, T, impl<S, K, V, H> ConsensusEncodable<S> for HashMap<K, V, H>
K:ConsensusEncodable<S,E>+Eq+Hash<T>, where S: SimpleEncoder,
V:ConsensusEncodable<S,E>, H: Hasher + Default,
H:Hasher<T>+Default> ConsensusEncodable<S, E> for HashMap<K, V, H> { K: ConsensusEncodable<S> + Eq + Hash,
V: ConsensusEncodable<S>
{
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
try!(VarInt(self.len() as u64).consensus_encode(s)); try!(VarInt(self.len() as u64).consensus_encode(s));
for (key, value) in self.iter() { for (key, value) in self.iter() {
try!(key.consensus_encode(s)); try!(key.consensus_encode(s));
@ -371,12 +371,14 @@ impl<S:SimpleEncoder<E>, E, T,
} }
} }
impl<D:SimpleDecoder<E>, E, T, impl<D, K, V, H> ConsensusDecodable<D> for HashMap<K, V, H>
K:ConsensusDecodable<D,E>+Eq+Hash<T>, where D: SimpleDecoder,
V:ConsensusDecodable<D,E>, H: Hasher + Default,
H:Hasher<T>+Default> ConsensusDecodable<D, E> for HashMap<K, V, H> { K: ConsensusDecodable<D> + Eq + Hash,
V: ConsensusDecodable<D>
{
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<HashMap<K, V, H>, E> { fn consensus_decode(d: &mut D) -> Result<HashMap<K, V, H>, D::Error> {
let VarInt(len): VarInt = try!(ConsensusDecodable::consensus_decode(d)); let VarInt(len): VarInt = try!(ConsensusDecodable::consensus_decode(d));
let mut ret = HashMap::with_capacity_and_hasher(len as usize, Default::default()); let mut ret = HashMap::with_capacity_and_hasher(len as usize, Default::default());

View File

@ -38,9 +38,9 @@ use util::misc::prepend_err;
#[derive(PartialEq, Eq, Clone, Debug)] #[derive(PartialEq, Eq, Clone, Debug)]
pub struct CommandString(pub String); pub struct CommandString(pub String);
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for CommandString { impl<S: SimpleEncoder> ConsensusEncodable<S> for CommandString {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
let &CommandString(ref inner_str) = self; let &CommandString(ref inner_str) = self;
let mut rawbytes = [0u8; 12]; let mut rawbytes = [0u8; 12];
rawbytes.clone_from_slice(inner_str.as_bytes().as_slice()); rawbytes.clone_from_slice(inner_str.as_bytes().as_slice());
@ -48,9 +48,9 @@ impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for CommandString {
} }
} }
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for CommandString { impl<D: SimpleDecoder> ConsensusDecodable<D> for CommandString {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<CommandString, E> { fn consensus_decode(d: &mut D) -> Result<CommandString, D::Error> {
let rawbytes: [u8; 12] = try!(ConsensusDecodable::consensus_decode(d)); let rawbytes: [u8; 12] = try!(ConsensusDecodable::consensus_decode(d));
let rv = iter::FromIterator::from_iter(rawbytes.iter().filter_map(|&u| if u > 0 { Some(u as char) } else { None })); let rv = iter::FromIterator::from_iter(rawbytes.iter().filter_map(|&u| if u > 0 { Some(u as char) } else { None }));
Ok(CommandString(rv)) Ok(CommandString(rv))
@ -133,8 +133,8 @@ impl RawNetworkMessage {
} }
} }
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for RawNetworkMessage { impl<S: SimpleEncoder> ConsensusEncodable<S> for RawNetworkMessage {
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
try!(self.magic.consensus_encode(s)); try!(self.magic.consensus_encode(s));
try!(CommandString(self.command()).consensus_encode(s)); try!(CommandString(self.command()).consensus_encode(s));
try!(CheckedData(match self.payload { try!(CheckedData(match self.payload {
@ -156,7 +156,7 @@ impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for RawNetworkMessage {
} }
} }
impl<D:SimpleDecoder<io::Error>> ConsensusDecodable<D, io::Error> for RawNetworkMessage { impl<D: SimpleDecoder<Error=io::Error>> ConsensusDecodable<D> for RawNetworkMessage {
fn consensus_decode(d: &mut D) -> io::Result<RawNetworkMessage> { fn consensus_decode(d: &mut D) -> io::Result<RawNetworkMessage> {
let magic = try!(ConsensusDecodable::consensus_decode(d)); let magic = try!(ConsensusDecodable::consensus_decode(d));
let CommandString(cmd): CommandString= try!(ConsensusDecodable::consensus_decode(d)); let CommandString(cmd): CommandString= try!(ConsensusDecodable::consensus_decode(d));

View File

@ -97,9 +97,9 @@ impl GetHeadersMessage {
impl_consensus_encoding!(GetHeadersMessage, version, locator_hashes, stop_hash); impl_consensus_encoding!(GetHeadersMessage, version, locator_hashes, stop_hash);
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Inventory { impl<S: SimpleEncoder> ConsensusEncodable<S> for Inventory {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
try!(match self.inv_type { try!(match self.inv_type {
InvType::Error => 0u32, InvType::Error => 0u32,
InvType::Transaction => 1, InvType::Transaction => 1,
@ -109,9 +109,9 @@ impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Inventory {
} }
} }
impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for Inventory { impl<D: SimpleDecoder> ConsensusDecodable<D> for Inventory {
#[inline] #[inline]
fn consensus_decode(d: &mut D) -> Result<Inventory, E> { fn consensus_decode(d: &mut D) -> Result<Inventory, D::Error> {
let int_type: u32 = try!(ConsensusDecodable::consensus_decode(d)); let int_type: u32 = try!(ConsensusDecodable::consensus_decode(d));
Ok(Inventory { Ok(Inventory {
inv_type: match int_type { inv_type: match int_type {

View File

@ -18,7 +18,7 @@
//! capabilities //! capabilities
//! //!
use std::io::Result; use std::io;
use network::constants; use network::constants;
use network::address::Address; use network::address::Address;
@ -54,7 +54,7 @@ pub struct VersionMessage {
impl VersionMessage { impl VersionMessage {
// TODO: we have fixed services and relay to 0 // TODO: we have fixed services and relay to 0
/// Constructs a new `version` message /// Constructs a new `version` message
pub fn new(timestamp: i64, mut socket: Socket, nonce: u64, start_height: i32) -> Result<VersionMessage> { pub fn new(timestamp: i64, mut socket: Socket, nonce: u64, start_height: i32) -> io::Result<VersionMessage> {
let recv_addr = socket.receiver_address(); let recv_addr = socket.receiver_address();
let send_addr = socket.sender_address(); let send_addr = socket.sender_address();
// If we are not connected, we might not be able to get these address.s // If we are not connected, we might not be able to get these address.s
@ -88,7 +88,7 @@ impl_consensus_encoding!(VersionMessage, version, services, timestamp,
mod tests { mod tests {
use super::VersionMessage; use super::VersionMessage;
use std::io::Result; use std::io;
use serialize::hex::FromHex; use serialize::hex::FromHex;
use network::serialize::{deserialize, serialize}; use network::serialize::{deserialize, serialize};
@ -98,7 +98,7 @@ mod tests {
// This message is from my satoshi node, morning of May 27 2014 // This message is from my satoshi node, morning of May 27 2014
let from_sat = "721101000100000000000000e6e0845300000000010000000000000000000000000000000000ffff0000000000000100000000000000fd87d87eeb4364f22cf54dca59412db7208d47d920cffce83ee8102f5361746f7368693a302e392e39392f2c9f040001".from_hex().unwrap(); let from_sat = "721101000100000000000000e6e0845300000000010000000000000000000000000000000000ffff0000000000000100000000000000fd87d87eeb4364f22cf54dca59412db7208d47d920cffce83ee8102f5361746f7368693a302e392e39392f2c9f040001".from_hex().unwrap();
let decode: Result<VersionMessage> = deserialize(from_sat.clone()); let decode: io::Result<VersionMessage> = deserialize(from_sat.clone());
assert!(decode.is_ok()); assert!(decode.is_ok());
let real_decode = decode.unwrap(); let real_decode = decode.unwrap();
assert_eq!(real_decode.version, 70002); assert_eq!(real_decode.version, 70002);

View File

@ -39,20 +39,20 @@ impl BitcoinHash for Vec<u8> {
} }
/// Encode an object into a vector /// Encode an object into a vector
pub fn serialize<T: ConsensusEncodable<RawEncoder<Cursor>, io::Error>>(obj: &T) -> io::Result<Vec<u8>> { pub fn serialize<T: ConsensusEncodable<RawEncoder<Cursor<Vec<u8>>>>>(obj: &T) -> io::Result<Vec<u8>> {
let mut encoder = RawEncoder::new(Cursor::new(vec![])); let mut encoder = RawEncoder::new(Cursor::new(vec![]));
try!(obj.consensus_encode(&mut encoder)); try!(obj.consensus_encode(&mut encoder));
Ok(encoder.unwrap().unwrap()) Ok(encoder.unwrap().unwrap())
} }
/// Encode an object into a hex-encoded string /// Encode an object into a hex-encoded string
pub fn serialize_hex<T: ConsensusEncodable<RawEncoder<Cursor>, io::Error>>(obj: &T) -> io::Result<String> { pub fn serialize_hex<T: ConsensusEncodable<RawEncoder<Cursor<Vec<u8>>>>>(obj: &T) -> io::Result<String> {
let serial = try!(serialize(obj)); let serial = try!(serialize(obj));
Ok(serial.as_slice().to_hex()) Ok(serial.as_slice().to_hex())
} }
/// Deserialize an object from a vector /// Deserialize an object from a vector
pub fn deserialize<T: ConsensusDecodable<RawDecoder<Cursor>, io::Error>>(data: Vec<u8>) -> io::Result<T> { pub fn deserialize<T: ConsensusDecodable<RawDecoder<Cursor<Vec<u8>>>>>(data: Vec<u8>) -> io::Result<T> {
let mut decoder = RawDecoder::new(Cursor::new(data)); let mut decoder = RawDecoder::new(Cursor::new(data));
ConsensusDecodable::consensus_decode(&mut decoder) ConsensusDecodable::consensus_decode(&mut decoder)
} }
@ -92,59 +92,65 @@ impl<R:Read> RawDecoder<R> {
} }
/// A simple Encoder trait /// A simple Encoder trait
pub trait SimpleEncoder<E> { pub trait SimpleEncoder {
type Error;
/// Output a 64-bit uint /// Output a 64-bit uint
fn emit_u64(&mut self, v: u64) -> Result<(), E>; fn emit_u64(&mut self, v: u64) -> Result<(), Self::Error>;
/// Output a 32-bit uint /// Output a 32-bit uint
fn emit_u32(&mut self, v: u32) -> Result<(), E>; fn emit_u32(&mut self, v: u32) -> Result<(), Self::Error>;
/// Output a 16-bit uint /// Output a 16-bit uint
fn emit_u16(&mut self, v: u16) -> Result<(), E>; fn emit_u16(&mut self, v: u16) -> Result<(), Self::Error>;
/// Output a 8-bit uint /// Output a 8-bit uint
fn emit_u8(&mut self, v: u8) -> Result<(), E>; fn emit_u8(&mut self, v: u8) -> Result<(), Self::Error>;
/// Output a 64-bit int /// Output a 64-bit int
fn emit_i64(&mut self, v: i64) -> Result<(), E>; fn emit_i64(&mut self, v: i64) -> Result<(), Self::Error>;
/// Output a 32-bit int /// Output a 32-bit int
fn emit_i32(&mut self, v: i32) -> Result<(), E>; fn emit_i32(&mut self, v: i32) -> Result<(), Self::Error>;
/// Output a 16-bit int /// Output a 16-bit int
fn emit_i16(&mut self, v: i16) -> Result<(), E>; fn emit_i16(&mut self, v: i16) -> Result<(), Self::Error>;
/// Output a 8-bit int /// Output a 8-bit int
fn emit_i8(&mut self, v: i8) -> Result<(), E>; fn emit_i8(&mut self, v: i8) -> Result<(), Self::Error>;
/// Output a boolean /// Output a boolean
fn emit_bool(&mut self, v: bool) -> Result<(), E>; fn emit_bool(&mut self, v: bool) -> Result<(), Self::Error>;
} }
/// A simple Decoder trait /// A simple Decoder trait
pub trait SimpleDecoder<E> { pub trait SimpleDecoder {
type Error;
/// Read a 64-bit uint /// Read a 64-bit uint
fn read_u64(&mut self) -> Result<u64, E>; fn read_u64(&mut self) -> Result<u64, Self::Error>;
/// Read a 32-bit uint /// Read a 32-bit uint
fn read_u32(&mut self) -> Result<u32, E>; fn read_u32(&mut self) -> Result<u32, Self::Error>;
/// Read a 16-bit uint /// Read a 16-bit uint
fn read_u16(&mut self) -> Result<u16, E>; fn read_u16(&mut self) -> Result<u16, Self::Error>;
/// Read a 8-bit uint /// Read a 8-bit uint
fn read_u8(&mut self) -> Result<u8, E>; fn read_u8(&mut self) -> Result<u8, Self::Error>;
/// Read a 64-bit int /// Read a 64-bit int
fn read_i64(&mut self) -> Result<i64, E>; fn read_i64(&mut self) -> Result<i64, Self::Error>;
/// Read a 32-bit int /// Read a 32-bit int
fn read_i32(&mut self) -> Result<i32, E>; fn read_i32(&mut self) -> Result<i32, Self::Error>;
/// Read a 16-bit int /// Read a 16-bit int
fn read_i16(&mut self) -> Result<i16, E>; fn read_i16(&mut self) -> Result<i16, Self::Error>;
/// Read a 8-bit int /// Read a 8-bit int
fn read_i8(&mut self) -> Result<i8, E>; fn read_i8(&mut self) -> Result<i8, Self::Error>;
/// Read a boolean /// Read a boolean
fn read_bool(&mut self) -> Result<bool, E>; fn read_bool(&mut self) -> Result<bool, Self::Error>;
/// Signal a decoding error /// Signal a decoding error
fn error(&mut self, err: &str) -> E; fn error(&mut self, err: &str) -> Self::Error;
} }
// TODO: trait reform: impl SimpleEncoder for every Encoder, ditto for Decoder // TODO: trait reform: impl SimpleEncoder for every Encoder, ditto for Decoder
impl<W:Write> SimpleEncoder<io::Error> for RawEncoder<W> { impl<W: Write> SimpleEncoder for RawEncoder<W> {
type Error = io::Error;
#[inline] #[inline]
fn emit_u64(&mut self, v: u64) -> io::Result<()> { self.writer.write_le_u64(v) } fn emit_u64(&mut self, v: u64) -> io::Result<()> { self.writer.write_le_u64(v) }
#[inline] #[inline]
@ -167,7 +173,9 @@ impl<W:Write> SimpleEncoder<io::Error> for RawEncoder<W> {
fn emit_bool(&mut self, v: bool) -> io::Result<()> { self.writer.write_i8(if v {1} else {0}) } fn emit_bool(&mut self, v: bool) -> io::Result<()> { self.writer.write_i8(if v {1} else {0}) }
} }
impl<R:Read> SimpleDecoder<io::Error> for RawDecoder<R> { impl<R: Read> SimpleDecoder for RawDecoder<R> {
type Error = io::Error;
#[inline] #[inline]
fn read_u64(&mut self) -> io::Result<u64> { self.reader.read_le_u64() } fn read_u64(&mut self) -> io::Result<u64> { self.reader.read_le_u64() }
#[inline] #[inline]

View File

@ -16,7 +16,7 @@
use byteorder::{ByteOrder, LittleEndian}; use byteorder::{ByteOrder, LittleEndian};
use std::string; use std::str;
use util::hash::Sha256dHash; use util::hash::Sha256dHash;
@ -132,7 +132,7 @@ pub fn base58_encode_slice(data: &[u8]) -> String {
// Unsafely translate the bytes to a utf8 string // Unsafely translate the bytes to a utf8 string
unsafe { unsafe {
// Copy leading zeroes directly // Copy leading zeroes directly
let mut ret = string::raw::from_utf8(data.iter().take_while(|&&x| x == 0) let mut ret = str::from_utf8(data.iter().take_while(|&&x| x == 0)
.map(|_| BASE58_CHARS[0]) .map(|_| BASE58_CHARS[0])
.collect()); .collect());
// Copy rest of string // Copy rest of string

View File

@ -18,9 +18,6 @@
use std::io; use std::io;
/// A success/failure return value
pub type Result<T> = Result<T, Error>;
/// A general error code /// A general error code
#[derive(PartialEq, Eq, Debug, Clone)] #[derive(PartialEq, Eq, Debug, Clone)]
pub enum Error { pub enum Error {

View File

@ -22,7 +22,7 @@ use std::fmt;
use std::io::Cursor; use std::io::Cursor;
use std::mem::transmute; use std::mem::transmute;
use std::hash; use std::hash;
use serialize::json::{self, ToJson}; use serde;
use byteorder::{ByteOrder, LittleEndian}; use byteorder::{ByteOrder, LittleEndian};
use crypto::digest::Digest; use crypto::digest::Digest;
@ -160,38 +160,49 @@ impl Sha256dHash {
// used only for user-facing stuff. Internal and network serialization is // used only for user-facing stuff. Internal and network serialization is
// little-endian and should be done using the consensus `encodable::ConsensusEncodable` // little-endian and should be done using the consensus `encodable::ConsensusEncodable`
// interface. // interface.
impl ToJson for Sha256dHash { impl serde::Serialize for Sha256dHash {
#[inline] fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
fn to_json(&self) -> json::Json { where S: serde::Serializer,
json::String(self.be_hex_string()) {
serializer.visit_str(&self.be_hex_string())
} }
} }
// Non-consensus encoding (big-endian hex string) impl serde::Deserialize for Sha256dHash {
impl<S: ::serialize::Encoder<E>, E> ::serialize::Encodable<S, E> for Sha256dHash {
#[inline] #[inline]
fn encode(&self, s: &mut S) -> Result<(), E> { fn deserialize<D>(d: &mut D) -> Result<Sha256dHash, D::Error>
s.emit_str(self.be_hex_string().as_slice()) where D: serde::Deserializer
} {
}
impl<D: ::serialize::Decoder<E>, E> ::serialize::Decodable<D, E> for Sha256dHash {
#[inline]
fn decode(d: &mut D) -> Result<Sha256dHash, E> {
use serialize::hex::FromHex; use serialize::hex::FromHex;
let hex_str = try!(d.read_str()); struct Sha256dHashVisitor;
impl serde::de::Visitor for Sha256dHashVisitor {
type Value = Sha256dHash;
fn visit_string<E>(&mut self, v: String) -> Result<Sha256dHash, E>
where E: serde::de::Error
{
self.visit_str(&v)
}
fn visit_str<E>(&mut self, hex_str: &str) -> Result<Sha256dHash, E>
where E: serde::de::Error
{
if hex_str.len() != 64 { if hex_str.len() != 64 {
d.error("incorrect hash length"); return Err(serde::de::Error::syntax_error());
} }
let raw_str = try!(hex_str.as_slice().from_hex() let raw_str = try!(hex_str.as_slice().from_hex()
.map_err(|_| d.error("non-hexadecimal hash string"))); .map_err(|_| serde::de::Error::syntax_error()));
let mut ret = [0u8; 32]; let mut ret = [0u8; 32];
for i in 0..32 { for i in 0..32 {
ret[i] = raw_str[31 - i]; ret[i] = raw_str[31 - i];
} }
Ok(Sha256dHash(ret)) Ok(Sha256dHash(ret))
} }
}
d.visit(Sha256dHashVisitor)
}
} }
// Consensus encoding (little-endian) // Consensus encoding (little-endian)

View File

@ -18,14 +18,18 @@
//! standard library. //! standard library.
/// An iterator that returns pairs of elements /// An iterator that returns pairs of elements
pub struct Pair<A, I> { pub struct Pair<I>
where I: Iterator
{
iter: I, iter: I,
last_elem: Option<A> last_elem: Option<I::Item>
} }
impl<A, I: Iterator<A>> Iterator<(A, A)> for Pair<A, I> { impl<I: Iterator> Iterator for Pair<I> {
type Item = (I::Item, I::Item);
#[inline] #[inline]
fn next(&mut self) -> Option<(A, A)> { fn next(&mut self) -> Option<(I::Item, I::Item)> {
let elem1 = self.iter.next(); let elem1 = self.iter.next();
if elem1.is_none() { if elem1.is_none() {
None None
@ -49,28 +53,28 @@ impl<A, I: Iterator<A>> Iterator<(A, A)> for Pair<A, I> {
} }
} }
impl<A, I: Iterator<A>> Pair<A, I> { impl<I: Iterator> Pair<I> {
/// Returns the last element of the iterator if there were an odd /// Returns the last element of the iterator if there were an odd
/// number of elements remaining before it was Pair-ified. /// number of elements remaining before it was Pair-ified.
#[inline] #[inline]
pub fn remainder(self) -> Option<A> { pub fn remainder(self) -> Option<I::Item> {
self.last_elem self.last_elem
} }
} }
/// Returns an iterator that returns elements of the original iterator 2 at a time /// Returns an iterator that returns elements of the original iterator 2 at a time
pub trait Pairable<A> { pub trait Pairable {
/// Returns an iterator that returns elements of the original iterator 2 at a time /// Returns an iterator that returns elements of the original iterator 2 at a time
fn pair(self) -> Pair<A, Self>; fn pair(self) -> Pair<Self>;
} }
impl<A, I: Iterator<A>> Pairable<A> for I { impl<I: Iterator> Pairable for I {
/// Creates an iterator that yields pairs ef elements from the underlying /// Creates an iterator that yields pairs ef elements from the underlying
/// iterator, yielding `None` when there are fewer than two elements to /// iterator, yielding `None` when there are fewer than two elements to
/// return. /// return.
#[inline] #[inline]
fn pair(self) -> Pair<A, I> { fn pair(self) -> Pair<I> {
Pair{iter: self, last_elem: None} Pair {iter: self, last_elem: None }
} }
} }

View File

@ -38,7 +38,9 @@ pub struct PatriciaTree<K, V> {
skip_len: u8 skip_len: u8
} }
impl<K:BitArray+cmp::Eq+Zero+One+ops::BitXor<K,K>+ops::Shl<usize,K>+ops::Shr<usize,K>, V> PatriciaTree<K, V> { impl<K, V> PatriciaTree<K, V>
where K: BitArray + cmp::Eq + Zero + One + ops::BitXor<K> + ops::Shl<usize> + ops::Shr<usize>
{
/// Constructs a new Patricia tree /// Constructs a new Patricia tree
pub fn new() -> PatriciaTree<K, V> { pub fn new() -> PatriciaTree<K, V> {
PatriciaTree { PatriciaTree {
@ -214,7 +216,9 @@ impl<K:BitArray+cmp::Eq+Zero+One+ops::BitXor<K,K>+ops::Shl<usize,K>+ops::Shr<usi
pub fn delete(&mut self, key: &K, key_len: usize) -> Option<V> { pub fn delete(&mut self, key: &K, key_len: usize) -> Option<V> {
/// Return value is (deletable, actual return value), where `deletable` is true /// Return value is (deletable, actual return value), where `deletable` is true
/// is true when the entire node can be deleted (i.e. it has no children) /// is true when the entire node can be deleted (i.e. it has no children)
fn recurse<K:BitArray+cmp::Eq+Zero+One+ops::Add<K,K>+ops::Shr<usize,K>+ops::Shl<usize,K>, V>(tree: &mut PatriciaTree<K, V>, key: &K, key_len: usize) -> (bool, Option<V>) { fn recurse<K, V>(tree: &mut PatriciaTree<K, V>, key: &K, key_len: usize) -> (bool, Option<V>)
where K: BitArray + cmp::Eq + Zero + One + ops::Add<K> + ops::Shr<usize> + ops::Shl<usize>
{
// If the search key is shorter than the node prefix, there is no // If the search key is shorter than the node prefix, there is no
// way we can match, so fail. // way we can match, so fail.
if key_len < tree.skip_len as usize { if key_len < tree.skip_len as usize {
@ -386,8 +390,12 @@ impl<K:BitArray, V:Debug> PatriciaTree<K, V> {
} }
} }
impl<S:SimpleEncoder<E>, E, K:ConsensusEncodable<S, E>, V:ConsensusEncodable<S, E>> ConsensusEncodable<S, E> for PatriciaTree<K, V> { impl<S, K, V> ConsensusEncodable<S> for PatriciaTree<K, V>
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { where S: SimpleEncoder,
K: ConsensusEncodable<S>,
V: ConsensusEncodable<S>
{
fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
// Depth-first serialization: serialize self, then children // Depth-first serialization: serialize self, then children
try!(self.skip_prefix.consensus_encode(s)); try!(self.skip_prefix.consensus_encode(s));
try!(self.skip_len.consensus_encode(s)); try!(self.skip_len.consensus_encode(s));
@ -398,8 +406,12 @@ impl<S:SimpleEncoder<E>, E, K:ConsensusEncodable<S, E>, V:ConsensusEncodable<S,
} }
} }
impl<D:SimpleDecoder<E>, E, K:ConsensusDecodable<D, E>, V:ConsensusDecodable<D, E>> ConsensusDecodable<D, E> for PatriciaTree<K, V> { impl<D, K, V> ConsensusDecodable<D> for PatriciaTree<K, V>
fn consensus_decode(d: &mut D) -> Result<PatriciaTree<K, V>, E> { where D: SimpleDecoder,
K: ConsensusDecodable<D>,
V: ConsensusDecodable<D>
{
fn consensus_decode(d: &mut D) -> Result<PatriciaTree<K, V>, D::Error> {
Ok(PatriciaTree { Ok(PatriciaTree {
skip_prefix: try!(ConsensusDecodable::consensus_decode(d)), skip_prefix: try!(ConsensusDecodable::consensus_decode(d)),
skip_len: try!(ConsensusDecodable::consensus_decode(d)), skip_len: try!(ConsensusDecodable::consensus_decode(d)),
@ -425,7 +437,9 @@ pub struct MutItems<'tree, K, V> {
marker: marker::PhantomData<&'tree PatriciaTree<K, V>> marker: marker::PhantomData<&'tree PatriciaTree<K, V>>
} }
impl<'a, K, V> Iterator<&'a V> for Items<'a, K, V> { impl<'a, K, V> Iterator for Items<'a, K, V> {
type Item = &'a V;
fn next(&mut self) -> Option<&'a V> { fn next(&mut self) -> Option<&'a V> {
fn borrow_opt<'a, K, V>(opt_ptr: &'a Option<Box<PatriciaTree<K, V>>>) -> Option<&'a PatriciaTree<K, V>> { fn borrow_opt<'a, K, V>(opt_ptr: &'a Option<Box<PatriciaTree<K, V>>>) -> Option<&'a PatriciaTree<K, V>> {
opt_ptr.as_ref().map(|b| &**b) opt_ptr.as_ref().map(|b| &**b)
@ -469,7 +483,9 @@ impl<'a, K, V> Iterator<&'a V> for Items<'a, K, V> {
} }
} }
impl<'a, K, V> Iterator<&'a mut V> for MutItems<'a, K, V> { impl<'a, K, V> Iterator for MutItems<'a, K, V> {
type Item = &'a mut V;
fn next(&mut self) -> Option<&'a mut V> { fn next(&mut self) -> Option<&'a mut V> {
fn borrow_opt<'a, K, V>(opt_ptr: &'a Option<Box<PatriciaTree<K, V>>>) -> *mut PatriciaTree<K, V> { fn borrow_opt<'a, K, V>(opt_ptr: &'a Option<Box<PatriciaTree<K, V>>>) -> *mut PatriciaTree<K, V> {
match *opt_ptr { match *opt_ptr {

View File

@ -90,7 +90,9 @@ macro_rules! construct_uint {
} }
} }
impl ::std::ops::Add<$name,$name> for $name { impl ::std::ops::Add<$name> for $name {
type Output = $name;
fn add(&self, other: &$name) -> $name { fn add(&self, other: &$name) -> $name {
let &$name(ref me) = self; let &$name(ref me) = self;
let &$name(ref you) = other; let &$name(ref you) = other;
@ -108,14 +110,18 @@ macro_rules! construct_uint {
} }
} }
impl ::std::ops::Sub<$name,$name> for $name { impl ::std::ops::Sub<$name> for $name {
type Output = $name;
#[inline] #[inline]
fn sub(&self, other: &$name) -> $name { fn sub(&self, other: &$name) -> $name {
*self + !*other + One::one() *self + !*other + One::one()
} }
} }
impl ::std::ops::Mul<$name,$name> for $name { impl ::std::ops::Mul<$name> for $name {
type Output = $name;
fn mul(&self, other: &$name) -> $name { fn mul(&self, other: &$name) -> $name {
let mut me = *self; let mut me = *self;
// TODO: be more efficient about this // TODO: be more efficient about this
@ -126,7 +132,9 @@ macro_rules! construct_uint {
} }
} }
impl ::std::ops::Div<$name,$name> for $name { impl ::std::ops::Div<$name> for $name {
type Output = $name;
fn div(&self, other: &$name) -> $name { fn div(&self, other: &$name) -> $name {
let mut sub_copy = *self; let mut sub_copy = *self;
let mut shift_copy = *other; let mut shift_copy = *other;
@ -197,7 +205,9 @@ macro_rules! construct_uint {
} }
} }
impl ::std::ops::BitAnd<$name,$name> for $name { impl ::std::ops::BitAnd<$name> for $name {
type Output = $name;
#[inline] #[inline]
fn bitand(&self, other: &$name) -> $name { fn bitand(&self, other: &$name) -> $name {
let &$name(ref arr1) = self; let &$name(ref arr1) = self;
@ -210,7 +220,9 @@ macro_rules! construct_uint {
} }
} }
impl ::std::ops::BitXor<$name,$name> for $name { impl ::std::ops::BitXor<$name> for $name {
type Output = $name;
#[inline] #[inline]
fn bitxor(&self, other: &$name) -> $name { fn bitxor(&self, other: &$name) -> $name {
let &$name(ref arr1) = self; let &$name(ref arr1) = self;
@ -223,7 +235,9 @@ macro_rules! construct_uint {
} }
} }
impl ::std::ops::BitOr<$name,$name> for $name { impl ::std::ops::BitOr<$name> for $name {
type Output = $name;
#[inline] #[inline]
fn bitor(&self, other: &$name) -> $name { fn bitor(&self, other: &$name) -> $name {
let &$name(ref arr1) = self; let &$name(ref arr1) = self;
@ -236,7 +250,9 @@ macro_rules! construct_uint {
} }
} }
impl ::std::ops::Not<$name> for $name { impl ::std::ops::Not for $name {
type Output = $name;
#[inline] #[inline]
fn not(&self) -> $name { fn not(&self) -> $name {
let &$name(ref arr) = self; let &$name(ref arr) = self;
@ -248,7 +264,9 @@ macro_rules! construct_uint {
} }
} }
impl ::std::ops::Shl<usize, $name> for $name { impl ::std::ops::Shl<usize> for $name {
type Output = $name;
fn shl(&self, shift: &usize) -> $name { fn shl(&self, shift: &usize) -> $name {
let &$name(ref original) = self; let &$name(ref original) = self;
let mut ret = [0u64; $n_words]; let mut ret = [0u64; $n_words];
@ -268,7 +286,9 @@ macro_rules! construct_uint {
} }
} }
impl ::std::ops::Shr<usize, $name> for $name { impl ::std::ops::Shr<usize> for $name {
type Output = $name;
#[allow(unsigned_negate)] #[allow(unsigned_negate)]
fn shr(&self, shift: &usize) -> $name { fn shr(&self, shift: &usize) -> $name {
let &$name(ref original) = self; let &$name(ref original) = self;
@ -316,9 +336,9 @@ macro_rules! construct_uint {
} }
} }
impl<S: ::network::serialize::SimpleEncoder<E>, E> ::network::encodable::ConsensusEncodable<S, E> for $name { impl<S: ::network::serialize::SimpleEncoder> ::network::encodable::ConsensusEncodable<S> for $name {
#[inline] #[inline]
fn consensus_encode(&self, s: &mut S) -> Result<(), E> { fn consensus_encode(&self, s: &mut S) -> Result<(), S::Error> {
use network::encodable::ConsensusEncodable; use network::encodable::ConsensusEncodable;
let &$name(ref data) = self; let &$name(ref data) = self;
for word in data.iter() { try!(word.consensus_encode(s)); } for word in data.iter() { try!(word.consensus_encode(s)); }
@ -326,8 +346,8 @@ macro_rules! construct_uint {
} }
} }
impl<D: ::network::serialize::SimpleDecoder<E>, E> ::network::encodable::ConsensusDecodable<D, E> for $name { impl<D: ::network::serialize::SimpleDecoder> ::network::encodable::ConsensusDecodable<D> for $name {
fn consensus_decode(d: &mut D) -> Result<$name, E> { fn consensus_decode(d: &mut D) -> Result<$name, D::Error> {
use network::encodable::ConsensusDecodable; use network::encodable::ConsensusDecodable;
let ret: [u64; $n_words] = try!(ConsensusDecodable::consensus_decode(d)); let ret: [u64; $n_words] = try!(ConsensusDecodable::consensus_decode(d));
Ok($name(ret)) Ok($name(ret))