use std::str;
use crate::{
common::{buf2lstr, str_from_utf8},
ErrorKind,
};
pub trait ParseUtf8<'a> {
fn parse_as_utf8<T: FromUtf8<'a>>(self) -> Result<T, ErrorKind>;
}
pub trait FromUtf8<'a>: Sized {
fn from_utf8(buf: &'a [u8]) -> Result<Self, ErrorKind>;
}
impl<'a> ParseUtf8<'a> for &'a [u8] {
fn parse_as_utf8<T: FromUtf8<'a>>(self: &'a [u8]) -> Result<T, ErrorKind> {
T::from_utf8(self)
}
}
impl<'a> FromUtf8<'a> for &'a str {
fn from_utf8(buf: &'a [u8]) -> Result<Self, ErrorKind> {
str_from_utf8(buf)
}
}
impl FromUtf8<'_> for String {
fn from_utf8(buf: &[u8]) -> Result<Self, ErrorKind> {
Ok(str_from_utf8(buf)?.to_owned())
}
}
impl FromUtf8<'_> for Box<str> {
fn from_utf8(buf: &[u8]) -> Result<Self, ErrorKind> {
Ok(str_from_utf8(buf)?.into())
}
}
impl FromUtf8<'_> for bool {
fn from_utf8(buf: &[u8]) -> Result<Self, ErrorKind> {
if buf == b"T" {
Ok(true)
} else if buf == b"F" {
Ok(false)
} else {
Err(ErrorKind::ExpectedBool(buf2lstr(buf)))
}
}
}
impl FromUtf8<'_> for u8 {
fn from_utf8(buf: &[u8]) -> Result<Self, ErrorKind> {
let s = str_from_utf8(buf)?;
s.parse().map_err(|e| ErrorKind::ExpectedInt(s.into(), e))
}
}
impl FromUtf8<'_> for i8 {
fn from_utf8(buf: &[u8]) -> Result<Self, ErrorKind> {
let s = str_from_utf8(buf)?;
s.parse().map_err(|e| ErrorKind::ExpectedInt(s.into(), e))
}
}
impl FromUtf8<'_> for u16 {
fn from_utf8(buf: &[u8]) -> Result<Self, ErrorKind> {
let s = str_from_utf8(buf)?;
s.parse().map_err(|e| ErrorKind::ExpectedInt(s.into(), e))
}
}
impl FromUtf8<'_> for i16 {
fn from_utf8(buf: &[u8]) -> Result<Self, ErrorKind> {
let s = str_from_utf8(buf)?;
s.parse().map_err(|e| ErrorKind::ExpectedInt(s.into(), e))
}
}
impl FromUtf8<'_> for u32 {
fn from_utf8(buf: &[u8]) -> Result<Self, ErrorKind> {
let s = str_from_utf8(buf)?;
s.parse().map_err(|e| ErrorKind::ExpectedInt(s.into(), e))
}
}
impl FromUtf8<'_> for i32 {
fn from_utf8(buf: &[u8]) -> Result<Self, ErrorKind> {
let s = str_from_utf8(buf)?;
s.parse().map_err(|e| ErrorKind::ExpectedInt(s.into(), e))
}
}
impl FromUtf8<'_> for f32 {
fn from_utf8(buf: &[u8]) -> Result<Self, ErrorKind> {
let s = str_from_utf8(buf)?;
s.parse().map_err(|e| ErrorKind::ExpectedFloat(s.into(), e))
}
}
impl FromUtf8<'_> for usize {
fn from_utf8(buf: &[u8]) -> Result<Self, ErrorKind> {
let s = str_from_utf8(buf)?;
s.parse().map_err(|e| ErrorKind::ExpectedInt(s.into(), e))
}
}