rustsim-core 0.0.1

Core ABM engine: agents, models, stores, schedulers, stepping, data collection
Documentation
//! Abstract model trait - the interface shared by all model types.
//!
//! Both [`StandardModel`] and [`EventQueueModel`] implement this trait,
//! which provides uniform access to time, RNG, space, properties, and agents.
//!
//! [`StandardModel`]: crate::standard::StandardModel
//! [`EventQueueModel`]: crate::event_queue::EventQueueModel

use rand::RngCore;
use std::ops::{Deref, DerefMut};

use crate::{
    agent::Agent,
    space::Space,
    types::{AgentId, Time},
};

/// The abstract model interface.
///
/// Provides read access to the simulation state (time, space, properties, agents)
/// and mutable access to the RNG. Concrete model types add stepping methods.
///
/// # Generic Associated Types
///
/// `AgentRef` and `AgentRefMut` are GATs that allow models using interior
/// mutability (e.g. `RefCell`) to return borrowed references without
/// requiring `&mut self` for agent access.
pub trait Model {
    /// The agent type stored in this model.
    type Agent: Agent;
    /// The space type used by this model.
    type Space: Space;
    /// User-defined model properties (can be `()` if unused).
    type Properties;
    /// The random number generator type.
    type Rng: RngCore;

    /// Borrowed reference to an agent (may be `Ref<'a, A>` for `RefCell`-based stores).
    type AgentRef<'a>: Deref<Target = Self::Agent>
    where
        Self: 'a;
    /// Mutably borrowed reference to an agent (may be `RefMut<'a, A>`).
    type AgentRefMut<'a>: DerefMut<Target = Self::Agent>
    where
        Self: 'a;

    /// Current simulation time.
    fn time(&self) -> Time;

    /// Mutable access to the model's RNG.
    ///
    /// Takes `&self` (not `&mut self`) because the RNG is stored behind interior
    /// mutability, allowing agent step functions to use it without borrowing
    /// the entire model exclusively.
    fn rng_mut(&self) -> impl DerefMut<Target = Self::Rng> + '_;

    /// Immutable reference to the simulation space.
    fn space(&self) -> &Self::Space;

    /// Immutable reference to user-defined properties.
    fn properties(&self) -> &Self::Properties;

    /// Mutable reference to user-defined properties.
    fn properties_mut(&mut self) -> &mut Self::Properties;

    /// Look up an agent by ID, returning a borrowed reference.
    fn agent(&self, id: AgentId) -> Option<Self::AgentRef<'_>>;

    /// Look up an agent by ID, returning a mutably borrowed reference.
    fn agent_mut(&self, id: AgentId) -> Option<Self::AgentRefMut<'_>>;

    /// Check whether an agent with the given ID exists.
    fn has_id(&self, id: AgentId) -> bool {
        self.agent(id).is_some()
    }
}