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 LedgerStatement<'i> = super::LedgerStatement<'i, Tracking>;
33pub type Transaction<'i> = super::Transaction<'i, Tracking>;
34pub type Posting<'i> = super::Posting<'i, Tracking>;
35pub type PostingAmount<'i> = super::PostingAmount<'i, Tracking>;
36pub type Lot<'i> = super::Lot<'i, Tracking>;
37
38#[derive(Debug, PartialEq, Eq, Clone)]
42pub struct TrackedSpan(Range<usize>);
43
44impl TrackedSpan {
45 pub(crate) fn as_range(&self) -> Range<usize> {
49 self.0.clone()
50 }
51
52 #[cfg(test)]
54 pub fn new(span: Range<usize>) -> TrackedSpan {
55 TrackedSpan(span)
56 }
57}
58
59#[derive(Debug, PartialEq, Eq)]
61pub struct Tracked<T> {
62 value: T,
63 span: TrackedSpan,
64}
65
66impl<T> AsUndecorated<T> for Tracked<T> {
67 fn as_undecorated(&self) -> &T {
68 &self.value
69 }
70}
71
72impl<T> Tracked<T> {
73 pub fn span(&self) -> TrackedSpan {
75 self.span.clone()
76 }
77
78 pub fn new(value: T, span: TrackedSpan) -> Self {
80 Self { value, span }
81 }
82}