fips_md/parser/
simulation.rs

1//! Structures related to simulation blocks
2
3use super::{CompileTimeConstant, Statement};
4
5/// Structure representing a simulation
6#[derive(Debug,PartialEq)]
7pub struct Simulation {
8    pub name: String,
9    pub default_particle: Option<String>,
10    pub blocks: Vec<SimulationBlock>
11}
12
13/// All possible blocks inside a simulation
14#[derive(Debug,PartialEq)]
15pub enum SimulationBlock {
16    Once(OnceBlock),
17    Step(StepBlock)
18}
19
20/// Block representing a one-time only action
21#[derive(Debug,PartialEq)]
22pub struct OnceBlock {
23    pub step: CompileTimeConstant<usize>,
24    pub subblocks: Vec<SimulationSubBlock>
25}
26
27/// Block representing an action that is to be repeated according to a step range
28#[derive(Debug,PartialEq)]
29pub struct StepBlock {
30    pub step_range: StepRange,
31    pub subblocks: Vec<SimulationSubBlock>
32}
33
34/// Range of steps with start <= i < end 
35#[derive(Debug,PartialEq)]
36pub struct StepRange {
37    pub start: CompileTimeConstant<usize>,
38    pub end: CompileTimeConstant<usize>,
39    pub step: CompileTimeConstant<usize>
40}
41
42impl Default for StepRange {
43    fn default() -> Self {
44        Self {
45            start: CompileTimeConstant::Literal(0),
46            end: CompileTimeConstant::Literal(usize::MAX),
47            step: CompileTimeConstant::Literal(1)
48        }
49    }
50}
51
52/// Subblocks in a simulation that contain the actual statements
53#[derive(Debug,PartialEq)]
54pub struct SimulationSubBlock {
55    pub particle: Option<String>,
56    pub statements: Vec<Statement>
57}
58
59mod tests {
60    #[allow(unused_imports)] // Rust analyzer bug
61    use super::super::*;
62
63    #[test]
64    fn step_range() {
65        assert!(fips_parser::step_range("1..2..3").is_err(),
66            "1..2..3 not caught as invalid");
67        let test_cases = std::collections::HashMap::from([
68            ("..",    (0,usize::MAX,1)),
69            ("1..",   (1,usize::MAX,1)),
70            ("..2",   (0,2,1)),
71            ("1..2",  (1,2,1)),
72            ("..,3",  (0,usize::MAX,3)),
73            ("1..,3", (1,usize::MAX,3)),
74            ("..2,3", (0,2,3)),
75            ("1..2,3",(1,2,3)),
76        ]);
77        for (s,(start,end,step)) in test_cases {
78            assert_eq!(fips_parser::step_range(s).expect(&format!("Cannot parse {} as step range", s)),
79            StepRange {
80                start: start.into(),
81                end: end.into(),
82                step: step.into(),
83            });
84        }
85    }
86}