gramma 0.2.24

Generate a scannerless parser by declaring types.
Documentation
use core::fmt;
use core::ops::ControlFlow::{self, Break, Continue};

pub(crate) fn default<T: Default>() -> T {
    T::default()
}

pub struct DebugFn<F: Fn(&mut fmt::Formatter) -> fmt::Result>(pub F);

impl<F: Fn(&mut fmt::Formatter) -> fmt::Result> fmt::Debug for DebugFn<F> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.0(f)
    }
}

impl<F: Fn(&mut fmt::Formatter) -> fmt::Result> fmt::Display for DebugFn<F> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.0(f)
    }
}

pub(crate) fn simple_name<T: ?Sized>() -> &'static str {
    let mut name = core::any::type_name::<T>();
    if let Some((first, _)) = name.split_once('<') {
        name = first;
    }

    if let Some((_, last)) = name.rsplit_once("::") {
        name = last;
    }

    name
}

pub(crate) fn try_run<T, E>(f: impl FnOnce() -> Result<T, E>) -> Result<T, E> {
    f()
}

pub(crate) trait MyTryKind: MyTry<Continue = (), Kind = Self> {
    type WithContinue<T>: MyTry<Continue = T, Break = Self::Break, Kind = Self>;
}

pub(crate) trait MyTry: Sized {
    type Continue;
    type Break;
    type Kind: MyTryKind<Break = Self::Break, WithContinue<Self::Continue> = Self>;
    fn into_ctrl(self) -> ControlFlow<Self::Break, Self::Continue>;
    fn from_ctrl(ctrl: ControlFlow<Self::Break, Self::Continue>) -> Self;

    fn from_continue(c: Self::Continue) -> Self {
        Self::from_ctrl(Continue(c))
    }

    fn from_break(b: Self::Break) -> Self {
        Self::from_ctrl(Break(b))
    }

    fn map<C>(self, f: impl FnOnce(Self::Continue) -> C) -> WithContinue<Self, C> {
        match self.into_ctrl() {
            Continue(c) => MyTry::from_continue(f(c)),
            Break(b) => MyTry::from_break(b),
        }
    }

    fn flat_map<X>(self, f: impl FnOnce(Self::Continue) -> X) -> X
    where
        X: MyTry<Break = Self::Break>,
    {
        match self.into_ctrl() {
            Continue(c) => f(c),
            Break(b) => MyTry::from_break(b),
        }
    }

    fn continue_also(self, f: impl FnOnce(&mut Self::Continue)) -> Self {
        self.map(|mut c| {
            f(&mut c);
            c
        })
    }

    fn break_also(self, f: impl FnOnce(&mut Self::Break)) -> Self {
        let mut ctrl = self.into_ctrl();
        if let Break(ref mut b) = ctrl {
            f(b)
        }
        Self::from_ctrl(ctrl)
    }

    fn continue_also_with<R>(
        self,
        f: impl FnOnce(&mut Self::Continue) -> R,
    ) -> WithContinue<Self, (Self::Continue, R)> {
        self.map(|mut c| {
            let out = f(&mut c);
            (c, out)
        })
    }
    fn map_break<B>(self, f: impl FnOnce(Self::Break) -> B) -> Self::WithBreak<B>
    where
        Self: MapBreak,
    {
        match self.into_ctrl() {
            Continue(c) => MyTry::from_continue(c),
            Break(b) => MyTry::from_break(f(b)),
        }
    }

    fn flat_map_break<X>(self, f: impl FnOnce(Self::Break) -> X) -> X
    where
        X: MyTry<Continue = Self::Continue>,
    {
        match self.into_ctrl() {
            Continue(c) => X::from_continue(c),
            Break(b) => f(b),
        }
    }

    fn break_also_with<R>(
        self,
        f: impl FnOnce(&mut Self::Continue) -> R,
    ) -> WithContinue<Self, (Self::Continue, R)>
    where
        Self: MapBreak,
    {
        self.map(|mut c| {
            let out = f(&mut c);
            (c, out)
        })
    }
}

pub(crate) trait MapBreak: MyTry {
    type WithBreak<B>: MapBreak<WithBreak<Self::Break> = Self, Continue = Self::Continue, Break = B>;
}

pub(crate) type WithContinue<T, C> = <<T as MyTry>::Kind as MyTryKind>::WithContinue<C>;

impl MyTryKind for Option<()> {
    type WithContinue<T> = Option<T>;
}

impl<T> MyTry for Option<T> {
    type Continue = T;
    type Break = ();
    type Kind = Option<()>;

    fn into_ctrl(self) -> ControlFlow<Self::Break, Self::Continue> {
        self.map_or(Break(()), Continue)
    }

    fn from_ctrl(ctrl: ControlFlow<Self::Break, Self::Continue>) -> Self {
        match ctrl {
            Continue(x) => Some(x),
            Break(()) => None,
        }
    }

    fn map<C>(self, f: impl FnOnce(Self::Continue) -> C) -> WithContinue<Self, C> {
        self.map(f)
    }
}

impl<E> MyTryKind for Result<(), E> {
    type WithContinue<T> = Result<T, E>;
}

impl<T, E> MyTry for Result<T, E> {
    type Continue = T;
    type Break = E;
    type Kind = Result<(), E>;
    fn into_ctrl(self) -> ControlFlow<Self::Break, Self::Continue> {
        self.map_or_else(Break, Continue)
    }

    fn from_ctrl(ctrl: ControlFlow<Self::Break, Self::Continue>) -> Self {
        match ctrl {
            Continue(x) => Ok(x),
            Break(e) => Err(e),
        }
    }

    fn map<C>(self, f: impl FnOnce(Self::Continue) -> C) -> WithContinue<Self, C> {
        self.map(f)
    }
}

impl<T, E> MapBreak for Result<T, E> {
    type WithBreak<B> = Result<T, B>;
}

impl<B> MyTryKind for ControlFlow<B> {
    type WithContinue<C> = ControlFlow<B, C>;
}

impl<B, C> MyTry for ControlFlow<B, C> {
    type Continue = C;
    type Break = B;
    type Kind = ControlFlow<B>;

    fn into_ctrl(self) -> Self {
        self
    }

    fn from_ctrl(ctrl: Self) -> Self {
        ctrl
    }
}

impl<B, C> MapBreak for ControlFlow<B, C> {
    type WithBreak<B2> = ControlFlow<B2, C>;
}

pub(crate) trait FunctionalExt: Sized {
    fn then_do<R>(self, f: impl FnOnce(Self) -> R) -> R {
        f(self)
    }

    fn also_with<R>(mut self, f: impl FnOnce(&mut Self) -> R) -> (Self, R) {
        let value = f(&mut self);
        (self, value)
    }

    fn also(mut self, f: impl FnOnce(&mut Self)) -> Self {
        f(&mut self);
        self
    }
}

impl<T> FunctionalExt for T {}