okane_core/syntax/
decoration.rs

1//! Module decoration defines the trait,
2//! which describes the extra information attached to [crate::syntax] data.
3
4use std::fmt::Debug;
5
6/// `AsUndecorated<T>` is equivalent to [AsRef], with specific meaning.
7/// AsRef can be too generic and not suitable for use case.
8pub trait AsUndecorated<T: ?Sized> {
9    fn as_undecorated(&self) -> &T;
10}
11
12/// Decoration associates the extra information attached to
13/// [Transaction][super::Transaction] or any other [crate::syntax] data.
14/// See [super::plain] or [super::tracked] for implementations.
15pub trait Decoration: 'static {
16    type Decorated<T>: AsUndecorated<T> + Debug + PartialEq + Eq
17    where
18        T: AsUndecorated<T> + Debug + PartialEq + Eq;
19
20    fn decorate_parser<PIn, I, O, E>(parser: PIn) -> impl winnow::Parser<I, Self::Decorated<O>, E>
21    where
22        I: winnow::stream::Stream + winnow::stream::Location,
23        O: AsUndecorated<O> + Debug + PartialEq + Eq,
24        PIn: winnow::Parser<I, O, E>;
25}
26
27macro_rules! define_as_undecorated {
28    ([$($impl_generics:tt)*],
29     $type_name:ty) => {
30        impl<$($impl_generics)*> AsUndecorated<$type_name> for $type_name {
31            fn as_undecorated(&self) -> &$type_name {
32                self
33            }
34        }
35    };
36}
37
38define_as_undecorated!(['i, Deco: Decoration], super::LedgerEntry<'i, Deco>);
39define_as_undecorated!(['i, Deco: Decoration], super::Transaction<'i, Deco>);
40define_as_undecorated!(['i, Deco: Decoration], super::Posting<'i, Deco>);
41define_as_undecorated!(['i, Deco: Decoration], super::PostingAmount<'i, Deco>);
42define_as_undecorated!(['i], super::Exchange<'i>);
43define_as_undecorated!(['i], super::expr::ValueExpr<'i>);