Skip to content

Commit de0226a

Browse files
committed
feat: permission::Error (#301)
A lightweight, general purpose error to display permissions violations that cause errors. This should make it useable across crates.
1 parent 7d98b21 commit de0226a

File tree

2 files changed

+48
-5
lines changed

2 files changed

+48
-5
lines changed

git-sec/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ serde1 = [ "serde" ]
1919
[dependencies]
2020
serde = { version = "1.0.114", optional = true, default-features = false, features = ["std", "derive"] }
2121
bitflags = "1.3.2"
22+
thiserror = { version = "1.0.26", optional = true }
2223

2324
[target.'cfg(not(windows))'.dependencies]
2425
libc = "0.2.123"

git-sec/src/lib.rs

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#![deny(unsafe_code, rust_2018_idioms, missing_docs)]
22
//! A shared trust model for `gitoxide` crates.
33
4+
use std::fmt::{Debug, Display, Formatter};
45
use std::marker::PhantomData;
56
use std::ops::Deref;
67

@@ -75,19 +76,22 @@ pub mod trust {
7576
///
7677
pub mod permission {
7778
use crate::Access;
79+
use std::fmt::{Debug, Display};
7880

7981
/// A marker trait to signal tags for permissions.
80-
pub trait Tag {}
82+
pub trait Tag: Debug {}
8183

8284
/// A tag indicating that a permission is applying to the contents of a configuration file.
85+
#[derive(Debug)]
8386
pub struct Config;
8487
impl Tag for Config {}
8588

8689
/// A tag indicating that a permission is applying to the resource itself.
90+
#[derive(Debug)]
8791
pub struct Resource;
8892
impl Tag for Resource {}
8993

90-
impl<P> Access<Config, P> {
94+
impl<P: Debug + Display> Access<Config, P> {
9195
/// Create a permission for values contained in git configuration files.
9296
///
9397
/// This applies permissions to values contained inside of these files.
@@ -99,7 +103,7 @@ pub mod permission {
99103
}
100104
}
101105

102-
impl<P> Access<Resource, P> {
106+
impl<P: Debug + Display> Access<Resource, P> {
103107
/// Create a permission a file or directory itself.
104108
///
105109
/// This applies permissions to a configuration file itself and whether it can be used at all, or to a directory
@@ -111,6 +115,18 @@ pub mod permission {
111115
}
112116
}
113117
}
118+
119+
/// An error to use if an operation cannot proceed due to insufficient permissions.
120+
///
121+
/// It's up to the implementation to decide which permission is required for an operation, and which one
122+
/// causes errors.
123+
#[cfg(feature = "thiserror")]
124+
#[derive(Debug, thiserror::Error)]
125+
#[error("Not allowed to handle resource {:?}: permission {}", .resource, .permission)]
126+
pub struct Error<R: Debug, P: Debug + Display> {
127+
resource: R,
128+
permission: P,
129+
}
114130
}
115131

116132
/// Allow, deny or forbid using a resource or performing an action.
@@ -125,6 +141,19 @@ pub enum Permission {
125141
Allow,
126142
}
127143

144+
impl Display for Permission {
145+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
146+
Display::fmt(
147+
match self {
148+
Permission::Allow => "allowed",
149+
Permission::Deny => "denied",
150+
Permission::Forbid => "forbidden",
151+
},
152+
f,
153+
)
154+
}
155+
}
156+
128157
bitflags::bitflags! {
129158
/// Whether something can be read or written.
130159
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
@@ -136,14 +165,27 @@ bitflags::bitflags! {
136165
}
137166
}
138167

168+
impl Display for ReadWrite {
169+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
170+
Debug::fmt(self, f)
171+
}
172+
}
173+
139174
/// A container to define tagged access permissions, rendering the permission read-only.
140-
pub struct Access<T: permission::Tag, P> {
175+
#[derive(Debug)]
176+
pub struct Access<T: permission::Tag, P: Debug + Display> {
141177
/// The access permission itself.
142178
permission: P,
143179
_data: PhantomData<T>,
144180
}
145181

146-
impl<T: permission::Tag, P> Deref for Access<T, P> {
182+
impl<T: permission::Tag, P: Debug + Display> Display for Access<T, P> {
183+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
184+
Display::fmt(&self.permission, f)
185+
}
186+
}
187+
188+
impl<T: permission::Tag, P: Debug + Display> Deref for Access<T, P> {
147189
type Target = P;
148190

149191
fn deref(&self) -> &Self::Target {

0 commit comments

Comments
 (0)