ic-backup 0.24.2

Host-side snapshot backup and same-release recovery for Internet Computer canisters
Documentation
//! Shared local sequence for immutable bounded declarations.

use super::json::check_json_size;
use super::{
    BackupLayoutGuard, JournalLock, JournalLockError, PersistenceError, create_json_durable,
    read_json,
};
use serde::{Serialize, de::DeserializeOwned};

pub(super) fn create<T, E>(
    layout: &BackupLayoutGuard,
    name: &str,
    limit: u64,
    record: &T,
) -> Result<(), E>
where
    T: Serialize,
    E: From<JournalLockError> + From<PersistenceError>,
{
    layout.check_root()?;
    let path = layout.root().join(name);
    let _lock = JournalLock::acquire(&path)?;
    check_json_size(record, limit)?;
    create_json_durable(&path, record)?;
    Ok(())
}

pub(super) fn read<T, E>(
    layout: &BackupLayoutGuard,
    name: &str,
    limit: u64,
    matches_original: impl FnOnce(&T) -> bool,
    mismatch: impl FnOnce() -> E,
) -> Result<T, E>
where
    T: DeserializeOwned + Serialize,
    E: From<JournalLockError> + From<PersistenceError>,
{
    read_with(layout, name, limit, |record| {
        if matches_original(record) {
            Ok(())
        } else {
            Err(mismatch())
        }
    })
}

pub(super) fn read_with<T, E>(
    layout: &BackupLayoutGuard,
    name: &str,
    limit: u64,
    validate: impl FnOnce(&T) -> Result<(), E>,
) -> Result<T, E>
where
    T: DeserializeOwned + Serialize,
    E: From<JournalLockError> + From<PersistenceError>,
{
    layout.check_root()?;
    let path = layout.root().join(name);
    let _lock = JournalLock::acquire(&path)?;
    let record: T = read_json(&path, limit)?;
    check_json_size(&record, limit)?;
    validate(&record)?;
    Ok(record)
}