From 8e50099a18d9ca185d8356fd37447ac6e800ba31 Mon Sep 17 00:00:00 2001 From: fi3 Date: Mon, 19 Aug 2024 11:03:54 +0200 Subject: [PATCH] Add support for data types defined by sv2 extensions In no-serde-sv2 an sv2 sequence is generic over T. If we want this sequence to be Deserialize we need T to be Fixed and GerMarker. This 2 traits were private since all the sv2 types are already defined in no-serde-sv2. But if we want to use sv2 types defined in an sv2 extensions we need to make these traits public. The Encodable dervive macro in derive_codec implement GetSize for the passed struct. But GetSize is also a blanket implementation for every type that implement Fixed. So if we implement Fixed for our new sv2 type and then we derive Encodable (commonly renamed Serialize) we get an error. This commit add an attribute to Encodable called already_sized if the struct that we want derive Encodable is market as already_sized the macro will not implement GetSize for it. This commit also bump minor version of derive_codec and no-serde-sv2 consequentially also of binary-sv2 since it reexport the above libs. --- protocols/Cargo.lock | 6 +- protocols/v2/binary-sv2/binary-sv2/Cargo.toml | 2 +- .../binary-sv2/no-serde-sv2/codec/Cargo.toml | 2 +- .../binary-sv2/no-serde-sv2/codec/src/lib.rs | 8 +-- .../no-serde-sv2/derive_codec/Cargo.toml | 2 +- .../no-serde-sv2/derive_codec/src/lib.rs | 59 +++++++++++++------ roles/Cargo.lock | 4 +- 7 files changed, 52 insertions(+), 31 deletions(-) diff --git a/protocols/Cargo.lock b/protocols/Cargo.lock index 9e04903ff..1f853f4ad 100644 --- a/protocols/Cargo.lock +++ b/protocols/Cargo.lock @@ -77,7 +77,7 @@ checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" [[package]] name = "binary_codec_sv2" -version = "1.0.0" +version = "1.1.0" dependencies = [ "buffer_sv2", "quickcheck", @@ -85,7 +85,7 @@ dependencies = [ [[package]] name = "binary_sv2" -version = "1.0.1" +version = "1.1.0" dependencies = [ "binary_codec_sv2", "derive_codec_sv2", @@ -260,7 +260,7 @@ dependencies = [ [[package]] name = "derive_codec_sv2" -version = "1.0.0" +version = "1.1.0" dependencies = [ "binary_codec_sv2", ] diff --git a/protocols/v2/binary-sv2/binary-sv2/Cargo.toml b/protocols/v2/binary-sv2/binary-sv2/Cargo.toml index 1fd78fcc1..b8742ad48 100644 --- a/protocols/v2/binary-sv2/binary-sv2/Cargo.toml +++ b/protocols/v2/binary-sv2/binary-sv2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "binary_sv2" -version = "1.0.1" +version = "1.1.0" authors = ["fi3 "] edition = "2018" description = "Sv2 data format" diff --git a/protocols/v2/binary-sv2/no-serde-sv2/codec/Cargo.toml b/protocols/v2/binary-sv2/no-serde-sv2/codec/Cargo.toml index 5f1f83e12..d564c96be 100644 --- a/protocols/v2/binary-sv2/no-serde-sv2/codec/Cargo.toml +++ b/protocols/v2/binary-sv2/no-serde-sv2/codec/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "binary_codec_sv2" -version = "1.0.0" +version = "1.1.0" authors = ["fi3 "] edition = "2018" description = "Sv2 data format" diff --git a/protocols/v2/binary-sv2/no-serde-sv2/codec/src/lib.rs b/protocols/v2/binary-sv2/no-serde-sv2/codec/src/lib.rs index 8f7d96e62..2199d47e7 100644 --- a/protocols/v2/binary-sv2/no-serde-sv2/codec/src/lib.rs +++ b/protocols/v2/binary-sv2/no-serde-sv2/codec/src/lib.rs @@ -25,14 +25,14 @@ use std::io::{Error as E, ErrorKind}; mod codec; mod datatypes; pub use datatypes::{ - PubKey, Seq0255, Seq064K, ShortTxId, Signature, Str0255, Sv2Option, U32AsRef, B016M, B0255, - B032, B064K, U24, U256, + PubKey, Seq0255, Seq064K, ShortTxId, Signature, Str0255, Sv2DataType, Sv2Option, U32AsRef, + B016M, B0255, B032, B064K, U24, U256, }; pub use crate::codec::{ - decodable::Decodable, + decodable::{Decodable, GetMarker}, encodable::{Encodable, EncodableField}, - GetSize, SizeHint, + Fixed, GetSize, SizeHint, }; #[allow(clippy::wrong_self_convention)] diff --git a/protocols/v2/binary-sv2/no-serde-sv2/derive_codec/Cargo.toml b/protocols/v2/binary-sv2/no-serde-sv2/derive_codec/Cargo.toml index 62e62bd9c..93f202d8b 100644 --- a/protocols/v2/binary-sv2/no-serde-sv2/derive_codec/Cargo.toml +++ b/protocols/v2/binary-sv2/no-serde-sv2/derive_codec/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "derive_codec_sv2" -version = "1.0.0" +version = "1.1.0" authors = ["fi3 "] edition = "2018" description = "Derive macro for Sv2 binary format serializer and deserializer" diff --git a/protocols/v2/binary-sv2/no-serde-sv2/derive_codec/src/lib.rs b/protocols/v2/binary-sv2/no-serde-sv2/derive_codec/src/lib.rs index 6821abb6a..aef883ba1 100644 --- a/protocols/v2/binary-sv2/no-serde-sv2/derive_codec/src/lib.rs +++ b/protocols/v2/binary-sv2/no-serde-sv2/derive_codec/src/lib.rs @@ -2,6 +2,24 @@ extern crate proc_macro; use core::iter::FromIterator; use proc_macro::{Group, TokenStream, TokenTree}; +fn is_already_sized(item: TokenStream) -> bool { + let stream = item.into_iter(); + + for next in stream { + if let TokenTree::Group(g) = next.clone() { + if g.delimiter() == proc_macro::Delimiter::Bracket { + for t in g.stream().into_iter() { + if let TokenTree::Ident(i) = t { + if i.to_string() == "already_sized" { + return true; + } + } + } + } + } + } + false +} fn remove_attributes(item: TokenStream) -> TokenStream { let stream = item.into_iter(); let mut is_attribute = false; @@ -356,8 +374,9 @@ fn get_static_generics(gen: &str) -> &str { } } -#[proc_macro_derive(Encodable)] +#[proc_macro_derive(Encodable, attributes(already_sized))] pub fn encodable(item: TokenStream) -> TokenStream { + let is_already_sized = is_already_sized(item.clone()); let parsed_struct = get_struct_properties(item); let fields = parsed_struct.fields.clone(); @@ -392,6 +411,23 @@ pub fn encodable(item: TokenStream) -> TokenStream { "<'decoder>".to_string() }; + let get_size = if is_already_sized { + String::new() + } else { + format!( + " + impl{} GetSize for {}{} {{ + fn get_size(&self) -> usize {{ + let mut size = 0; + {} + size + }} + }} + ", + impl_generics, parsed_struct.name, parsed_struct.generics, sizes + ) + }; + let result = format!( "mod impl_parse_encodable_{} {{ @@ -408,14 +444,7 @@ pub fn encodable(item: TokenStream) -> TokenStream { }} }} - - impl{} GetSize for {}{} {{ - fn get_size(&self) -> usize {{ - let mut size = 0; - {} - size - }} - }} + {} }}", // imports @@ -428,16 +457,8 @@ pub fn encodable(item: TokenStream) -> TokenStream { parsed_struct.name, parsed_struct.generics, field_into_decoded_field, - // impl Encodable for Struct - //impl{} Encodable<'decoder> for {}{} {{}} - //impl_generics, - //parsed_struct.name, - //parsed_struct.generics, - // impl GetSize for Struct - impl_generics, - parsed_struct.name, - parsed_struct.generics, - sizes, + // impl get_size + get_size, ); //println!("{}", result); diff --git a/roles/Cargo.lock b/roles/Cargo.lock index e0dfec0c1..d46de28ea 100644 --- a/roles/Cargo.lock +++ b/roles/Cargo.lock @@ -373,14 +373,14 @@ checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" [[package]] name = "binary_codec_sv2" -version = "1.0.0" +version = "1.1.0" dependencies = [ "buffer_sv2", ] [[package]] name = "binary_sv2" -version = "1.0.1" +version = "1.1.0" dependencies = [ "binary_codec_sv2", "derive_codec_sv2",