nandi/rustnimpublic Fork 0
428f3741e2904549bd0157081162006f3952b324
Commits
Clone
git clone https://git.rickub.com/nandi/rustnim.git
git clone ssh://git@rickub.com/nandi/rustnim.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

main.rs · 83 lines · 2.4 KBRust Blame HistoryRaw
Add trait impls and slice iterators; base16ct's decoder now goes through ae9f986 nandithebull yesterday1//@ args: run
2// base16ct 1.0.0, transpiled as a multi-file crate.
3//
4// `error.rs` and `mixed.rs` are the crate's own files, byte-for-byte.
5// This file carries `lib.rs`'s core -- `decoded_len`, `encoded_len` and
6// `decode_inner` verbatim -- plus a driver, because the runner needs a `main`.
7// The `alloc`-gated items are off, as they are by default in the crate.
8
9mod error;
10mod mixed;
11
12pub use crate::error::{Error, Result};
13
14/// Compute decoded length of the given hex-encoded input.
15#[inline(always)]
16pub fn decoded_len(bytes: &[u8]) -> Result<usize> {
17 if bytes.len() & 1 == 0 {
18 Ok(bytes.len() / 2)
19 } else {
20 Err(Error::InvalidLength)
21 }
22}
23
24/// Get the length of Base16 (hex) produced by encoding the given bytes.
25#[inline(always)]
26pub fn encoded_len(bytes: &[u8]) -> usize {
27 bytes.len() * 2
28}
29
30fn decode_inner<'a>(
31 src: &[u8],
32 dst: &'a mut [u8],
33 decode_nibble: impl Fn(u8) -> u16,
34) -> Result<&'a [u8]> {
35 let dst = dst
36 .get_mut(..decoded_len(src)?)
37 .ok_or(Error::InvalidLength)?;
38
39 let mut err: u16 = 0;
40 for (src, dst) in src.chunks_exact(2).zip(dst.iter_mut()) {
41 let byte = (decode_nibble(src[0]) << 4) | decode_nibble(src[1]);
42 err |= byte >> 8;
43 *dst = byte as u8;
44 }
45
46 match err {
47 0 => Ok(dst),
48 _ => Err(Error::InvalidEncoding),
49 }
50}
51
52fn show(tag: &str, r: Result<&[u8]>) {
53 match r {
54 Ok(v) => {
55 print!("{} ok ", tag);
56 for b in v.iter() {
57 print!("{:02x}", b);
58 }
59 println!(" len={}", v.len());
60 }
61 Err(e) => println!("{} err {:?} / {}", tag, e, e),
62 }
63}
64
65fn main() {
66 let mut buf = [0u8; 16];
67
68 show("mixed-l", mixed::decode(b"abcd1234", &mut buf));
69 show("mixed-u", mixed::decode(b"ABCD1234", &mut buf));
70 show("mixed-m", mixed::decode(b"abCD1234", &mut buf));
71 show("edge", mixed::decode(b"00ff7f80", &mut buf));
72 show("oddlen", mixed::decode(b"abc", &mut buf));
73 show("bad", mixed::decode(b"zzzz", &mut buf));
74 show("empty", mixed::decode(b"", &mut buf));
75
76 let mut small = [0u8; 2];
77 show("short-dst", mixed::decode(b"abcd1234", &mut small));
78
79 // `lower::encode` is not here: `lower.rs` also defines `encode_str`, whose
80 // body is a closure over an `unsafe` block, and neither is implemented.
81
82 println!("{} {}", decoded_len(b"abcd").unwrap(), encoded_len(b"\xab\xcd"));
83}