use std::path::Path;
#[derive(Debug)]
#[non_exhaustive]
pub struct DataRequest<'a> {
pub(crate) layers: LayerFilter<'a>,
pub lib: bool,
pub groups: bool,
pub kerning: bool,
pub features: bool,
pub data: bool,
pub images: bool,
}
type FilterFn<'a> = dyn Fn(&str, &Path) -> bool + 'a;
pub(crate) struct LayerFilter<'a> {
all: bool,
load_default: bool,
custom: Option<Box<FilterFn<'a>>>,
}
impl LayerFilter<'_> {
fn from_bool(b: bool) -> Self {
LayerFilter { all: b, ..Default::default() }
}
pub(crate) fn should_load(&self, name: &str, path: &Path) -> bool {
self.all
|| (self.load_default && path == Path::new("glyphs"))
|| self.custom.as_ref().map(|f| f(name, path)).unwrap_or(false)
}
pub(crate) fn includes_default_layer(&self) -> bool {
self.all || self.load_default
}
}
impl<'a> DataRequest<'a> {
fn from_bool(b: bool) -> Self {
DataRequest {
layers: LayerFilter::from_bool(b),
lib: b,
groups: b,
kerning: b,
features: b,
data: b,
images: b,
}
}
pub fn all() -> Self {
DataRequest::from_bool(true)
}
pub fn none() -> Self {
DataRequest::from_bool(false)
}
pub fn layers(mut self, b: bool) -> Self {
self.layers.all = b;
self
}
pub fn default_layer(mut self, b: bool) -> Self {
self.layers.load_default = b;
self.layers.all = false;
self
}
pub fn filter_layers(mut self, filter: impl Fn(&str, &Path) -> bool + 'a) -> Self {
self.layers.custom = Some(Box::new(filter));
self.layers.all = false;
self
}
pub fn lib(mut self, b: bool) -> Self {
self.lib = b;
self
}
pub fn groups(mut self, b: bool) -> Self {
self.groups = b;
self
}
pub fn kerning(mut self, b: bool) -> Self {
self.kerning = b;
self
}
pub fn features(mut self, b: bool) -> Self {
self.features = b;
self
}
pub fn data(mut self, b: bool) -> Self {
self.data = b;
self
}
pub fn images(mut self, b: bool) -> Self {
self.images = b;
self
}
}
impl Default for DataRequest<'_> {
fn default() -> Self {
DataRequest::from_bool(true)
}
}
impl Default for LayerFilter<'_> {
fn default() -> Self {
Self { all: true, load_default: false, custom: None }
}
}
impl std::fmt::Debug for LayerFilter<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.debug_struct("LayerFilter")
.field("all", &self.all)
.field("load_default", &self.load_default)
.field("custom", &self.custom.is_some())
.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
fn all_fields_are_true(dr: &DataRequest) -> bool {
dr.layers.all && dr.lib && dr.groups && dr.kerning && dr.features && dr.data && dr.images
}
fn all_fields_are_false(dr: &DataRequest) -> bool {
!dr.layers.all
&& !dr.lib
&& !dr.groups
&& !dr.kerning
&& !dr.features
&& !dr.data
&& !dr.images
}
#[test]
fn test_datarequest_default() {
assert!(all_fields_are_true(&DataRequest::default()));
}
#[test]
fn test_datarequest_all() {
assert!(all_fields_are_true(&DataRequest::all()));
}
#[test]
fn test_datarequest_none() {
assert!(all_fields_are_false(&DataRequest::none()));
}
#[test]
fn test_datarequest_builder() {
let dr = DataRequest::default()
.layers(false)
.lib(false)
.groups(false)
.kerning(false)
.features(false)
.data(false)
.images(false);
assert!(all_fields_are_false(&dr));
}
}