use std::{
fmt::Debug,
hash::{Hash, Hasher},
marker::PhantomData,
};
use thiserror::Error;
use crate::{DecodeError, Group, Models};
#[derive(Debug, Error)]
#[error("Invalid point data")]
pub struct InvalidPointData<T: Debug> {
pub model: T,
}
#[derive(Debug, Error)]
pub enum ParseError<T: Debug> {
#[error(transparent)]
Decode(#[from] DecodeError),
#[error(transparent)]
InvalidPointData(InvalidPointData<T>),
}
pub trait Model: Sized + Group + Debug {
const ID: u16;
fn addr(models: &Models) -> ModelAddr<Self>;
fn parse(data: &[u16]) -> Result<Self, ParseError<Self>>;
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
pub struct ModelAddr<M: Model> {
pub addr: u16,
pub len: u16,
model: PhantomData<M>,
}
impl<M: Model> ModelAddr<M> {
pub fn set_addr(&mut self, addr: u16, len: u16) {
self.addr = addr;
self.len = len;
}
}
impl<M: Model> Clone for ModelAddr<M> {
fn clone(&self) -> Self {
*self
}
}
impl<M: Model> Copy for ModelAddr<M> {}
impl<M: Model> PartialEq for ModelAddr<M> {
fn eq(&self, other: &Self) -> bool {
self.addr == other.addr && self.len == other.len
}
}
impl<M: Model> Eq for ModelAddr<M> {}
impl<M: Model> Hash for ModelAddr<M> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.addr.hash(state);
self.len.hash(state);
}
}
impl<M: Model> Default for ModelAddr<M> {
fn default() -> Self {
Self {
addr: Default::default(),
len: Default::default(),
model: Default::default(),
}
}
}