Skip to content

Commit

Permalink
Add no-assert-string feature
Browse files Browse the repository at this point in the history
When no-assert-string is enabled, remove string generation in .rodata section.
When writing parsers made for embedded platforms that are limited in storage
these strings add up when many assertions are added.
  • Loading branch information
wcampbell0x2a committed Jan 17, 2024
1 parent f568eca commit 9ca16f0
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 32 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ default = ["std"]
std = ["deku_derive/std", "bitvec/std", "alloc", "no_std_io/std"]
alloc = ["bitvec/alloc"]
logging = ["deku_derive/logging", "log"]
no-assert-string = ["deku_derive/no-assert-string"]

[dependencies]
deku_derive = { version = "^0.16.0", path = "deku-derive", default-features = false}
Expand Down
1 change: 1 addition & 0 deletions deku-derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ proc-macro = true
[features]
std = ["proc-macro-crate"]
logging = []
no-assert-string = []

[dependencies]
quote = "1.0"
Expand Down
22 changes: 6 additions & 16 deletions deku-derive/src/macros/deku_read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ use crate::macros::{
};
use crate::{DekuData, DekuDataEnum, DekuDataStruct, FieldData, Id};

use super::assertion_failed;

pub(crate) fn emit_deku_read(input: &DekuData) -> Result<TokenStream, syn::Error> {
match &input.data {
Data::Enum(_) => emit_enum(input),
Expand Down Expand Up @@ -566,31 +568,19 @@ fn emit_field_read(
let internal_field_ident = gen_internal_field_ident(&field_ident);

let field_assert = f.assert.as_ref().map(|v| {
let return_error = assertion_failed(v, &ident, &field_ident_str, None);
quote! {
if (!(#v)) {
// assertion is false, raise error
return Err(::#crate_::DekuError::Assertion(format!(
"{}.{} field failed assertion: {}",
#ident,
#field_ident_str,
stringify!(#v)
)));
} else {
// do nothing
#return_error
}
}
});

let field_assert_eq = f.assert_eq.as_ref().map(|v| {
let return_error = assertion_failed(v, &ident, &field_ident_str, Some(&field_ident));
quote! {
if (!(#internal_field_ident == (#v))) {
// assertion is false, raise error
return Err(::#crate_::DekuError::Assertion(format!(
"{}.{} field failed assertion: {}",
#ident,
#field_ident_str,
stringify!(#field_ident == #v)
)));
#return_error
} else {
// do nothing
}
Expand Down
22 changes: 6 additions & 16 deletions deku-derive/src/macros/deku_write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use proc_macro2::TokenStream;
use quote::quote;

use crate::macros::{
gen_ctx_types_and_arg, gen_field_args, gen_struct_destruction, pad_bits, token_contains_string,
wrap_default_ctx,
assertion_failed, gen_ctx_types_and_arg, gen_field_args, gen_struct_destruction, pad_bits,
token_contains_string, wrap_default_ctx,
};
use crate::{DekuData, DekuDataEnum, DekuDataStruct, FieldData, Id};

Expand Down Expand Up @@ -497,31 +497,21 @@ fn emit_field_write(
let field_ident_str = field_ident.to_string();

let field_assert = f.assert.as_ref().map(|v| {
let return_error = assertion_failed(v, ident, &field_ident_str, None);
quote! {
if (!(#v)) {
// assertion is false, raise error
return Err(::#crate_::DekuError::Assertion(format!(
"{}.{} field failed assertion: {}",
#ident,
#field_ident_str,
stringify!(#v)
)));
#return_error
} else {
// do nothing
}
}
});

let field_assert_eq = f.assert_eq.as_ref().map(|v| {
let return_error = assertion_failed(v, ident, &field_ident_str, Some(&field_ident));
quote! {
if (!(*(#field_ident) == (#v))) {
// assertion is false, raise error
return Err(::#crate_::DekuError::Assertion(format!(
"{}.{} field failed assertion: {}",
#ident,
#field_ident_str,
stringify!(#field_ident == #v)
)));
#return_error
} else {
// do nothing
}
Expand Down
32 changes: 32 additions & 0 deletions deku-derive/src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,3 +344,35 @@ fn pad_bits(
(None, None) => quote!(),
}
}

/// assertion is false, raise error
fn assertion_failed(
v: &TokenStream,
ident: &str,
field_ident_str: &str,
field_ident: Option<&TokenStream>,
) -> TokenStream {
let crate_ = get_crate_name();
let stringify = if let Some(field_ident) = field_ident {
quote! { stringify!(#field_ident == #v) }
} else {
quote! { stringify!(#v) }
};
#[cfg(feature = "no-assert-string")]
{
quote! {
return Err(::#crate_::DekuError::AssertionNoStr);
}
}
#[cfg(not(feature = "no-assert-string"))]
{
quote! {
return Err(::#crate_::DekuError::Assertion(format!(
"{}.{} field failed assertion: {}",
#ident,
#field_ident_str,
#stringify,
)));
}
}
}
4 changes: 4 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ pub enum DekuError {
Unexpected(String),
/// Assertion error from `assert` or `assert_eq` attributes
Assertion(String),
/// Assertion error from `assert` or `assert_eq` attributes, without string
AssertionNoStr,
/// Could not resolve `id` for variant
IdVariantNotFound,
}
Expand Down Expand Up @@ -77,6 +79,7 @@ impl core::fmt::Display for DekuError {
DekuError::InvalidParam(ref err) => write!(f, "Invalid param error: {err}"),
DekuError::Unexpected(ref err) => write!(f, "Unexpected error: {err}"),
DekuError::Assertion(ref err) => write!(f, "Assertion error: {err}"),
DekuError::AssertionNoStr => write!(f, "Assertion error"),
DekuError::IdVariantNotFound => write!(f, "Could not resolve `id` for variant"),
}
}
Expand All @@ -99,6 +102,7 @@ impl From<DekuError> for std::io::Error {
DekuError::InvalidParam(_) => io::Error::new(io::ErrorKind::InvalidInput, error),
DekuError::Unexpected(_) => io::Error::new(io::ErrorKind::Other, error),
DekuError::Assertion(_) => io::Error::new(io::ErrorKind::InvalidData, error),
DekuError::AssertionNoStr => io::Error::from(io::ErrorKind::InvalidData),
DekuError::IdVariantNotFound => io::Error::new(io::ErrorKind::NotFound, error),
}
}
Expand Down

0 comments on commit 9ca16f0

Please sign in to comment.