diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f26be2a..b22bf67 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,7 +36,7 @@ jobs: - name: Install nightly toolchain for cargo-sync-rdme uses: dtolnay/rust-toolchain@master with: - toolchain: nightly-2026-04-30 + toolchain: nightly-2026-09-30 - name: Regenerate readmes run: just generate-readmes - name: Check for differences @@ -69,6 +69,23 @@ jobs: - name: Doctests run: just powerset test --doc + no-std: + name: Build for no_std + runs-on: ubuntu-latest + env: + RUSTFLAGS: -D warnings + steps: + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 + - uses: dtolnay/rust-toolchain@stable + with: + targets: thumbv7em-none-eabi + - uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0 + - uses: taiki-e/install-action@cargo-hack + - uses: taiki-e/install-action@just + # schemars 0.8 requires std, so exclude it here. + - name: Build for a no_std target + run: just powerset --exclude-features schemars08 check --target thumbv7em-none-eabi + docs: name: Deploy docs to GitHub Pages # Only deploy on pushes to main. diff --git a/CHANGELOG.md b/CHANGELOG.md index 90f4d28..cb11836 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,15 @@ ## Unreleased - ReleaseDate +### Changed + +- Updated the `base64` dependency to 0.23. + +### Fixed + +- The `base64` feature now builds on `no_std` targets. Previously, the `base64` + dependency was built with its `std` feature. + ## [0.1.0] - 2026-03-05 Initial release, with support for fixed-length hex arrays and variable-length base64 vectors. diff --git a/Cargo.lock b/Cargo.lock index e050956..36cb06a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -27,9 +27,9 @@ dependencies = [ [[package]] name = "base64" -version = "0.22.1" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" [[package]] name = "bitflags" diff --git a/Cargo.toml b/Cargo.toml index 32acf49..c404867 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,7 +49,7 @@ schemars08 = ["alloc", "dep:schemars08", "dep:serde_json"] serde = ["dep:serde_core"] [dependencies] -base64 = { version = "0.22", optional = true } +base64 = { version = "0.23", default-features = false, features = ["alloc"], optional = true } hex = { version = "0.4", default-features = false, optional = true } schemars08 = { package = "schemars", version = "0.8", optional = true } serde_core = { version = "1", default-features = false, optional = true } diff --git a/Justfile b/Justfile index e0d8e16..05e96e9 100644 --- a/Justfile +++ b/Justfile @@ -16,7 +16,7 @@ rustdoc *args: # Generate README.md using `cargo-sync-rdme`. generate-readmes: - cargo sync-rdme --toolchain nightly-2026-04-30 --all-features + cargo +stable sync-rdme --toolchain nightly-2026-09-30 --all-features # Run cargo release in CI. ci-cargo-release: diff --git a/README.md b/README.md index 77e4710..a1528a9 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ Several crates solve parts of this problem, often using slightly different approaches from `byte-wrapper`. |feature|`byte-wrapper`|[`serde-human-bytes`] 0.1.2|[`serde-encoded-bytes`] 0.2.1|[`serde_with`] 3.17.0|[`hex-buffer-serde`] 0.4.0|[`hexutil`] 0.1.0|[`serde-bytes-repr`] 0.3.0| -|-------|--------------|-------------------------|---------------------------|-------------------|------------------------|---------------|------------------------| +|-------|--------------|------|------|-------|------|------|------| |newtype wrappers|yes|yes (hex only)|no|no|no|no|no| |[`is_human_readable()`] switch|yes|yes|yes|no|yes|yes|no| |[`Display`] / [`FromStr`] / [`Deref`]|yes|[`Deref`] only|no|no|no|[`Display`] / [`FromStr`] via macro|no| @@ -113,7 +113,9 @@ The closest alternatives are: * **`serde`**: implements `Serialize` and `Deserialize` for enabled types. *Not enabled by default.* * **`schemars08`**: derives `JsonSchema` for enabled types. - *Not enabled by default.* + Requires `std`. *Not enabled by default.* + +All features other than `schemars08` are compatible with `no_std`. [`HexArray`]: https://docs.rs/byte-wrapper/0.1.0/byte_wrapper/hex_array/struct.HexArray.html "struct byte_wrapper::hex_array::HexArray" [`Base64Vec`]: https://docs.rs/byte-wrapper/0.1.0/byte_wrapper/base64_vec/struct.Base64Vec.html "struct byte_wrapper::base64_vec::Base64Vec" @@ -126,9 +128,9 @@ The closest alternatives are: [`hexutil`]: https://docs.rs/hexutil [`serde-bytes-repr`]: https://docs.rs/serde-bytes-repr [`is_human_readable()`]: https://docs.rs/serde/latest/serde/trait.Serializer.html#method.is_human_readable -[`Display`]: https://doc.rust-lang.org/nightly/core/fmt/trait.Display.html "trait core::fmt::Display" -[`FromStr`]: https://doc.rust-lang.org/nightly/core/str/traits/trait.FromStr.html "trait core::str::traits::FromStr" -[`Deref`]: https://doc.rust-lang.org/nightly/core/ops/deref/trait.Deref.html "trait core::ops::deref::Deref" +[`Display`]: https://doc.rust-lang.org/stable/core/fmt/trait.Display.html "trait core::fmt::Display" +[`FromStr`]: https://doc.rust-lang.org/stable/core/str/traits/trait.FromStr.html "trait core::str::traits::FromStr" +[`Deref`]: https://doc.rust-lang.org/stable/core/ops/deref/trait.Deref.html "trait core::ops::deref::Deref" [`HexArray`]: https://docs.rs/byte-wrapper/0.1.0/byte_wrapper/hex_array/struct.HexArray.html "struct byte_wrapper::hex_array::HexArray" diff --git a/src/base64_vec.rs b/src/base64_vec.rs index c626e20..45547fb 100644 --- a/src/base64_vec.rs +++ b/src/base64_vec.rs @@ -107,9 +107,11 @@ fn from_decode_error(e: base64::DecodeError) -> ParseBase64Error { base64::DecodeError::InvalidLength(length) => { ParseBase64Error::InvalidLength { length } } - base64::DecodeError::InvalidLastSymbol(offset, byte) => { - ParseBase64Error::InvalidLastSymbol { offset, byte } - } + base64::DecodeError::InvalidLastSymbol { + offset, + symbol, + symbol_value: _, + } => ParseBase64Error::InvalidLastSymbol { offset, byte: symbol }, base64::DecodeError::InvalidPadding => ParseBase64Error::InvalidPadding, } } diff --git a/src/lib.rs b/src/lib.rs index 586a434..e5c0c56 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -126,7 +126,9 @@ //! - **`serde`**: implements `Serialize` and `Deserialize` for //! enabled types. *Not enabled by default.* //! - **`schemars08`**: derives `JsonSchema` for enabled types. -//! *Not enabled by default.* +//! Requires `std`. *Not enabled by default.* +//! +//! All features other than `schemars08` are compatible with `no_std`. #![deny(missing_docs)] #![no_std] diff --git a/tests/integration/base64.rs b/tests/integration/base64.rs index 8e2a4a5..e235b4d 100644 --- a/tests/integration/base64.rs +++ b/tests/integration/base64.rs @@ -37,6 +37,25 @@ fn base64_from_str_invalid_length() { assert_eq!(err, ParseBase64Error::InvalidLength { length: 1 }); } +#[test] +fn base64_from_str_invalid_last_symbol() { + // "QQ==" is an encoding of [0x41]. "QR==" sets trailing bits. + let err = "QR==".parse::().expect_err("invalid last symbol"); + assert_eq!( + err, + ParseBase64Error::InvalidLastSymbol { offset: 1, byte: b'R' }, + "got: {err}", + ); + assert!(err.to_string().contains("offset 1"), "got: {err}"); +} + +#[test] +fn base64_from_str_invalid_padding() { + // The standard engine requires canonical padding. + let err = "QQ".parse::().expect_err("missing padding"); + assert_eq!(err, ParseBase64Error::InvalidPadding); +} + // -- Display and Debug formatting tests -- #[test]