aboutsummaryrefslogtreecommitdiff
path: root/crates/tor-persist/src/fs_mistrust_error_ext.rs
blob: 70f180597ee90711e57bb99192850d7229c7895e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
//! [`FsMistrustErrorExt`]

use extend::ext;
use paste::paste;

use tor_error::ErrorKind;

use ErrorKind as EK;

/// Helper; `access_failed` should be `FooAccessFaile` for the appropriate `Foo`
fn mistrust_error_kind(e: &fs_mistrust::Error, access_failed: ErrorKind) -> ErrorKind {
    if e.is_bad_permission() {
        EK::FsPermissions
    } else {
        access_failed
    }
}

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

    /// Extension trait for getting a [`tor_error::ErrorKind`] from a [`fs_mistrust::Error`]
    #[ext(name = FsMistrustErrorExt, supertraits = Sealed)]
    pub impl fs_mistrust::Error {
        $(

            #[doc = concat!("The error kind if we were trying to access", $description)]
            fn [<$kind _error_kind>](&self) -> tor_error::ErrorKind {
                mistrust_error_kind(self, EK::[<$($prefix)? $kind:camel AccessFailed>])
            }
        )*
    }

} } }

/// Sealed
pub trait Sealed {}
impl Sealed for fs_mistrust::Error {}

accesses! {
    cache, "a cache directory";
    [Persistent] state, "a persistent state directory";
    keystore, "a keystore";
}