Added more convenience methods and trait impls to `PluginTrust<"a>`.

Fortune for rng's current commit: Small blessing − 小吉
plugin
Avril 2 years ago
parent f462d11025
commit 1348b0b9df
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -5,7 +5,7 @@ use std::path::{
Path,
};
use std::{
fs, io,
fs, io, ops,
borrow::{
Cow, Borrow,
},
@ -561,6 +561,32 @@ impl<P: AsRef<Path>> LookupVisitor<P>
}
}
impl<'a, T: ToOwned<Owned = PathBuf> + 'a> From<(T, bool)> for PluginTrust<'a>
{
fn from((from, trust): (T, bool)) -> Self
{
(if trust {
Self::Trusted
} else {
Self::Untrusted
})(Cow::Owned(from.to_owned()))
.enforce_validity::<true>()
}
}
impl<'a> From<locations::PathTrust<'a>> for PluginTrust<'a>
{
#[inline]
fn from(from: locations::PathTrust<'a>) -> Self
{
match from {
locations::PathTrust::Trusted(a) => PluginTrust::Trusted(Cow::from(Path::new(a))),
locations::PathTrust::Untrusted(a) => PluginTrust::Untrusted(Cow::from(Path::new(a))),
}.enforce_validity::<true>()
}
}
/// Denoted a plugin and if it was loaded from a trusted path or not
#[derive(Debug, Clone, Eq, Hash, PartialOrd, Ord)]
pub enum PluginTrust<'a>
@ -569,6 +595,15 @@ pub enum PluginTrust<'a>
Untrusted(Cow<'a, Path>)
}
impl<'a> ops::Deref for PluginTrust<'a>
{
type Target = Path;
#[inline]
fn deref(&self) -> &Self::Target {
self.as_path()
}
}
impl<'a> Borrow<Path> for PluginTrust<'a>
{
#[inline(always)]
@ -600,6 +635,15 @@ impl<'a> From<PluginTrust<'a>> for Cow<'a, Path>
}
}
impl<'a> From<PluginTrust<'a>> for PathBuf
{
#[inline]
fn from(from: PluginTrust<'a>) -> Self {
let cow: Cow<Path> = from.into();
cow.into_owned()
}
}
impl<'a, T: AsRef<Path> + ?Sized> PartialEq<T> for PluginTrust<'a>
{
#[inline]
@ -628,15 +672,52 @@ impl<'a> PluginTrust<'a>
{
!self.is_trusted()
}
}
impl From<PluginTrust<'static>> for PathBuf
/// Get the `Path`, trusted or otherwise.
#[inline(always)]
fn as_path(&self) -> &Path
{
self.borrow()
}
/// Map this path to another.
///
/// # Panics
/// If the output of `func` is not a file-like object or does not exist.
#[inline]
fn from(from: PluginTrust<'static>) -> Self
pub fn map<F, T: Into<Cow<'a, Path>>>(self, func: F) -> Self
where F: FnOnce(Cow<'a, Path>) -> T
{
match from {
PluginTrust::Trusted(a) | PluginTrust::Untrusted(a) => a.into_owned()
match self {
Self::Trusted(yes) => Self::Trusted(func(yes).into()),
Self::Untrusted(no) => Self::Untrusted(func(no).into())
}.enforce_validity::<false>()
}
#[inline(always)]
pub(super) fn is_valid(&self) -> bool
{
let path = self.as_path();
path.exists() && !path.is_dir() //XXX: Is this okay for validation for now? What about symlinked files?
}
#[inline(always)]
fn enforce_validity<const DEBUG: bool>(self) -> Self
{
if !DEBUG || cfg!(debug_assertions) {
#[inline(never)]
#[cold]
fn _panic_invalid(path: impl Into<PathBuf>) -> !
{
panic!("Illegal plugin path name: {:?}", path.into())
}
if !self.is_valid() {
_panic_invalid(self)
} else {
self
}
} else {
self
}
}
}

Loading…
Cancel
Save