vstorage 0.7.0

Common API for various icalendar/vcard storages.
Documentation
// Copyright 2023-2024 Hugo Osvaldo Barrera
//
// SPDX-License-Identifier: EUPL-1.2

//! Types for granular error management.
//!
//! These types represent non-fatal errors which may occurs during synchronisation.

use super::{execute::ExecutionError, operation::Operation};

/// An error synchronising two items between storages.
///
/// Details on a non-fatal error that occurred during synchronisation. This contains
/// enough data to provide a meaningful description of what has gone wrong.
///
/// Use the [`std::fmt::Display`] implementation for a quick description.
#[derive(Debug)]
pub struct SyncError {
    operation: Operation,
    error: ExecutionError,
}

impl SyncError {
    #[must_use]
    pub(crate) fn new(operation: Operation, error: ExecutionError) -> Self {
        Self { operation, error }
    }
}

impl std::fmt::Display for SyncError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match &self.operation {
            Operation::FlushStaleMappings { stale_uids } => {
                // Should never happen; failues for this Op is always fatal.
                write!(
                    f,
                    "Error flushing stale mapping(s) for {stale_uids:?}: {}",
                    self.error
                )
            }
            Operation::Collection(op) => write!(
                f,
                "Error executing collection operation {op}: {}",
                self.error
            ),
            Operation::Item(op) => write!(f, "Error executing item operation {op}: {}", self.error),
            Operation::Property(op) => {
                write!(f, "Error executing property operation {op}: {}", self.error)
            }
        }
    }
}

impl std::error::Error for SyncError {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        Some(&self.error)
    }
}