alma 0.1.1

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

use super::PluginEffectCommitError;
use std::{
    fmt::{Debug, Display, Formatter},
    num::NonZeroUsize,
};

/// Default effect cap for one guest update.
pub const DEFAULT_PLUGIN_EFFECT_LIMIT: usize = 256;

/// Effect batch limit fields with stable diagnostic spellings.
#[derive(Clone, Copy, Eq, PartialEq)]
pub enum PluginEffectBatchLimitField {
    /// Maximum effects accepted from one guest update.
    MaxEffects,
}

impl PluginEffectBatchLimitField {
    /// Stable field name used in diagnostics.
    #[must_use]
    pub const fn as_str(self) -> &'static str {
        match self {
            Self::MaxEffects => "max_effects",
        }
    }
}

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

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

/// Effect cap for one plugin update.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct PluginEffectBatchLimit {
    /// Maximum accepted effects.
    max_effects: NonZeroUsize,
}

impl PluginEffectBatchLimit {
    /// Creates an effect limit.
    ///
    /// # Errors
    ///
    /// Returns [`PluginEffectCommitError::ZeroLimit`] when `max_effects` is zero.
    pub const fn try_new(max_effects: usize) -> Result<Self, PluginEffectCommitError> {
        match NonZeroUsize::new(max_effects) {
            Some(max_effects) => Ok(Self { max_effects }),
            None => Err(PluginEffectCommitError::ZeroLimit {
                field: PluginEffectBatchLimitField::MaxEffects,
            }),
        }
    }

    /// Returns the effect cap.
    #[must_use]
    pub const fn max_effects(self) -> usize {
        self.max_effects.get()
    }

    /// Returns the effect cap as a non-zero proof for diagnostics.
    #[must_use]
    pub(in crate::plugin::host::effect) const fn max_effects_limit(self) -> NonZeroUsize {
        self.max_effects
    }
}

impl Default for PluginEffectBatchLimit {
    fn default() -> Self {
        Self::try_new(DEFAULT_PLUGIN_EFFECT_LIMIT).expect("default effect limit should be non-zero")
    }
}