forester_rs/simulator/
builder.rs1
2use crate::get_pb;
3use crate::runtime::action::keeper::ActionImpl;
4use crate::runtime::builder::ForesterBuilder;
5use crate::runtime::{RtResult, RuntimeError};
6use crate::simulator::actions::SimAction;
7use crate::simulator::config::{SimProfile, TracerSimConfig};
8use crate::simulator::RtAction;
9use crate::simulator::Simulator;
10use crate::tracer::{Tracer, TracerConfig};
11use std::path::PathBuf;
12
13#[derive(Default)]
73pub struct SimulatorBuilder {
74 profile: Option<PathBuf>,
75 root: Option<PathBuf>,
76 fb: Option<ForesterBuilder>,
77}
78
79impl SimulatorBuilder {
80 pub fn new() -> Self {
81 SimulatorBuilder {
82 profile: None,
83 fb: None,
84 root: None,
85 }
86 }
87 pub fn profile(&mut self, profile: PathBuf) {
89 self.profile = Some(profile);
90 }
91
92 pub fn forester_builder(&mut self, fb: ForesterBuilder) {
95 self.fb = Some(fb);
96 }
97 pub fn root(&mut self, root: PathBuf) {
99 self.root = Some(root);
100 }
101 #[allow(irrefutable_let_patterns)]
102 pub fn build(&mut self) -> RtResult<Simulator> {
104 let mut fb = self.fb.take().ok_or(RuntimeError::uex(
105 "the forester builder is absent".to_string(),
106 ))?;
107
108 let profile = if let Some(p) = &self.profile {
109 SimProfile::parse_file(&get_pb(p, &self.root.clone())?)?
110 } else {
111 SimProfile::default()
112 };
113
114 let pr = profile.clone();
115
116 if let TracerSimConfig { file, dt_fmt } = profile.config.tracer {
117 let cfg = match file {
118 None => TracerConfig::in_memory(dt_fmt),
119 Some(f) => {
120 TracerConfig::in_file(get_pb(&PathBuf::from(f), &self.root.clone())?, dt_fmt)
121 }
122 };
123
124 fb.tracer(Tracer::create(cfg)?)
125 }
126
127 if let Some(bb_load_path) = profile.config.bb.load {
128 fb.bb_load(bb_load_path);
129 }
130
131 if let Some(http) = profile.config.http {
132 fb.http_serv(http.port);
133 }
134
135 for action in profile.actions.iter() {
136 let sim_action = SimAction::create(action.stub.as_str(), action.params.clone())?;
137 let name = action.name.as_str();
138
139 if sim_action.is_remote() {
140 fb.register_remote_action(name, sim_action);
141 } else {
142 fb.register_sync_action(name, sim_action);
143 }
144 }
145
146 let forester =
147 fb.build_with(|| ActionImpl::Present(RtAction::sync(SimAction::Success(0))))?;
148 Ok(Simulator::new(self.root.take(), pr, forester))
149 }
150}