use binrw::{BinRead, BinReaderExt, BinResult, BinWrite, BinWriterExt, ReadOptions, WriteOptions};
use rgb::RGB8;
use serde::{Deserialize, Serialize};
use std::{
io::{Cursor, Read, Seek},
str::FromStr,
};
pub trait ToVec: BinWrite {
fn to_vec(self) -> Vec<u8>;
}
impl<T> ToVec for T
where
<T as BinWrite>::Args: Default,
T: BinWrite,
{
fn to_vec(self) -> Vec<u8> {
let mut buf = Cursor::new(Vec::new());
self.write_to(&mut buf).unwrap();
buf.into_inner()
}
}
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct OwnRGB8(RGB8);
impl OwnRGB8 {
pub fn new(r: u8, g: u8, b: u8) -> Self {
Self(RGB8 { r, g, b })
}
}
impl From<RGB8> for OwnRGB8 {
fn from(val: RGB8) -> Self {
Self(val)
}
}
impl BinRead for OwnRGB8 {
type Args = ();
fn read_options<R: Read + Seek>(
reader: &mut R,
_: &ReadOptions,
_: Self::Args,
) -> BinResult<Self> {
let rgb = RGB8 {
r: reader.read_ne()?,
g: reader.read_ne()?,
b: reader.read_ne()?,
};
Ok(Self(rgb))
}
}
impl BinWrite for OwnRGB8 {
type Args = ();
fn write_options<W: std::io::Write + Seek>(
&self,
writer: &mut W,
_: &WriteOptions,
_: Self::Args,
) -> BinResult<()> {
writer.write_ne(&self.0.r)?;
writer.write_ne(&self.0.g)?;
writer.write_ne(&self.0.b)?;
Ok(())
}
}
impl FromStr for OwnRGB8 {
type Err = hex::FromHexError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let val = match s.len() {
6 => {
let bytes = hex::decode(s)?;
RGB8 {
r: bytes[0],
g: bytes[1],
b: bytes[2],
}
.into()
}
_ => {
return Err(hex::FromHexError::InvalidStringLength);
}
};
Ok(val)
}
}