Skip to content

Commit

Permalink
feat: add inline const constructors
Browse files Browse the repository at this point in the history
also bump msrv to 1.83
  • Loading branch information
polazarus committed Dec 28, 2024
1 parent 0815fa9 commit 51ae3cd
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 11 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ categories = ["memory-management", "data-structures"]
license = "MIT OR Apache-2.0"
edition = "2021"
readme = "README.md"
rust-version = "1.81.0"
rust-version = "1.83.0"

[package.metadata.docs.rs]
all-features = true
Expand Down
44 changes: 44 additions & 0 deletions src/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,50 @@ where
Self::inline_empty()
}

/// Creates a new inline `HipByt` by copying the given slice.
/// The slice **must not** be too large to be inlined.
///
/// # Panics
///
/// It panics if the slice is too large.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use hipstr::HipByt;
/// let s = HipByt::inline(b"hello\0");
/// assert_eq!(s, b"hello\0");
/// ```
pub const fn inline(bytes: &[u8]) -> Self {
assert!(bytes.len() <= Self::inline_capacity(), "slice too large");

// SAFETY: length checked above
unsafe { Self::inline_unchecked(bytes) }
}

/// Creates a new inline `HipByt` by copying the given the slice.
/// Return `None` if the given slice is too large to be inlined.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use hipstr::HipByt;
/// let s = HipByt::try_inline(b"hello\0").unwrap();
/// assert_eq!(s, b"hello\0");
/// ```
pub const fn try_inline(bytes: &[u8]) -> Option<Self> {
if bytes.len() <= Self::inline_capacity() {
// SAFETY: length checked above
Some(unsafe { Self::inline_unchecked(bytes) })
} else {
None
}
}

/// Creates a new `HipByt` with the given capacity.
///
/// The underlying representation is not **normalized**.
Expand Down
18 changes: 9 additions & 9 deletions src/bytes/raw/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,19 +106,21 @@ impl<const INLINE_CAPACITY: usize> Inline<INLINE_CAPACITY> {
/// Creates a new `Inline` string by copying a byte slice.
#[inline]
#[cfg(test)]
fn new(sl: &[u8]) -> Self {
assert!(sl.len() <= INLINE_CAPACITY);

// SAFETY: length check above
unsafe { Self::new_unchecked(sl) }
const fn new(sl: &[u8]) -> Option<Self> {
if sl.len() <= INLINE_CAPACITY {
// SAFETY: length check above
Some(unsafe { Self::new_unchecked(sl) })
} else {
None
}
}

/// Creates a new `Inline` string by copying a short byte slice.
///
/// # Safety
///
/// The input slice's length MUST be at most `INLINE_CAPACITY`.
pub unsafe fn new_unchecked(sl: &[u8]) -> Self {
pub const unsafe fn new_unchecked(sl: &[u8]) -> Self {
let len = sl.len();
debug_assert!(len <= INLINE_CAPACITY);

Expand Down Expand Up @@ -167,9 +169,7 @@ impl<const INLINE_CAPACITY: usize> Inline<INLINE_CAPACITY> {

/// Returns a mutable view of this inline string.
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [u8] {
// XXX should add const: waiting for const_mut_refs

pub const fn as_mut_slice(&mut self) -> &mut [u8] {
debug_assert!(self.is_valid());

// HACK could be done without less unsafe: maybe_uninit_slice
Expand Down
2 changes: 1 addition & 1 deletion src/bytes/raw/inline/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ type I = Inline<N>;

#[test]
fn test_clone() {
let a: I = Inline::new(b"abc");
let a: I = Inline::new(b"abc").unwrap();
let b = a.clone();
assert_eq!(a.as_slice(), b.as_slice());
}
Expand Down

0 comments on commit 51ae3cd

Please sign in to comment.