Skip to content
Open
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
12 changes: 5 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,16 @@ exclude = ["afl/*", "benches/*", "fuzz/*", "CHANGELOG.md"]

[dependencies]
defmt = { version = "0.3", optional = true }
heapless = { version = "0.8", optional = true }
serde = { version = "1.0", default-features = false, optional = true }

[features]
default = ["std", "serde"]
std = ["alloc", "serde?/std"]
alloc = ["defmt?/alloc"]
serde = ["dep:serde", "alloc"]
defmt-03 = ["dep:defmt"]

[target.'cfg(not(feature = "alloc"))'.dependencies]
heapless = { version = "0.8" }

[target.'cfg(not(feature = "alloc"))'.features]
defmt-03 = ["dep:defmt", "heapless/defmt-03"]
defmt-03 = ["dep:defmt", "heapless?/defmt-03"]
heapless = ["dep:heapless"]

[dev-dependencies]
criterion = "0.5"
Expand All @@ -41,11 +37,13 @@ serde_json = { version = "1.0" }
[[bench]]
name = "hex"
harness = false
required-features = ["alloc"]


[[bench]]
name = "check"
harness = false
required-features = ["alloc"]

[lints.clippy]
undocumented_unsafe_blocks = "warn"
4 changes: 4 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fn main() {
#[cfg(all(feature = "alloc", feature = "heapless"))]
compile_error!("Features `alloc` and `heapless` work with different implementations of String and are mutually exclusive");
}
16 changes: 8 additions & 8 deletions src/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,25 +382,25 @@ pub fn hex_decode_fallback(src: &[u8], dst: &mut [u8]) {
#[cfg(test)]
mod tests {
use crate::decode::NIL;
use crate::{
decode::{
hex_check_fallback, hex_check_fallback_with_case, hex_decode_fallback, CheckCase,
},
encode::hex_string,
use crate::decode::{
hex_check_fallback, hex_check_fallback_with_case, hex_decode_fallback, CheckCase,
};
#[cfg(any(feature = "alloc", feature = "heapless"))]
use crate::encode::hex_string;
use proptest::proptest;

#[cfg(not(feature = "alloc"))]
#[cfg(feature = "heapless")]
const CAPACITY: usize = 128;

#[cfg(any(feature = "alloc", feature = "heapless"))]
fn _test_decode_fallback(s: &String) {
let len = s.as_bytes().len();
let mut dst = Vec::with_capacity(len);
dst.resize(len, 0);

#[cfg(feature = "alloc")]
let hex_string = hex_string(s.as_bytes());
#[cfg(not(feature = "alloc"))]
#[cfg(feature = "heapless")]
let hex_string = hex_string::<CAPACITY>(s.as_bytes());

hex_decode_fallback(hex_string.as_bytes(), &mut dst);
Expand All @@ -416,7 +416,7 @@ mod tests {
}
}

#[cfg(not(feature = "alloc"))]
#[cfg(feature = "heapless")]
proptest! {
#[test]
fn test_decode_fallback(ref s in ".{1,16}") {
Expand Down
8 changes: 4 additions & 4 deletions src/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use core::arch::aarch64::*;
#[cfg(feature = "alloc")]
use alloc::{string::String, vec};

#[cfg(not(feature = "alloc"))]
#[cfg(feature = "heapless")]
use heapless::{String, Vec};

use crate::error::Error;
Expand All @@ -34,7 +34,7 @@ fn hex_string_custom_case(src: &[u8], upper_case: bool) -> String {
}
}

#[cfg(not(feature = "alloc"))]
#[cfg(feature = "heapless")]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we change above L20 from

#[cfg(feature = "alloc")]
fn hex_string_custom_case(src: &[u8], upper_case: bool) -> String {

to

#[cfg(not(feature = "heapless"))]
fn hex_string_custom_case(src: &[u8], upper_case: bool) -> String {

?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, without neither alloc nor heapless you don't have a String.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this PR ready to be merged?

fn hex_string_custom_case<const N: usize>(src: &[u8], upper_case: bool) -> String<N> {
let mut buffer = Vec::<_, N>::new();
buffer
Expand All @@ -59,7 +59,7 @@ pub fn hex_string(src: &[u8]) -> String {
hex_string_custom_case(src, false)
}

#[cfg(not(feature = "alloc"))]
#[cfg(feature = "heapless")]
pub fn hex_string<const N: usize>(src: &[u8]) -> String<N> {
hex_string_custom_case(src, false)
}
Expand All @@ -69,7 +69,7 @@ pub fn hex_string_upper(src: &[u8]) -> String {
hex_string_custom_case(src, true)
}

#[cfg(not(feature = "alloc"))]
#[cfg(feature = "heapless")]
pub fn hex_string_upper<const N: usize>(src: &[u8]) -> String<N> {
hex_string_custom_case(src, true)
}
Expand Down
27 changes: 16 additions & 11 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ pub use crate::decode::{
hex_decode_unchecked,
};
pub use crate::encode::{
hex_encode, hex_encode_fallback, hex_encode_upper, hex_encode_upper_fallback, hex_string,
hex_string_upper,
hex_encode, hex_encode_fallback, hex_encode_upper, hex_encode_upper_fallback,
};
#[cfg(any(feature = "alloc", feature = "heapless"))]
pub use crate::encode::{hex_string, hex_string_upper};

pub use crate::error::Error;

Expand Down Expand Up @@ -175,11 +176,13 @@ fn vectorization_support_no_cache_arm() -> Vectorization {
#[cfg(test)]
mod tests {
use crate::decode::{hex_decode, hex_decode_with_case, CheckCase};
use crate::encode::{hex_encode, hex_string};
use crate::{hex_encode_upper, hex_string_upper, vectorization_support, Vectorization};
use crate::encode::hex_encode;
#[cfg(any(feature = "alloc", feature = "heapless"))]
use crate::{encode::hex_string, hex_string_upper};
use crate::{hex_encode_upper, vectorization_support, Vectorization};
use proptest::proptest;

#[cfg(not(feature = "alloc"))]
#[cfg(feature = "heapless")]
const CAPACITY: usize = 128;

#[test]
Expand Down Expand Up @@ -209,14 +212,15 @@ mod tests {
assert_eq!(vector_support, Vectorization::None);
}

#[cfg(any(feature = "alloc", feature = "heapless"))]
fn _test_hex_encode(s: &String) {
let mut buffer = vec![0; s.as_bytes().len() * 2];
{
let encode = &*hex_encode(s.as_bytes(), &mut buffer).unwrap();

#[cfg(feature = "alloc")]
let hex_string = hex_string(s.as_bytes());
#[cfg(not(feature = "alloc"))]
#[cfg(feature = "heapless")]
let hex_string = hex_string::<CAPACITY>(s.as_bytes());

assert_eq!(encode, hex::encode(s));
Expand All @@ -228,7 +232,7 @@ mod tests {

#[cfg(feature = "alloc")]
let hex_string_upper = hex_string_upper(s.as_bytes());
#[cfg(not(feature = "alloc"))]
#[cfg(feature = "heapless")]
let hex_string_upper = hex_string_upper::<CAPACITY>(s.as_bytes());

assert_eq!(encode_upper, hex::encode_upper(s));
Expand All @@ -244,22 +248,23 @@ mod tests {
}
}

#[cfg(not(feature = "alloc"))]
#[cfg(feature = "heapless")]
proptest! {
#[test]
fn test_hex_encode(ref s in ".{0,16}") {
_test_hex_encode(s);
}
}

#[cfg(any(feature = "alloc", feature = "heapless"))]
fn _test_hex_decode(s: &String) {
let len = s.as_bytes().len();
{
let mut dst = Vec::with_capacity(len);
dst.resize(len, 0);
#[cfg(feature = "alloc")]
let hex_string = hex_string(s.as_bytes());
#[cfg(not(feature = "alloc"))]
#[cfg(feature = "heapless")]
let hex_string = hex_string::<CAPACITY>(s.as_bytes());

hex_decode(hex_string.as_bytes(), &mut dst).unwrap();
Expand All @@ -273,7 +278,7 @@ mod tests {
dst.resize(len, 0);
#[cfg(feature = "alloc")]
let hex_string_upper = hex_string_upper(s.as_bytes());
#[cfg(not(feature = "alloc"))]
#[cfg(feature = "heapless")]
let hex_string_upper = hex_string_upper::<CAPACITY>(s.as_bytes());

hex_decode_with_case(hex_string_upper.as_bytes(), &mut dst, CheckCase::Upper).unwrap();
Expand All @@ -290,7 +295,7 @@ mod tests {
}
}

#[cfg(not(feature = "alloc"))]
#[cfg(feature = "heapless")]
proptest! {
#[test]
fn test_hex_decode(ref s in ".{1,16}") {
Expand Down