/ crates / tor-persist / src / fs_mistrust_error_ext.rs
fs_mistrust_error_ext.rs
 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  }