238 lines
7.6 KiB
Rust
238 lines
7.6 KiB
Rust
//! [`Mode`]-based parsing.
|
|
|
|
mod inlining;
|
|
mod regular;
|
|
mod serialization;
|
|
mod slice_deserializer;
|
|
mod stream;
|
|
|
|
use std::marker::PhantomData;
|
|
|
|
pub use self::inlining::InliningMode;
|
|
pub use self::regular::RegularMode;
|
|
pub use self::serialization::{Deserializer, DeserializerExt, Serializable, Serializer};
|
|
pub use self::slice_deserializer::SliceDeserializer;
|
|
pub use self::stream::{Stream, StreamExt, StreamResultExt};
|
|
|
|
/// See [`ModeResult`].
|
|
pub type ParseSuccess<M, A, I> = <M as Mode>::ParseSuccess<A, I>;
|
|
|
|
/// [`Mode`] equivalent of [`ParseResult`] for extension.
|
|
///
|
|
/// [`ParseResult`]: crate::rcore::ParseResult
|
|
pub type ExtensionResult<M, A, E> = <M as Mode>::ExtensionResult<A, E>;
|
|
|
|
/// See [`Mode::prepare`].
|
|
pub type ExtensionSource<M, A> = <M as Mode>::ExtensionSource<A>;
|
|
|
|
/// [`Mode`] equivalent of [`ParseResult`].
|
|
///
|
|
/// [`ParseResult`]: crate::rcore::ParseResult
|
|
pub type ModeResult<M, A, E, I> = Result<ParseSuccess<M, A, I>, E>;
|
|
|
|
/// Mode of parsing.
|
|
///
|
|
/// | [`Mode`] | [`Mode::ParseSuccess<A, I>`] | [`Mode::ExtensionResult<A, E>`] | [`Mode::ExtensionSource<A>`] |
|
|
/// |------------------|------------------------------|---------------------------------|------------------------------|
|
|
/// | [`RegularMode`] | `A` | [`Result<A, E>`] | `A` |
|
|
/// | [`InliningMode`] | [`(A, I)`] | `E` | [`()`] |
|
|
///
|
|
/// [`(A, I)`]: tuple
|
|
/// [`()`]: unit
|
|
pub trait Mode {
|
|
/// Successful parsing, may countain the parser itself
|
|
/// (`I`, usually [`Stream`]).
|
|
type ParseSuccess<A, I>;
|
|
|
|
/// Result of extending the value, failing sometimes or always.
|
|
type ExtensionResult<A, E>;
|
|
|
|
/// Data enough to try extending the value.
|
|
///
|
|
/// May be empty for always-failing extensions.
|
|
type ExtensionSource<A>;
|
|
|
|
/// Do something with the successfully parsed value, potentially failing.
|
|
///
|
|
/// Useful for for wrappers and chaining parsing after [`InliningFactory`].
|
|
///
|
|
/// See also [`Mode::map`]
|
|
///
|
|
/// [`InliningFactory`]: crate::rcore::InliningFactory
|
|
fn bind<A0, A1, E, I>(
|
|
s: Self::ParseSuccess<A0, I>,
|
|
f: impl FnOnce(A0) -> Result<A1, E>,
|
|
) -> ModeResult<Self, A1, E, I>;
|
|
|
|
/// Map the successfully parsed value.
|
|
///
|
|
/// Useful for for wrappers.
|
|
///
|
|
/// See also [`Mode::bind`]
|
|
fn map<A0, A1, I>(
|
|
s: Self::ParseSuccess<A0, I>,
|
|
f: impl FnOnce(A0) -> A1,
|
|
) -> Self::ParseSuccess<A1, I>;
|
|
|
|
/// Discard any extra information contained in [`Mode::ParseSuccess`].
|
|
fn seal<A, I>(s: Self::ParseSuccess<A, I>) -> A;
|
|
|
|
/// Map the error of an extension result.
|
|
///
|
|
/// Useful for for wrappers and chaining parsing after [`InliningFactory`].
|
|
///
|
|
/// [`InliningFactory`]: crate::rcore::InliningFactory
|
|
fn xmap_err<A, E0, E1>(
|
|
result: Self::ExtensionResult<A, E0>,
|
|
f: impl FnOnce(E0) -> E1,
|
|
) -> Self::ExtensionResult<A, E1>;
|
|
|
|
/// Do something with the extension result, potentially failing.
|
|
///
|
|
/// Useful for wrappers and chaining extension after [`InliningFactory`].
|
|
///
|
|
/// [`InliningFactory`]: crate::rcore::InliningFactory
|
|
fn xbind<A0, A1, E>(
|
|
result: Self::ExtensionResult<A0, E>,
|
|
f: impl FnOnce(A0) -> Result<A1, E>,
|
|
) -> Self::ExtensionResult<A1, E>;
|
|
|
|
/// Convert [`Mode::ExtensionResult`] to [`Result`].
|
|
fn xseal<A, E>(result: Self::ExtensionResult<A, E>) -> Result<A, E>;
|
|
|
|
fn smap<A0, A1>(
|
|
source: Self::ExtensionSource<A0>,
|
|
f: impl FnOnce(A0) -> A1,
|
|
) -> Self::ExtensionSource<A1>;
|
|
|
|
fn prepare<A>(a: A) -> Self::ExtensionSource<A>;
|
|
|
|
/// For abstract extension implementations.
|
|
fn xsbind<AB, A, B, E>(
|
|
ab: Self::ExtensionSource<AB>,
|
|
t2ab: impl FnOnce(AB) -> (A, B),
|
|
ce: impl FnOnce(Self::ExtensionSource<B>) -> Self::ExtensionResult<B, E>,
|
|
ab2t: impl FnOnce(A, B) -> Result<AB, E>,
|
|
) -> Self::ExtensionResult<AB, E>;
|
|
}
|
|
|
|
/// Type that a [`Mode`] associated with it.
|
|
pub trait ParseMode {
|
|
/// Associated [`Mode`].
|
|
type Mode: ?Sized + Mode;
|
|
}
|
|
|
|
/// [`ParseMode`] equivalent of [`ParseSuccess`].
|
|
pub type ParseSuccessP<F, A, I> = ParseSuccess<<F as ParseMode>::Mode, A, I>;
|
|
|
|
/// [`ParseMode`] equivalent of [`ExtensionResult`].
|
|
pub type ExtensionResultP<F, A, E> = ExtensionResult<<F as ParseMode>::Mode, A, E>;
|
|
|
|
/// [`ParseMode`] equivalent of [`ExtensionSource`].
|
|
pub type ExtensionSourceP<F, A> = ExtensionSource<<F as ParseMode>::Mode, A>;
|
|
|
|
/// [`ParseMode`] equivalent of [`ModeResult`].
|
|
pub type ModeResultP<F, A, E, I> = ModeResult<<F as ParseMode>::Mode, A, E, I>;
|
|
|
|
/// Extension trait for all [`ParseMode`] types, re-exporting [`Mode`] traits.
|
|
pub trait ParseModeExt: ParseMode {
|
|
/// [`Mode::bind`].
|
|
fn bind<A0, A1, E, I>(
|
|
s: ParseSuccessP<Self, A0, I>,
|
|
f: impl FnOnce(A0) -> Result<A1, E>,
|
|
) -> ModeResultP<Self, A1, E, I> {
|
|
<Self::Mode as Mode>::bind(s, f)
|
|
}
|
|
|
|
/// [`Mode::map`].
|
|
fn map<A0, A1, I>(
|
|
s: ParseSuccessP<Self, A0, I>,
|
|
f: impl FnOnce(A0) -> A1,
|
|
) -> ParseSuccessP<Self, A1, I> {
|
|
<Self::Mode as Mode>::map(s, f)
|
|
}
|
|
|
|
/// [`Mode::seal`].
|
|
fn seal<A, I>(s: ParseSuccessP<Self, A, I>) -> A {
|
|
<Self::Mode as Mode>::seal(s)
|
|
}
|
|
|
|
/// [`Mode::xmap_err`].
|
|
fn xmap_err<A, E0, E1>(
|
|
result: ExtensionResultP<Self, A, E0>,
|
|
f: impl FnOnce(E0) -> E1,
|
|
) -> ExtensionResultP<Self, A, E1> {
|
|
<Self::Mode as Mode>::xmap_err(result, f)
|
|
}
|
|
|
|
/// [`Mode::xbind`].
|
|
fn xbind<A0, A1, E>(
|
|
result: ExtensionResultP<Self, A0, E>,
|
|
f: impl FnOnce(A0) -> Result<A1, E>,
|
|
) -> ExtensionResultP<Self, A1, E> {
|
|
<Self::Mode as Mode>::xbind(result, f)
|
|
}
|
|
|
|
/// [`Mode::xseal`].
|
|
fn xseal<A, E>(result: ExtensionResultP<Self, A, E>) -> Result<A, E> {
|
|
<Self::Mode as Mode>::xseal(result)
|
|
}
|
|
|
|
/// [`Mode::smap`].
|
|
fn smap<A0, A1>(
|
|
source: ExtensionSourceP<Self, A0>,
|
|
f: impl FnOnce(A0) -> A1,
|
|
) -> ExtensionSourceP<Self, A1> {
|
|
<Self::Mode as Mode>::smap(source, f)
|
|
}
|
|
|
|
/// [`Mode::prepare`].
|
|
fn prepare<A>(a: A) -> ExtensionSourceP<Self, A> {
|
|
<Self::Mode as Mode>::prepare(a)
|
|
}
|
|
|
|
/// [`Mode::xsbind`].
|
|
fn xsbind<AB, A, B, E>(
|
|
ab: ExtensionSourceP<Self, AB>,
|
|
t2ab: impl FnOnce(AB) -> (A, B),
|
|
ce: impl FnOnce(ExtensionSourceP<Self, B>) -> ExtensionResultP<Self, B, E>,
|
|
ab2t: impl FnOnce(A, B) -> Result<AB, E>,
|
|
) -> ExtensionResultP<Self, AB, E> {
|
|
<Self::Mode as Mode>::xsbind(ab, t2ab, ce, ab2t)
|
|
}
|
|
}
|
|
|
|
impl<F: ParseMode> ParseModeExt for F {}
|
|
|
|
/// For auto-implementing [`FactoryParse`] and [`Atomic`].
|
|
///
|
|
/// [`FactoryParse`]: crate::rcore::FactoryParse
|
|
/// [`Atomic`]: crate::atomic::Atomic
|
|
pub trait ImplMode {
|
|
/// Same as [`ParseMode::Mode`]
|
|
type Mode: ?Sized + Mode;
|
|
}
|
|
|
|
/// Used with [`WithMode`] for linking [`ImplMode`] to [`FactoryParse`] and [`Atomic`].
|
|
///
|
|
/// [`FactoryParse`]: crate::rcore::FactoryParse
|
|
/// [`Atomic`]: crate::atomic::Atomic
|
|
pub trait WithParseMode: ImplMode {
|
|
/// [`WithMode`] implementing [`FactoryModeProxy`] or [`AtomicModeProxy`].
|
|
///
|
|
/// [`FactoryModeProxy`]: crate::rcore::FactoryModeProxy
|
|
/// [`AtomicModeProxy`]: crate::atomic::AtomicModeProxy
|
|
type WithMode: ?Sized;
|
|
}
|
|
|
|
impl<T: ?Sized + ImplMode> ParseMode for T {
|
|
type Mode = <Self as ImplMode>::Mode;
|
|
}
|
|
|
|
impl<T: ?Sized + ImplMode> WithParseMode for T {
|
|
type WithMode = WithMode<Self, <Self as ParseMode>::Mode>;
|
|
}
|
|
|
|
/// Used as [`WithParseMode::WithMode`].
|
|
pub struct WithMode<T: ?Sized, M: ?Sized>(PhantomData<M>, T);
|