Skip to content

Commit

Permalink
Add encode_to API
Browse files Browse the repository at this point in the history
In https://github.com/ostreedev/ostree-rs-ext/ we are performing
hex encoding in loops and recursively, and it could be helpful
for performance to support re-using a buffer instead of allocating
a new `String` on the heap.

Currently we are using `encode_to_slice`, but then we need to
use e.g. `std::str::from_utf8` which unnecessarily performs UTF-8
validation and is also hence fallible even though it doesn't need to be.
  • Loading branch information
cgwalters committed Dec 17, 2021
1 parent aa8f300 commit d6d0122
Showing 1 changed file with 43 additions and 0 deletions.
43 changes: 43 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,30 @@ pub fn encode<T: AsRef<[u8]>>(data: T) -> String {
data.encode_hex()
}

/// Encodes `data` as hex string using lowercase characters, appending to target string.
///
/// This is otherwise the same as [`encode`]. One reason to use this function
/// is that if you are performing multiple encodings on distinct data in
/// a loop, this will allow reusing the allocation of a string.
///
/// Alternatively, this is also more efficient to use when you have an
/// existing string and just want to append to it.
///
/// # Example
///
/// ```
/// let mut s = "The hex encoding is: ".to_string();
/// hex::encode_to("Hello world!", &mut s);
/// assert_eq!(s, "The hex encoding is: 48656c6c6f20776f726c6421");
/// ```
#[cfg(feature = "alloc")]
pub fn encode_to<T: AsRef<[u8]>>(data: T, s: &mut String) {
let data = data.as_ref();
for c in BytesToHexChars::new(data, HEX_CHARS_LOWER) {
s.push(c);
}
}

/// Encodes `data` as hex string using uppercase characters.
///
/// Apart from the characters' casing, this works exactly like `encode()`.
Expand All @@ -276,6 +300,25 @@ pub fn encode_upper<T: AsRef<[u8]>>(data: T) -> String {
data.encode_hex_upper()
}

/// Encodes `data` as hex string using uppercase characters, appending to target string.
///
/// This is the same as [`encode_to`], but uses uppercase characters.
///
/// # Example
///
/// ```
/// let mut s = "The hex encoding is: ".to_string();
/// hex::encode_upper_to("Hello world!", &mut s);
/// assert_eq!(s, "The hex encoding is: 48656C6C6F20776F726C6421");
/// ```
#[cfg(feature = "alloc")]
pub fn encode_upper_to<T: AsRef<[u8]>>(data: T, s: &mut String) {
let data = data.as_ref();
for c in BytesToHexChars::new(data, HEX_CHARS_UPPER) {
s.push(c);
}
}

/// Decodes a hex string into raw bytes.
///
/// Both, upper and lower case characters are valid in the input string and can
Expand Down

0 comments on commit d6d0122

Please sign in to comment.