KokaKiwi / rust-hex

A basic crate to encode values to hexadecimal representation. Originally extracted from rustc-serialize.
https://crates.io/crates/hex
Apache License 2.0
201 stars 55 forks source link

no-std, PR welcome? #16

Closed dvdplm closed 3 years ago

dvdplm commented 6 years ago

It'd be great to be able to use hex in no-std projects but as it currently depends on std 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.

LukasKalbertodt commented 6 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...

KokaKiwi commented 6 years ago

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:

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 ^^

KokaKiwi commented 6 years ago

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

KokaKiwi commented 5 years ago

Mentioning #20 for issue update, not gonna close it tho until we can get it working without alloc

Luro02 commented 4 years ago

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)

NickeZ commented 4 years ago

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() });
fouge commented 3 years ago

+1

KokaKiwi commented 3 years ago

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