gix_config/parse/
error.rs1use std::fmt::Display;
2
3use crate::parse::Error;
4
5#[derive(PartialEq, Debug)]
6pub(crate) enum Kind {
7 Parse {
8 line_number: usize,
9 last_attempted_parser: ParseNode,
10 parsed_until: bstr::BString,
11 },
12 InputTooLarge {
13 actual: usize,
14 },
15}
16
17#[derive(PartialEq, Debug, Clone, Copy)]
19pub(crate) enum ParseNode {
20 SectionHeader,
21 Name,
22 Value,
23}
24
25impl Display for ParseNode {
26 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27 match self {
28 Self::SectionHeader => write!(f, "section header"),
29 Self::Name => write!(f, "name"),
30 Self::Value => write!(f, "value"),
31 }
32 }
33}
34
35impl Error {
36 pub(crate) fn parse(line_number: usize, last_attempted_parser: ParseNode, parsed_until: bstr::BString) -> Self {
37 Self {
38 kind: Kind::Parse {
39 line_number,
40 last_attempted_parser,
41 parsed_until,
42 },
43 }
44 }
45
46 pub(crate) fn input_too_large(actual: usize) -> Self {
47 Self {
48 kind: Kind::InputTooLarge { actual },
49 }
50 }
51
52 #[must_use]
55 pub const fn line_number(&self) -> usize {
56 match self.kind {
57 Kind::Parse { line_number, .. } => line_number + 1,
58 Kind::InputTooLarge { .. } => 1,
59 }
60 }
61
62 #[must_use]
64 pub fn remaining_data(&self) -> &[u8] {
65 match &self.kind {
66 Kind::Parse { parsed_until, .. } => parsed_until,
67 Kind::InputTooLarge { .. } => &[],
68 }
69 }
70}
71
72impl Display for Error {
73 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
74 let (line_number, last_attempted_parser, parsed_until) = match &self.kind {
75 Kind::InputTooLarge { actual } => {
76 return write!(
77 f,
78 "Configuration input is {actual} bytes large, but at most {} bytes are supported",
79 u32::MAX
80 );
81 }
82 Kind::Parse {
83 line_number,
84 last_attempted_parser,
85 parsed_until,
86 } => (line_number, last_attempted_parser, parsed_until),
87 };
88 write!(
89 f,
90 "Got an unexpected token on line {} while trying to parse a {}: ",
91 line_number + 1,
92 last_attempted_parser,
93 )?;
94
95 let data_size = parsed_until.len();
96 let data = std::str::from_utf8(parsed_until);
97 match (data, data_size) {
98 (Ok(data), _) if data_size > 10 => {
99 write!(
100 f,
101 "'{}' ... ({} characters omitted)",
102 data.chars().take(10).collect::<String>(),
103 data_size - 10
104 )
105 }
106 (Ok(data), _) => write!(f, "'{data}'"),
107 (Err(_), _) => parsed_until.fmt(f),
108 }
109 }
110}
111
112impl std::error::Error for Error {}