-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add const generic support #52
Comments
Heya, sorry for the late reply. Const generics are not implemented in the derive but the EString is fairly simple you can implement Serialize like this: impl<const N: usize> Serialize for EString<N> {
fn json_write<W>(&self, writer: &mut W) -> simd_json_derive::Result
where
W: std::io::Write,
{
self.0.json_write(writer)
}
} Adding it to the derive, while not impossible I think, might be a bit tricky and I don't have tons of time at the moment :( NOTE: I ran this example and it gives UTF8 Error, is the string valid UTF8, it fails while decoding from what I can tell? |
Thanks for getting back! EDIT: _field1: u64,
_field2: u32, .. to just print some val, and not an array. Header {
len: 432,
_field1: 33045482017786,
_field2: 18948879,
want: EString(
"S0W1",
),
} |
This is the whole code that compiles for me, but the inout seems to be invalid as the funk function crashes: use binrw::BinRead;
use simd_json_derive::Serialize;
use std::io::Cursor;
pub fn funk(bytes: &[u8]) -> String {
String::from_utf8(Vec::from(bytes)).unwrap()
}
#[derive(Debug, PartialEq, BinRead)]
pub struct EString<const N: usize>(#[br(map = |bytes: [u8; N]| funk(&bytes))] String);
impl<const N: usize> Serialize for EString<N> {
fn json_write<W>(&self, writer: &mut W) -> simd_json_derive::Result
where
W: std::io::Write,
{
self.0.json_write(writer)
}
}
#[derive(Debug, PartialEq, BinRead, Serialize)]
#[br(big)]
pub struct Header {
len: u16,
_field: [u8; 12],
want: EString<4>,
// want: u32,
}
fn main() {
let rec = vec![
0x01, 0xB0, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x37, 0x93, 0xfa, 0x01, 0x21, 0x23, 0x0f, 0xe2,
0xf0, 0xe6, 0xf1,
];
let value = Header::read(&mut Cursor::new(rec)).unwrap();
dbg!(&value);
// value.json_string().unwrap()
println!("\n{}", value.json_string().unwrap());
} |
Oh, didn't notice that #[derive(Debug, PartialEq, BinRead)]
pub struct EString<const N: usize>(#[br(map = |bytes: [u8; N]| funk(&bytes))] String); Thank you, this is amazing! |
nice glad we got that working and it's really cool to hear this could cut the execution time in half :D |
Now for a dumb question - say I have loads of these - Can I do something like - |
if they're all the same do they need to be different sturcts? (could you give examples of how CustmField1 and 2 are looking?) |
I'm invoking different map functions on them though: #[derive(Debug, PartialEq, BinRead)]
pub struct CustomType1 (
#[br(map = yyyyddd)]
String,
);
#[derive(Debug, PartialEq, BinRead)]
pub struct CustomType2(
#[br(map = hhmmss)]
String
); ... and in the main tme: CustomType1,
dte: CustomType2, ... so the below is repetitive: impl Serialize for CustomType1 {
fn json_write<W>(&self, writer: &mut W) -> simd_json_derive::Result
where
W: std::io::Write,
{
self.0.json_write(writer)
}
}
impl Serialize for CustomType2 {
fn json_write<W>(&self, writer: &mut W) -> simd_json_derive::Result
where
W: std::io::Write,
{
self.0.json_write(writer)
}
} |
Ah I see, one way to deal with that is making a macro for it something like (the syntax might be slightly off): macro_rules! string_type {
( $x:ident ) => {
impl Serialize for $x {
fn json_write<W>(&self, writer: &mut W) -> simd_json_derive::Result
where
W: std::io::Write,
{
self.0.json_write(writer)
}
}
};
}
string_type!(CustomType1);
string_type!(CustomType2); |
If I implement a wrapper struct like this: pub struct CustomStuff {
#[br(map=funk1)
tme: Custom1,
#[br(map=funk2)
dte: Custom2,
} and then in tme: CustomStuff.Custom1,
dte: CustomStuff.Custom2, so I can impl Serialize for CustomStuff {
fn json_write<W>(&self, writer: &mut W) -> simd_json_derive::Result
where
W: std::io::Write,
{
self.tme.0.json_write(writer)
}
} ... note that it has to have |
that would be something that needs flattening and be implemented in the upper level, so you'd either need to hand roll the entire serializer to not use the wrapper |
Can't say I understand fully but I'm glad the macro you've shared works. |
Thank you :)! I'll rename the issue if you don't mind to better capture that support or const generics would be nice. |
@Licenser Similar to the Serialize impl in this comment, I attempted to impl for a unit struct with a field that uses const generic like so: pub struct OString<const L: usize>(
#[br(map = fenk)]
String<L>
); ... where And when I try to impl, it says So... I think this comment is still relevant to this new issue name (const generic support). PS: Another item in the wishlist - Serialize impl for types from the speedate crate. |
Hello @Licenser!
Thank you for sharing your excellent work.
I'm delighted to see that this crate shaves off about half the run time when parsing a huge binary file into structs, then into JSON.
As a novice programmer in general, I'm quite stuck by the below error.
When you have time, could you please help?
Code to reproduce:
Happy output:
When the
EString
struct is commented out, and whenHeader.want
ofu32
is used instead ofEString<4>
.{"len":432,"_field":[0,0,30,14,0,55,147,250,1,33,35,15],"want":3807438577}
Sad output:
The text was updated successfully, but these errors were encountered: