alma 0.1.1

A Bevy-native modal text editor with Vim-style navigation.
Documentation
//! Effect admission error vocabulary.

use super::PluginEffectBatchLimitField;
use crate::plugin::PluginIdentity;
use std::{
    fmt::{Debug, Display, Formatter},
    num::NonZeroUsize,
};

/// Plugin effect commit rejection class.
#[derive(Clone, Copy, Eq, PartialEq)]
pub enum PluginEffectCommitErrorKind {
    /// A batch limit was zero.
    ZeroLimit,
    /// The pending effect batch was full.
    TooManyEffects,
}

impl PluginEffectCommitErrorKind {
    /// Stable diagnostic spelling.
    #[must_use]
    pub const fn as_str(self) -> &'static str {
        match self {
            Self::ZeroLimit => "zero-limit",
            Self::TooManyEffects => "too-many-effects",
        }
    }
}

impl Display for PluginEffectCommitErrorKind {
    fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
        formatter.write_str(self.as_str())
    }
}

impl Debug for PluginEffectCommitErrorKind {
    fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
        formatter.write_str(self.as_str())
    }
}

/// Plugin effect commit failure.
#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
#[non_exhaustive]
pub enum PluginEffectCommitError {
    /// Effect limit was zero.
    ZeroLimit {
        /// Limit field name.
        field: PluginEffectBatchLimitField,
    },
    /// Effect limit was exceeded.
    TooManyEffects {
        /// Stable plugin identity.
        identity: PluginIdentity,
        /// Maximum accepted effects.
        limit: NonZeroUsize,
    },
}

impl PluginEffectCommitError {
    /// Closed rejection class for caller decisions and diagnostics.
    #[must_use]
    pub const fn kind(&self) -> PluginEffectCommitErrorKind {
        match self {
            Self::ZeroLimit { .. } => PluginEffectCommitErrorKind::ZeroLimit,
            Self::TooManyEffects { .. } => PluginEffectCommitErrorKind::TooManyEffects,
        }
    }
}

impl Display for PluginEffectCommitError {
    fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::ZeroLimit { .. } => formatter.write_str("plugin effect limit must be non-zero"),
            Self::TooManyEffects { identity, limit } => {
                let identity = identity.as_str();
                let limit = limit.get();
                write!(
                    formatter,
                    "plugin {identity:?} exceeded effect limit of {limit}"
                )
            }
        }
    }
}