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

View File

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