Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,31 @@ jobs:
command: test
args: --all

test_miri:
name: Miri Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
components: miri
- run: cargo miri test

test_miri_big_endian:
name: Miri Test Big Endian
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
components: miri
target: mips64-unknown-linux-gnuabi64
- run: cargo miri test --target mips64-unknown-linux-gnuabi64

examples:
name: Examples
runs-on: ubuntu-latest
Expand Down
4 changes: 2 additions & 2 deletions deku-derive/src/macros/deku_read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ fn emit_field_read(
if (!(#v)) {
// assertion is false, raise error
return Err(::#crate_::DekuError::Assertion(format!(
"field '{}' failed assertion: {}",
"field {} failed assertion: {}",
#field_ident_str,
stringify!(#v)
)));
Expand All @@ -543,7 +543,7 @@ fn emit_field_read(
if (!(#internal_field_ident == (#v))) {
// assertion is false, raise error
return Err(::#crate_::DekuError::Assertion(format!(
"field '{}' failed assertion: {}",
"field {} failed assertion: {}",
#field_ident_str,
stringify!(#field_ident == #v)
)));
Expand Down
4 changes: 2 additions & 2 deletions deku-derive/src/macros/deku_write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ fn emit_field_write(
if (!(#v)) {
// assertion is false, raise error
return Err(::#crate_::DekuError::Assertion(format!(
"field '{}' failed assertion: {}",
"field {} failed assertion: {}",
#field_ident_str,
stringify!(#v)
)));
Expand All @@ -507,7 +507,7 @@ fn emit_field_write(
if (!(*(#field_ident) == (#v))) {
// assertion is false, raise error
return Err(::#crate_::DekuError::Assertion(format!(
"field '{}' failed assertion: {}",
"field {} failed assertion: {}",
#field_ident_str,
stringify!(#field_ident == #v)
)));
Expand Down
4 changes: 2 additions & 2 deletions src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ let data: Vec<u8> = vec![0x00, 0x01, 0x02];
let value = DekuTest::try_from(data.as_ref());

assert_eq!(
Err(DekuError::Assertion("field 'data' failed assertion: * data >= 8".into())),
Err(DekuError::Assertion("field data failed assertion: * data >= 8".into())),
value
);
```
Expand Down Expand Up @@ -220,7 +220,7 @@ value.data = 0x02;
let value: Result<Vec<u8>, DekuError> = value.try_into();

assert_eq!(
Err(DekuError::Assertion("field 'data' failed assertion: data == 0x01".into())),
Err(DekuError::Assertion("field data failed assertion: data == 0x01".into())),
value
);
```
Expand Down
3 changes: 2 additions & 1 deletion src/impls/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,13 @@ where
mod tests {
use super::*;
use crate::ctx::*;
use crate::native_endian;
use rstest::rstest;

#[rstest(input, expected, expected_rest,
case(
&[0xEF, 0xBE],
Box::new(0xBEEF),
Box::new(native_endian!(0xBEEF_u16)),
bits![Msb0, u8;]
),
)]
Expand Down
3 changes: 2 additions & 1 deletion src/impls/cow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,13 @@ where
#[cfg(test)]
mod tests {
use super::*;
use crate::native_endian;
use rstest::rstest;

#[rstest(input, expected, expected_rest,
case(
&[0xEF, 0xBE],
Cow::Owned(0xBEEF),
Cow::Owned(native_endian!(0xBEEF_u16)),
bits![Msb0, u8;]
),
)]
Expand Down
49 changes: 35 additions & 14 deletions src/impls/primitive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ ImplDekuTraits!(f64);
#[cfg(test)]
mod tests {
use super::*;
use crate::native_endian;
use rstest::rstest;

static ENDIAN: Endian = Endian::new();
Expand All @@ -244,13 +245,23 @@ mod tests {
}

TestPrimitive!(test_u8, u8, vec![0xAAu8], 0xAAu8);
TestPrimitive!(test_u16, u16, vec![0xABu8, 0xCD], 0xCDAB);
TestPrimitive!(test_u32, u32, vec![0xABu8, 0xCD, 0xEF, 0xBE], 0xBEEFCDAB);
TestPrimitive!(
test_u16,
u16,
vec![0xABu8, 0xCD],
native_endian!(0xCDAB_u16)
);
TestPrimitive!(
test_u32,
u32,
vec![0xABu8, 0xCD, 0xEF, 0xBE],
native_endian!(0xBEEFCDAB_u32)
);
TestPrimitive!(
test_u64,
u64,
vec![0xABu8, 0xCD, 0xEF, 0xBE, 0xAB, 0xCD, 0xFE, 0xC0],
0xC0FECDABBEEFCDAB
native_endian!(0xC0FECDABBEEFCDAB_u64)
);
TestPrimitive!(
test_u128,
Expand All @@ -259,26 +270,31 @@ mod tests {
0xABu8, 0xCD, 0xEF, 0xBE, 0xAB, 0xCD, 0xFE, 0xC0, 0xAB, 0xCD, 0xEF, 0xBE, 0xAB, 0xCD,
0xFE, 0xC0
],
0xC0FECDABBEEFCDABC0FECDABBEEFCDAB
native_endian!(0xC0FECDABBEEFCDABC0FECDABBEEFCDAB_u128)
);
TestPrimitive!(
test_usize,
usize,
vec![0xABu8, 0xCD, 0xEF, 0xBE, 0xAB, 0xCD, 0xFE, 0xC0],
if core::mem::size_of::<usize>() == 8 {
0xC0FECDABBEEFCDAB
native_endian!(0xC0FECDABBEEFCDAB_usize)
} else {
0xBEEFCDAB
native_endian!(0xBEEFCDAB_usize)
}
);
TestPrimitive!(test_i8, i8, vec![0xFBu8], -5);
TestPrimitive!(test_i16, i16, vec![0xFDu8, 0xFE], -259);
TestPrimitive!(test_i32, i32, vec![0x02u8, 0x3F, 0x01, 0xEF], -0x10FEC0FE);
TestPrimitive!(test_i16, i16, vec![0xFDu8, 0xFE], native_endian!(-259_i16));
TestPrimitive!(
test_i32,
i32,
vec![0x02u8, 0x3F, 0x01, 0xEF],
native_endian!(-0x10FEC0FE_i32)
);
TestPrimitive!(
test_i64,
i64,
vec![0x02u8, 0x3F, 0x01, 0xEF, 0x01, 0x3F, 0x01, 0xEF],
-0x10FEC0FE10FEC0FE
native_endian!(-0x10FEC0FE10FEC0FE_i64)
);
TestPrimitive!(
test_i128,
Expand All @@ -287,24 +303,29 @@ mod tests {
0x02u8, 0x3F, 0x01, 0xEF, 0x01, 0x3F, 0x01, 0xEF, 0x01, 0x3F, 0x01, 0xEF, 0x01, 0x3F,
0x01, 0xEF
],
-0x10FEC0FE10FEC0FE10FEC0FE10FEC0FE
native_endian!(-0x10FEC0FE10FEC0FE10FEC0FE10FEC0FE_i128)
);
TestPrimitive!(
test_isize,
isize,
vec![0x02u8, 0x3F, 0x01, 0xEF, 0x01, 0x3F, 0x01, 0xEF],
if core::mem::size_of::<isize>() == 8 {
-0x10FEC0FE10FEC0FE
native_endian!(-0x10FEC0FE10FEC0FE_isize)
} else {
-0x10FEC0FE
native_endian!(-0x10FEC0FE_isize)
}
);
TestPrimitive!(test_f32, f32, vec![0xA6u8, 0x9B, 0xC4, 0xBB], -0.006);
TestPrimitive!(
test_f32,
f32,
vec![0xA6u8, 0x9B, 0xC4, 0xBB],
native_endian!(-0.006_f32)
);
TestPrimitive!(
test_f64,
f64,
vec![0xFAu8, 0x7E, 0x6A, 0xBC, 0x74, 0x93, 0x78, 0xBF],
-0.006
native_endian!(-0.006_f64)
);

#[rstest(input, endian, bit_size, expected, expected_rest,
Expand Down
11 changes: 6 additions & 5 deletions src/impls/tuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,16 @@ ImplDekuTupleTraits! { A, B, C, D, E, F, G, H, I, J, K, }
#[cfg(test)]
mod tests {
use super::*;
use crate::native_endian;
use core::fmt::Debug;

use rstest::rstest;

#[rstest(input, expected, expected_rest,
case::length_1([0xef, 0xbe, 0xad, 0xde].as_ref(), (0xdeadbeefu32,), bits![Msb0, u8;]),
case::length_2([1, 0x24, 0x98, 0x82, 0].as_ref(), (true, 0x829824u32), bits![Msb0, u8;]),
case::length_1([0xef, 0xbe, 0xad, 0xde].as_ref(), (native_endian!(0xdeadbeef_u32),), bits![Msb0, u8;]),
case::length_2([1, 0x24, 0x98, 0x82, 0].as_ref(), (true, native_endian!(0x829824_u32)), bits![Msb0, u8;]),
case::length_11([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].as_ref(), (0u8, 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8), bits![Msb0, u8;]),
case::extra_rest([1, 0x24, 0x98, 0x82, 0, 0].as_ref(), (true, 0x829824u32), bits![Msb0, u8; 0, 0, 0, 0, 0, 0, 0, 0]),
case::extra_rest([1, 0x24, 0x98, 0x82, 0, 0].as_ref(), (true, native_endian!(0x829824_u32)), bits![Msb0, u8; 0, 0, 0, 0, 0, 0, 0, 0]),
)]
fn test_tuple_read<'a, T>(input: &'a [u8], expected: T, expected_rest: &BitSlice<Msb0, u8>)
where
Expand All @@ -104,8 +105,8 @@ mod tests {
}

#[rstest(input, expected,
case::length_1((0xdeadbeefu32,), vec![0xef, 0xbe, 0xad, 0xde]),
case::length_2((true, 0x829824u32), vec![1, 0x24, 0x98, 0x82, 0]),
case::length_1((native_endian!(0xdeadbeef_u32),), vec![0xef, 0xbe, 0xad, 0xde]),
case::length_2((true, native_endian!(0x829824_u32)), vec![1, 0x24, 0x98, 0x82, 0]),
case::length_11((0u8, 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8), vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
)]
fn test_tuple_write<T>(input: T, expected: Vec<u8>)
Expand Down
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,3 +363,7 @@ where
Ok(())
}
}

#[cfg(test)]
#[path = "../tests/test_common/mod.rs"]
pub mod test_common;
1 change: 1 addition & 0 deletions tests/test_alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ mod tests {
use std::convert::TryFrom;

#[test]
#[cfg_attr(miri, ignore)]
fn test_simple() {
let input = hex!("aabbbbcc0102ddffffffaa");

Expand Down
4 changes: 2 additions & 2 deletions tests/test_attributes/test_assert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ struct TestStruct {
field_b: 0x02,
}),

#[should_panic(expected = r#"Assertion("field \'field_b\' failed assertion: * field_a + * field_b >= 3")"#)]
#[should_panic(expected = r#"Assertion("field field_b failed assertion: * field_a + * field_b >= 3")"#)]
case(&hex!("0101"), TestStruct::default())
)]
fn test_assert_read(input: &[u8], expected: TestStruct) {
Expand All @@ -30,7 +30,7 @@ fn test_assert_read(input: &[u8], expected: TestStruct) {
field_b: 0x02,
}, hex!("0102").to_vec()),

#[should_panic(expected = r#"Assertion("field \'field_b\' failed assertion: * field_a + * field_b >= 3")"#)]
#[should_panic(expected = r#"Assertion("field field_b failed assertion: * field_a + * field_b >= 3")"#)]
case(TestStruct {
field_a: 0x01,
field_b: 0x01,
Expand Down
4 changes: 2 additions & 2 deletions tests/test_attributes/test_assert_eq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ struct TestStruct {
field_b: 0x01,
}),

#[should_panic(expected = r#"Assertion("field \'field_b\' failed assertion: field_b == * field_a")"#)]
#[should_panic(expected = r#"Assertion("field field_b failed assertion: field_b == * field_a")"#)]
case(&hex!("0102"), TestStruct::default())
)]
fn test_assert_eq_read(input: &[u8], expected: TestStruct) {
Expand All @@ -30,7 +30,7 @@ fn test_assert_eq_read(input: &[u8], expected: TestStruct) {
field_b: 0x01,
}, hex!("0101").to_vec()),

#[should_panic(expected = r#"Assertion("field \'field_b\' failed assertion: field_b == * field_a")"#)]
#[should_panic(expected = r#"Assertion("field field_b failed assertion: field_b == * field_a")"#)]
case(TestStruct {
field_a: 0x01,
field_b: 0x02,
Expand Down
41 changes: 41 additions & 0 deletions tests/test_common/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
pub trait FromBeBytes: Sized {
type Bytes;
fn from_be_bytes(_: Self::Bytes) -> Self;
}

macro_rules! implFromBeBytes {(
$($T:ident),* $(,)?) => ($(
impl FromBeBytes for $T {
type Bytes = [u8; ::core::mem::size_of::<$T>()];
fn from_be_bytes (bytes: Self::Bytes) -> Self {
#![deny(unconditional_recursion)]
Self::from_be_bytes(bytes)
}
}
)*
)}

implFromBeBytes![u8, u16, u32, usize, u64, u128, i8, i16, i32, isize, i64, i128, f32, f64,];

/// Converts value to native endian
///
/// Input is assumed to be little endian and the result is swapped if
/// target is big endian.
#[macro_export]
macro_rules! native_endian {
($num:expr) => {{
#[cfg(target_endian = "little")]
let res = $num;

#[cfg(target_endian = "big")]
let res = {
let mut val = $num;
let bytes = val.to_le_bytes();
val = $crate::test_common::FromBeBytes::from_be_bytes(bytes);

val
};

res
}};
}
1 change: 1 addition & 0 deletions tests/test_compile/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#[test]
#[cfg(not(tarpaulin))]
#[cfg_attr(miri, ignore)]
fn test_compile() {
let t = trybuild::TestCases::new();
t.compile_fail("tests/test_compile/cases/*.rs");
Expand Down
Loading