Mercurial > public > mercurial-scm > hg-stable
comparison rust/hg-core/src/errors.rs @ 46637:bc08c2331f99
rust: Add a `ConfigValueParseError` variant to common errors
Configuration files are parsed into sections of key/value pairs when
they are read, but at that point values are still arbitrary bytes.
Only when a value is accessed by various parts of the code do we know
its expected type and syntax, so values are parsed at that point.
Let?s make a new error type for this latter kind of parsing error,
and add a variant to the common `HgError` so that most code can propagate it
without much boilerplate.
Differential Revision: https://phab.mercurial-scm.org/D10009
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Tue, 16 Feb 2021 15:22:20 +0100 |
parents | f031fe1c6ede |
children | 1f55cd5b292f |
comparison
equal
deleted
inserted
replaced
46636:305d74c262de | 46637:bc08c2331f99 |
---|---|
1 use crate::config::ConfigValueParseError; | |
1 use std::fmt; | 2 use std::fmt; |
2 | 3 |
3 /// Common error cases that can happen in many different APIs | 4 /// Common error cases that can happen in many different APIs |
4 #[derive(Debug)] | 5 #[derive(Debug, derive_more::From)] |
5 pub enum HgError { | 6 pub enum HgError { |
6 IoError { | 7 IoError { |
7 error: std::io::Error, | 8 error: std::io::Error, |
8 context: IoErrorContext, | 9 context: IoErrorContext, |
9 }, | 10 }, |
27 /// Operation cannot proceed for some other reason. | 28 /// Operation cannot proceed for some other reason. |
28 /// | 29 /// |
29 /// The given string is a short explanation for users, not intended to be | 30 /// The given string is a short explanation for users, not intended to be |
30 /// machine-readable. | 31 /// machine-readable. |
31 Abort(String), | 32 Abort(String), |
33 | |
34 /// A configuration value is not in the expected syntax. | |
35 /// | |
36 /// These errors can happen in many places in the code because values are | |
37 /// parsed lazily as the file-level parser does not know the expected type | |
38 /// and syntax of each value. | |
39 #[from] | |
40 ConfigValueParseError(ConfigValueParseError), | |
32 } | 41 } |
33 | 42 |
34 /// Details about where an I/O error happened | 43 /// Details about where an I/O error happened |
35 #[derive(Debug, derive_more::From)] | 44 #[derive(Debug, derive_more::From)] |
36 pub enum IoErrorContext { | 45 pub enum IoErrorContext { |
61 | 70 |
62 // TODO: use `DisplayBytes` instead to show non-Unicode filenames losslessly? | 71 // TODO: use `DisplayBytes` instead to show non-Unicode filenames losslessly? |
63 impl fmt::Display for HgError { | 72 impl fmt::Display for HgError { |
64 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | 73 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
65 match self { | 74 match self { |
75 HgError::Abort(explanation) => write!(f, "{}", explanation), | |
66 HgError::IoError { error, context } => { | 76 HgError::IoError { error, context } => { |
67 write!(f, "{}: {}", error, context) | 77 write!(f, "{}: {}", error, context) |
68 } | 78 } |
69 HgError::CorruptedRepository(explanation) => { | 79 HgError::CorruptedRepository(explanation) => { |
70 write!(f, "corrupted repository: {}", explanation) | 80 write!(f, "corrupted repository: {}", explanation) |
71 } | 81 } |
72 HgError::UnsupportedFeature(explanation) => { | 82 HgError::UnsupportedFeature(explanation) => { |
73 write!(f, "unsupported feature: {}", explanation) | 83 write!(f, "unsupported feature: {}", explanation) |
74 } | 84 } |
75 HgError::Abort(explanation) => explanation.fmt(f), | 85 HgError::ConfigValueParseError(ConfigValueParseError { |
86 origin: _, | |
87 line: _, | |
88 section, | |
89 item, | |
90 value, | |
91 expected_type, | |
92 }) => { | |
93 // TODO: add origin and line number information, here and in | |
94 // corresponding python code | |
95 write!( | |
96 f, | |
97 "config error: {}.{} is not a {} ('{}')", | |
98 String::from_utf8_lossy(section), | |
99 String::from_utf8_lossy(item), | |
100 expected_type, | |
101 String::from_utf8_lossy(value) | |
102 ) | |
103 } | |
76 } | 104 } |
77 } | 105 } |
78 } | 106 } |
79 | 107 |
80 // TODO: use `DisplayBytes` instead to show non-Unicode filenames losslessly? | 108 // TODO: use `DisplayBytes` instead to show non-Unicode filenames losslessly? |