use crate::{FormatDescriptor, FormatKind, ProbeRegistry};
#[derive(Clone, Copy)]
pub struct FormatInventoryEntry {
pub descriptor: FormatDescriptor,
register_probes: fn(&mut ProbeRegistry),
}
impl FormatInventoryEntry {
pub const fn new(descriptor: FormatDescriptor, register_probes: fn(&mut ProbeRegistry)) -> Self {
Self {
descriptor,
register_probes,
}
}
pub fn register_probes(&self, registry: &mut ProbeRegistry) {
(self.register_probes)(registry);
}
}
inventory::collect!(FormatInventoryEntry);
#[derive(Clone)]
pub struct FormatInventory {
entries: Vec<&'static FormatInventoryEntry>,
}
impl FormatInventory {
pub fn new(entries: Vec<&'static FormatInventoryEntry>) -> Self {
Self { entries }
}
pub fn entries(&self) -> &[&'static FormatInventoryEntry] {
&self.entries
}
pub fn len(&self) -> usize {
self.entries.len()
}
pub fn entries_of_kind(
&self, kind: FormatKind,
) -> impl Iterator<Item = &'static FormatInventoryEntry> + '_ {
self
.entries
.iter()
.copied()
.filter(move |entry| entry.descriptor.kind == kind)
}
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
}
pub fn builtin_inventory() -> FormatInventory {
let mut entries: Vec<_> = inventory::iter::<FormatInventoryEntry>
.into_iter()
.collect();
entries.sort_by_key(|entry| (entry.descriptor.kind.probe_sort_rank(), entry.descriptor.id));
FormatInventory::new(entries)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{images::ewf, volumes::gpt};
#[test]
fn builtin_inventory_contains_known_formats() {
let inventory = builtin_inventory();
assert!(!inventory.is_empty());
assert!(
inventory
.entries()
.iter()
.any(|entry| entry.descriptor == gpt::DESCRIPTOR)
);
assert!(
inventory
.entries()
.iter()
.any(|entry| entry.descriptor == ewf::DESCRIPTOR)
);
}
#[test]
fn builtin_inventory_filters_entries_by_kind() {
let inventory = builtin_inventory();
let image_ids = inventory
.entries_of_kind(FormatKind::Image)
.map(|entry| entry.descriptor.id)
.collect::<Vec<_>>();
assert!(image_ids.contains(&ewf::DESCRIPTOR.id));
assert!(!image_ids.contains(&gpt::DESCRIPTOR.id));
}
}