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> = Tracked<T>
14 where
15 T: AsUndecorated<T> + Debug + PartialEq + Eq;
16
17 fn decorate_parser<PIn, I, O, E>(parser: PIn) -> impl winnow::Parser<I, Self::Decorated<O>, E>
18 where
19 I: winnow::stream::Stream + winnow::stream::Location,
20 O: AsUndecorated<O> + Debug + PartialEq + Eq,
21 PIn: winnow::Parser<I, O, E>,
22 {
23 use winnow::Parser;
24 parser
25 .with_span()
26 .map(|(value, span)| Tracked::new(value, TrackedSpan(span)))
27 }
28}
29
30pub type LedgerEntry<'i> = super::LedgerEntry<'i, Tracking>;
31pub type Transaction<'i> = super::Transaction<'i, Tracking>;
32pub type Posting<'i> = super::Posting<'i, Tracking>;
33pub type PostingAmount<'i> = super::PostingAmount<'i, Tracking>;
34pub type Lot<'i> = super::Lot<'i, Tracking>;
35
36#[derive(Debug, PartialEq, Eq, Clone)]
39pub struct TrackedSpan(Range<usize>);
40
41impl TrackedSpan {
42 pub(crate) fn as_range(&self) -> Range<usize> {
46 self.0.clone()
47 }
48
49 #[cfg(test)]
51 pub fn new(span: Range<usize>) -> TrackedSpan {
52 TrackedSpan(span)
53 }
54}
55
56#[derive(Debug, PartialEq, Eq)]
58pub struct Tracked<T> {
59 value: T,
60 span: TrackedSpan,
61}
62
63impl<T> AsUndecorated<T> for Tracked<T> {
64 fn as_undecorated(&self) -> &T {
65 &self.value
66 }
67}
68
69impl<T> Tracked<T> {
70 pub fn span(&self) -> TrackedSpan {
72 self.span.clone()
73 }
74
75 pub fn new(value: T, span: TrackedSpan) -> Self {
77 Self { value, span }
78 }
79}