1
//! [`FsMistrustErrorExt`]
2

            
3
use extend::ext;
4
use paste::paste;
5

            
6
use tor_error::ErrorKind;
7

            
8
use ErrorKind as EK;
9

            
10
/// Helper; `access_failed` should be `FooAccessFaile` for the appropriate `Foo`
11
fn 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
/// ```
29
macro_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
48
pub trait Sealed {}
49
impl Sealed for fs_mistrust::Error {}
50

            
51
accesses! {
52
    cache, "a cache directory";
53
    [Persistent] state, "a persistent state directory";
54
    keystore, "a keystore";
55
}