diff --git a/Cargo-recent.lock b/Cargo-recent.lock index c56d0661..5455afee 100644 --- a/Cargo-recent.lock +++ b/Cargo-recent.lock @@ -212,6 +212,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd" +[[package]] +name = "itoa" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" + [[package]] name = "jobserver" version = "0.1.34" @@ -451,6 +457,19 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + [[package]] name = "shlex" version = "1.3.0" @@ -503,6 +522,7 @@ dependencies = [ "miniscript", "santiago", "serde", + "serde_json", "simplicity-sys 0.6.1", ] @@ -626,3 +646,9 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/Cargo.toml b/Cargo.toml index 076b1f9a..9420f8fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,6 +40,7 @@ getrandom = { version = "0.2", features = ["js"] } simplicity-sys = { version = "0.6.1", path = "./simplicity-sys", features = [ "test-utils", ] } +serde_json = "1.0.149" [workspace] members = ["simpcli", "simplicity-sys", "fuzz"] diff --git a/src/bit_encoding/encode.rs b/src/bit_encoding/encode.rs index 890dff71..1c024bcd 100644 --- a/src/bit_encoding/encode.rs +++ b/src/bit_encoding/encode.rs @@ -347,7 +347,7 @@ mod test { let mut w = BitWriter::from(&mut sink); encode_natural(n, &mut w).expect("encoding to vector"); w.flush_all().expect("flushing"); - let m = BitIter::from(sink.into_iter()) + let m: usize = BitIter::from(sink.into_iter()) .read_natural(None) .expect("decoding from vector"); assert_eq!(n, m); diff --git a/src/lib.rs b/src/lib.rs index 15385bae..4f9b7951 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -96,6 +96,8 @@ mod merkle; pub mod node; #[cfg(feature = "elements")] pub mod policy; +#[cfg(feature = "serde")] +pub mod serializers; pub mod types; mod value; diff --git a/src/serializers/mod.rs b/src/serializers/mod.rs new file mode 100644 index 00000000..99f6ea8b --- /dev/null +++ b/src/serializers/mod.rs @@ -0,0 +1 @@ +pub mod stringify; diff --git a/src/serializers/stringify.rs b/src/serializers/stringify.rs new file mode 100644 index 00000000..fb633e38 --- /dev/null +++ b/src/serializers/stringify.rs @@ -0,0 +1,58 @@ +/// This module provides a generic serializer that serializes any type T: +/// Display as a string and can be used with `#[serde(with = +/// "simplicity::serializers::stringify")` over a struct field that implements +/// `std::fmt::Display`. +/// +///```rust +/// use simplicity::Value; +/// +/// #[derive(serde::Serialize)] +/// struct Foo { +/// #[serde(with = "simplicity::serializers::stringify")] +/// v: Value, +/// } +/// +/// assert_eq!( +/// serde_json::to_value(&Foo { v: Value::u1(0) }).unwrap(), +/// serde_json::json!( { "v": "0b0" } ) +/// ); +///``` +use std::fmt::Display; + +use serde::Serializer; + +pub fn serialize(value: &T, serializer: S) -> Result +where + S: Serializer, + T: Display, +{ + serializer.serialize_str(&value.to_string()) +} + +#[cfg(test)] +mod tests { + use crate::Value; + use serde::Serialize; + + #[test] + fn can_stringify_value() { + #[derive(Serialize)] + struct Foo { + #[serde(with = "crate::serde::stringify")] + v: Value, + } + + // values taken from Value's `value_display` test + let value_string_pairs = [ + (Value::u1(0), "0b0"), + (Value::u1(1), "0b1"), + (Value::u4(6), "0x6"), + ]; + for (v, want) in value_string_pairs { + assert_eq!( + serde_json::to_value(&Foo { v }).unwrap(), + serde_json::json!({ "v": want }), + ); + } + } +}