jugar_core/
lib.rs

1//! # jugar-core
2//!
3//! Core ECS (Entity-Component-System), Game Loop, and State Management for Jugar.
4//!
5//! This crate provides the foundational data structures and systems for the Jugar
6//! game engine. It follows Toyota Way principles:
7//!
8//! - **Poka-Yoke**: Type-safe entity/component relationships prevent invalid states
9//! - **Heijunka**: Fixed timestep game loop ensures physics consistency
10//! - **Mieruka**: Debug-friendly types with comprehensive Display/Debug impls
11//!
12//! ## Probar Integration
13//!
14//! When the `probar` feature is enabled, this crate exposes introspection hooks
15//! for the Probar test runner. This allows debugging and testing of ECS state
16//! without modifying game behavior.
17
18#![forbid(unsafe_code)]
19#![warn(missing_docs)]
20#![warn(clippy::pedantic)]
21#![allow(clippy::module_name_repetitions)]
22
23use thiserror::Error;
24
25pub mod components;
26pub mod ecs;
27pub mod game_loop;
28
29/// Probar introspection hooks (only compiled with `probar` feature)
30#[cfg(feature = "jugar-probar")]
31pub mod introspection;
32
33pub use components::*;
34pub use ecs::*;
35pub use game_loop::*;
36
37#[cfg(feature = "jugar-probar")]
38pub use introspection::*;
39
40/// Errors that can occur in jugar-core
41#[derive(Error, Debug, Clone, PartialEq, Eq)]
42pub enum CoreError {
43    /// Entity not found in the world
44    #[error("Entity {0:?} not found")]
45    EntityNotFound(Entity),
46
47    /// Component not found on entity
48    #[error("Component not found on entity {0:?}")]
49    ComponentNotFound(Entity),
50
51    /// Invalid game state transition
52    #[error("Invalid state transition from {from} to {to}")]
53    InvalidStateTransition {
54        /// Current state
55        from: String,
56        /// Attempted target state
57        to: String,
58    },
59}
60
61/// Result type for jugar-core operations
62pub type Result<T> = core::result::Result<T, CoreError>;
63
64#[cfg(test)]
65#[allow(clippy::unwrap_used, clippy::expect_used)]
66mod tests {
67    use super::*;
68
69    #[test]
70    fn test_error_display() {
71        let err = CoreError::EntityNotFound(Entity(42));
72        assert!(err.to_string().contains("42"));
73    }
74}