use core::str::{Bytes, CharIndices, Chars};
use crate::{GString, GStringError, Validator};
impl<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool>
GString<V, MIN, MAX, ASCII_ONLY>
{
#[inline]
pub const fn len(&self) -> usize {
self.len
}
#[inline]
pub const fn capacity(&self) -> usize {
MAX
}
#[inline]
pub fn count(&self) -> usize {
self.chars().count()
}
#[inline]
pub const fn is_empty(&self) -> bool {
self.len == 0
}
#[inline]
pub const fn is_full(&self) -> bool {
self.len == MAX
}
#[inline]
pub const fn is_char_boundary(&self, index: usize) -> bool {
self.as_str().is_char_boundary(index)
}
#[inline]
pub const fn as_str(&self) -> &str {
unsafe {
let slice = core::slice::from_raw_parts(self.buf.as_ptr(), self.len);
core::str::from_utf8_unchecked(slice)
}
}
#[inline(always)]
pub const fn as_bytes(&self) -> &[u8] {
unsafe { core::slice::from_raw_parts(self.buf.as_ptr(), self.len) }
}
}
#[cfg(feature = "grapheme")]
impl<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool>
GString<V, MIN, MAX, ASCII_ONLY>
{
#[inline]
pub fn grapheme_count(&self) -> usize {
use crate::UnicodeSegmentation;
self.as_str().graphemes(true).count()
}
#[inline]
pub fn graphemes(&self) -> crate::Graphemes<'_> {
use crate::UnicodeSegmentation;
self.as_str().graphemes(true)
}
}
impl<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool>
GString<V, MIN, MAX, ASCII_ONLY>
{
#[inline]
pub fn chars(&self) -> Chars<'_> {
self.as_str().chars()
}
#[inline]
pub fn char_indices(&self) -> CharIndices<'_> {
self.as_str().char_indices()
}
#[inline]
pub fn bytes(&self) -> Bytes<'_> {
self.as_str().bytes()
}
}
use core::str::FromStr;
use core::str::{EncodeUtf16, EscapeDebug, EscapeDefault, EscapeUnicode, Lines, SplitWhitespace};
pub trait Pattern {
type SplitIter<'a>: Iterator<Item = &'a str>
where
Self: 'a;
type MatchesIter<'a>: Iterator<Item = &'a str>
where
Self: 'a;
type RMatchesIter<'a>: Iterator<Item = &'a str>
where
Self: 'a;
type MatchIndicesIter<'a>: Iterator<Item = (usize, &'a str)>
where
Self: 'a;
type RMatchIndicesIter<'a>: Iterator<Item = (usize, &'a str)>
where
Self: 'a;
fn split<'a>(self, s: &'a str) -> Self::SplitIter<'a>
where
Self: 'a;
fn split_once<'a>(&self, s: &'a str) -> Option<(&'a str, &'a str)>;
fn rsplit_once<'a>(&self, s: &'a str) -> Option<(&'a str, &'a str)>;
fn strip_prefix<'a>(&self, s: &'a str) -> Option<&'a str>;
fn strip_suffix<'a>(&self, s: &'a str) -> Option<&'a str>;
fn matches<'a>(self, s: &'a str) -> Self::MatchesIter<'a>
where
Self: 'a;
fn rmatches<'a>(self, s: &'a str) -> Self::RMatchesIter<'a>
where
Self: 'a;
fn match_indices<'a>(self, s: &'a str) -> Self::MatchIndicesIter<'a>
where
Self: 'a;
fn rmatch_indices<'a>(self, s: &'a str) -> Self::RMatchIndicesIter<'a>
where
Self: 'a;
fn contains(&self, s: &str) -> bool;
fn starts_with(&self, s: &str) -> bool;
fn ends_with(&self, s: &str) -> bool;
fn find(&self, s: &str) -> Option<usize>;
fn rfind(&self, s: &str) -> Option<usize>;
}
impl<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool>
GString<V, MIN, MAX, ASCII_ONLY>
{
#[inline]
pub fn contains<P>(&self, pat: P) -> bool
where
P: Pattern,
{
pat.contains(self.as_str())
}
#[inline]
pub fn starts_with<P>(&self, pat: P) -> bool
where
P: Pattern,
{
pat.starts_with(self.as_str())
}
#[inline]
pub fn ends_with<P>(&self, pat: P) -> bool
where
P: Pattern,
{
pat.ends_with(self.as_str())
}
#[inline]
pub fn find<P>(&self, pat: P) -> Option<usize>
where
P: Pattern,
{
pat.find(self.as_str())
}
#[inline]
pub fn rfind<P>(&self, pat: P) -> Option<usize>
where
P: Pattern,
{
pat.rfind(self.as_str())
}
}
impl<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool>
GString<V, MIN, MAX, ASCII_ONLY>
{
#[inline]
pub fn get<I>(&self, i: I) -> Option<&<I as core::slice::SliceIndex<str>>::Output>
where
I: core::slice::SliceIndex<str>,
{
self.as_str().get(i)
}
}
impl<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool>
GString<V, MIN, MAX, ASCII_ONLY>
{
#[inline]
pub fn split<P: Pattern>(&self, pat: P) -> P::SplitIter<'_> {
pat.split(self.as_str())
}
#[inline]
pub fn split_whitespace(&self) -> SplitWhitespace<'_> {
self.as_str().split_whitespace()
}
#[inline]
pub fn lines(&self) -> Lines<'_> {
self.as_str().lines()
}
#[inline]
pub fn split_once<P: Pattern>(&self, delimiter: P) -> Option<(&str, &str)> {
delimiter.split_once(self.as_str())
}
#[inline]
pub fn rsplit_once<P: Pattern>(&self, delimiter: P) -> Option<(&str, &str)> {
delimiter.rsplit_once(self.as_str())
}
}
impl<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool>
GString<V, MIN, MAX, ASCII_ONLY>
{
#[inline]
pub fn try_trim(&self) -> Result<Self, GStringError<V::Err>> {
Self::try_new(self.as_str().trim())
}
#[inline]
pub fn try_trim_start(&self) -> Result<Self, GStringError<V::Err>> {
Self::try_new(self.as_str().trim_start())
}
#[inline]
pub fn try_trim_end(&self) -> Result<Self, GStringError<V::Err>> {
Self::try_new(self.as_str().trim_end())
}
#[inline]
pub fn strip_prefix<P: Pattern>(&self, prefix: P) -> Option<&str> {
prefix.strip_prefix(self.as_str())
}
#[inline]
pub fn strip_suffix<P: Pattern>(&self, suffix: P) -> Option<&str> {
suffix.strip_suffix(self.as_str())
}
}
impl<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool>
GString<V, MIN, MAX, ASCII_ONLY>
{
#[inline]
pub fn matches<P: Pattern>(&self, pat: P) -> P::MatchesIter<'_> {
pat.matches(self.as_str())
}
#[inline]
pub fn rmatches<P: Pattern>(&self, pat: P) -> P::RMatchesIter<'_> {
pat.rmatches(self.as_str())
}
#[inline]
pub fn match_indices<P: Pattern>(&self, pat: P) -> P::MatchIndicesIter<'_> {
pat.match_indices(self.as_str())
}
#[inline]
pub fn rmatch_indices<P: Pattern>(&self, pat: P) -> P::RMatchIndicesIter<'_> {
pat.rmatch_indices(self.as_str())
}
}
impl<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool>
GString<V, MIN, MAX, ASCII_ONLY>
{
#[inline]
pub fn parse<F>(&self) -> Result<F, F::Err>
where
F: FromStr,
{
self.as_str().parse()
}
#[inline]
pub fn is_ascii(&self) -> bool {
self.as_str().is_ascii()
}
#[inline]
pub fn eq_ignore_ascii_case(&self, other: &str) -> bool {
self.as_str().eq_ignore_ascii_case(other)
}
}
impl<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool>
GString<V, MIN, MAX, ASCII_ONLY>
{
#[inline]
pub fn escape_debug(&self) -> EscapeDebug<'_> {
self.as_str().escape_debug()
}
#[inline]
pub fn escape_default(&self) -> EscapeDefault<'_> {
self.as_str().escape_default()
}
#[inline]
pub fn escape_unicode(&self) -> EscapeUnicode<'_> {
self.as_str().escape_unicode()
}
}
impl<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool>
GString<V, MIN, MAX, ASCII_ONLY>
{
#[inline]
pub fn encode_utf16(&self) -> EncodeUtf16<'_> {
self.as_str().encode_utf16()
}
}