okane_core/syntax/
tracked.rs1use std::fmt::Debug;
5use std::ops::Range;
6
7use super::decoration::{AsUndecorated, Decoration};
8
9pub struct Tracking;
11
12impl Decoration for Tracking {
13 type Decorated<T>
14 = Tracked<T>
15 where
16 T: AsUndecorated<T> + Debug + PartialEq + Eq;
17
18 fn decorate_parser<PIn, I, O, E>(parser: PIn) -> impl winnow::Parser<I, Self::Decorated<O>, E>
19 where
20 I: winnow::stream::Stream + winnow::stream::Location,
21 O: AsUndecorated<O> + Debug + PartialEq + Eq,
22 PIn: winnow::Parser<I, O, E>,
23 {
24 use winnow::Parser;
25 parser
26 .with_span()
27 .map(|(value, span)| Tracked::new(value, TrackedSpan(span)))
28 }
29}
30
31pub type LedgerEntry<'i> = super::LedgerEntry<'i, Tracking>;
32pub type Transaction<'i> = super::Transaction<'i, Tracking>;
33pub type Posting<'i> = super::Posting<'i, Tracking>;
34pub type PostingAmount<'i> = super::PostingAmount<'i, Tracking>;
35pub type Lot<'i> = super::Lot<'i, Tracking>;
36
37#[derive(Debug, PartialEq, Eq, Clone)]
41pub struct TrackedSpan(Range<usize>);
42
43impl TrackedSpan {
44 pub(crate) fn as_range(&self) -> Range<usize> {
48 self.0.clone()
49 }
50
51 #[cfg(test)]
53 pub fn new(span: Range<usize>) -> TrackedSpan {
54 TrackedSpan(span)
55 }
56}
57
58#[derive(Debug, PartialEq, Eq)]
60pub struct Tracked<T> {
61 value: T,
62 span: TrackedSpan,
63}
64
65impl<T> AsUndecorated<T> for Tracked<T> {
66 fn as_undecorated(&self) -> &T {
67 &self.value
68 }
69}
70
71impl<T> Tracked<T> {
72 pub fn span(&self) -> TrackedSpan {
74 self.span.clone()
75 }
76
77 pub fn new(value: T, span: TrackedSpan) -> Self {
79 Self { value, span }
80 }
81}