From 474d04d1549e7c9bfa7fb19aa692fee023ba9d07 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Sun, 3 Aug 2014 06:03:00 -0700 Subject: [PATCH] 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. --- src/network/constants.rs | 49 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/src/network/constants.rs b/src/network/constants.rs index 7d98ec2..321e800 100644 --- a/src/network/constants.rs +++ b/src/network/constants.rs @@ -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, E> Encodable for Network { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_str(self.to_string().as_slice()) + } +} + +impl , E> Decodable for Network { + fn decode(d: &mut D) -> Result { + 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, E> ConsensusDecodable 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 = deserialize(Vec::from_slice("fakenet".as_bytes())); + assert!(bad.is_err()); + } +} +