use crate::utf_32::Utf32;
use crate::utf_8::Utf8;
use std::fs;
pub trait UnicodeEncoding {
fn from_utf_32(data_utf_32: &Utf32) -> Self;
fn to_utf_32(&self) -> Utf32;
fn from_bytes_no_check(bytes: &[u8], big_endian: bool) -> Result<Self, UnicodeEncodingError> where Self: Sized;
fn to_bytes(&self, big_endian: bool) -> Vec<u8>;
fn to_string(&self) -> String {
let utf8 = self.convert_to::<Utf8>();
return utf8.to_string();
}
fn from_string(s: &str) -> Result<Self, UnicodeEncodingError> where Self: Sized {
let utf8 = Utf8::from_string(s)?;
return Ok(utf8.convert_to::<Self>());
}
fn convert_to<T: UnicodeEncoding> (&self) -> T {
let utf32 = self.to_utf_32();
let ret: T = T::from_utf_32(&utf32);
return ret;
}
fn content_eq<T: UnicodeEncoding>(&self, other: &T) -> bool {
return self.to_utf_32() == other.to_utf_32();
}
fn check_sanity(&self) -> UnicodeEncodingError {
let utf32 = self.to_utf_32();
return utf32.check_sanity_utf32();
}
fn from_bytes(bytes: &[u8], big_endian: bool) -> Result<Self, UnicodeEncodingError> where Self: Sized {
let ret: Self = Self::from_bytes_no_check(bytes, big_endian)?;
match ret.check_sanity() {
UnicodeEncodingError::NoError => Ok(ret),
x => Err(x),
}
}
fn from_file(filename: &str, big_endian: bool) -> Result<Result<Self, UnicodeEncodingError>, std::io::Error> where Self: Sized {
let bytes = fs::read(filename)?;
return Ok(Self::from_bytes(&bytes, big_endian));
}
fn to_file(data: &Self, filename: &str, big_endian: bool) -> Option<std::io::Error> {
let bytes = data.to_bytes(big_endian);
match fs::write(filename, &bytes) {
Ok(_) => None,
Err(x) => Some(x),
}
}
}
#[derive(Debug)]
pub enum UnicodeEncodingError {
NoError,
InvalidCodepointTooManyBits,
InvalidUtf8Prefix,
IncoherentUtf8Codepoint,
InvalidStreamSize,
AmbiguousUnpairedSurrogates,
UnpairedSurrogateNotification,
MissingEncodedBytes,
}