Manually implement Encodable/Decodable/Show for Network

Since TOML will not encode C-like enums as strings, we do it
ourselves. This is also worthwhile so that we can get the
lowercase "bitcoin" and "testnet" as encodings for the actual
enum values, which are more verbose and camel case.
This commit is contained in:
Andrew Poelstra 2014-08-03 06:03:00 -07:00
parent a6eb33efd0
commit 474d04d154
1 changed files with 48 additions and 1 deletions

View File

@ -18,11 +18,14 @@
//! protocol, such as protocol versioning and magic header bytes.
//!
use std::fmt;
use serialize::{Decoder, Encoder, Encodable, Decodable};
use network::encodable::{ConsensusDecodable, ConsensusEncodable};
use network::serialize::{SimpleEncoder, SimpleDecoder};
/// The cryptocurrency to operate on
#[deriving(Encodable, Decodable, PartialEq, Eq, Clone, Show, Hash)]
#[deriving(PartialEq, Eq, Clone, Hash)]
pub enum Network {
/// Classic Bitcoin
Bitcoin,
@ -30,6 +33,32 @@ pub enum Network {
BitcoinTestnet,
}
impl fmt::Show for Network {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad(match *self {
Bitcoin => "bitcoin",
BitcoinTestnet => "testnet",
})
}
}
impl<S:Encoder<E>, E> Encodable<S, E> for Network {
fn encode(&self, s: &mut S) -> Result<(), E> {
s.emit_str(self.to_string().as_slice())
}
}
impl <D:Decoder<E>, E> Decodable<D, E> for Network {
fn decode(d: &mut D) -> Result<Network, E> {
let s = try!(d.read_str());
match s.as_slice() {
"bitcoin" => Ok(Bitcoin),
"testnet" => Ok(BitcoinTestnet),
_ => Err(d.error(format!("Unknown network {}", s).as_slice()))
}
}
}
pub static PROTOCOL_VERSION: u32 = 70001;
pub static SERVICES: u64 = 0;
pub static USER_AGENT: &'static str = "bitcoin-rust v0.1";
@ -63,3 +92,21 @@ impl<D:SimpleDecoder<E>, E> ConsensusDecodable<D, E> for Network {
}
}
#[cfg(test)]
mod tests {
use super::{Network, Bitcoin, BitcoinTestnet};
use network::serialize::{deserialize, serialize};
fn serialize_test() {
assert_eq!(serialize(&Bitcoin).unwrap().as_slice(), "bitcoin".as_bytes());
assert_eq!(serialize(&BitcoinTestnet).unwrap().as_slice(), "testnet".as_bytes());
assert_eq!(deserialize(Vec::from_slice("bitcoin".as_bytes())), Ok(Bitcoin));
assert_eq!(deserialize(Vec::from_slice("testnet".as_bytes())), Ok(BitcoinTestnet));
let bad: Result<Network, _> = deserialize(Vec::from_slice("fakenet".as_bytes()));
assert!(bad.is_err());
}
}