mabi_scenario/lib.rs
1//! # mabi-scenario
2//!
3//! Scenario engine for the OTSIM protocol simulator.
4//!
5//! This crate provides:
6//! - Scenario definition and parsing (YAML/JSON)
7//! - Pattern generators (Sine, Ramp, Step, Random, Follow, Replay)
8//! - Scenario player with time scaling
9//! - Event triggers and conditions
10//! - Comprehensive schema validation
11//! - Industrial scenario templates
12//!
13//! ## Architecture
14//!
15//! ```text
16//! ┌─────────────────────────────────────────────────────────────┐
17//! │ Scenario Engine │
18//! │ (Parser, Validator, Player, Event Manager) │
19//! └─────────────────────────────────────────────────────────────┘
20//! │
21//! ┌──────────────────┼──────────────────┐
22//! ▼ ▼ ▼
23//! ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
24//! │ Patterns │ │ Events │ │ Templates │
25//! │ (Generator) │ │ (Triggers/Acts) │ │ (Industrial) │
26//! └─────────────────┘ └─────────────────┘ └─────────────────┘
27//! │ │
28//! ▼ ▼
29//! ┌─────────────────┐ ┌─────────────────┐
30//! │ Follow/Replay │ │ Validation │
31//! │ (Advanced) │ │ (Schema Check) │
32//! └─────────────────┘ └─────────────────┘
33//! ```
34//!
35//! ## Quick Start
36//!
37//! ```rust,ignore
38//! use mabi_scenario::prelude::*;
39//!
40//! // Load scenario from file
41//! let scenario = ScenarioParser::parse_file("scenario.yaml")?;
42//!
43//! // Validate
44//! let validator = ScenarioValidator::new();
45//! let result = validator.validate(&scenario);
46//! if !result.is_valid() {
47//! for error in result.errors() {
48//! eprintln!("{}: {}", error.path, error.message);
49//! }
50//! }
51//!
52//! // Create player and run
53//! let mut player = ScenarioPlayer::new(scenario, PlayerConfig::default());
54//! let mut rx = player.subscribe();
55//!
56//! tokio::spawn(async move {
57//! player.run().await;
58//! });
59//!
60//! // Process updates
61//! while let Ok(update) = rx.recv().await {
62//! println!("{}: {}", update.point_id, update.value);
63//! }
64//! ```
65
66pub mod event;
67pub mod executor;
68pub mod follow;
69pub mod generator;
70pub mod parser;
71pub mod player;
72pub mod replay;
73pub mod schema;
74pub mod templates;
75pub mod bacnet_templates;
76pub mod validation;
77
78pub use generator::{PatternGenerator, PatternType};
79pub use parser::ScenarioParser;
80pub use player::{PlayerConfig, ScenarioPlayer};
81pub use schema::{Scenario, ScenarioEvent, ScenarioPoint};
82
83// Prelude for common imports
84pub mod prelude {
85 pub use crate::event::{
86 ActionCommand, ActionResult, ComparisonOperator, EventBuilder, EventContext,
87 EventInstance, EventManager, LogLevel,
88 };
89 pub use crate::executor::{
90 DeviceRegistry, ExecutorBuilder, ExecutorConfig, ExecutorMetrics, ExecutorState,
91 ScenarioExecutor,
92 };
93 pub use crate::follow::{
94 DelayBuffer, FollowConfig, FollowManager, FollowState, SourceRegistry, TimestampedValue,
95 };
96 pub use crate::generator::{PatternGenerator, PatternType};
97 pub use crate::parser::ScenarioParser;
98 pub use crate::player::{PlayerConfig, PlayerState, ScenarioPlayer, ValueUpdate};
99 pub use crate::replay::{
100 InterpolationMethod, ReplayConfig, ReplayDataPoint, ReplayLoader, ReplayManager,
101 ReplaySeries, ReplayState,
102 };
103 pub use crate::schema::{
104 EventAction, EventTrigger, PatternConfig, Scenario, ScenarioEvent, ScenarioPoint,
105 };
106 pub use crate::templates::{
107 Template, TemplateCategory, TemplateInfo, TemplateOptions, TemplateRegistry,
108 };
109 pub use crate::bacnet_templates::register_bacnet_templates;
110 pub use crate::validation::{
111 ScenarioValidator, ValidationCode, ValidationIssue, ValidationOptions, ValidationResult,
112 ValidationSeverity,
113 };
114 pub use crate::{ScenarioError, ScenarioResult};
115}
116
117use thiserror::Error;
118use mabi_core::Error as CoreError;
119
120/// Scenario result type.
121pub type ScenarioResult<T> = Result<T, ScenarioError>;
122
123/// Scenario error types.
124#[derive(Debug, Error)]
125pub enum ScenarioError {
126 #[error("Parse error: {0}")]
127 Parse(String),
128
129 #[error("Invalid pattern: {0}")]
130 InvalidPattern(String),
131
132 #[error("Scenario not found: {0}")]
133 NotFound(String),
134
135 #[error("Player error: {0}")]
136 Player(String),
137
138 #[error("I/O error: {0}")]
139 Io(#[from] std::io::Error),
140
141 #[error("YAML error: {0}")]
142 Yaml(#[from] serde_yaml::Error),
143
144 #[error("JSON error: {0}")]
145 Json(#[from] serde_json::Error),
146
147 #[error("Core error: {0}")]
148 Core(#[from] CoreError),
149}