hledger_parser/directive/
year.rs1use chumsky::prelude::*;
2
3use crate::component::whitespace::whitespace;
4use crate::state::State;
5use crate::utils::end_of_line;
6
7#[derive(Clone, Debug, PartialEq)]
8pub struct Year(pub i32);
9
10pub fn year<'a>() -> impl Parser<'a, &'a str, Year, extra::Full<Rich<'a, char>, State, ()>> {
11 just("Y")
12 .or(just("year").then_ignore(whitespace().repeated().at_least(1)))
13 .ignore_then(
14 any()
15 .filter(|c: &char| c.is_ascii_digit())
16 .repeated()
17 .at_least(1)
18 .collect::<String>()
19 .map_with(|p, e| {
20 let state: &mut State = e.state();
21 let year = p.parse::<i32>().unwrap();
22 state.year = year;
23 year
24 }),
25 )
26 .then_ignore(end_of_line())
27 .map(Year)
28}
29
30#[cfg(test)]
31mod tests {
32 use super::*;
33
34 #[test]
35 fn should_update_state() {
36 let mut state = State { year: 1 };
37 let result = year()
38 .then_ignore(end())
39 .parse_with_state("Y2024", &mut state)
40 .into_result();
41 assert_eq!(result, Ok(Year(2024)));
42 assert_eq!(state.year, 2024);
43 }
44
45 #[test]
46 fn deprecated_form() {
47 let result = year()
48 .then_ignore(end())
49 .parse("year 2024 ; just a comment")
50 .into_result();
51 assert_eq!(result, Ok(Year(2024)));
52 }
53
54 #[test]
55 fn ok_with_comment() {
56 let result = year()
57 .then_ignore(end())
58 .parse("Y2024 ; just a comment")
59 .into_result();
60 assert_eq!(result, Ok(Year(2024)));
61 }
62}