feat: allow predicate to generate an error and return it boxed

This commit is contained in:
2025-11-11 16:30:58 +01:00
parent bbc6105452
commit 34808ccf74
2 changed files with 25 additions and 3 deletions

View File

@@ -4,14 +4,14 @@ impl Catalog {
pub fn for_each_mut<T, F>(&self, mut predicate: F) -> Result<(), FailedTo>
where
T: EAV,
F: FnMut(&mut T),
F: FnMut(&mut T) -> Result<(), Box<dyn error::Error>>,
{
self.on_items(|items| {
for entity in items.values_mut() {
let original_item =
T::try_from(entity.clone()).map_err(|_| FailedTo::ConvertEntity)?;
let mut item = T::try_from(entity.clone()).map_err(|_| FailedTo::ConvertEntity)?;
predicate(&mut item);
predicate(&mut item).map_err(FailedTo::ExecutePredicate)?;
if item != original_item {
*entity = T::try_into(item).map_err(|_| FailedTo::ConvertObject)?;
entity.state = EntityState::Updated;

View File

@@ -1,7 +1,7 @@
use crate::*;
/// Represents the possible failures that can occur in the library.
#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, Hash)]
#[derive(Debug)]
pub enum FailedTo {
/// Failed to compose filter statement
ComposeFilter,
@@ -11,6 +11,8 @@ pub enum FailedTo {
ConvertObject,
/// Failed to convert from Value to type.
ConvertValue,
/// Failed to execute predicate to mutate an item.
ExecutePredicate(Box<dyn error::Error>),
/// Failed to initialize the database.
InitDatabase,
/// Failed to load data from the database.
@@ -27,6 +29,26 @@ pub enum FailedTo {
SQLite(sqlite::FailedTo),
}
impl PartialEq for FailedTo {
fn eq(&self, other: &FailedTo) -> bool {
matches!(
(self, other),
(FailedTo::ComposeFilter, FailedTo::ComposeFilter)
| (FailedTo::ConvertEntity, FailedTo::ConvertEntity)
| (FailedTo::ConvertObject, FailedTo::ConvertObject)
| (FailedTo::ConvertValue, FailedTo::ConvertValue)
| (FailedTo::ExecutePredicate(_), FailedTo::ExecutePredicate(_))
| (FailedTo::InitDatabase, FailedTo::InitDatabase)
| (FailedTo::LoadFromDB, FailedTo::LoadFromDB)
| (FailedTo::LockCatalog, FailedTo::LockCatalog)
| (FailedTo::MapAttribute, FailedTo::MapAttribute)
| (FailedTo::MapEntity, FailedTo::MapEntity)
| (FailedTo::PersistCatalog, FailedTo::PersistCatalog)
| (FailedTo::SQLite(_), FailedTo::SQLite(_))
)
}
}
impl From<sqlite::FailedTo> for FailedTo {
fn from(value: sqlite::FailedTo) -> Self {
Self::SQLite(value)