You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
2.5 KiB

use super::*;
use std::{
error,
fmt,
};
use std::ffi::OsStr;
/// Builder for creating [`Entry`] instances.
#[derive(Debug, Clone, Eq, PartialEq, Hash, Default)]
pub struct EntryBuilder<'a>
{
name: Option<&'a str>,
desc: Option<&'a str>,
tags: Option<&'a[&'a str]>,
key: Option<aes::AesKey>,
hash: Option<sha256::Sha256Hash>,
location: Option<&'a Path>,
filename: Option<&'a OsStr>,
}
macro_rules! build_fn {
($name:ident: $ty:ty $(, $com:literal)?) => {
$(#[doc=$com])?
#[inline] pub const fn $name(self, $name: $ty) -> Self
{
Self {
$name: Some($name),
..self
}
}
};
}
impl<'a> EntryBuilder<'a>
{
/// Create a new entry builder
#[inline] pub const fn new() -> Self
{
macro_rules! default {
($($name:ident),*) => {
Self {
$(
$name: None
),*
}
}
}
default!{
name, desc, tags, key, hash, location, filename
}
}
build_fn!(name: &'a str, "Insert the name of this entry");
build_fn!(desc: &'a str, "Insert a description for this entry");
build_fn!(tags: &'a [&'a str], "Insert the tags for this entry");
build_fn!(key: aes::AesKey, "Insert the encryption key for this entry");
build_fn!(hash: sha256::Sha256Hash, "Insert the hash for this entry");
build_fn!(location: &'a Path, "Insert the location for this entry");
build_fn!(filename: &'a OsStr, "Insert the original filename for this entry");
/// Try to build an `Entry` from this builder.
#[inline] pub fn build(self) -> Result<Entry, EntryBuildError>
{
macro_rules! fail_on {
($name:ident) => {
self.$name.ok_or(EntryBuildError)?
};
($name:ident: $or:expr) =>{
if let Some(name) = self.$name {
name
} else {
$or
}
};
}
Ok(
Entry {
name: fail_on!(name).into(),
description: fail_on!(desc: "").into(),
tags: fail_on!(tags: &[]).iter().map(|&x| x.to_owned()).collect(),
key: self.key,
hash: fail_on!(hash),
location: fail_on!(location).into(),
filename: fail_on!(filename: OsStr::new("")).into(),
cache: Default::default(),
}
)
}
}
/// Error for when an improporly configured [`EntryBuilder`] called `.build()`.
/// Usually this is because of missing fields.
#[derive(Debug)]
pub struct EntryBuildError;
impl error::Error for EntryBuildError{}
impl fmt::Display for EntryBuildError
{
#[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "improporly configured builder")
}
}