1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
//! # `mut-str`
//!
//! A toolkit for working with mutable string slices (`&mut str`), and immutable ones too!
//!
//! Pretty much all you can do safely in the standard library with mutable string slices is make them lower or upper case.
//! This package allows for splitting and slicing by character index (rather than byte index), replacing strings and using references to characters.
//!
//! All functions on string slices are available either at the package root or as methods on the `StrExt` trait.
//!
//! ```
//! use mut_str::StrExt;
//!
//! let mut welcome = Box::<str>::from("Hello, World!");
//!
//! // Split by character index
//! let (l, r) = welcome.char_split_at_mut(7).unwrap();
//! assert_eq!(l, "Hello, ");
//! assert_eq!(r, "World!");
//!
//! // Replace string slices
//! l.replace_with("mut-str").unwrap();
//! assert_eq!(l, "mut-str");
//!
//! // Replace with padding
//! let sub = r.replace_with_pad_left_char("👑!", ' ').unwrap();
//! assert_eq!(sub, "👑!");
//! assert_eq!(r, " 👑!");
//!
//! assert_eq!(&*welcome, "mut-str 👑!");
//!
//! // Get character references
//! let crown = welcome.get_char_mut(8).unwrap();
//! assert_eq!(crown, '👑');
//!
//! // Mutate characters
//! crown.replace('🌍').unwrap();
//! assert_eq!(crown, '🌍');
//!
//! // Slice by character index
//! let l = welcome.char_slice_mut(..7).unwrap();
//! l.replace_with_pad_left_space("👋").unwrap();
//!
//! assert_eq!(&*welcome, " 👋 🌍!");
//! ```
//!
//! ## Links
//! [Latest version of `mut-str` on crates.io](https://crates.io/crates/mut-str)
#![doc = concat!("[This version of `mut-str` on crates.io](https://crates.io/crates/mut-str/", env!("CARGO_PKG_VERSION"), ") ")]
//! [`mut-str` on GitHub](https://github.com/tomBoddaert/mut-str)
//!
//! # Features
#![doc = concat!("[Features on docs.rs](https://docs.rs/crate/mut-str/", env!("CARGO_PKG_VERSION"), "/features) ")]
//! - `alloc` (enabled by default) adds implementations that require the `alloc` library.
//! - `std` (enabled by default, requires `alloc`) adds implementations specific to the standard library.
//!
//! To make this package `no-std` compatible, disable the `std` feature.
//! ```sh
//! cargo add mut-str --no-default-features
//! ```
//! ```sh
//! cargo add mut-str --no-default-features --features=alloc
//! ```
//!
//! ## License
//!
//! [`mut-str`](https://github.com/tomBoddaert/mut-str) is dual-licensed under either the Apache License Version 2.0 or MIT license at your option.
#![warn(
clippy::all,
clippy::pedantic,
clippy::nursery,
clippy::perf,
clippy::cargo,
clippy::alloc_instead_of_core,
clippy::std_instead_of_alloc,
clippy::std_instead_of_core,
clippy::get_unwrap,
clippy::panic_in_result_fn,
clippy::todo,
clippy::undocumented_unsafe_blocks
)]
#![allow(clippy::module_name_repetitions)]
#![cfg_attr(not(feature = "std"), no_std)]
use core::str;
mod char_owned;
mod char_ref;
/// Errors.
pub mod errors;
mod get;
/// Iterators over UTF-8 character references.
pub mod iter;
mod replace;
mod slice;
mod split;
mod traits;
pub use char_owned::*;
pub use char_ref::*;
pub use get::*;
pub use replace::*;
pub use slice::*;
pub use split::*;
pub use traits::*;
#[inline]
/// Copy the [`prim@str`] to a byte buffer and get the new [`prim@str`] containing the inserted character.
/// Returns `None` if `buffer` is shorter than the string slice.
///
/// ```
/// use mut_str::copy_to;
///
/// let s = "Hello, World!";
/// let mut buffer = [0; 50];
/// let new_s = copy_to(s, &mut buffer).unwrap();
///
/// assert_eq!(new_s, s);
/// ```
pub fn copy_to<'a>(s: &str, buffer: &'a mut [u8]) -> Option<&'a mut str> {
if s.len() > buffer.len() {
None
} else {
let exact_buffer = &mut buffer[..s.len()];
exact_buffer.copy_from_slice(s.as_bytes());
// SAFETY:
// This is valid as a utf8 string slice of the same length was just
// copied to the slice.
Some(unsafe { str::from_utf8_unchecked_mut(exact_buffer) })
}
}
#[cfg(test)]
#[allow(clippy::module_name_repetitions)]
mod test {
pub static TEST_STR: &str = "oΦ⏣🌑";
pub fn test_str_owned() -> Box<str> {
Box::from(TEST_STR)
}
}