use std::marker::PhantomData;
use std::{error::Error, fmt::Display};
use crate::mode::*;
use crate::rcore::*;
use crate::rstd::inlining::*;
impl<'a, Ctx: Context<'a>, A: MentionableBase<'a>> Serializable for Point<'a, Ctx, A> {
fn serialize(&self, serializer: &mut dyn Serializer) {
serializer.write(&self.point)
}
}
impl<'a, Ctx: Context<'a>, A: MentionableBase<'a>> MentionableBase<'a> for Point<'a, Ctx, A> {
type Fctr = PointFactory<Ctx, A::Fctr>;
fn factory(&self) -> Self::Fctr {
PointFactory::new(self.origin.factory())
}
}
impl<Ctx, F> PointFactory<Ctx, F> {
fn new(factory: F) -> Self {
Self {
factory,
_ctx: PhantomData,
}
}
}
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> MentionableTop<'a, Ctx> for Point<'a, Ctx, A> {
fn topology_hash(&self) -> Hash {
Ctx::hash(&self.point)
}
fn points_typed(&self, points: &mut impl PointsVisitor<'a, Ctx>) {
points.visit(self)
}
}
pub struct PointFactory<Ctx, F> {
factory: F,
_ctx: PhantomData<Ctx>,
}
impl<Ctx, F: Clone> Clone for PointFactory<Ctx, F> {
fn clone(&self) -> Self {
Self::new(self.factory.clone())
}
}
impl<Ctx, F: Clone> PointFactory<Ctx, F> {
pub fn inner(&self) -> F {
self.factory.clone()
}
}
#[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: MentionableBase<'a>> AsRef<[u8]> for Point<'a, Ctx, A> {
fn as_ref(&self) -> &[u8] {
&self.point
}
}
impl<'a, Ctx: Context<'a>, F: FactoryBase<'a>> FactoryBase<'a> for PointFactory<Ctx, F> {
type Mtbl = Point<'a, Ctx, F::Mtbl>;
type ParseError = PointParseError;
}
impl<Ctx, F> ImplMode for PointFactory<Ctx, F> {
type Mode = InliningMode;
}
impl<'a, Ctx: Context<'a>, F: FactoryBase<'a>> CInliningFactory<'a, Ctx> for PointFactory<Ctx, F> {
fn cextension_error(&self, tail: &[u8]) -> Self::ParseError {
PointParseError::WrongLength(HASH_SIZE + tail.len())
}
fn cideserialize<I: InCtx<'a, Ctx>>(&self, inctx: I) -> IParseResult<'a, Self, I> {
inctx.icnext_point(self.inner(), PointParseError::from_ref)
}
}
impl<Ctx, F> AlwaysConstSize for PointFactory<Ctx, F> {
const ASIZE: usize = HASH_SIZE;
}