Skip to main content

tor_persist/
fs_mistrust_error_ext.rs

1//! [`FsMistrustErrorExt`]
2
3use extend::ext;
4use paste::paste;
5
6use tor_error::ErrorKind;
7
8use ErrorKind as EK;
9
10/// Helper; `access_failed` should be `FooAccessFaile` for the appropriate `Foo`
11fn mistrust_error_kind(e: &fs_mistrust::Error, access_failed: ErrorKind) -> ErrorKind {
12    if e.is_bad_permission() {
13        EK::FsPermissions
14    } else {
15        access_failed
16    }
17}
18
19/// Generate the extension trait and its impl
20///
21/// Input is the set of "kinds of thing", each of which corresponds to an `ErrorKind`.
22///
23/// # Input syntax
24///
25/// ```text
26///     thing, "DESCRIPTION";           // Provide thing_error_kind(), using ThingAccessFailed
27///     [Prefix] THING, "DESCRIPTION";  // uses PrefixThingAccessFAiled
28/// ```
29macro_rules! accesses { {
30    $( $([ $prefix:ident ])? $kind:ident, $description:tt; )*
31} => { paste!{
32
33    /// Extension trait for getting a [`tor_error::ErrorKind`] from a [`fs_mistrust::Error`]
34    #[ext(name = FsMistrustErrorExt, supertraits = Sealed)]
35    pub impl fs_mistrust::Error {
36        $(
37
38            #[doc = concat!("The error kind if we were trying to access", $description)]
39            fn [<$kind _error_kind>](&self) -> tor_error::ErrorKind {
40                mistrust_error_kind(self, EK::[<$($prefix)? $kind:camel AccessFailed>])
41            }
42        )*
43    }
44
45} } }
46
47/// Sealed
48pub trait Sealed {}
49impl Sealed for fs_mistrust::Error {}
50
51accesses! {
52    cache, "a cache directory";
53    [Persistent] state, "a persistent state directory";
54    keystore, "a keystore";
55}