radn-rs/src/atomic.rs

81 lines
2.6 KiB
Rust

//! This module allows to describe a primitive subset of [Mentionable] types, [Atomic]s,
//! simple static types, which are completely [Context]-independent.
//!
//! [Mentionable]: crate::rcore::Mentionable
//! [Context]: crate::rcore::Context
mod inlining;
mod modes;
mod regular;
use std::error::Error;
use crate::mode::*;
pub use self::inlining::{AIParseResult, CInliningAtomic, InliningAtomic};
pub use self::modes::{
AExtensionResultM, AExtensionSourceM, AModeResultM, AtomicModeParse, AtomicModeProxy,
};
pub use self::regular::{CRegularAtomic, RegularAtomic};
/// [`Atomic`] version of [`ParseError`].
///
/// [`ParseError`]: crate::rcore::ParseError
pub type AParseError<A> = <A as AtomicBase>::AParseError;
/// [`Atomic`] version of [`ParseResult`]
///
/// [`ParseResult`]: crate::rcore::ParseResult
pub type AParseResult<A> = Result<A, AParseError<A>>;
/// [`Atomic`] base.
pub trait AtomicBase: 'static + Send + Sync + Clone + Serializable {
/// Equivalent of [`FactoryBase::ParseError`].
///
/// [`FactoryBase::ParseError`]: crate::rcore::FactoryBase::ParseError
type AParseError: Error;
}
/// This trait combines functionality of [`Mentionable`] and [`Factory`],
/// while limiting [`MentionableTop::points_typed`] (and corresponding [`MentionableTop::topology`])
/// to an empty sequence.
///
/// [`Mentionable`]: crate::rcore::Mentionable
/// [`Factory`]: crate::rcore::Factory
/// [`MentionableTop::points_typed`]: crate::rcore::MentionableTop::points_typed
/// [`MentionableTop::topology`]: crate::rcore::MentionableTop::topology
pub trait Atomic: AtomicModeParse {
/// Static equivalent of [`FactoryParse::deserialize`].
///
/// [`FactoryParse::deserialize`]: crate::rcore::FactoryParse::deserialize
fn a_deserialize(stream: impl Stream) -> AParseResult<Self>;
/// Static equivalent of [`FactoryParse::extend`].
///
/// [`FactoryParse::extend`]: crate::rcore::FactoryParse::extend
fn a_extend(self, tail: &[u8]) -> AParseResult<Self>;
}
fn _parse_slice<A: Atomic>(slice: &[u8]) -> AParseResult<A> {
let mut deserializer = SliceDeserializer::from(slice);
let atomic = A::a_deserialize(&mut deserializer)?;
let tail = deserializer.read_all();
if tail.is_empty() {
Ok(atomic)
} else {
atomic.a_extend(tail)
}
}
/// Extension trait to provide method-like utilities associated with [Atomic]s.
pub trait AtomicExt: Atomic {
/// Static equivalent of [`FactoryExt::parse_slice`].
///
/// [`FactoryExt::parse_slice`]: crate::rcore::FactoryExt::parse_slice
fn parse_slice(slice: &[u8]) -> AParseResult<Self> {
_parse_slice(slice)
}
}
impl<A: Atomic> AtomicExt for A {}