//! Error handling for VOA configuration files.

use std::path::PathBuf;

/// The error that can occur when using VOA configuration files.
#[derive(Debug, thiserror::Error)]
pub enum Error {
    /// There are no context settings.
    #[error("There must be at least one context settings")]
    ContextSettingsMissing,

    /// An I/O error occurred at a path.
    #[error("I/O error at path {path} while {context}:\n{source}")]
    IoPath {
        /// The path at which the error occurred.
        path: PathBuf,
        /// The context in which the error occurred.
        ///
        /// This is meant to complete the sentence "I/O error at path while ".
        context: &'static str,
        /// The error source.
        source: std::io::Error,
    },

    /// An OpenPGP technology error occurred.
    #[error(transparent)]
    OpenpgpTechnology(#[from] crate::config::technology::openpgp::Error),

    /// An error occurred while deserializing an object as a YAML string.
    #[error("YAML deserialization error while {context}:\n{source}")]
    YamlDeserialize {
        /// The context in which the error occurred.
        ///
        /// This is meant to complete the sentence "YAML deserialization error while ".
        context: String,
        /// The error source.
        source: serde_saphyr::Error,
    },

    /// An error occurred while serializing an object as a YAML string.
    #[error("YAML serialization error while {context}:\n{source}")]
    YamlSerialize {
        /// The context in which the error occurred.
        ///
        /// This is meant to complete the sentence "YAML serialization error while ".
        context: &'static str,
        /// The error source.
        source: serde_saphyr::ser_error::Error,
    },

    /// A garde validation error occurred.
    #[error("Validation error while {context}: {source}")]
    Validation {
        /// The context in which the error occurred.
        ///
        /// This is meant to complete the sentence "Validation error while ".
        context: String,

        /// The error source.
        source: garde::Report,
    },

    /// A [`voa_core::Error`] occurred.
    #[error(transparent)]
    VoaCore(#[from] voa_core::Error),
}
