#![no_std]
use core::{borrow::Borrow, fmt::Display};
mod slice;
mod merge;
mod split;
mod iter_fns;
mod interval;
mod pattern;
mod iterators;
mod string_ext;
pub use merge::Merge;
pub use string_ext::{StringExt, StringIndex};
pub use pattern::{
Pattern,
Sep,
SetSep,
Never,
FallibleBool,
CharStrPredicate, StrPredicate
};
pub mod iter {
pub use crate::iterators::*;
pub use crate::merge::MergeIter;
pub use crate::split::SplitIter;
}
pub mod patterns {
pub use crate::pattern:: {
SizedCharStrPredicate,
SizedStrPredicate,
SepConfig,
};
pub use crate::interval::Interval;
}
pub mod prelude {
#[doc(no_inline)]
pub use crate::StringIterable;
#[doc(no_inline)]
pub use crate::string_ext::StringExt;
#[doc(no_inline)]
pub use crate::pattern::{Sep, SetSep, CharStrPredicate, StrPredicate};
#[doc(no_inline)]
pub use crate::merge::Merge;
pub use crate::interval;
pub use crate::pat;
}
pub trait StringIterable {
fn str_iter<'t>(&'t self) -> StringIter<'t>;
}
impl<T> StringIterable for T where T: AsRef<str>{
fn str_iter<'t>(&'t self) -> StringIter<'t> {
StringIter { str: self.as_ref() }
}
}
#[repr(transparent)]
#[derive(Debug, Clone)]
pub struct StringIter<'t>{
str: &'t str,
}
impl<'t> StringIter<'t> {
pub const fn new(s: &'t str) -> Self {
StringIter {
str: s
}
}
pub const fn len(&self) -> usize{
self.str.len()
}
pub const fn is_empty(&self) -> bool{
self.str.is_empty()
}
pub const fn as_str(&self) -> &'t str {
self.str
}
pub const fn as_bytes(&self) -> &'t[u8] {
self.str.as_bytes()
}
unsafe fn slice_front_ptr(&self, ptr: *const u8) -> &'t str{
let len = ptr as usize - self.str.as_ptr() as usize;
self.str.get_unchecked(..len)
}
unsafe fn slice_back_ptr(&self, ptr: *const u8) -> &'t str{
let len = ptr as usize - self.str.as_ptr() as usize;
self.str.get_unchecked(len..)
}
pub fn startswith(&self, s: &str) -> bool{
self.str.starts_with(s)
}
pub fn endswith(&self, s: &str) -> bool{
self.str.ends_with(s)
}
pub fn trim(&mut self){
self.str = self.str.trim()
}
pub fn trim_start(&mut self){
self.str = self.str.trim_start()
}
pub fn trim_end(&mut self){
self.str = self.str.trim_end()
}
pub fn skip_front(&mut self, n: usize) -> bool{
for _ in 0..n{
self.next();
}
self.is_empty()
}
pub fn skip_back(&mut self, n: usize) -> bool{
for _ in 0..n{
self.next_back();
}
self.is_empty()
}
}
impl AsRef<str> for StringIter<'_> {
fn as_ref(&self) -> &str {
self.str
}
}
impl Borrow<str> for StringIter<'_> {
fn borrow(&self) -> &str {
self.str
}
}
impl<'t> From<&'t str> for StringIter<'t> {
fn from(value: &'t str) -> Self {
Self { str: value }
}
}
impl<'t> Into<&'t str> for StringIter<'t> {
fn into(self) -> &'t str {
self.str
}
}
impl<'t> Display for StringIter<'t> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(self.str)
}
}
impl PartialEq<str> for StringIter<'_> {
fn eq(&self, other: &str) -> bool {
self.str == other
}
}
impl PartialOrd<str> for StringIter<'_> {
fn partial_cmp(&self, other: &str) -> Option<core::cmp::Ordering> {
self.str.partial_cmp(other)
}
}
impl PartialEq<&str> for StringIter<'_> {
fn eq(&self, other: &&str) -> bool {
self.str == *other
}
}
impl PartialOrd<&str> for StringIter<'_> {
fn partial_cmp(&self, other: &&str) -> Option<core::cmp::Ordering> {
self.str.partial_cmp(other)
}
}
#[cfg(feature="std")]
const _: () = {
extern crate alloc;
use alloc::boxed::Box;
use alloc::rc::Rc;
use alloc::string::String;
use alloc::borrow::Cow;
use alloc::sync::Arc;
impl<'t> Into<String> for StringIter<'t> {
fn into(self) -> String {
self.str.into()
}
}
impl<'t> Into<Box<str>> for StringIter<'t> {
fn into(self) -> Box<str> {
self.str.into()
}
}
impl<'t> Into<Rc<str>> for StringIter<'t> {
fn into(self) -> Rc<str> {
self.str.into()
}
}
impl<'t> Into<Arc<str>> for StringIter<'t> {
fn into(self) -> Arc<str> {
self.str.into()
}
}
impl<'t> Into<Cow<'t, str>> for StringIter<'t> {
fn into(self) -> Cow<'t, str> {
Cow::Borrowed(self.str)
}
}
impl<'t> From<&'t String> for StringIter<'t> {
fn from(s: &'t String) -> Self {
Self::new(s.as_ref())
}
}
impl<'t> From<&'t Box<str>> for StringIter<'t> {
fn from(s: &'t Box<str>) -> Self {
Self::new(s.as_ref())
}
}
impl<'t> From<&'t Rc<str>> for StringIter<'t> {
fn from(s: &'t Rc<str>) -> Self {
Self::new(s.as_ref())
}
}
impl<'t> From<&'t Arc<str>> for StringIter<'t> {
fn from(s: &'t Arc<str>) -> Self {
Self::new(s.as_ref())
}
}
impl<'a, 't: 'a> From<&'t Cow<'a, str>> for StringIter<'t> {
fn from(s: &'t Cow<'a, str>) -> Self {
Self::new(s.as_ref())
}
}
impl<'t> TryFrom<Cow<'t, str>> for StringIter<'t> {
type Error = ();
fn try_from(cow: Cow<'t, str>) -> Result<Self, ()> {
match cow {
Cow::Borrowed(s) => Ok(Self { str: s }),
Cow::Owned(_) => Err(()),
}
}
}
};