Mercurial > public > mercurial-scm > hg
annotate rust/hg-core/src/errors.rs @ 47123:d8ac62374943
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer
? that has the contents of the `.hg/dirstate` file.
This only applies to the tree-based flavor of `DirstateMap`.
For now only the entire `&[u8]` slice is stored, so this is not useful yet.
Adding a lifetime parameter to the `DirstateMap` struct (in hg-core) makes
Python bindings non-trivial because we keep that struct in a Python object
that has a dynamic lifetime tied to Python?s reference-counting and GC.
As long as we keep the `PyBytes` that owns the borrowed bytes buffer next to
the borrowing struct, the buffer will live long enough for the borrows to stay
valid. However this relationship cannot be expressed in safe Rust code in a
way that would statisfy they borrow-checker. We use `unsafe` code to erase
that lifetime parameter, and encapsulate it in a safe abstraction similar to
the owning-ref crate: https://docs.rs/owning_ref/
Differential Revision: https://phab.mercurial-scm.org/D10557
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Fri, 30 Apr 2021 18:24:54 +0200 |
parents | bcdcb4423ae3 |
children | 6e49769b7f97 |
rev | line source |
---|---|
46598
bc08c2331f99
rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
1 use crate::config::ConfigValueParseError; |
46438
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
2 use std::fmt; |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
3 |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
4 /// Common error cases that can happen in many different APIs |
46598
bc08c2331f99
rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
5 #[derive(Debug, derive_more::From)] |
46438
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
6 pub enum HgError { |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
7 IoError { |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
8 error: std::io::Error, |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
9 context: IoErrorContext, |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
10 }, |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
11 |
46485
f031fe1c6ede
rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
12 /// A file under `.hg/` normally only written by Mercurial is not in the |
f031fe1c6ede
rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
13 /// expected format. This indicates a bug in Mercurial, filesystem |
f031fe1c6ede
rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
14 /// corruption, or hardware failure. |
46438
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
15 /// |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
16 /// The given string is a short explanation for users, not intended to be |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
17 /// machine-readable. |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
18 CorruptedRepository(String), |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
19 |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
20 /// The respository or requested operation involves a feature not |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
21 /// supported by the Rust implementation. Falling back to the Python |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
22 /// implementation may or may not work. |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
23 /// |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
24 /// The given string is a short explanation for users, not intended to be |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
25 /// machine-readable. |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
26 UnsupportedFeature(String), |
46485
f031fe1c6ede
rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
27 |
f031fe1c6ede
rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
28 /// Operation cannot proceed for some other reason. |
f031fe1c6ede
rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
29 /// |
f031fe1c6ede
rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
30 /// The given string is a short explanation for users, not intended to be |
f031fe1c6ede
rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
31 /// machine-readable. |
f031fe1c6ede
rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
32 Abort(String), |
46598
bc08c2331f99
rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
33 |
bc08c2331f99
rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
34 /// A configuration value is not in the expected syntax. |
bc08c2331f99
rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
35 /// |
bc08c2331f99
rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
36 /// These errors can happen in many places in the code because values are |
bc08c2331f99
rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
37 /// parsed lazily as the file-level parser does not know the expected type |
bc08c2331f99
rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
38 /// and syntax of each value. |
bc08c2331f99
rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
39 #[from] |
bc08c2331f99
rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
40 ConfigValueParseError(ConfigValueParseError), |
46438
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
41 } |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
42 |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
43 /// Details about where an I/O error happened |
46599
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
44 #[derive(Debug)] |
46438
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
45 pub enum IoErrorContext { |
46599
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
46 ReadingFile(std::path::PathBuf), |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
47 WritingFile(std::path::PathBuf), |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
48 RemovingFile(std::path::PathBuf), |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
49 RenamingFile { |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
50 from: std::path::PathBuf, |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
51 to: std::path::PathBuf, |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
52 }, |
46740
97ac588b6d9e
rhg: Don?t make repository path absolute too early
Simon Sapin <simon.sapin@octobus.net>
parents:
46735
diff
changeset
|
53 /// `std::fs::canonicalize` |
97ac588b6d9e
rhg: Don?t make repository path absolute too early
Simon Sapin <simon.sapin@octobus.net>
parents:
46735
diff
changeset
|
54 CanonicalizingPath(std::path::PathBuf), |
46483
2845892dd489
rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
55 /// `std::env::current_dir` |
46438
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
56 CurrentDir, |
46483
2845892dd489
rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
57 /// `std::env::current_exe` |
2845892dd489
rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
58 CurrentExe, |
46438
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
59 } |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
60 |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
61 impl HgError { |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
62 pub fn corrupted(explanation: impl Into<String>) -> Self { |
46443
43d63979a75e
rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents:
46438
diff
changeset
|
63 // TODO: capture a backtrace here and keep it in the error value |
43d63979a75e
rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents:
46438
diff
changeset
|
64 // to aid debugging? |
43d63979a75e
rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents:
46438
diff
changeset
|
65 // https://doc.rust-lang.org/std/backtrace/struct.Backtrace.html |
46438
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
66 HgError::CorruptedRepository(explanation.into()) |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
67 } |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46443
diff
changeset
|
68 |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46443
diff
changeset
|
69 pub fn unsupported(explanation: impl Into<String>) -> Self { |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46443
diff
changeset
|
70 HgError::UnsupportedFeature(explanation.into()) |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46443
diff
changeset
|
71 } |
46485
f031fe1c6ede
rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
72 pub fn abort(explanation: impl Into<String>) -> Self { |
f031fe1c6ede
rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
73 HgError::Abort(explanation.into()) |
f031fe1c6ede
rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
74 } |
46438
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
75 } |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
76 |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
77 // TODO: use `DisplayBytes` instead to show non-Unicode filenames losslessly? |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
78 impl fmt::Display for HgError { |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
79 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
80 match self { |
46598
bc08c2331f99
rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
81 HgError::Abort(explanation) => write!(f, "{}", explanation), |
46438
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
82 HgError::IoError { error, context } => { |
46731
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46599
diff
changeset
|
83 write!(f, "abort: {}: {}", context, error) |
46438
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
84 } |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
85 HgError::CorruptedRepository(explanation) => { |
46735
12d59eec7f1d
rhg: Align with Python on some more error messages
Simon Sapin <simon.sapin@octobus.net>
parents:
46731
diff
changeset
|
86 write!(f, "abort: {}", explanation) |
46438
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
87 } |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
88 HgError::UnsupportedFeature(explanation) => { |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
89 write!(f, "unsupported feature: {}", explanation) |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
90 } |
46797
bcdcb4423ae3
rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents:
46740
diff
changeset
|
91 HgError::ConfigValueParseError(error) => error.fmt(f), |
46438
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
92 } |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
93 } |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
94 } |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
95 |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
96 // TODO: use `DisplayBytes` instead to show non-Unicode filenames losslessly? |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
97 impl fmt::Display for IoErrorContext { |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
98 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
99 match self { |
46599
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
100 IoErrorContext::ReadingFile(path) => { |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
101 write!(f, "when reading {}", path.display()) |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
102 } |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
103 IoErrorContext::WritingFile(path) => { |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
104 write!(f, "when writing {}", path.display()) |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
105 } |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
106 IoErrorContext::RemovingFile(path) => { |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
107 write!(f, "when removing {}", path.display()) |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
108 } |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
109 IoErrorContext::RenamingFile { from, to } => write!( |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
110 f, |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
111 "when renaming {} to {}", |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
112 from.display(), |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
113 to.display() |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
114 ), |
46740
97ac588b6d9e
rhg: Don?t make repository path absolute too early
Simon Sapin <simon.sapin@octobus.net>
parents:
46735
diff
changeset
|
115 IoErrorContext::CanonicalizingPath(path) => { |
97ac588b6d9e
rhg: Don?t make repository path absolute too early
Simon Sapin <simon.sapin@octobus.net>
parents:
46735
diff
changeset
|
116 write!(f, "when canonicalizing {}", path.display()) |
97ac588b6d9e
rhg: Don?t make repository path absolute too early
Simon Sapin <simon.sapin@octobus.net>
parents:
46735
diff
changeset
|
117 } |
46731
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46599
diff
changeset
|
118 IoErrorContext::CurrentDir => { |
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46599
diff
changeset
|
119 write!(f, "error getting current working directory") |
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46599
diff
changeset
|
120 } |
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46599
diff
changeset
|
121 IoErrorContext::CurrentExe => { |
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46599
diff
changeset
|
122 write!(f, "error getting current executable") |
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46599
diff
changeset
|
123 } |
46438
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
124 } |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
125 } |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
126 } |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
127 |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
128 pub trait IoResultExt<T> { |
46599
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
129 /// Annotate a possible I/O error as related to a reading a file at the |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
130 /// given path. |
46438
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
131 /// |
46599
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
132 /// This allows printing something like “File not found when reading |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
133 /// example.txt” instead of just “File not found”. |
46438
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
134 /// |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
135 /// Converts a `Result` with `std::io::Error` into one with `HgError`. |
46599
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
136 fn when_reading_file(self, path: &std::path::Path) -> Result<T, HgError>; |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
137 |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
138 fn with_context( |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
139 self, |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
140 context: impl FnOnce() -> IoErrorContext, |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
141 ) -> Result<T, HgError>; |
46438
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
142 } |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
143 |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
144 impl<T> IoResultExt<T> for std::io::Result<T> { |
46599
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
145 fn when_reading_file(self, path: &std::path::Path) -> Result<T, HgError> { |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
146 self.with_context(|| IoErrorContext::ReadingFile(path.to_owned())) |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
147 } |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
148 |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
149 fn with_context( |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
150 self, |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
151 context: impl FnOnce() -> IoErrorContext, |
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
152 ) -> Result<T, HgError> { |
46438
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
153 self.map_err(|error| HgError::IoError { |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
154 error, |
46599
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46598
diff
changeset
|
155 context: context(), |
46438
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
156 }) |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
157 } |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
158 } |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
159 |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
160 pub trait HgResultExt<T> { |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
161 /// Handle missing files separately from other I/O error cases. |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
162 /// |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
163 /// Wraps the `Ok` type in an `Option`: |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
164 /// |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
165 /// * `Ok(x)` becomes `Ok(Some(x))` |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
166 /// * An I/O "not found" error becomes `Ok(None)` |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
167 /// * Other errors are unchanged |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
168 fn io_not_found_as_none(self) -> Result<Option<T>, HgError>; |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
169 } |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
170 |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
171 impl<T> HgResultExt<T> for Result<T, HgError> { |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
172 fn io_not_found_as_none(self) -> Result<Option<T>, HgError> { |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
173 match self { |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
174 Ok(x) => Ok(Some(x)), |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
175 Err(HgError::IoError { error, .. }) |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
176 if error.kind() == std::io::ErrorKind::NotFound => |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
177 { |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
178 Ok(None) |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
179 } |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
180 Err(other_error) => Err(other_error), |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
181 } |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
182 } |
39e9407820ac
rust: Introduce an `HgError` enum for common error cases
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
183 } |