use std::char;
use std::fmt::Debug;
pub trait UCSChar: Debug + Sized + Default + Copy + Ord + Eq {
const NULL: Self;
fn is_in_range(&self, low: u32, high: u32) -> bool;
fn is_contains(&self, search: &[u32]) -> bool;
fn is_match(&self, target: u32) -> bool;
fn is_surrogate(&self) -> bool;
fn is_high_surrogate(&self) -> bool;
fn is_low_surrogate(&self) -> bool;
fn is_null(&self) -> bool;
fn addition(&self, value: u32) -> Self;
fn subtraction(&self, value: u32) -> Self;
fn as_scalar(&self) -> u32;
fn from_scalar<T>(value: T) -> Self where T: UCSChar;
}
impl UCSChar for char {
const NULL: char = 0 as char;
#[inline]
fn is_in_range(&self, low: u32, high: u32) -> bool {
let target_trans = *self as u32;
target_trans >= low && target_trans <= high
}
#[inline]
fn is_contains(&self, search: &[u32]) -> bool {
let target_trans = *self as u32;
search.contains(&target_trans)
}
#[inline]
fn is_match(&self, target: u32) -> bool {
(*self as u32) == target
}
#[inline]
fn is_surrogate(&self) -> bool {
Self::is_high_surrogate(self) || Self::is_low_surrogate(self)
}
#[inline]
fn is_high_surrogate(&self) -> bool {
let scalar = self.as_scalar();
0xD800 <= scalar && scalar < 0xDC00
}
#[inline]
fn is_low_surrogate(&self) -> bool {
let scalar = self.as_scalar();
0xDC00 <= scalar && scalar < 0xE000
}
#[inline]
fn is_null(&self) -> bool {
*self == Self::NULL
}
#[inline]
fn addition(&self, value: u32) -> Self {
unsafe { char::from_u32_unchecked((*self as u32) + value) }
}
#[inline]
fn subtraction(&self, value: u32) -> Self {
unsafe { char::from_u32_unchecked((*self as u32) - value) }
}
#[inline]
fn as_scalar(&self) -> u32 {
*self as u32
}
#[inline]
fn from_scalar<T>(value: T) -> Self where T: UCSChar {
unsafe { char::from_u32_unchecked(value.as_scalar()) }
}
}
impl UCSChar for u16 {
const NULL: u16 = 0;
#[inline]
fn is_in_range(&self, low: u32, high: u32) -> bool {
let target_trans = *self as u32;
target_trans >= low && target_trans <= high
}
#[inline]
fn is_contains(&self, search: &[u32]) -> bool {
let target_trans = *self as u32;
search.contains(&target_trans)
}
#[inline]
fn is_match(&self, target: u32) -> bool {
(*self as u32) == target
}
#[inline]
fn is_surrogate(&self) -> bool {
Self::is_high_surrogate(self) || Self::is_low_surrogate(self)
}
#[inline]
fn is_high_surrogate(&self) -> bool {
let scalar = self.as_scalar();
0xD800 <= scalar && scalar < 0xDC00
}
#[inline]
fn is_low_surrogate(&self) -> bool {
let scalar = self.as_scalar();
0xDC00 <= scalar && scalar < 0xE000
}
#[inline]
fn is_null(&self) -> bool {
*self == Self::NULL
}
#[inline]
fn addition(&self, value: u32) -> Self {
((*self as u32) + value) as u16
}
#[inline]
fn subtraction(&self, value: u32) -> Self {
((*self as u32) - value) as u16
}
#[inline]
fn as_scalar(&self) -> u32 {
*self as u32
}
#[inline]
fn from_scalar<T>(value: T) -> Self where T: UCSChar {
value.as_scalar() as u16
}
}
impl UCSChar for u32 {
const NULL: u32 = 0;
#[inline]
fn is_in_range(&self, low: u32, high: u32) -> bool {
let target_trans = *self;
target_trans >= low && target_trans <= high
}
#[inline]
fn is_contains(&self, search: &[u32]) -> bool {
search.contains(self)
}
#[inline]
fn is_match(&self, target: u32) -> bool {
(*self) == target
}
#[inline]
fn is_surrogate(&self) -> bool {
Self::is_high_surrogate(self) || Self::is_low_surrogate(self)
}
#[inline]
fn is_high_surrogate(&self) -> bool {
let scalar = self.as_scalar();
0xD800 <= scalar && scalar < 0xDC00
}
#[inline]
fn is_low_surrogate(&self) -> bool {
let scalar = self.as_scalar();
0xDC00 <= scalar && scalar < 0xE000
}
#[inline]
fn is_null(&self) -> bool {
*self == Self::NULL
}
#[inline]
fn addition(&self, value: u32) -> Self {
((*self) + value) as u32
}
#[inline]
fn subtraction(&self, value: u32) -> Self {
((*self) - value) as u32
}
#[inline]
fn as_scalar(&self) -> u32 {
*self
}
#[inline]
fn from_scalar<T>(value: T) -> Self where T: UCSChar {
value.as_scalar()
}
}