Closed dvdplm closed 3 years ago
How would that be a breaking change? I assume you would add a no-std
feature to this crate which is disabled by default. And with it disabled, nothing about the API would change, right? Maybe I'm missing something?
EDIT: The "API Evolution" RFC explicitly states something about cargo features...
Having hex
work in a no-std environment would be great I think, yes
About breaking change, the project is still in 0.x version (for now... I really need to work on a 1.x release...), so I think it's acceptable at this state.
Also yeah, I don't think a breaking change is needed here as it would be only an opt-in feature (no-std
) which would keep the API stable for current usages.
Actually the only things I see which would need to be refactored are:
std::error::Error
for FromHexError
as this trait is not present in core
FromHex
for Vec<u8>
using iterator too, as it's actually already a collect
used thereencode
/decode
functions as it relies on String
and Vec
(or maybe generic-ize them too ?)Also unlike rustc-hex
, I think there's no need to remove usage of fmt
module as it is present in core::fmt
in Rust stable
But same for me, if I missed something, tell me ^^
So I got a random energy wave to work a bit on hex
and created a no-std
branch to work a bit on a no_std
implementation and see what could be done in this way.
It doesn't meant I won't accept a PR, it's just to work on this side too and see :)
PS; Also I created a decode_to_slice
function in addition to decode
to get a more "basic" function to decode hexadecimal values to raw bytes which can be used by FromHex
implementations
Mentioning #20 for issue update, not gonna close it tho until we can get it working without alloc
this might be useful: (it doesn't require any allocations at all)
fn byte2hex(byte: u8, table: &[u8; 16]) -> (u8, u8) {
let high = table[((byte & 0xf0) >> 4) as usize];
let low = table[(byte & 0x0f) as usize];
(high, low)
}
pub fn encode_to_slice(input: &[u8], output: &mut [u8]) -> Result<(), FromHexError> {
if input.len() * 2 != output.len() {
return Err(FromHexError::InvalidStringLength);
}
for (byte, (i, j)) in input.iter().zip(generate_iter(input.len() * 2)) {
let (high, low) = byte2hex(*byte, HEX_CHARS_LOWER);
output[i] = high;
output[j] = low;
}
Ok(())
}
// generates an iterator like this
// (0, 1)
// (2, 3)
// (4, 5)
// (6, 7)
// ...
fn generate_iter(len: usize) -> impl Iterator<Item = (usize, usize)> {
(0..len).step_by(2).zip((0..len).skip(1).step_by(2))
}
(I wrote the code, but am too lazy to make a PR, feel free to use it)
Hey, thanks for a great crate, we tried to use your crate in a no-std environment but it seems to bring in allocations:
error: no global memory allocator found but one is required; link to std or add `#[global_allocator]` to a static item that implements the GlobalAlloc trait.
error: `#[alloc_error_handler]` function required, but not found
error: aborting due to 2 previous errors
I only call a single function, that I think doesn't allocate:
hex::encode_to_slice(buf, unsafe { res.as_bytes_mut() });
+1
As #42 has been merged, i think it's safe to say that this issue can be closed :)
A new version of hex
in crates.io with latest changes will come soon
It'd be great to be able to use
hex
in no-std projects but as it currently depends onstd
this is not possible. I think this would be a breaking change so before submitting a PR I wanted to check if this is something you'd be willing to consider merging?I'd probably port over code from https://github.com/rphmeier/rustc-hex that uses iterators.