#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[cfg(feature = "diesel-support")]
mod diesel_support {
pub use super::*;
pub use diesel::{
pg::Pg,
serialize::Output,
sql_types::Jsonb,
types::{FromSql, ToSql},
};
pub use std::io::Write;
impl FromSql<Jsonb, Pg> for Permissions {
fn from_sql(bytes: Option<&[u8]>) -> diesel::deserialize::Result<Self> {
let value =
<serde_json::Value as FromSql<Jsonb, Pg>>::from_sql(bytes)?;
Ok(serde_json::from_value(value)?)
}
}
impl ToSql<Jsonb, Pg> for Permissions {
fn to_sql<W: Write>(
&self,
out: &mut Output<W, Pg>,
) -> diesel::serialize::Result {
let value = serde_json::to_value(self)?;
<serde_json::Value as ToSql<Jsonb, Pg>>::to_sql(&value, out)
}
}
}
#[cfg(feature = "diesel-support")]
use diesel_support::*;
#[derive(Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd, Default)]
#[cfg_attr(
feature = "diesel-support",
derive(FromSqlRow, AsExpression),
sql_type = "Jsonb"
)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Permissions {
#[cfg_attr(feature = "serde", serde(rename = "permissions"))]
pub vec: Vec<Permission>,
}
impl Permissions {
#[must_use]
pub fn new(vec: Vec<Permission>) -> Self {
Self { vec }
}
pub fn get_permission<T>(&self, path: &[T], r#mut: bool) -> bool where String: PartialEq<T>{
let mut best = None;
let mut bestn = 0;
if path.is_empty() {
return false;
}
'_permission: for permission in &self.vec {
if permission.path.len() > path.len() { continue; }
let mut matches = 0_usize;
'_segments: for (n, permission_seg) in permission.path.iter().enumerate() {
match path.get(n) {
Some(path_seg) => {
if permission_seg != path_seg {
continue '_permission;
} else {
matches += 1
}
},
None => break '_segments,
}
}
if matches > bestn {
best = Some(permission);
bestn = matches;
}
}
if let Some(best) = best {
return best.auth && (best.r#mut || !r#mut);
}
false
}
}
impl From<Vec<Permission>> for Permissions {
fn from(vec: Vec<Permission>) -> Self {
Self { vec }
}
}
#[derive(Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Permission {
pub path: Vec<String>,
pub auth: bool,
#[cfg_attr(feature = "serde", serde(default))]
pub r#mut: bool,
}
impl Permission {
#[must_use]
pub fn new(path: Vec<String>, auth: bool, r#mut: bool) -> Self {
Self { path, auth, r#mut }
}
}