1
//! [`FsMistrustErrorExt`]
2

            
3
use paste::paste;
4

            
5
use tor_error::ErrorKind;
6

            
7
use ErrorKind as EK;
8

            
9
/// Helper; `access_failed` should be `FooAccessFaile` for the appropriate `Foo`
10
fn mistrust_error_kind(e: &fs_mistrust::Error, access_failed: ErrorKind) -> ErrorKind {
11
    if e.is_bad_permission() {
12
        EK::FsPermissions
13
    } else {
14
        access_failed
15
    }
16
}
17

            
18
/// Generate the extension trait and its impl
19
///
20
/// Input is the set of "kinds of thing", each of which corresponds to an `ErrorKind`.
21
///
22
/// # Input syntax
23
///
24
/// ```text
25
///     thing, "DESCRIPTION";           // Provide thing_error_kind(), using ThingAccessFailed
26
///     [Prefix] THING, "DESCRIPTION";  // uses PrefixThingAccessFAiled
27
/// ```
28
macro_rules! accesses { {
29
    $( $([ $prefix:ident ])? $kind:ident, $description:tt; )*
30
} => { paste!{
31

            
32
    /// Extension trait for getting a [`tor_error::ErrorKind`] from a [`fs_mistrust::Error`]
33
    pub trait FsMistrustErrorExt: Sealed {
34
        $(
35

            
36
            #[doc = concat!("The error kind if we were trying to access", $description)]
37
            fn [<$kind _error_kind>](&self) -> ErrorKind;
38
        )*
39
    }
40

            
41
    impl FsMistrustErrorExt for fs_mistrust::Error {
42
        $(
43
            fn [<$kind _error_kind>](&self) -> tor_error::ErrorKind {
44
                mistrust_error_kind(self, EK::[<$($prefix)? $kind:camel AccessFailed>])
45
            }
46
        )*
47
    }
48

            
49
} } }
50

            
51
/// Sealed
52
pub trait Sealed {}
53
impl Sealed for fs_mistrust::Error {}
54

            
55
accesses! {
56
    cache, "a cache directory";
57
    [Persistent] state, "a persistent state directory";
58
    keystore, "a keystore";
59
}