diff --git a/Cargo.lock b/Cargo.lock index 833b62d737..7b326ff2bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1002,6 +1002,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", + "serde", ] [[package]] @@ -1494,7 +1495,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap", + "indexmap 2.2.5", "slab", "tokio", "tokio-util 0.7.10", @@ -1511,6 +1512,12 @@ dependencies = [ "crunchy", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.14.3" @@ -1686,6 +1693,17 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + [[package]] name = "indexmap" version = "2.2.5" @@ -1693,7 +1711,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.14.3", + "serde", ] [[package]] @@ -2262,6 +2281,7 @@ dependencies = [ "serde", "serde-hex", "serde_json", + "serde_with", "serde_yaml", "sha3", "sysinfo", @@ -2309,6 +2329,7 @@ dependencies = [ "derive_more", "serde", "serde_json", + "serde_with", "thiserror", ] @@ -3057,7 +3078,7 @@ version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" dependencies = [ - "indexmap", + "indexmap 2.2.5", "itoa", "ryu", "serde", @@ -3085,13 +3106,43 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_with" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee80b0e361bbf88fd2f6e242ccd19cfda072cb0faa6ae694ecee08199938569a" +dependencies = [ + "base64 0.21.7", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.2.5", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6561dc161a9224638a31d876ccdfefbc1df91d3f3a8342eddb35f055d48c7655" +dependencies = [ + "darling 0.20.8", + "proc-macro2", + "quote", + "syn 2.0.52", +] + [[package]] name = "serde_yaml" version = "0.9.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fd075d994154d4a774f95b51fb96bdc2832b0ea48425c92546073816cda1f2f" dependencies = [ - "indexmap", + "indexmap 2.2.5", "itoa", "ryu", "serde", diff --git a/Cargo.toml b/Cargo.toml index 3f15d37982..f57afa0706 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,6 +60,7 @@ rustls-acme = { version = "0.8.1", features = ["axum"] } serde = { version = "1.0.137", features = ["derive"] } serde-hex = "0.1.0" serde_json = { version = "1.0.81", features = ["preserve_order"] } +serde_with = "3.7.0" serde_yaml = "0.9.17" sha3 = "0.10.8" sysinfo = "0.30.3" diff --git a/crates/ordinals/Cargo.toml b/crates/ordinals/Cargo.toml index bb13ec2729..adc439385e 100644 --- a/crates/ordinals/Cargo.toml +++ b/crates/ordinals/Cargo.toml @@ -12,6 +12,7 @@ rust-version = "1.67" bitcoin = { version = "0.30.1", features = ["rand"] } derive_more = "0.99.17" serde = { version = "1.0.137", features = ["derive"] } +serde_with = "3.7.0" thiserror = "1.0.56" [dev-dependencies] diff --git a/crates/ordinals/src/lib.rs b/crates/ordinals/src/lib.rs index 5f178ade34..21f99db1f6 100644 --- a/crates/ordinals/src/lib.rs +++ b/crates/ordinals/src/lib.rs @@ -7,7 +7,8 @@ use { OutPoint, }, derive_more::{Display, FromStr}, - serde::{Deserialize, Deserializer, Serialize, Serializer}, + serde::{Deserialize, Serialize}, + serde_with::{DeserializeFromStr, SerializeDisplay}, std::{ cmp, fmt::{self, Display, Formatter}, @@ -26,12 +27,8 @@ pub use { sat_point::SatPoint, }; -#[doc(hidden)] -pub use self::deserialize_from_str::DeserializeFromStr; - mod decimal_sat; mod degree; -mod deserialize_from_str; mod epoch; mod height; mod rarity; diff --git a/crates/ordinals/src/rarity.rs b/crates/ordinals/src/rarity.rs index eb98e15dc4..a92fce72a9 100644 --- a/crates/ordinals/src/rarity.rs +++ b/crates/ordinals/src/rarity.rs @@ -1,6 +1,6 @@ use super::*; -#[derive(Debug, PartialEq, PartialOrd, Copy, Clone)] +#[derive(Debug, PartialEq, PartialOrd, Copy, Clone, DeserializeFromStr, SerializeDisplay)] pub enum Rarity { Common, Uncommon, @@ -90,24 +90,6 @@ impl FromStr for Rarity { } } -impl Serialize for Rarity { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.collect_str(self) - } -} - -impl<'de> Deserialize<'de> for Rarity { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - DeserializeFromStr::with(deserializer) - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/crates/ordinals/src/sat_point.rs b/crates/ordinals/src/sat_point.rs index 2398a14edc..e08f337145 100644 --- a/crates/ordinals/src/sat_point.rs +++ b/crates/ordinals/src/sat_point.rs @@ -9,7 +9,19 @@ use {super::*, bitcoin::transaction::ParseOutPointError}; /// that of the second sat of the genesis block coinbase output is /// `000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f:0:1`, and /// so on and so on. -#[derive(Debug, PartialEq, Copy, Clone, Eq, PartialOrd, Ord, Default, Hash)] +#[derive( + Debug, + PartialEq, + Copy, + Clone, + Eq, + PartialOrd, + Ord, + Default, + Hash, + DeserializeFromStr, + SerializeDisplay, +)] pub struct SatPoint { pub outpoint: OutPoint, pub offset: u64, @@ -39,24 +51,6 @@ impl Decodable for SatPoint { } } -impl Serialize for SatPoint { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.collect_str(self) - } -} - -impl<'de> Deserialize<'de> for SatPoint { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - DeserializeFromStr::with(deserializer) - } -} - impl FromStr for SatPoint { type Err = Error; diff --git a/src/decimal.rs b/src/decimal.rs index ac102a5d96..21a8c63508 100644 --- a/src/decimal.rs +++ b/src/decimal.rs @@ -1,6 +1,6 @@ use super::*; -#[derive(Debug, PartialEq, Copy, Clone, Default)] +#[derive(Debug, PartialEq, Copy, Clone, Default, DeserializeFromStr, SerializeDisplay)] pub struct Decimal { value: u128, scale: u8, @@ -85,24 +85,6 @@ impl FromStr for Decimal { } } -impl Serialize for Decimal { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.collect_str(self) - } -} - -impl<'de> Deserialize<'de> for Decimal { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - DeserializeFromStr::with(deserializer) - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/crates/ordinals/src/deserialize_from_str.rs b/src/deserialize_from_str.rs similarity index 71% rename from crates/ordinals/src/deserialize_from_str.rs rename to src/deserialize_from_str.rs index 175c640652..edd90d9b76 100644 --- a/crates/ordinals/src/deserialize_from_str.rs +++ b/src/deserialize_from_str.rs @@ -2,18 +2,6 @@ use super::*; pub struct DeserializeFromStr(pub T); -impl<'de, T: FromStr> DeserializeFromStr -where - T::Err: Display, -{ - pub fn with(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - Ok(DeserializeFromStr::::deserialize(deserializer)?.0) - } -} - impl<'de, T: FromStr> Deserialize<'de> for DeserializeFromStr where T::Err: Display, diff --git a/src/inscriptions/inscription_id.rs b/src/inscriptions/inscription_id.rs index 773b0ac715..92fc0a844f 100644 --- a/src/inscriptions/inscription_id.rs +++ b/src/inscriptions/inscription_id.rs @@ -1,6 +1,8 @@ use super::*; -#[derive(Debug, PartialEq, Copy, Clone, Hash, Eq, PartialOrd, Ord)] +#[derive( + Debug, PartialEq, Copy, Clone, Hash, Eq, PartialOrd, Ord, DeserializeFromStr, SerializeDisplay, +)] pub struct InscriptionId { pub txid: Txid, pub index: u32, @@ -34,24 +36,6 @@ impl InscriptionId { } } -impl<'de> Deserialize<'de> for InscriptionId { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - DeserializeFromStr::with(deserializer) - } -} - -impl Serialize for InscriptionId { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.collect_str(self) - } -} - impl Display for InscriptionId { fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "{}i{}", self.txid, self.index) diff --git a/src/lib.rs b/src/lib.rs index ad4903775b..68bc473239 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,6 +16,7 @@ use { arguments::Arguments, blocktime::Blocktime, decimal::Decimal, + deserialize_from_str::DeserializeFromStr, index::BitcoinCoreRpcResultExt, inscriptions::{ inscription_id, @@ -52,10 +53,11 @@ use { html_escaper::{Escape, Trusted}, http::HeaderMap, lazy_static::lazy_static, - ordinals::{DeserializeFromStr, Epoch, Height, Rarity, Sat, SatPoint}, + ordinals::{Epoch, Height, Rarity, Sat, SatPoint}, regex::Regex, reqwest::Url, - serde::{Deserialize, Deserializer, Serialize, Serializer}, + serde::{Deserialize, Deserializer, Serialize}, + serde_with::{DeserializeFromStr, SerializeDisplay}, std::{ cmp::{self, Reverse}, collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque}, @@ -111,6 +113,7 @@ pub mod arguments; mod blocktime; pub mod chain; mod decimal; +mod deserialize_from_str; mod fee_rate; pub mod index; mod inscriptions; diff --git a/src/object.rs b/src/object.rs index 611f592934..159acb16e2 100644 --- a/src/object.rs +++ b/src/object.rs @@ -1,6 +1,6 @@ use super::*; -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone, DeserializeFromStr, SerializeDisplay)] pub enum Object { Address(Address), Hash([u8; 32]), @@ -53,24 +53,6 @@ impl Display for Object { } } -impl Serialize for Object { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.collect_str(self) - } -} - -impl<'de> Deserialize<'de> for Object { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - DeserializeFromStr::with(deserializer) - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/src/outgoing.rs b/src/outgoing.rs index c9ae6de2b1..87bc310e69 100644 --- a/src/outgoing.rs +++ b/src/outgoing.rs @@ -1,6 +1,6 @@ use super::*; -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone, DeserializeFromStr, SerializeDisplay)] pub enum Outgoing { Amount(Amount), InscriptionId(InscriptionId), @@ -82,24 +82,6 @@ impl FromStr for Outgoing { } } -impl Serialize for Outgoing { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.collect_str(self) - } -} - -impl<'de> Deserialize<'de> for Outgoing { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - DeserializeFromStr::with(deserializer) - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/src/runes/rune.rs b/src/runes/rune.rs index 8688ec530a..bd49af12d6 100644 --- a/src/runes/rune.rs +++ b/src/runes/rune.rs @@ -1,6 +1,8 @@ use super::*; -#[derive(Default, Debug, PartialEq, Copy, Clone, PartialOrd, Ord, Eq)] +#[derive( + Default, Debug, PartialEq, Copy, Clone, PartialOrd, Ord, Eq, DeserializeFromStr, SerializeDisplay, +)] pub struct Rune(pub u128); impl Rune { @@ -86,24 +88,6 @@ impl Rune { } } -impl Serialize for Rune { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.collect_str(self) - } -} - -impl<'de> Deserialize<'de> for Rune { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - DeserializeFromStr::with(deserializer) - } -} - impl Display for Rune { fn fmt(&self, f: &mut Formatter) -> fmt::Result { let mut n = self.0; diff --git a/src/runes/rune_id.rs b/src/runes/rune_id.rs index 266804bf83..c8a600560c 100644 --- a/src/runes/rune_id.rs +++ b/src/runes/rune_id.rs @@ -1,6 +1,18 @@ use super::*; -#[derive(Debug, PartialEq, Copy, Clone, Hash, Eq, Ord, PartialOrd, Default)] +#[derive( + Debug, + PartialEq, + Copy, + Clone, + Hash, + Eq, + Ord, + PartialOrd, + Default, + DeserializeFromStr, + SerializeDisplay, +)] pub struct RuneId { pub block: u32, pub tx: u32, @@ -83,24 +95,6 @@ impl FromStr for RuneId { } } -impl Serialize for RuneId { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.collect_str(self) - } -} - -impl<'de> Deserialize<'de> for RuneId { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - DeserializeFromStr::with(deserializer) - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/src/runes/spaced_rune.rs b/src/runes/spaced_rune.rs index c71d671a91..54c74cc10c 100644 --- a/src/runes/spaced_rune.rs +++ b/src/runes/spaced_rune.rs @@ -1,6 +1,8 @@ use super::*; -#[derive(Copy, Clone, Debug, PartialEq, Ord, PartialOrd, Eq, Default)] +#[derive( + Copy, Clone, Debug, PartialEq, Ord, PartialOrd, Eq, Default, DeserializeFromStr, SerializeDisplay, +)] pub struct SpacedRune { pub rune: Rune, pub spacers: u32, @@ -54,24 +56,6 @@ impl Display for SpacedRune { } } -impl Serialize for SpacedRune { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.collect_str(self) - } -} - -impl<'de> Deserialize<'de> for SpacedRune { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - DeserializeFromStr::with(deserializer) - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/src/subcommand/decode.rs b/src/subcommand/decode.rs index cb8581e469..551c6a7466 100644 --- a/src/subcommand/decode.rs +++ b/src/subcommand/decode.rs @@ -11,24 +11,19 @@ pub struct RawOutput { } #[derive(Serialize, Eq, PartialEq, Deserialize, Debug)] +#[serde_with::skip_serializing_none] pub struct CompactInscription { - #[serde(default, skip_serializing_if = "Option::is_none")] pub body: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] pub content_encoding: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] pub content_type: Option, #[serde(default, skip_serializing_if = "std::ops::Not::not")] pub duplicate_field: bool, #[serde(default, skip_serializing_if = "std::ops::Not::not")] pub incomplete_field: bool, - #[serde(default, skip_serializing_if = "Option::is_none")] pub metadata: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] pub metaprotocol: Option, #[serde(default, skip_serializing_if = "Vec::is_empty")] pub parents: Vec, - #[serde(default, skip_serializing_if = "Option::is_none")] pub pointer: Option, #[serde(default, skip_serializing_if = "std::ops::Not::not")] pub unrecognized_even_field: bool,