rustsim-spaces 0.0.1

Space implementations (grid, continuous, graph, hybrid) for rustsim
Documentation
use rustsim_core::interaction::{PositionedAgent, SpaceInteraction};
use rustsim_core::prelude::{Agent, AgentId};
use rustsim_spaces::continuous::{ContinuousSpace2D, ContinuousSpaceError};
use rustsim_spaces::graph::{GraphSpace, GraphSpaceError};
use rustsim_spaces::grid::{Grid2D, Grid2DSingle, GridError};

// --- Helper agent types ---

#[derive(Debug, Clone)]
struct GridAgent {
    id: AgentId,
    pos: (usize, usize),
}

impl Agent for GridAgent {
    fn id(&self) -> AgentId {
        self.id
    }
}

impl PositionedAgent for GridAgent {
    type Position = (usize, usize);
    fn position(&self) -> &Self::Position {
        &self.pos
    }
    fn set_position(&mut self, p: Self::Position) {
        self.pos = p;
    }
}

#[derive(Debug, Clone)]
struct GraphAgent {
    id: AgentId,
    pos: usize,
}

impl Agent for GraphAgent {
    fn id(&self) -> AgentId {
        self.id
    }
}

impl PositionedAgent for GraphAgent {
    type Position = usize;
    fn position(&self) -> &Self::Position {
        &self.pos
    }
    fn set_position(&mut self, p: Self::Position) {
        self.pos = p;
    }
}

// --- Grid2D OOB ---

#[test]
fn grid2d_add_oob_returns_error() {
    let mut grid = Grid2D::new(3, 3, false);
    let err = grid.add_agent((10, 10), 1);
    assert_eq!(err, Err(GridError::OutOfBounds((10, 10))));
}

#[test]
fn grid2d_remove_oob_returns_error() {
    let mut grid = Grid2D::new(3, 3, false);
    let err = grid.remove_agent((10, 10), 1);
    assert_eq!(err, Err(GridError::OutOfBounds((10, 10))));
}

#[test]
fn grid2d_remove_nonexistent_agent_returns_false() {
    let mut grid = Grid2D::new(3, 3, false);
    grid.add_agent((1, 1), 1).unwrap();
    let removed = grid.remove_agent((1, 1), 999).unwrap();
    assert!(!removed);
}

// --- Grid2DSingle OOB + Occupied ---

#[test]
fn grid2d_single_add_oob_returns_error() {
    let mut grid = Grid2DSingle::new(3, 3, false);
    let err = grid.add_agent((10, 10), 1);
    assert_eq!(err, Err(GridError::OutOfBounds((10, 10))));
}

#[test]
fn grid2d_single_add_occupied_returns_error() {
    let mut grid = Grid2DSingle::new(3, 3, false);
    grid.add_agent((1, 1), 1).unwrap();
    let err = grid.add_agent((1, 1), 2);
    assert_eq!(err, Err(GridError::Occupied((1, 1))));
}

// --- Grid2D via SpaceInteraction ---

#[test]
fn grid2d_space_interaction_add_oob() {
    let mut grid = Grid2D::new(3, 3, false);
    let agent = GridAgent {
        id: 1,
        pos: (99, 99),
    };
    let err = SpaceInteraction::<GridAgent>::add_agent(&mut grid, &agent);
    assert!(err.is_err());
}

// --- ContinuousSpace2D OOB ---

#[test]
fn continuous_space_oob_non_periodic() {
    use rustsim_spaces::continuous::ContinuousPos;

    let mut space = ContinuousSpace2D::new(10.0, 10.0, false, 2.0).unwrap();
    let err = space.move_agent_pos(1, ContinuousPos::new(-1.0, 5.0));
    assert_eq!(err, Err(ContinuousSpaceError::OutOfBounds));
}

// --- GraphSpace invalid node ---

#[test]
fn graph_space_add_agent_invalid_node() {
    let mut graph = GraphSpace::new(3);
    let agent = GraphAgent { id: 1, pos: 99 };
    let err = SpaceInteraction::<GraphAgent>::add_agent(&mut graph, &agent);
    assert_eq!(err, Err(GraphSpaceError::InvalidNode(99)));
}

#[test]
fn graph_space_remove_agent_invalid_node() {
    let mut graph = GraphSpace::new(3);
    let agent = GraphAgent { id: 1, pos: 99 };
    let err = SpaceInteraction::<GraphAgent>::remove_agent(&mut graph, &agent);
    assert_eq!(err, Err(GraphSpaceError::InvalidNode(99)));
}