use core::char;
use core::cmp::Ordering;
use core::fmt;
use crate::helpers::cmp_iter;
#[cfg(feature = "alloc")]
use {
crate::error::Result,
alloc::string::String,
alloc::vec::Vec,
widestring::{decode_utf16, decode_utf16_lossy, U16String},
};
#[derive(Clone, Debug, Eq)]
pub struct U16StrLe<'a>(pub &'a [u8]);
impl<'a> U16StrLe<'a> {
pub const fn is_empty(&self) -> bool {
self.len() == 0
}
pub const fn len(&self) -> usize {
self.0.len()
}
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
pub fn to_string(&self) -> Result<String> {
decode_utf16(self.u16_iter())
.collect::<Result<String, _>>()
.map_err(Into::into)
}
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
pub fn to_string_lossy(&self) -> String {
decode_utf16_lossy(self.u16_iter()).collect()
}
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
pub fn to_ustring(&self) -> U16String {
U16String::from_vec(self.u16_iter().collect::<Vec<u16>>())
}
pub fn u16_iter(&'a self) -> impl Iterator<Item = u16> + 'a {
self.0
.chunks_exact(2)
.map(|two_bytes| u16::from_le_bytes(two_bytes.try_into().unwrap()))
}
}
impl<'a> fmt::Display for U16StrLe<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let utf16_iter =
char::decode_utf16(self.u16_iter()).map(|x| x.unwrap_or(char::REPLACEMENT_CHARACTER));
for single_char in utf16_iter {
single_char.fmt(f)?;
}
Ok(())
}
}
impl<'a> Ord for U16StrLe<'a> {
fn cmp(&self, other: &Self) -> Ordering {
cmp_iter(self.u16_iter(), other.u16_iter())
}
}
impl<'a, 'b> PartialEq<U16StrLe<'a>> for U16StrLe<'b> {
fn eq(&self, other: &U16StrLe<'a>) -> bool {
self.0 == other.0
}
}
impl<'a> PartialEq<str> for U16StrLe<'a> {
fn eq(&self, other: &str) -> bool {
cmp_iter(self.u16_iter(), other.encode_utf16()) == Ordering::Equal
}
}
impl<'a> PartialEq<U16StrLe<'a>> for str {
fn eq(&self, other: &U16StrLe<'a>) -> bool {
cmp_iter(self.encode_utf16(), other.u16_iter()) == Ordering::Equal
}
}
impl<'a> PartialEq<&str> for U16StrLe<'a> {
fn eq(&self, other: &&str) -> bool {
cmp_iter(self.u16_iter(), other.encode_utf16()) == Ordering::Equal
}
}
impl<'a> PartialEq<U16StrLe<'a>> for &str {
fn eq(&self, other: &U16StrLe<'a>) -> bool {
cmp_iter(self.encode_utf16(), other.u16_iter()) == Ordering::Equal
}
}
impl<'a, 'b> PartialOrd<U16StrLe<'a>> for U16StrLe<'b> {
fn partial_cmp(&self, other: &U16StrLe<'a>) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<'a> PartialOrd<str> for U16StrLe<'a> {
fn partial_cmp(&self, other: &str) -> Option<Ordering> {
Some(cmp_iter(self.u16_iter(), other.encode_utf16()))
}
}
impl<'a> PartialOrd<U16StrLe<'a>> for str {
fn partial_cmp(&self, other: &U16StrLe<'a>) -> Option<Ordering> {
Some(cmp_iter(self.encode_utf16(), other.u16_iter()))
}
}
impl<'a> PartialOrd<&str> for U16StrLe<'a> {
fn partial_cmp(&self, other: &&str) -> Option<Ordering> {
Some(cmp_iter(self.u16_iter(), other.encode_utf16()))
}
}
impl<'a> PartialOrd<U16StrLe<'a>> for &str {
fn partial_cmp(&self, other: &U16StrLe<'a>) -> Option<Ordering> {
Some(cmp_iter(self.encode_utf16(), other.u16_iter()))
}
}