Add Is helper trait
This commit is contained in:
parent
2d83796ef2
commit
a246144c26
1 changed files with 100 additions and 0 deletions
|
@ -17,4 +17,104 @@
|
|||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
//
|
||||
|
||||
use error::EntryUtilError as EUE;
|
||||
use error::Result;
|
||||
|
||||
use toml::Value;
|
||||
use toml_query::read::TomlValueReadExt;
|
||||
|
||||
/// Trait to check whether an entry is a certain kind of entry
|
||||
///
|
||||
/// If an entry is marked with a `bool` flag in the header to contain a certain amount of data (for
|
||||
/// example a "wiki" entry may provide some meta information in the `[wiki]` section of its header),
|
||||
/// this trait provides a check whether the entry has set the flag to `true` or `false`.
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// This trait is solely for library implementations, as convenience functionality for implementing
|
||||
/// some function like this:
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # extern crate libimagstore;
|
||||
/// # #[macro_use]
|
||||
/// # extern crate libimagentryutil;
|
||||
///
|
||||
/// # use libimagentryutil::error::Result as Result;
|
||||
/// use libimagentryutil::isa::IsKindHeaderPathProvider;
|
||||
/// use libimagentryutil::isa::Is;
|
||||
///
|
||||
/// trait WikiArticle {
|
||||
/// fn is_wiki_article(&self) -> Result<bool>;
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// provide_kindflag_path!(IsWikiEntry, "wiki.is_entry");
|
||||
///
|
||||
/// impl WikiArticle for ::libimagstore::store::Entry {
|
||||
/// fn is_wiki_article(&self) -> Result<bool> {
|
||||
/// self.is::<IsWikiEntry>()
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// # fn main() { }
|
||||
/// ```
|
||||
///
|
||||
/// # See also
|
||||
///
|
||||
/// * Documentation for `IsKindHeaderPathProvider`
|
||||
/// * Helper macro `provide_kindflag_path!()`
|
||||
///
|
||||
pub trait Is {
|
||||
fn is<T: IsKindHeaderPathProvider>(&self) -> Result<bool>;
|
||||
}
|
||||
|
||||
impl Is for ::libimagstore::store::Entry {
|
||||
fn is<T: IsKindHeaderPathProvider>(&self) -> Result<bool> {
|
||||
let field = T::kindflag_header_location();
|
||||
|
||||
match self.get_header().read(field) {
|
||||
Ok(Some(&Value::Boolean(b))) => Ok(b),
|
||||
Ok(Some(_)) => Err(format!("Field {} has not a boolean type", field)).map_err(EUE::from),
|
||||
Ok(None) => Err(format!("Field {} not available", field)).map_err(EUE::from),
|
||||
Err(e) => Err(EUE::from(e))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// The IsKindHeaderPathProvider trait provides a function `typeflag_header_location()` which
|
||||
/// returns a `toml-query` path.
|
||||
///
|
||||
/// This path points to a `bool` entry in the header of an entry which marks the entry to be an
|
||||
/// entry of a certain kind.
|
||||
///
|
||||
/// For example, an "Wiki" entry might contain a `true` at `"wiki.is_entry"` in the header.
|
||||
/// This trait provides `"wiki.is_entry"`.
|
||||
pub trait IsKindHeaderPathProvider {
|
||||
fn kindflag_header_location() -> &'static str;
|
||||
}
|
||||
|
||||
/// Create (pub/non-pub) type for providing a `kindflag_header_location()` implementation.
|
||||
#[macro_export]
|
||||
macro_rules! provide_kindflag_path {
|
||||
(pub $entry_header_path_provider_type:ident, $path:expr) => {
|
||||
pub struct $entry_header_path_provider_type;
|
||||
provide_kindflag_path!(impl for $entry_header_path_provider_type, $path);
|
||||
};
|
||||
|
||||
($entry_header_path_provider_type:ident, $path:expr) => {
|
||||
struct $entry_header_path_provider_type;
|
||||
provide_kindflag_path!(impl for $entry_header_path_provider_type, $path);
|
||||
};
|
||||
|
||||
(impl for $entry_header_path_provider_type:ident, $path:expr) => {
|
||||
impl IsKindHeaderPathProvider for $entry_header_path_provider_type {
|
||||
fn kindflag_header_location() -> &'static str {
|
||||
$path
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue