//! Module responsible for making [Point]s [Mentionable]. use std::{error::Error, fmt::Display, rc::Rc}; use crate::core::*; impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Serializable for Point<'a, Ctx, A> { fn serialize(&self, serializer: &mut dyn Serializer) { serializer.write(&self.point) } } impl<'a, Ctx: 'a + Context, 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(&self, points: &mut Vec>>) { points.push(self.typeless()); } } #[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 { PointParseError::WrongLength(length) => f.write_fmt(format_args!( "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: 'a + Context, A: Mentionable<'a, Ctx>> AsRef<[u8]> for Point<'a, Ctx, A> { fn as_ref(&self) -> &[u8] { &self.point } } impl<'a, Ctx: 'a + Context, 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 unexpected_tail(&self, tail: &[u8]) -> Self::ParseError { PointParseError::WrongLength(HASH_SIZE + tail.len()) } }