__declare_string_cmp_fns! {
import_path = "konst",
equality_fn = eq_str,
ordering_fn = cmp_str,
ordering_fn_inner = cmp_str_inner,
}
#[cfg(feature = "cmp")]
__declare_fns_with_docs! {
(Option<&'a str>, (eq_option_str, cmp_option_str))
docs(default)
macro = __impl_option_cmp_fns!(
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "cmp")))]
for['a,]
params(l, r)
eq_comparison = crate::polymorphism::CmpWrapper(l).const_eq(r),
cmp_comparison = crate::polymorphism::CmpWrapper(l).const_cmp(r),
parameter_copyability = copy,
),
}
#[deprecated(
since = "0.2.10",
note = "reexports for `0.2.*` patch releases, will be removed in `0.3.0`"
)]
pub mod deprecated_reexports {
macro_rules! declare_deprecated {
(
$deprecation:literal
fn $fn_name:ident($($arg:ident : $arg_ty:ty),*) -> $ret:ty {
$delegating_to:ident
}
) => {
#[deprecated(
since = "0.2.10",
note = $deprecation,
)]
#[doc = $deprecation]
#[inline(always)]
pub const fn $fn_name($($arg: $arg_ty,)*) -> $ret {
super::$delegating_to($($arg),*)
}
};
}
declare_deprecated! {
"renamed to `starts_with`, full path: `konst::string::starts_with`"
fn str_starts_with(left: &str, right: &str) -> bool {
starts_with
}
}
declare_deprecated! {
"renamed to `ends_with`, full path: `konst::string::ends_with`"
fn str_ends_with(left: &str, right: &str) -> bool {
ends_with
}
}
declare_deprecated! {
"renamed to `find`, full path: `konst::string::find`"
fn str_find(left: &str, right: &str, from: usize) -> Option<usize> {
find
}
}
declare_deprecated! {
"renamed to `contains`, full path: `konst::string::contains`"
fn str_contains(left: &str, right: &str, from: usize) -> bool {
contains
}
}
declare_deprecated! {
"renamed to `rfind`, full path: `konst::string::rfind`"
fn str_rfind(left: &str, right: &str, from: usize) -> Option<usize> {
rfind
}
}
declare_deprecated! {
"renamed to `rcontains`, full path: `konst::string::rcontains`"
fn str_rcontains(left: &str, right: &str, from: usize) -> bool {
rcontains
}
}
}
#[allow(deprecated)]
pub use deprecated_reexports::*;
#[doc(hidden)]
pub use konst_macro_rules::string::check_utf8 as __priv_check_utf8;
pub use konst_macro_rules::from_utf8_macro as from_utf8;
#[cfg(feature = "rust_1_55")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_55")))]
pub use konst_macro_rules::string::from_utf8_fn as from_utf8;
pub use konst_macro_rules::string::Utf8Error;
#[inline(always)]
pub const fn starts_with(left: &str, right: &str) -> bool {
crate::slice::bytes_start_with(left.as_bytes(), right.as_bytes())
}
#[inline(always)]
pub const fn ends_with(left: &str, right: &str) -> bool {
crate::slice::bytes_end_with(left.as_bytes(), right.as_bytes())
}
#[inline]
pub const fn find(left: &str, right: &str, from: usize) -> Option<usize> {
crate::slice::bytes_find(left.as_bytes(), right.as_bytes(), from)
}
#[inline(always)]
pub const fn contains(left: &str, right: &str, from: usize) -> bool {
matches!(
crate::slice::bytes_find(left.as_bytes(), right.as_bytes(), from),
Some(_)
)
}
#[inline]
pub const fn rfind(left: &str, right: &str, from: usize) -> Option<usize> {
crate::slice::bytes_rfind(left.as_bytes(), right.as_bytes(), from)
}
#[inline(always)]
pub const fn rcontains(left: &str, right: &str, from: usize) -> bool {
matches!(
crate::slice::bytes_rfind(left.as_bytes(), right.as_bytes(), from),
Some(_)
)
}
#[cfg(feature = "rust_1_55")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_55")))]
pub const fn str_up_to(string: &str, len: usize) -> &str {
let bytes = string.as_bytes();
if is_char_boundary(bytes, len) {
unsafe { core::str::from_utf8_unchecked(crate::slice::slice_up_to(bytes, len)) }
} else {
[][len]
}
}
#[cfg(feature = "rust_1_55")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_55")))]
pub const fn get_up_to(string: &str, len: usize) -> Option<&str> {
let bytes = string.as_bytes();
crate::option::and_then!(
crate::slice::get_up_to(bytes, len),
|x| if is_char_boundary_get(bytes, len) {
unsafe { Some(core::str::from_utf8_unchecked(x)) }
} else {
None
}
)
}
#[cfg(feature = "rust_1_55")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_55")))]
pub const fn str_from(string: &str, start: usize) -> &str {
let bytes = string.as_bytes();
if is_char_boundary(bytes, start) {
unsafe { core::str::from_utf8_unchecked(crate::slice::slice_from(bytes, start)) }
} else {
[][start]
}
}
#[cfg(feature = "rust_1_55")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_55")))]
pub const fn get_from(string: &str, from: usize) -> Option<&str> {
let bytes = string.as_bytes();
crate::option::and_then!(
crate::slice::get_from(bytes, from),
|x| if is_char_boundary_get(bytes, from) {
unsafe { Some(core::str::from_utf8_unchecked(x)) }
} else {
None
}
)
}
#[cfg(feature = "rust_1_55")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_55")))]
pub const fn split_at(string: &str, at: usize) -> (&str, &str) {
(str_up_to(string, at), str_from(string, at))
}
#[cfg(feature = "rust_1_55")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_55")))]
pub const fn str_range(string: &str, start: usize, end: usize) -> &str {
let bytes = string.as_bytes();
let start_inbounds = is_char_boundary(bytes, start);
if start_inbounds && is_char_boundary(bytes, end) {
unsafe { core::str::from_utf8_unchecked(crate::slice::slice_range(bytes, start, end)) }
} else if start_inbounds {
[][end]
} else {
[][start]
}
}
#[cfg(feature = "rust_1_55")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_55")))]
pub const fn get_range(string: &str, start: usize, end: usize) -> Option<&str> {
let bytes = string.as_bytes();
crate::option::and_then!(
crate::slice::get_range(bytes, start, end),
|x| if is_char_boundary_get(bytes, start) && is_char_boundary_get(bytes, end) {
unsafe { Some(core::str::from_utf8_unchecked(x)) }
} else {
None
}
)
}
#[cfg(feature = "rust_1_55")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_55")))]
pub const fn strip_prefix<'a>(string: &'a str, prefix: &str) -> Option<&'a str> {
unsafe {
crate::option::map!(
crate::slice::bytes_strip_prefix(string.as_bytes(), prefix.as_bytes()),
core::str::from_utf8_unchecked,
)
}
}
#[cfg(feature = "rust_1_55")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_55")))]
pub const fn strip_suffix<'a>(string: &'a str, suffix: &str) -> Option<&'a str> {
unsafe {
crate::option::map!(
crate::slice::bytes_strip_suffix(string.as_bytes(), suffix.as_bytes()),
core::str::from_utf8_unchecked,
)
}
}
#[cfg(feature = "rust_1_55")]
const fn is_char_boundary(bytes: &[u8], position: usize) -> bool {
position >= bytes.len() || (bytes[position] as i8) >= -0x40
}
#[cfg(feature = "rust_1_55")]
const fn is_char_boundary_get(bytes: &[u8], position: usize) -> bool {
let len = bytes.len();
position == len || (bytes[position] as i8) >= -0x40
}
#[cfg(feature = "rust_1_55")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_55")))]
pub const fn trim(this: &str) -> &str {
let trimmed = crate::slice::bytes_trim(this.as_bytes());
unsafe { core::str::from_utf8_unchecked(trimmed) }
}
#[cfg(feature = "rust_1_55")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_55")))]
pub const fn trim_start(this: &str) -> &str {
let trimmed = crate::slice::bytes_trim_start(this.as_bytes());
unsafe { core::str::from_utf8_unchecked(trimmed) }
}
#[cfg(feature = "rust_1_55")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_55")))]
pub const fn trim_end(this: &str) -> &str {
let trimmed = crate::slice::bytes_trim_end(this.as_bytes());
unsafe { core::str::from_utf8_unchecked(trimmed) }
}
#[cfg(feature = "rust_1_55")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_55")))]
pub const fn trim_matches<'a>(this: &'a str, needle: &str) -> &'a str {
let trimmed = crate::slice::bytes_trim_matches(this.as_bytes(), needle.as_bytes());
unsafe { core::str::from_utf8_unchecked(trimmed) }
}
#[cfg(feature = "rust_1_55")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_55")))]
pub const fn trim_start_matches<'a>(this: &'a str, needle: &str) -> &'a str {
let trimmed = crate::slice::bytes_trim_start_matches(this.as_bytes(), needle.as_bytes());
unsafe { core::str::from_utf8_unchecked(trimmed) }
}
#[cfg(feature = "rust_1_55")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_55")))]
pub const fn trim_end_matches<'a>(this: &'a str, needle: &str) -> &'a str {
let trimmed = crate::slice::bytes_trim_end_matches(this.as_bytes(), needle.as_bytes());
unsafe { core::str::from_utf8_unchecked(trimmed) }
}
#[cfg(feature = "rust_1_55")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_55")))]
pub const fn find_skip<'a>(this: &'a str, needle: &str) -> Option<&'a str> {
unsafe {
crate::option::map!(
crate::slice::bytes_find_skip(this.as_bytes(), needle.as_bytes()),
core::str::from_utf8_unchecked,
)
}
}
#[cfg(feature = "rust_1_55")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_55")))]
pub const fn find_keep<'a>(this: &'a str, needle: &str) -> Option<&'a str> {
unsafe {
crate::option::map!(
crate::slice::bytes_find_keep(this.as_bytes(), needle.as_bytes()),
core::str::from_utf8_unchecked,
)
}
}
#[cfg(feature = "rust_1_55")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_55")))]
pub const fn rfind_skip<'a>(this: &'a str, needle: &str) -> Option<&'a str> {
unsafe {
crate::option::map!(
crate::slice::bytes_rfind_skip(this.as_bytes(), needle.as_bytes()),
core::str::from_utf8_unchecked,
)
}
}
#[cfg(feature = "rust_1_55")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_55")))]
pub const fn rfind_keep<'a>(this: &'a str, needle: &str) -> Option<&'a str> {
unsafe {
crate::option::map!(
crate::slice::bytes_rfind_keep(this.as_bytes(), needle.as_bytes()),
core::str::from_utf8_unchecked,
)
}
}