Skip to content
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

Fixes for 427 #428

Merged
merged 4 commits into from
Nov 7, 2021
Merged

Fixes for 427 #428

merged 4 commits into from
Nov 7, 2021

Conversation

VictorKoenders
Copy link
Contributor

#427 uncovered some issues.

  1. if there is a newline in a doc comment, rust's token stream feeds us 2x '#' in a row with no attribute group. bincode_derive now handles this correctly
  2. bincode_derive now supports min_const_generics
  3. bincode_derive now supports c-style enums where the variants have a fixed value

For 3 I have made it so that bincode_derive outputs code like this:

CStyleEnum output
enum CStyleEnum {
    A = 1,
    B = 2,
    C,
    D = 5,
    E,
}


impl bincode::de::Decode for CStyleEnum {
    fn decode<D: bincode::de::Decoder>(
        mut decoder: D,
    ) -> Result<Self, bincode::error::DecodeError> {
        let variant_index = <u32 as bincode::de::Decode>::decode(&mut decoder)?;
        match variant_index {
            1 => Ok(Self::A {}),
            2 => Ok(Self::B {}),
            x if x == 2 + 1u32 => Ok(Self::C {}),
            5 => Ok(Self::D {}),
            x if x == 5 + 1u32 => Ok(Self::E {}),
            variant => Err(bincode::error::DecodeError::UnexpectedVariant {
                found: variant,
                type_name: "CStyleEnum",
                allowed: bincode::error::AllowedEnumVariants::Allowed(&[
                    1,
                    2,
                    2 + 1u32,
                    5,
                    5 + 1u32,
                ]),
            }),
        }
    }
}

impl bincode::enc::Encode for CStyleEnum {
    fn encode<E: bincode::enc::Encoder>(
        &self,
        mut encoder: E,
    ) -> core::result::Result<(), bincode::error::EncodeError> {
        match self {
            Self::A => {
                <u32 as bincode::enc::Encode>::encode(&(1), &mut encoder)?;
            }
            Self::B => {
                <u32 as bincode::enc::Encode>::encode(&(2), &mut encoder)?;
            }
            Self::C => {
                <u32 as bincode::enc::Encode>::encode(&(2 + 1u32), &mut encoder)?;
            }
            Self::D => {
                <u32 as bincode::enc::Encode>::encode(&(5), &mut encoder)?;
            }
            Self::E => {
                <u32 as bincode::enc::Encode>::encode(&(5 + 1u32), &mut encoder)?;
            }
        }
        Ok(())
    }
}

@VictorKoenders
Copy link
Contributor Author

@haata the only thing that is left of #427 is that heapless::Vec does not support Decode/Encode for now. I think it's be best to use a wrapper for this that implements Decode/Encode. Something like:

#[repr(transparent)]
struct BincodeVec<T, const N: usize>(heapless::Vec<T, N>);

impl<T: Decode + Default, const N: usize> Decode for BincodeVec<T, N> {
    fn decode<D: bincode::de::Decoder>(
        mut decoder: D,
    ) -> Result<Self, bincode::error::DecodeError> {
        let len = usize::decode(&mut decoder)?;
        let mut vec = heapless::Vec::default();
        for _ in 0..len {
            // TODO: handle the heapless error?
            let _ = vec.push(T::decode(&mut decoder)?);
        }
        Ok(Self(vec))
    }
}

impl<T: Encode, const N: usize> Encode for BincodeVec<T, N> {
    fn encode<E: bincode::enc::Encoder>(
        &self,
        mut encoder: E,
    ) -> Result<(), bincode::error::EncodeError> {
        self.0.len().encode(&mut encoder)?;
        for val in self.0.iter() {
            val.encode(&mut encoder)?;
        }
        Ok(())
    }
}

@codecov-commenter
Copy link

Codecov Report

Merging #428 (57ed145) into trunk (4120069) will decrease coverage by 1.75%.
The diff coverage is 31.57%.

Impacted file tree graph

@@            Coverage Diff             @@
##            trunk     #428      +/-   ##
==========================================
- Coverage   71.04%   69.28%   -1.76%     
==========================================
  Files          41       41              
  Lines        2811     2924     +113     
==========================================
+ Hits         1997     2026      +29     
- Misses        814      898      +84     
Impacted Files Coverage Δ
derive/src/derive_enum.rs 0.00% <0.00%> (ø)
derive/src/generate/stream_builder.rs 0.00% <ø> (ø)
derive/src/lib.rs 7.40% <0.00%> (ø)
derive/src/parse/mod.rs 90.74% <0.00%> (-5.34%) ⬇️
src/de/impls.rs 76.47% <0.00%> (+0.88%) ⬆️
src/error.rs 0.00% <ø> (ø)
src/features/impl_std.rs 72.86% <0.00%> (+1.11%) ⬆️
derive/src/parse/body.rs 68.24% <25.58%> (-4.11%) ⬇️
derive/src/parse/generics.rs 62.45% <52.23%> (-4.50%) ⬇️
derive/src/parse/attributes.rs 62.06% <55.00%> (-11.85%) ⬇️
... and 4 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 4120069...57ed145. Read the comment docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants