pub trait Unpackage {
type Input;
type Media;
type Error;
fn unpackage(&mut self, input: Self::Input) -> Result<Self::Media, Self::Error>;
}
pub trait Package {
type Media;
type Output;
type Error;
fn package(&mut self, media: &Self::Media) -> Result<Self::Output, Self::Error>;
}
pub trait Decrypt {
type Media;
type Keys;
type Error;
fn decrypt(&self, media: &mut Self::Media, keys: &Self::Keys) -> Result<(), Self::Error>;
}
pub trait Encrypt {
type Media;
type Config;
type Error;
fn encrypt(&self, media: &mut Self::Media, cfg: &Self::Config) -> Result<(), Self::Error>;
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::vec::Vec;
#[derive(Debug, Clone, PartialEq, Eq, Default)]
struct Media {
tracks: Vec<Vec<u8>>,
}
struct Codec;
impl Unpackage for Codec {
type Input = &'static [u8];
type Media = Media;
type Error = ();
fn unpackage(&mut self, input: Self::Input) -> Result<Self::Media, Self::Error> {
Ok(Media {
tracks: input.iter().map(|b| alloc::vec![*b]).collect(),
})
}
}
impl Package for Codec {
type Media = Media;
type Output = Vec<u8>;
type Error = ();
fn package(&mut self, media: &Self::Media) -> Result<Self::Output, Self::Error> {
Ok(media.tracks.iter().map(|t| t[0]).collect())
}
}
impl Decrypt for Codec {
type Media = Media;
type Keys = u8;
type Error = ();
fn decrypt(&self, media: &mut Self::Media, keys: &Self::Keys) -> Result<(), Self::Error> {
for t in &mut media.tracks {
for b in t {
*b ^= *keys;
}
}
Ok(())
}
}
impl Encrypt for Codec {
type Media = Media;
type Config = u8;
type Error = ();
fn encrypt(&self, media: &mut Self::Media, cfg: &Self::Config) -> Result<(), Self::Error> {
for t in &mut media.tracks {
for b in t {
*b ^= *cfg;
}
}
Ok(())
}
}
#[test]
fn traits_compile_and_round_trip() {
let mut codec = Codec;
let input: &'static [u8] = &[1, 2, 3];
let media = codec.unpackage(input).unwrap();
assert_eq!(media.tracks.len(), 3);
assert_eq!(codec.package(&media).unwrap(), alloc::vec![1u8, 2, 3]);
let mut m = media.clone();
codec.encrypt(&mut m, &0xAA).unwrap();
assert_ne!(m, media);
codec.decrypt(&mut m, &0xAA).unwrap();
assert_eq!(m, media);
}
}