Merge rust-bitcoin/rust-bitcoin#1291: Remove `user_enum` macro
f429c22599
Remove user_enum macro (Tobin C. Harding)ad29084582
Add Network serde roundtrip test (Tobin C. Harding) Pull request description: Remove the `user_enum` macro because it is only used once and is unnecessarily complicated. Patch 1: Add a preparatory unit test to make sure patch 2 maintains the current serde logic. Patch 2: Simplify `Network` by removing `user_enum` ACKs for top commit: Kixunil: ACKf429c22599
apoelstra: ACKf429c22599
Tree-SHA512: 770ee0aa82be711ed11bdfda338de8d13071743cdc8d7e3e1252a6759dfdfa2be6ff1d8cd286acef75dc5a5d73a6bc5f565b02cb20d4b549e0714cef5d7c1973
This commit is contained in:
commit
b309f41076
|
@ -538,94 +538,6 @@ macro_rules! impl_bytes_newtype {
|
|||
}
|
||||
pub(crate) use impl_bytes_newtype;
|
||||
|
||||
macro_rules! user_enum {
|
||||
(
|
||||
$(#[$attr:meta])*
|
||||
pub enum $name:ident {
|
||||
$(#[$doc:meta]
|
||||
$elem:ident <-> $txt:literal),*
|
||||
}
|
||||
) => (
|
||||
$(#[$attr])*
|
||||
pub enum $name {
|
||||
$(#[$doc] $elem),*
|
||||
}
|
||||
|
||||
impl core::fmt::Display for $name {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
f.pad(match *self {
|
||||
$($name::$elem => $txt),*
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl core::str::FromStr for $name {
|
||||
type Err = $crate::io::Error;
|
||||
#[inline]
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
$($txt => Ok($name::$elem)),*,
|
||||
_ => {
|
||||
#[cfg(not(feature = "std"))] let message = "Unknown network";
|
||||
#[cfg(feature = "std")] let message = format!("Unknown network (type {})", s);
|
||||
Err($crate::io::Error::new(
|
||||
$crate::io::ErrorKind::InvalidInput,
|
||||
message,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
|
||||
impl<'de> $crate::serde::Deserialize<'de> for $name {
|
||||
#[inline]
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: $crate::serde::Deserializer<'de>,
|
||||
{
|
||||
use core::fmt::{self, Formatter};
|
||||
|
||||
struct Visitor;
|
||||
impl<'de> $crate::serde::de::Visitor<'de> for Visitor {
|
||||
type Value = $name;
|
||||
|
||||
fn expecting(&self, f: &mut Formatter) -> fmt::Result {
|
||||
f.write_str("an enum value")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: $crate::serde::de::Error,
|
||||
{
|
||||
static FIELDS: &'static [&'static str] = &[$(stringify!($txt)),*];
|
||||
|
||||
$( if v == $txt { Ok($name::$elem) } )else*
|
||||
else {
|
||||
Err(E::unknown_variant(v, FIELDS))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_str(Visitor)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
|
||||
impl $crate::serde::Serialize for $name {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: $crate::serde::Serializer,
|
||||
{
|
||||
serializer.collect_str(&self)
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
pub(crate) use user_enum;
|
||||
|
||||
/// Asserts a boolean expression at compile time.
|
||||
macro_rules! const_assert {
|
||||
($x:expr) => {{
|
||||
|
|
|
@ -27,10 +27,13 @@
|
|||
//! ```
|
||||
|
||||
use core::{fmt, ops, convert::From};
|
||||
use core::str::FromStr;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::io;
|
||||
use crate::consensus::encode::{self, Encodable, Decodable};
|
||||
use crate::internal_macros::user_enum;
|
||||
|
||||
/// Version of the protocol as appearing in network message headers
|
||||
/// This constant is used to signal to other peers which features you support.
|
||||
|
@ -49,19 +52,21 @@ use crate::internal_macros::user_enum;
|
|||
/// 60001 - Support `pong` message and nonce in `ping` message
|
||||
pub const PROTOCOL_VERSION: u32 = 70001;
|
||||
|
||||
user_enum! {
|
||||
/// The cryptocurrency to act on
|
||||
#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Debug)]
|
||||
pub enum Network {
|
||||
/// Classic Bitcoin
|
||||
Bitcoin <-> "bitcoin",
|
||||
/// Bitcoin's testnet
|
||||
Testnet <-> "testnet",
|
||||
/// Bitcoin's signet
|
||||
Signet <-> "signet",
|
||||
/// Bitcoin's regtest
|
||||
Regtest <-> "regtest"
|
||||
}
|
||||
/// The cryptocurrency network to act on.
|
||||
#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
|
||||
#[non_exhaustive]
|
||||
pub enum Network {
|
||||
/// Mainnet Bitcoin.
|
||||
Bitcoin,
|
||||
/// Bitcoin's testnet network.
|
||||
Testnet,
|
||||
/// Bitcoin's signet network.
|
||||
Signet,
|
||||
/// Bitcoin's regtest network.
|
||||
Regtest,
|
||||
}
|
||||
|
||||
impl Network {
|
||||
|
@ -108,6 +113,43 @@ impl Network {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Network {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
use Network::*;
|
||||
|
||||
let s = match *self {
|
||||
Bitcoin => "bitcoin",
|
||||
Testnet => "testnet",
|
||||
Signet => "signet",
|
||||
Regtest => "regtest",
|
||||
};
|
||||
write!(f, "{}", s)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Network {
|
||||
type Err = io::Error;
|
||||
#[inline]
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
use Network::*;
|
||||
|
||||
let network = match s {
|
||||
"bitcoin" => Bitcoin,
|
||||
"testnet" => Testnet,
|
||||
"signet" => Signet,
|
||||
"regtest" => Regtest,
|
||||
_ => {
|
||||
#[cfg(feature = "std")]
|
||||
let message = format!("Unknown network (type {})", s);
|
||||
#[cfg(not(feature = "std"))]
|
||||
let message = "Unknown network";
|
||||
return Err(io::Error::new(io::ErrorKind::InvalidInput, message));
|
||||
}
|
||||
};
|
||||
Ok(network)
|
||||
}
|
||||
}
|
||||
|
||||
/// Flags to indicate which network services a node supports.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct ServiceFlags(u64);
|
||||
|
@ -348,4 +390,22 @@ mod tests {
|
|||
let flag = ServiceFlags::WITNESS | 0xf0.into();
|
||||
assert_eq!("ServiceFlags(WITNESS|COMPACT_FILTERS|0xb0)", flag.to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "serde")]
|
||||
fn serde_roundtrip() {
|
||||
use Network::*;
|
||||
let tests = vec![(Bitcoin, "bitcoin"), (Testnet, "testnet"), (Signet, "signet"), (Regtest, "regtest")];
|
||||
|
||||
for tc in tests {
|
||||
let network = tc.0;
|
||||
|
||||
let want = format!("\"{}\"", tc.1);
|
||||
let got = serde_json::to_string(&tc.0).expect("failed to serialize network");
|
||||
assert_eq!(got, want);
|
||||
|
||||
let back: Network = serde_json::from_str(&got).expect("failed to deserialize network");
|
||||
assert_eq!(back, network);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue