proto-reg 0.1.0

Manage custom URL protocols in the Windows registry
//! Backup / restore support.
//!
//! Registered protocols can be exported to a JSON file (backup) and imported
//! again later (restore). The JSON file is plain `serde` data, so it can be
//! inspected or hand-edited before restoring.

use std::path::Path;

use serde::Serialize;

use crate::error::Result;
use crate::protocol::Protocol;

/// Outcome of a [`crate::ProtocolManager::restore_from_json`] /
/// [`crate::ProtocolManager::restore_from_file`] operation.
#[derive(Debug, Clone, Default, Serialize)]
pub struct RestoreReport {
    /// Number of protocols successfully written to the registry.
    pub restored: usize,
    /// `(protocol name, error message)` pairs for protocols that could not be
    /// restored. Restoration continues past individual failures.
    pub failed: Vec<(String, String)>,
}

impl RestoreReport {
    /// Returns `true` when every protocol was restored.
    pub fn is_success(&self) -> bool {
        self.failed.is_empty()
    }
}

/// Loads a backup from a JSON string.
pub(crate) fn parse_backup(json: &str) -> Result<Vec<Protocol>> {
    let protocols: Vec<Protocol> = serde_json::from_str(json)?;
    Ok(protocols)
}

/// Serializes a backup to pretty JSON.
pub(crate) fn to_json(protocols: &[Protocol]) -> Result<String> {
    Ok(serde_json::to_string_pretty(protocols)?)
}

/// Writes a backup to `path` as pretty JSON.
pub(crate) fn write_to_file(protocols: &[Protocol], path: impl AsRef<Path>) -> Result<()> {
    let json = to_json(protocols)?;
    std::fs::write(path.as_ref(), json)?;
    Ok(())
}

/// Reads a backup from `path`.
pub(crate) fn read_from_file(path: impl AsRef<Path>) -> Result<Vec<Protocol>> {
    let json = std::fs::read_to_string(path.as_ref())?;
    parse_backup(&json)
}