• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ngalaiko / hledger-desktop / 11782383692

11 Nov 2024 04:25PM CUT coverage: 68.111%. Remained the same
11782383692

push

github

ngalaiko
hledger-desktop: offload parsing to rayon

0 of 5 new or added lines in 1 file covered. (0.0%)

20 existing lines in 1 file now uncovered.

786 of 1154 relevant lines covered (68.11%)

2.11 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/crates/hledger-parser/src/lib.rs
1
//! Parser for Hledger journals.
2
//! See [hledger documentation](https://hledger.org/hledger.html)
3
//! for journal format description.
4

5
mod component;
6
mod directive;
7
mod state;
8
mod utils;
9

10
use chumsky::error::RichReason;
11
use chumsky::prelude::*;
12

13
use crate::directive::directives;
14
use crate::state::State;
15

16
pub use crate::component::amount::Amount;
17
pub use crate::component::period::interval::Interval;
18
pub use crate::component::period::Period;
19
pub use crate::component::price::AmountPrice;
20
pub use crate::directive::{
21
    Account, Assertion, AutoPosting, AutosPostingRule, Commodity, DecimalMark, Directive, Format,
22
    Include, Payee, PeriodicTransaction, Posting, Price, Query, Status, Tag, Term, Transaction,
23
    Year,
24
};
25

26
/// Parses the given content into a list of Hledger journal directives.
27
///
28
/// # Errors
29
///
30
/// Will return a list of parsing errors if input is not a valid hledger journal.
31
pub fn parse<I: AsRef<str>>(contents: I) -> Result<Vec<Directive>, Vec<ParseError>> {
×
32
    directives()
×
33
        .then_ignore(end())
×
34
        .parse_with_state(contents.as_ref(), &mut State::default())
×
35
        .into_result()
36
        .map_err(|errors| errors.into_iter().map(ParseError::from).collect())
×
37
}
38

39
/// Error type representing failures during parsing.
40
#[derive(Debug, Clone)]
41
pub struct ParseError {
42
    /// The span of text where the error occurred.
43
    pub span: std::ops::Range<usize>,
44
    /// A human-readable description of the error.
45
    pub message: String,
46
}
47

48
impl<'a, T: std::fmt::Debug> From<Rich<'a, T>> for ParseError {
49
    fn from(rich_error: Rich<'a, T>) -> Self {
×
50
        let span = rich_error.span().start..rich_error.span().end;
×
51

52
        let message = match rich_error.into_reason() {
×
53
            RichReason::Custom(msg) => msg,
×
54
            RichReason::ExpectedFound { expected, found } => {
×
55
                let expected_items: Vec<_> = expected
×
56
                    .into_iter()
57
                    .map(|pattern| format!("{pattern:?}"))
×
58
                    .collect();
59

60
                format!(
×
61
                    "Expected {}{}",
62
                    if expected_items.is_empty() {
×
63
                        String::from("something else")
×
64
                    } else {
65
                        format!("one of: [{}]", expected_items.join(", "))
×
66
                    },
67
                    if let Some(found) = found {
×
68
                        format!(", found: {found:?}")
×
69
                    } else {
70
                        String::new()
×
71
                    }
72
                )
73
            }
74
            RichReason::Many(reasons) => reasons
×
75
                .into_iter()
76
                .map(|reason| format!("{reason:?}"))
×
77
                .collect::<Vec<_>>()
78
                .join("; "),
79
        };
80

81
        ParseError { span, message }
82
    }
83
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc