//! Module responsible for making [Point]s [Mentionable]. use std::{error::Error, fmt::Display, rc::Rc}; use crate::rcore::*; impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Serializable for Point<'a, Ctx, A> { fn serialize(&self, serializer: &mut dyn Serializer) { serializer.write(&self.point) } } impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for Point<'a, Ctx, A> { type Fctr = PointFactory; fn factory(&self) -> Self::Fctr { PointFactory { factory: self.origin.factory(), } } fn topology(&self) -> Hash { Ctx::hash(&self.point) } fn points_typed(&self, points: &mut impl TakesPoints<'a, Ctx>) { points.take(self) } } #[derive(Clone)] pub struct PointFactory { factory: F, } #[derive(Debug)] pub enum PointParseError { WrongLength(usize), } impl Display for PointParseError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::WrongLength(length) => { write!(f, "expected {} bytes, received {}.", HASH_SIZE, length) } } } } impl Error for PointParseError {} impl From<&[u8]> for PointParseError { fn from(value: &[u8]) -> Self { PointParseError::WrongLength(value.len()) } } impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> AsRef<[u8]> for Point<'a, Ctx, A> { fn as_ref(&self) -> &[u8] { &self.point } } impl<'a, Ctx: Context<'a>, F: Factory<'a, Ctx>> Factory<'a, Ctx> for PointFactory { type Mtbl = Point<'a, Ctx, F::Mtbl>; type ParseError = PointParseError; fn deserialize( &self, deserializer: &mut dyn Deserializer, resolver: Rc>, addresses: &mut Addresses, ) -> ParseResult<'a, Ctx, Self> { Ok(addresses.next_point(deserializer, resolver, self.factory.clone())?) } fn extend(&self, _mentionable: Self::Mtbl, tail: &[u8]) -> ParseResult<'a, Ctx, Self> { Err(PointParseError::WrongLength(HASH_SIZE + tail.len())) } }