1use std::any::type_name;
17use std::convert::Infallible;
18use std::marker::PhantomData;
19use std::{
20 fmt::Display,
21 ops::{Deref, DerefMut},
22};
23
24use crate::actor::Actor;
25use crate::framework::model::{Check, Task};
26use crate::framework::network::{ActorOutputsError, OutputRx};
27use crate::prelude::FlowChart;
28
29mod implementations;
30mod interfaces;
31
32pub use interfaces::{System, SystemInput, SystemOutput};
33
34pub enum New {}
35pub enum Built {}
36
37#[derive(Debug, thiserror::Error)]
38pub enum SystemError {
39 #[error("failed to build system")]
40 Ouputs(#[from] ActorOutputsError),
41 #[error("{0}")]
42 SubSystem(String),
43 #[error("not an error")]
44 NoError(#[from] Infallible),
45}
46impl<U, CO, const NO: usize, const NI: usize> From<OutputRx<U, CO, NI, NO>> for SystemError
47where
48 U: 'static + interface::UniqueIdentifier,
49 CO: interface::TryWrite<U>,
50{
51 fn from(value: OutputRx<U, CO, NI, NO>) -> Self {
52 SystemError::Ouputs(ActorOutputsError {
53 actor: value.actor,
54 output: value.output,
55 })
56 }
57}
58
59#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
61pub struct Sys<T: System, S = Built> {
62 pub sys: T,
63 verbose: bool,
64 state: PhantomData<S>,
65}
66
67impl<T: System, S> Sys<T, S> {
68 pub fn quiet(mut self) -> Self {
69 self.verbose = false;
70 self
71 }
72 pub fn verbose(mut self) -> Self {
73 self.verbose = true;
74 self
75 }
76}
77impl<T: System, S> Clone for Sys<T, S> {
78 fn clone(&self) -> Self {
79 let mut sys = self.sys.clone();
80 sys.build().unwrap();
81 Self {
82 sys,
83 verbose: self.verbose,
84 state: PhantomData,
85 }
86 }
87}
88
89impl<T: System> Deref for Sys<T> {
90 type Target = T;
91
92 fn deref(&self) -> &Self::Target {
93 &self.sys
94 }
95}
96
97impl<T: System> DerefMut for Sys<T> {
98 fn deref_mut(&mut self) -> &mut Self::Target {
99 &mut self.sys
100 }
101}
102impl<T: System> Sys<T, New> {
103 pub fn new(sys: T) -> Self {
104 Self {
105 sys,
106 verbose: false,
107 state: PhantomData,
108 }
109 }
110
111 pub fn build(self) -> Result<Sys<T>, SystemError> {
112 log::info!("building Sys<{}>", type_name::<T>());
113 let mut this: Sys<T> = Sys {
114 sys: self.sys,
115 verbose: self.verbose,
116 state: PhantomData,
117 };
118 <T as System>::build(&mut this.sys)?;
119 Ok(this)
120 }
121}
122impl<T: System + FlowChart> Sys<T> {
123 pub fn sys_graph(&self) -> Option<crate::graph::Graph> {
131 self.sys.graph()
132 }
133}
134
135impl<T: System> Display for Sys<T> {
136 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
137 write!(f, "{}", self.sys)
138 }
139}
140
141impl<'a, T: System> IntoIterator for &'a Sys<T>
142where
143 &'a T: IntoIterator<
144 Item = Box<&'a dyn Check>,
145 IntoIter = std::vec::IntoIter<<&'a T as IntoIterator>::Item>,
146 >,
147{
148 type Item = Box<&'a dyn Check>;
149
150 type IntoIter = std::vec::IntoIter<Self::Item>;
151
152 fn into_iter(self) -> Self::IntoIter {
153 self.sys.into_iter()
154 }
155}
156
157impl<T: System> IntoIterator for Box<Sys<T>>
158where
159 Box<T>: IntoIterator<
160 Item = Box<dyn Task>,
161 IntoIter = std::vec::IntoIter<<Box<T> as IntoIterator>::Item>,
162 >,
163{
164 type Item = Box<dyn Task>;
165
166 type IntoIter = std::vec::IntoIter<Self::Item>;
167
168 fn into_iter(self) -> Self::IntoIter {
169 let q = *self;
170 let w = q.sys;
171 let b = Box::new(w);
172 b.into_iter()
173 }
174}
175
176impl<
177 T: System + SystemInput<C, NI, NO>,
178 C: interface::TryUpdate,
179 const NI: usize,
180 const NO: usize,
181 > SystemInput<C, NI, NO> for Sys<T>
182{
183 fn input(&mut self) -> &mut Actor<C, NI, NO> {
184 self.sys.input()
185 }
186}
187
188impl<
189 T: System + SystemOutput<C, NI, NO>,
190 C: interface::TryUpdate,
191 const NI: usize,
192 const NO: usize,
193 > SystemOutput<C, NI, NO> for Sys<T>
194{
195 fn output(&mut self) -> &mut Actor<C, NI, NO> {
196 self.sys.output()
197 }
198}
199
200#[cfg(feature = "filing")]
201impl<T> interface::filing::Codec for Sys<T> where
202 T: Sized + System + serde::ser::Serialize + for<'de> serde::de::Deserialize<'de>
203{
204}