Skip to content

Commit

Permalink
Add nostd tests
Browse files Browse the repository at this point in the history
* Fix `cargo test --no-default-features` to pass by making std-only tests/docs conditional (added to CI)
* Added `Error::Custom(&'static str)` for no-std mode

There are a few `FIXME` in the code where things seemed suspicious
  • Loading branch information
nyurik committed Nov 5, 2023
1 parent 598168f commit 2415a0c
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 13 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
matrix:
build: [MSRV, stable, nightly, macos, win32, win64]
include:
- build: MSRV # Minimum supported Rust version
- build: MSRV # Minimum supported Rust version, ensure it matches the rust-version in Cargo.toml
os: ubuntu-latest
rust: 1.62.1
- build: stable
Expand Down Expand Up @@ -56,3 +56,4 @@ jobs:
cargo fmt -- --check
- run: cargo build
- run: cargo test
- run: cargo test --no-default-features
5 changes: 5 additions & 0 deletions src/ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ pub trait FromCtx<Ctx: Copy = (), This: ?Sized = [u8]> {
/// `[u8]`), then you need to implement this trait
///
/// ```rust
/// ##[cfg(feature = "std")] {
/// use scroll::{self, ctx, Pread};
/// #[derive(Debug, PartialEq, Eq)]
/// pub struct Foo(u16);
Expand All @@ -286,6 +287,7 @@ pub trait FromCtx<Ctx: Copy = (), This: ?Sized = [u8]> {
///
/// let foo2 = bytes.pread_with::<Foo>(0, scroll::BE).unwrap();
/// assert_eq!(Foo(0xdeadu16), foo2);
/// # }
/// ```
///
/// # Advanced: Using Your Own Error in `TryFromCtx`
Expand Down Expand Up @@ -350,6 +352,7 @@ pub trait IntoCtx<Ctx: Copy = (), This: ?Sized = [u8]>: Sized {
/// To implement writing into an arbitrary byte buffer, implement `TryIntoCtx`
/// # Example
/// ```rust
/// ##[cfg(feature = "std")] {
/// use scroll::{self, ctx, LE, Endian, Pwrite};
/// #[derive(Debug, PartialEq, Eq)]
/// pub struct Foo(u16);
Expand All @@ -369,6 +372,7 @@ pub trait IntoCtx<Ctx: Copy = (), This: ?Sized = [u8]>: Sized {
///
/// let mut bytes: [u8; 4] = [0, 0, 0, 0];
/// bytes.pwrite_with(Foo(0x7f), 1, LE).unwrap();
/// # }
/// ```
pub trait TryIntoCtx<Ctx: Copy = (), This: ?Sized = [u8]>: Sized {
type Error;
Expand Down Expand Up @@ -864,6 +868,7 @@ impl TryIntoCtx for CString {

#[cfg(test)]
mod tests {
#[cfg(feature = "std")]
use super::*;

#[test]
Expand Down
7 changes: 7 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ pub enum Error {
#[cfg(feature = "std")]
/// A custom Scroll error for reporting messages to clients
Custom(String),
#[cfg(not(feature = "std"))]
/// A custom static Scroll error for reporting messages to clients
Custom(&'static str),
#[cfg(feature = "std")]
/// Returned when IO based errors are encountered
IO(io::Error),
Expand Down Expand Up @@ -73,6 +76,10 @@ impl Display for Error {
Error::Custom(ref msg) => {
write!(fmt, "{}", msg)
}
#[cfg(not(feature = "std"))]
Error::Custom(msg) => {
write!(fmt, "{msg}")
}
#[cfg(feature = "std")]
Error::IO(ref err) => {
write!(fmt, "{}", err)
Expand Down
3 changes: 3 additions & 0 deletions src/leb128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,20 +184,23 @@ mod tests {
let buf = [2u8 | CONTINUATION_BIT, 1];
let bytes = &buf[..];
let num = bytes.pread::<Uleb128>(0).unwrap();
#[cfg(feature = "std")]
println!("num: {:?}", &num);
assert_eq!(130u64, num.into());
assert_eq!(num.size(), 2);

let buf = [0x00, 0x01];
let bytes = &buf[..];
let num = bytes.pread::<Uleb128>(0).unwrap();
#[cfg(feature = "std")]
println!("num: {:?}", &num);
assert_eq!(0u64, num.into());
assert_eq!(num.size(), 1);

let buf = [0x21];
let bytes = &buf[..];
let num = bytes.pread::<Uleb128>(0).unwrap();
#[cfg(feature = "std")]
println!("num: {:?}", &num);
assert_eq!(0x21u64, num.into());
assert_eq!(num.size(), 1);
Expand Down
41 changes: 29 additions & 12 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
//! [FromCtx](ctx/trait.FromCtx.html) and [SizeWith](ctx/trait.SizeWith.html).
//!
//! ```rust
//! ##[cfg(feature = "std")] {
//! use std::io::Cursor;
//! use scroll::{IOread, ctx, Endian};
//! let bytes = [0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xef,0xbe,0x00,0x00,];
Expand All @@ -139,12 +140,14 @@
//! // read/written, e.g. switching between ELF32 or ELF64 at runtime.
//! let size = <u64 as ctx::SizeWith<Endian>>::size_with(&Endian::Little) as u64;
//! assert_eq!(prev + size, after);
//! # }
//! ```
//!
//! In the same vein as IOread we can use IOwrite to write a type to anything implementing
//! `std::io::Write`:
//!
//! ```rust
//! ##[cfg(feature = "std")] {
//! use std::io::Cursor;
//! use scroll::{IOwrite};
//!
Expand All @@ -155,6 +158,7 @@
//! cursor.iowrite_with(0xdeadbeef as u32, scroll::BE).unwrap();
//!
//! assert_eq!(cursor.into_inner(), [0xde, 0xad, 0xbe, 0xef, 0x0]);
//! # }
//! ```
//!
//! ## Complex use cases
Expand Down Expand Up @@ -355,18 +359,22 @@ mod tests {
let bytes: [u8; 2] = [0x2e, 0x0];
let b = &bytes[..];
let s: &str = b.pread(0).unwrap();
#[cfg(feature = "std")]
println!("str: {}", s);
assert_eq!(s.len(), bytes[..].len() - 1);
let bytes: &[u8] = b"hello, world!\0some_other_things";
let hello_world: &str = bytes.pread_with(0, StrCtx::Delimiter(NULL)).unwrap();
#[cfg(feature = "std")]
println!("{:?}", &hello_world);
assert_eq!(hello_world.len(), 13);
let hello: &str = bytes.pread_with(0, StrCtx::Delimiter(SPACE)).unwrap();
#[cfg(feature = "std")]
println!("{:?}", &hello);
assert_eq!(hello.len(), 6);
// this could result in underflow so we just try it
let _error = bytes.pread_with::<&str>(6, StrCtx::Delimiter(SPACE));
let error = bytes.pread_with::<&str>(7, StrCtx::Delimiter(SPACE));
#[cfg(feature = "std")]
println!("{:?}", &error);
assert!(error.is_ok());
}
Expand All @@ -377,13 +385,16 @@ mod tests {
use super::Pread;
let bytes: &[u8] = b"";
let hello_world = bytes.pread_with::<&str>(0, StrCtx::Delimiter(NULL));
#[cfg(feature = "std")]
println!("1 {:?}", &hello_world);
assert_eq!(hello_world.is_err(), true);
let error = bytes.pread_with::<&str>(7, StrCtx::Delimiter(SPACE));
#[cfg(feature = "std")]
println!("2 {:?}", &error);
assert!(error.is_err());
let bytes: &[u8] = b"\0";
let null = bytes.pread::<&str>(0).unwrap();
#[cfg(feature = "std")]
println!("3 {:?}", &null);
assert_eq!(null.len(), 0);
}
Expand Down Expand Up @@ -413,8 +424,7 @@ mod tests {
assert_eq!(bytes, "bytes");
}

use std::error;
use std::fmt::{self, Display};
use core::fmt::{self, Display};

#[derive(Debug)]
pub struct ExternalError {}
Expand All @@ -425,11 +435,12 @@ mod tests {
}
}

impl error::Error for ExternalError {
#[cfg(feature = "std")]
impl std::error::Error for ExternalError {
fn description(&self) -> &str {
"ExternalError"
}
fn cause(&self) -> Option<&dyn error::Error> {
fn cause(&self) -> Option<&dyn std::error::Error> {
None
}
}
Expand Down Expand Up @@ -499,7 +510,7 @@ mod tests {
let mut offset = 0;
let deadbeef: $typ = bytes.gread_with(&mut offset, LE).unwrap();
assert_eq!(deadbeef, $deadbeef as $typ);
assert_eq!(offset, ::std::mem::size_of::<$typ>());
assert_eq!(offset, ::core::mem::size_of::<$typ>());
}
};
}
Expand All @@ -518,7 +529,7 @@ mod tests {
let mut offset = 0;
let deadbeef: $typ = bytes.gread_with(&mut offset, LE).unwrap();
assert_eq!(deadbeef, $deadbeef as $typ);
assert_eq!(offset, ::std::mem::size_of::<$typ>());
assert_eq!(offset, ::core::mem::size_of::<$typ>());
}
};
}
Expand All @@ -537,8 +548,8 @@ mod tests {
let o2 = &mut 0;
let val: $typ = buffer.gread_with(o2, LE).unwrap();
assert_eq!(val, $val);
assert_eq!(*offset, ::std::mem::size_of::<$typ>());
assert_eq!(*o2, ::std::mem::size_of::<$typ>());
assert_eq!(*offset, ::core::mem::size_of::<$typ>());
assert_eq!(*o2, ::core::mem::size_of::<$typ>());
assert_eq!(*o2, *offset);
buffer.gwrite_with($val.clone(), offset, BE).unwrap();
let val: $typ = buffer.gread_with(o2, BE).unwrap();
Expand Down Expand Up @@ -612,12 +623,18 @@ mod tests {
let res = b.gread_with::<&str>(offset, StrCtx::Length(3));
assert!(res.is_err());
*offset = 0;
let astring: [u8; 3] = [0x45, 042, 0x44];
// FIXME: 0x2A used to be 042 -- a weird way to declare a number, probably a bug
let astring: [u8; 3] = [0x45, 0x2A, 0x44];
let string = astring.gread_with::<&str>(offset, StrCtx::Length(2));
match &string {
&Ok(_) => {}
&Err(ref err) => {
println!("{}", &err);
Ok(_) => {}
#[cfg(feature = "std")]
Err(err) => {
println!("{err}");
panic!();
}
#[cfg(not(feature = "std"))]
Err(_) => {
panic!();
}
}
Expand Down
1 change: 1 addition & 0 deletions tests/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ impl scroll::ctx::SizeWith<scroll::Endian> for Foo {
}

#[test]
#[cfg(feature = "std")]
fn ioread_api() {
use scroll::{IOread, LE};
use std::io::Cursor;
Expand Down

0 comments on commit 2415a0c

Please sign in to comment.