use crate::OtToolsIoError;
use serde::{Deserialize, Serialize};
use std::fmt::Debug;
use std::path::Path;
pub trait OctatrackFileIO: Serialize + for<'a> Deserialize<'a> {
fn repr(&self, newlines: Option<bool>)
where
Self: Debug,
{
if newlines.unwrap_or(true) {
println!("{self:#?}")
} else {
println!("{self:?}")
};
}
fn from_data_file(path: &Path) -> Result<Self, OtToolsIoError> {
let bytes = crate::read_bin_file(path)?;
let data = Self::from_bytes(&bytes)?;
Ok(data)
}
fn from_bytes(bytes: &[u8]) -> Result<Self, OtToolsIoError> {
let x = Self::decode(bytes)?;
Ok(x)
}
fn to_data_file(&self, path: &Path) -> Result<(), OtToolsIoError> {
let bytes = Self::to_bytes(self)?;
crate::write_bin_file(&bytes, path)?;
Ok(())
}
fn to_bytes(&self) -> Result<Vec<u8>, OtToolsIoError> {
self.encode()
}
fn from_yaml_file(path: &Path) -> Result<Self, OtToolsIoError> {
let string = crate::read_str_file(path)?;
let data = Self::from_yaml_str(&string)?;
Ok(data)
}
fn from_yaml_str(yaml: &str) -> Result<Self, OtToolsIoError> {
let x = serde_yml::from_str(yaml)?;
Ok(x)
}
fn to_yaml_file(&self, path: &Path) -> Result<(), OtToolsIoError> {
let yaml = Self::to_yaml_string(self)?;
crate::write_str_file(&yaml, path)?;
Ok(())
}
fn to_yaml_string(&self) -> Result<String, OtToolsIoError> {
Ok(serde_yml::to_string(self)?)
}
fn from_json_file(path: &Path) -> Result<Self, OtToolsIoError> {
let string = crate::read_str_file(path)?;
let data = Self::from_yaml_str(&string)?;
Ok(data)
}
fn from_json_str(json: &str) -> Result<Self, OtToolsIoError> {
Ok(serde_json::from_str::<Self>(json)?)
}
fn to_json_file(&self, path: &Path) -> Result<(), OtToolsIoError> {
let yaml = Self::to_json_string(self)?;
crate::write_str_file(&yaml, path)?;
Ok(())
}
fn to_json_string(&self) -> Result<String, OtToolsIoError> {
Ok(serde_json::to_string(&self)?)
}
fn encode(&self) -> Result<Vec<u8>, OtToolsIoError>
where
Self: Serialize,
{
Ok(bincode::serialize(&self)?)
}
fn decode(bytes: &[u8]) -> Result<Self, OtToolsIoError>
where
Self: Sized,
Self: for<'a> Deserialize<'a>,
{
bincode::deserialize::<Self>(bytes).map_err(|e| e.into())
}
}
pub(crate) trait SwapBytes {
fn swap_bytes(self) -> Self
where
Self: Sized;
}
pub trait Defaults<T> {
fn defaults() -> T
where
Self: Default;
}
pub trait IsDefault {
fn is_default(&self) -> bool
where
Self: Default + PartialEq,
{
&Self::default() == self
}
}
pub trait HasChecksumField {
fn calculate_checksum(&self) -> Result<u16, OtToolsIoError>;
fn check_checksum(&self) -> Result<bool, OtToolsIoError>;
}
pub trait HasHeaderField {
fn check_header(&self) -> Result<bool, OtToolsIoError>;
}
pub trait HasFileVersionField {
fn check_file_version(&self) -> Result<bool, OtToolsIoError>;
}
pub trait CheckFileIntegrity: HasHeaderField + HasChecksumField + HasFileVersionField {
fn check_integrity(&self) -> Result<bool, OtToolsIoError> {
Ok(self.check_header()? && self.check_checksum()? && self.check_file_version()?)
}
}