Skip to main content

gmt_dos_actors/
aggregation.rs

1//! # Actors aggregations
2//!
3//! Algebraic rules to add [Model] and [Actor] to create a new model
4
5use std::ops::{Add, AddAssign};
6
7use interface::TryUpdate;
8
9use crate::{
10    actor::Actor,
11    framework::model::TaskError,
12    model,
13    model::{Model, Unknown},
14};
15
16/// Aggregation of models into a new model
17impl Add for Model<Unknown> {
18    type Output = Model<Unknown>;
19
20    fn add(self, rhs: Self) -> Self::Output {
21        match (self.actors, rhs.actors) {
22            (None, None) => Model::new(vec![]),
23            (None, Some(b)) => Model::new(b),
24            (Some(a), None) => Model::new(a),
25            (Some(mut a), Some(mut b)) => {
26                a.append(&mut b);
27                Model::new(a)
28            }
29        }
30    }
31}
32
33/// Aggregation of a model and an actor into a new model
34impl<C, const NI: usize, const NO: usize> Add<Actor<C, NI, NO>> for Model<Unknown>
35where
36    C: TryUpdate + 'static,
37    TaskError: From<<C as TryUpdate>::Error>,
38{
39    type Output = Model<Unknown>;
40
41    fn add(self, rhs: Actor<C, NI, NO>) -> Self::Output {
42        self + model!(rhs)
43    }
44}
45
46/// Aggregation of an actor and a model into a new model
47impl<C, const NI: usize, const NO: usize> Add<Model<Unknown>> for Actor<C, NI, NO>
48where
49    C: TryUpdate + 'static,
50    TaskError: From<<C as TryUpdate>::Error>,
51{
52    type Output = Model<Unknown>;
53
54    fn add(self, rhs: Model<Unknown>) -> Self::Output {
55        model!(self) + rhs
56    }
57}
58
59/// Aggregation of actors into a model
60impl<A, const A_NI: usize, const A_NO: usize, B, const B_NI: usize, const B_NO: usize>
61    Add<Actor<B, B_NI, B_NO>> for Actor<A, A_NI, A_NO>
62where
63    A: TryUpdate + 'static,
64    B: TryUpdate + 'static,
65    TaskError: From<<A as TryUpdate>::Error>,
66    TaskError: From<<B as TryUpdate>::Error>,
67{
68    type Output = Model<Unknown>;
69
70    fn add(self, rhs: Actor<B, B_NI, B_NO>) -> Self::Output {
71        model!(self) + model!(rhs)
72    }
73}
74/* /// Aggregation of subsystems into a model
75impl<Right, Left> Add<SubSystem<Right>> for SubSystem<Left>
76where
77    Right: Gateways + BuildSystem<Right> + GetField + 'static,
78    Model<model::Unknown>: From<Right>,
79    Left: Gateways + BuildSystem<Left> + GetField + 'static,
80    Model<model::Unknown>: From<Left>,
81{
82    type Output = Model<Unknown>;
83
84    fn add(self, rhs: SubSystem<Right>) -> Self::Output {
85        model!(self, rhs)
86    }
87} */
88
89impl<C, const NI: usize, const NO: usize> AddAssign<Actor<C, NI, NO>> for Model<Unknown>
90where
91    C: TryUpdate + 'static,
92    TaskError: From<<C as TryUpdate>::Error>,
93{
94    fn add_assign(&mut self, rhs: Actor<C, NI, NO>) {
95        self.actors.get_or_insert(vec![]).push(Box::new(rhs));
96    }
97}