Skip to content

Commit

Permalink
Add support for data types defined by sv2 extensions
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
fi3 committed Aug 19, 2024
1 parent 51c0330 commit 32db718
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 29 deletions.
6 changes: 3 additions & 3 deletions protocols/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion protocols/v2/binary-sv2/binary-sv2/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "binary_sv2"
version = "1.0.1"
version = "1.1.0"
authors = ["fi3 <email@email.org>"]
edition = "2018"
description = "Sv2 data format"
Expand Down
2 changes: 1 addition & 1 deletion protocols/v2/binary-sv2/no-serde-sv2/codec/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "binary_codec_sv2"
version = "1.0.0"
version = "1.1.0"
authors = ["fi3 <email@email.org>"]
edition = "2018"
description = "Sv2 data format"
Expand Down
4 changes: 2 additions & 2 deletions protocols/v2/binary-sv2/no-serde-sv2/codec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ pub use datatypes::{
};

pub use crate::codec::{
decodable::Decodable,
decodable::{Decodable, GetMarker},
encodable::{Encodable, EncodableField},
GetSize, SizeHint,
Fixed, GetSize, SizeHint,
};

#[allow(clippy::wrong_self_convention)]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "derive_codec_sv2"
version = "1.0.0"
version = "1.1.0"
authors = ["fi3 <email@email.org>"]
edition = "2018"
description = "Derive macro for Sv2 binary format serializer and deserializer"
Expand Down
65 changes: 46 additions & 19 deletions protocols/v2/binary-sv2/no-serde-sv2/derive_codec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,30 @@ 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 {
match next.clone() {
TokenTree::Group(g) => {
if g.delimiter() == proc_macro::Delimiter::Bracket {
for t in g.stream().into_iter() {
match t {
TokenTree::Ident(i) => {
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;
Expand Down Expand Up @@ -356,8 +380,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();

Expand Down Expand Up @@ -392,6 +417,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_{} {{
Expand All @@ -408,14 +450,7 @@ pub fn encodable(item: TokenStream) -> TokenStream {
}}
}}
impl{} GetSize for {}{} {{
fn get_size(&self) -> usize {{
let mut size = 0;
{}
size
}}
}}
{}
}}",
// imports
Expand All @@ -428,16 +463,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);

Expand Down
4 changes: 2 additions & 2 deletions roles/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 32db718

Please sign in to comment.