use std::borrow::Borrow;
use std::ops::Deref;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct DecodedChar {
c: char,
len: usize,
}
impl DecodedChar {
#[inline(always)]
pub fn new(c: char, len: usize) -> Self {
Self { c, len }
}
#[inline(always)]
pub fn from_utf8(c: char) -> Self {
Self {
c,
len: c.len_utf8(),
}
}
#[inline(always)]
pub fn from_utf16(c: char) -> Self {
Self {
c,
len: c.len_utf16(),
}
}
#[inline(always)]
pub fn chr(&self) -> char {
self.c
}
#[inline(always)]
#[allow(clippy::len_without_is_empty)]
pub fn len(&self) -> usize {
self.len
}
#[inline(always)]
pub fn into_char(self) -> char {
self.c
}
#[inline(always)]
pub fn into_len(self) -> usize {
self.len
}
}
impl From<DecodedChar> for char {
#[inline(always)]
fn from(dc: DecodedChar) -> Self {
dc.into_char()
}
}
impl From<DecodedChar> for u32 {
#[inline(always)]
fn from(dc: DecodedChar) -> Self {
dc.into_char().into()
}
}
impl AsRef<char> for DecodedChar {
#[inline(always)]
fn as_ref(&self) -> &char {
&self.c
}
}
impl Borrow<char> for DecodedChar {
#[inline(always)]
fn borrow(&self) -> &char {
&self.c
}
}
impl Deref for DecodedChar {
type Target = char;
#[inline(always)]
fn deref(&self) -> &char {
&self.c
}
}
#[derive(Clone, Debug)]
pub struct Utf8Decoded<C>(pub C);
impl<C> Utf8Decoded<C> {
#[inline(always)]
pub fn new(chars: C) -> Self {
Self(chars)
}
}
impl<C: Iterator<Item = char>> Iterator for Utf8Decoded<C> {
type Item = DecodedChar;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(DecodedChar::from_utf8)
}
}
#[derive(Clone, Debug)]
pub struct FallibleUtf8Decoded<C>(pub C);
impl<C> FallibleUtf8Decoded<C> {
#[inline(always)]
pub fn new(chars: C) -> Self {
Self(chars)
}
}
impl<E, C: Iterator<Item = Result<char, E>>> Iterator for FallibleUtf8Decoded<C> {
type Item = Result<DecodedChar, E>;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
self.0
.next()
.map(|result| result.map(DecodedChar::from_utf8))
}
}
#[derive(Clone, Debug)]
pub struct Utf16Decoded<C>(pub C);
impl<C> Utf16Decoded<C> {
#[inline(always)]
pub fn new(chars: C) -> Self {
Self(chars)
}
}
impl<C: Iterator<Item = char>> Iterator for Utf16Decoded<C> {
type Item = DecodedChar;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(DecodedChar::from_utf16)
}
}
#[derive(Clone, Debug)]
pub struct FallibleUtf16Decoded<C>(pub C);
impl<C> FallibleUtf16Decoded<C> {
#[inline(always)]
pub fn new(chars: C) -> Self {
Self(chars)
}
}
impl<E, C: Iterator<Item = Result<char, E>>> Iterator for FallibleUtf16Decoded<C> {
type Item = Result<DecodedChar, E>;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
self.0
.next()
.map(|result| result.map(DecodedChar::from_utf16))
}
}
pub trait DecodedChars {
fn decoded_chars(&self) -> Utf8Decoded<std::str::Chars>;
}
impl DecodedChars for str {
fn decoded_chars(&self) -> Utf8Decoded<std::str::Chars> {
Utf8Decoded(self.chars())
}
}