Skip to content

Commit

Permalink
feat: add ToHexExt trait (#8)
Browse files Browse the repository at this point in the history
* feat: add `ToHexExt` trait to support prefix

* fmt

* improve docs

* feat: expand Ext trait

* fix: clippy

* fix: test

* test: improve trait tests

* fix: feature gate to alloc

* fix: import String

---------

Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com>
  • Loading branch information
yjhmelody and DaniPopes authored Feb 7, 2024
1 parent 288c9be commit 1b2c3dc
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 7 deletions.
11 changes: 9 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@
#![cfg_attr(not(feature = "hex"), doc = "[`hex`]: https://docs.rs/hex")]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
#![cfg_attr(feature = "nightly", feature(core_intrinsics, inline_const))]
#![cfg_attr(
feature = "nightly",
feature(core_intrinsics, inline_const),
allow(internal_features)
)]
#![cfg_attr(feature = "portable-simd", feature(portable_simd))]
#![warn(
missing_copy_implementations,
Expand Down Expand Up @@ -59,6 +63,10 @@ use arch::{generic, imp};

mod impl_core;

pub mod traits;
#[cfg(feature = "alloc")]
pub use traits::ToHexExt;

// If the `hex` feature is enabled, re-export the `hex` crate's traits.
// Otherwise, use our own with the more optimized implementation.
cfg_if! {
Expand All @@ -70,7 +78,6 @@ cfg_if! {
mod error;
pub use error::FromHexError;

mod traits;
#[allow(deprecated)]
pub use traits::{FromHex, ToHex};
}
Expand Down
68 changes: 63 additions & 5 deletions src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use alloc::{
borrow::{Cow, ToOwned},
boxed::Box,
rc::Rc,
string::String,
sync::Arc,
vec::Vec,
};
Expand All @@ -18,7 +19,7 @@ use alloc::{
/// This trait is implemented for all `T` which implement `AsRef<[u8]>`. This
/// includes `String`, `str`, `Vec<u8>` and `[u8]`.
///
/// *Note*: instead of using this trait, you might want to use [`encode`].
/// *Note*: instead of using this trait, you might want to use [`encode`](crate::encode) or [`ToHexExt`].
///
/// # Examples
///
Expand All @@ -27,20 +28,54 @@ use alloc::{
/// use const_hex::ToHex;
///
/// assert_eq!("Hello world!".encode_hex::<String>(), "48656c6c6f20776f726c6421");
/// assert_eq!("Hello world!".encode_hex_upper::<String>(), "48656C6C6F20776F726C6421");
/// ```
#[cfg_attr(feature = "alloc", doc = "\n[`encode`]: crate::encode")]
#[cfg_attr(not(feature = "alloc"), doc = "\n[`encode`]: crate::encode_to_slice")]
#[deprecated(note = "use `encode` or other specialized functions instead")]
pub trait ToHex {
/// Encode the hex strict representing `self` into the result. Lower case
/// letters are used (e.g. `f9b4ca`)
/// Encode the hex strict representing `self` into the result.
/// Lower case letters are used (e.g. `f9b4ca`).
fn encode_hex<T: iter::FromIterator<char>>(&self) -> T;

/// Encode the hex strict representing `self` into the result. Upper case
/// letters are used (e.g. `F9B4CA`)
/// Encode the hex strict representing `self` into the result.
/// Upper case letters are used (e.g. `F9B4CA`).
fn encode_hex_upper<T: iter::FromIterator<char>>(&self) -> T;
}

/// Encoding values as hex string with prefix `0x`.
///
/// This trait is implemented for all `T` which implement `AsRef<[u8]>`.
///
/// # Examples
///
/// ```
/// use const_hex::ToHexExt;
///
/// assert_eq!("Hello world!".encode_hex(), "48656c6c6f20776f726c6421");
/// assert_eq!("Hello world!".encode_hex_upper(), "48656C6C6F20776F726C6421");
/// assert_eq!("Hello world!".encode_hex_with_prefix(), "0x48656c6c6f20776f726c6421");
/// assert_eq!("Hello world!".encode_hex_upper_with_prefix(), "0x48656C6C6F20776F726C6421");
/// ```
#[cfg(feature = "alloc")]
pub trait ToHexExt {
/// Encode the hex strict representing `self` into the result.
/// Lower case letters are used (e.g. `f9b4ca`).
fn encode_hex(&self) -> String;

/// Encode the hex strict representing `self` into the result.
/// Upper case letters are used (e.g. `F9B4CA`).
fn encode_hex_upper(&self) -> String;

/// Encode the hex strict representing `self` into the result with prefix `0x`.
/// Lower case letters are used (e.g. `0xf9b4ca`).
fn encode_hex_with_prefix(&self) -> String;

/// Encode the hex strict representing `self` into the result with prefix `0X`.
/// Upper case letters are used (e.g. `0xF9B4CA`).
fn encode_hex_upper_with_prefix(&self) -> String;
}

struct BytesToHexChars<'a, const UPPER: bool> {
inner: core::slice::Iter<'a, u8>,
next: Option<char>,
Expand Down Expand Up @@ -88,6 +123,29 @@ impl<T: AsRef<[u8]>> ToHex for T {
}
}

#[cfg(feature = "alloc")]
impl<T: AsRef<[u8]>> ToHexExt for T {
#[inline]
fn encode_hex(&self) -> String {
crate::encode(self)
}

#[inline]
fn encode_hex_upper(&self) -> String {
crate::encode_upper(self)
}

#[inline]
fn encode_hex_with_prefix(&self) -> String {
crate::encode_prefixed(self)
}

#[inline]
fn encode_hex_upper_with_prefix(&self) -> String {
crate::encode_upper_prefixed(self)
}
}

/// Types that can be decoded from a hex string.
///
/// This trait is implemented for `Vec<u8>` and small `u8`-arrays.
Expand Down

0 comments on commit 1b2c3dc

Please sign in to comment.