-
Notifications
You must be signed in to change notification settings - Fork 66
Enable PacketBuilder in no_std (alloc/slice) while preserving std API #135
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| use crate::err::{ipv4_exts, ipv6_exts, SliceWriteSpaceError, ValueTooBigError}; | ||
|
|
||
| /// Error while serializing a packet into a byte slice. | ||
| #[derive(Clone, Debug, Eq, PartialEq, Hash)] | ||
| pub enum BuildSliceWriteError { | ||
| /// Not enough space is available in the target slice. | ||
| /// Contains the minimum required length. | ||
| Space(usize), | ||
|
|
||
| /// Error if the length of the payload is too | ||
| /// big to be representable by the length fields. | ||
| PayloadLen(ValueTooBigError<usize>), | ||
|
|
||
| /// Error if the IPv4 extensions can not be serialized | ||
| /// because of internal consistency errors. | ||
| Ipv4Exts(ipv4_exts::ExtsWalkError), | ||
|
|
||
| /// Error if the IPv6 extensions can not be serialized | ||
| /// because of internal consistency errors. | ||
| Ipv6Exts(ipv6_exts::ExtsWalkError), | ||
|
|
||
| /// Error if ICMPv6 is packaged in an IPv4 packet (it is undefined | ||
| /// how to calculate the checksum). | ||
| Icmpv6InIpv4, | ||
|
|
||
| /// Address size defined in the ARP header does not match the actual size. | ||
| ArpHeaderNotMatch, | ||
| } | ||
|
|
||
| impl From<ValueTooBigError<usize>> for BuildSliceWriteError { | ||
| fn from(value: ValueTooBigError<usize>) -> Self { | ||
| BuildSliceWriteError::PayloadLen(value) | ||
| } | ||
| } | ||
|
|
||
| impl From<SliceWriteSpaceError> for BuildSliceWriteError { | ||
| fn from(value: SliceWriteSpaceError) -> Self { | ||
| BuildSliceWriteError::Space(value.required_len) | ||
| } | ||
| } | ||
|
|
||
| impl From<super::TransportChecksumError> for BuildSliceWriteError { | ||
| fn from(value: super::TransportChecksumError) -> Self { | ||
| match value { | ||
| super::TransportChecksumError::PayloadLen(err) => BuildSliceWriteError::PayloadLen(err), | ||
| super::TransportChecksumError::Icmpv6InIpv4 => BuildSliceWriteError::Icmpv6InIpv4, | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl From<crate::WriteError<SliceWriteSpaceError, ipv4_exts::ExtsWalkError>> | ||
| for BuildSliceWriteError | ||
| { | ||
| fn from(value: crate::WriteError<SliceWriteSpaceError, ipv4_exts::ExtsWalkError>) -> Self { | ||
| match value { | ||
| crate::WriteError::Io(err) => BuildSliceWriteError::Space(err.required_len), | ||
| crate::WriteError::Content(err) => BuildSliceWriteError::Ipv4Exts(err), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl From<crate::WriteError<SliceWriteSpaceError, ipv6_exts::ExtsWalkError>> | ||
| for BuildSliceWriteError | ||
| { | ||
| fn from(value: crate::WriteError<SliceWriteSpaceError, ipv6_exts::ExtsWalkError>) -> Self { | ||
| match value { | ||
| crate::WriteError::Io(err) => BuildSliceWriteError::Space(err.required_len), | ||
| crate::WriteError::Content(err) => BuildSliceWriteError::Ipv6Exts(err), | ||
| } | ||
| } | ||
| } | ||
|
Comment on lines
+36
to
+71
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Find any code that constructs/returns BuildSliceWriteError from a SliceWriteSpaceError
# or from WriteError<SliceWriteSpaceError, _>.
rg -nP -C3 'SliceWriteSpaceError' --type=rust
echo '--- call sites returning BuildSliceWriteError ---'
rg -nP -C2 'BuildSliceWriteError' --type=rust
echo '--- SliceCoreWriteError usage ---'
rg -nP -C2 'SliceCoreWriteError' --type=rustRepository: JulianSchmid/etherparse Length of output: 25197 🏁 Script executed: # Search for places where SliceWriteSpaceError is converted to BuildSliceWriteError
# Look for .into() calls, ? operators, or explicit From::from calls
rg -n 'SliceWriteSpaceError' --type=rust -A 5 | grep -E '(\.into\(\)|\.from\(|BuildSliceWriteError)' -B 2 -A 1
# Also check if there are tests specifically for these From impls
fd -e rs --type f | xargs grep -l 'BuildSliceWriteError' | xargs grep -l 'SliceWriteSpaceError'
# Search for uses of the individual header write_to_slice methods
rg 'write_to_slice' --type=rust -B 2 -A 3Repository: JulianSchmid/etherparse Length of output: 11984 🏁 Script executed: # Check visibility and how BuildSliceWriteError is exported
rg -n 'pub.*BuildSliceWriteError' --type=rust
# Check the error enum structure and variant documentation
cat -n etherparse/src/err/packet/build_slice_write_error.rs | head -35
# Check if there's any documentation suggesting these conversions should be used
rg -B 3 'From<SliceWriteSpaceError>' etherparse/src/err/packet/build_slice_write_error.rs
# Look for any public API that might return these error types mixed
rg 'pub.*fn.*BuildSliceWriteError' --type=rust -A 2Repository: JulianSchmid/etherparse Length of output: 2029 Remove unused The three 🤖 Prompt for AI Agents |
||
|
|
||
| impl core::fmt::Display for BuildSliceWriteError { | ||
| fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | ||
| use BuildSliceWriteError::*; | ||
| match self { | ||
| Space(required_len) => write!( | ||
| f, | ||
| "Not enough space to write packet to slice. Needed {} byte(s).", | ||
| required_len | ||
| ), | ||
| PayloadLen(err) => err.fmt(f), | ||
| Ipv4Exts(err) => err.fmt(f), | ||
| Ipv6Exts(err) => err.fmt(f), | ||
| ArpHeaderNotMatch => write!( | ||
| f, | ||
| "address size defined in the ARP header does not match the actual size" | ||
| ), | ||
| Icmpv6InIpv4 => write!( | ||
| f, | ||
| "Error: ICMPv6 can not be combined with an IPv4 header (checksum can not be calculated)." | ||
| ), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl core::error::Error for BuildSliceWriteError { | ||
| fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { | ||
| use BuildSliceWriteError::*; | ||
| match self { | ||
| Space(_) => None, | ||
| PayloadLen(err) => Some(err), | ||
| Ipv4Exts(err) => Some(err), | ||
| Ipv6Exts(err) => Some(err), | ||
| Icmpv6InIpv4 => None, | ||
| ArpHeaderNotMatch => None, | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| use crate::err::{ipv4_exts, ipv6_exts, ValueTooBigError}; | ||
| use core::convert::Infallible; | ||
|
|
||
| /// Error while serializing a packet into a [`alloc::vec::Vec`]. | ||
| #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] | ||
| #[derive(Clone, Debug, Eq, PartialEq, Hash)] | ||
| pub enum BuildVecWriteError { | ||
|
coderabbitai[bot] marked this conversation as resolved.
JulianSchmid marked this conversation as resolved.
|
||
| /// Error if the length of the payload is too | ||
| /// big to be representable by the length fields. | ||
| PayloadLen(ValueTooBigError<usize>), | ||
|
|
||
| /// Error if the IPv4 extensions can not be serialized | ||
| /// because of internal consistency errors. | ||
| Ipv4Exts(ipv4_exts::ExtsWalkError), | ||
|
|
||
| /// Error if the IPv6 extensions can not be serialized | ||
| /// because of internal consistency errors. | ||
| Ipv6Exts(ipv6_exts::ExtsWalkError), | ||
|
|
||
| /// Error if ICMPv6 is packaged in an IPv4 packet (it is undefined | ||
| /// how to calculate the checksum). | ||
| Icmpv6InIpv4, | ||
|
|
||
| /// Address size defined in the ARP header does not match the actual size. | ||
| ArpHeaderNotMatch, | ||
| } | ||
|
|
||
| impl From<Infallible> for BuildVecWriteError { | ||
| fn from(value: Infallible) -> Self { | ||
| match value {} | ||
| } | ||
| } | ||
|
|
||
| impl From<ValueTooBigError<usize>> for BuildVecWriteError { | ||
| fn from(value: ValueTooBigError<usize>) -> Self { | ||
| BuildVecWriteError::PayloadLen(value) | ||
| } | ||
| } | ||
|
|
||
| impl From<super::TransportChecksumError> for BuildVecWriteError { | ||
| fn from(value: super::TransportChecksumError) -> Self { | ||
| match value { | ||
| super::TransportChecksumError::PayloadLen(err) => BuildVecWriteError::PayloadLen(err), | ||
| super::TransportChecksumError::Icmpv6InIpv4 => BuildVecWriteError::Icmpv6InIpv4, | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl From<crate::WriteError<Infallible, ipv4_exts::ExtsWalkError>> for BuildVecWriteError { | ||
| fn from(value: crate::WriteError<Infallible, ipv4_exts::ExtsWalkError>) -> Self { | ||
| match value { | ||
| crate::WriteError::Io(err) => match err {}, | ||
| crate::WriteError::Content(err) => BuildVecWriteError::Ipv4Exts(err), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl From<crate::WriteError<Infallible, ipv6_exts::ExtsWalkError>> for BuildVecWriteError { | ||
| fn from(value: crate::WriteError<Infallible, ipv6_exts::ExtsWalkError>) -> Self { | ||
| match value { | ||
| crate::WriteError::Io(err) => match err {}, | ||
| crate::WriteError::Content(err) => BuildVecWriteError::Ipv6Exts(err), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl core::fmt::Display for BuildVecWriteError { | ||
| fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | ||
| use BuildVecWriteError::*; | ||
| match self { | ||
| PayloadLen(err) => err.fmt(f), | ||
| Ipv4Exts(err) => err.fmt(f), | ||
| Ipv6Exts(err) => err.fmt(f), | ||
| ArpHeaderNotMatch => write!( | ||
| f, | ||
| "address size defined in the ARP header does not match the actual size" | ||
| ), | ||
| Icmpv6InIpv4 => write!( | ||
| f, | ||
| "Error: ICMPv6 can not be combined with an IPv4 headers (checksum can not be calculated)." | ||
| ), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl core::error::Error for BuildVecWriteError { | ||
| fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { | ||
| use BuildVecWriteError::*; | ||
| match self { | ||
| PayloadLen(err) => Some(err), | ||
| Ipv4Exts(err) => Some(err), | ||
| Ipv6Exts(err) => Some(err), | ||
| Icmpv6InIpv4 => None, | ||
| ArpHeaderNotMatch => None, | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clean up the new public error text.
The IPv4 extension docs end with an incomplete sentence, and the ICMPv6/IPv4 display message has a grammar issue.
📝 Proposed wording cleanup
Also applies to: 90-92
🤖 Prompt for AI Agents