cosmic_space/
particle.rs

1use core::str::FromStr;
2use std::collections::HashMap;
3
4use nom::bytes::complete::tag;
5use nom::combinator::all_consuming;
6use serde::{Deserialize, Serialize};
7
8use cosmic_nom::{new_span, Res, Span};
9
10use crate::kind::{Kind, KindParts};
11use crate::parse::error::result;
12use crate::parse::{Env, parse_alpha1_str, point_and_kind};
13use crate::substance::Substance;
14use crate::util::ToResolved;
15use crate::{BaseKind, SpaceErr};
16use crate::point::{Point, PointCtx, PointVar};
17
18pub mod property;
19pub mod traversal;
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct StatusUpdate {
23    pub from: Point,
24    pub status: Status,
25}
26
27#[derive(
28    Debug,
29    Clone,
30    Serialize,
31    Deserialize,
32    Eq,
33    PartialEq,
34    strum_macros::Display,
35    strum_macros::EnumString,
36)]
37pub enum Status {
38    Unknown,  // initial status or when we status cannot be determined
39    Pending,  // initial status
40    Init, // undergoing custom initialization...This particle can send requests but not receive requests.
41    Panic, // something is wrong... all requests are blocked and responses are cancelled.
42    Fatal, // unrecoverable panic
43    Ready, // ready to take requests
44    Paused, // can not receive requests (probably because it is waiting for some other particle to make updates)...
45    Resuming, // like Initializing but triggered after a pause is lifted, the particle may be doing something before it is ready to accept requests again.
46    Done, // this particle had a life span and has now completed succesfully it can no longer receive requests.
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
50pub enum Code {
51    Ok,
52    Error(i32),
53}
54
55impl ToString for Code {
56    fn to_string(&self) -> String {
57        match self {
58            Code::Ok => "Ok".to_string(),
59            Code::Error(code) => {
60                format!("Err({})", code)
61            }
62        }
63    }
64}
65
66#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
67pub struct Progress {
68    pub step: u16,
69    pub total: u16,
70}
71
72impl ToString for Progress {
73    fn to_string(&self) -> String {
74        format!("{}/{}", self.step, self.total)
75    }
76}
77
78pub fn ok_code<I: Span>(input: I) -> Res<I, Code> {
79    tag("Ok")(input).map(|(next, code)| (next, Code::Ok))
80}
81
82pub fn status<I: Span>(input: I) -> Res<I, Status> {
83    parse_alpha1_str(input)
84}
85
86pub type Properties = HashMap<String, Property>;
87
88#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
89pub struct Property {
90    pub key: String,
91    pub value: String,
92    pub locked: bool,
93}
94
95#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
96pub struct Archetype {
97    pub kind: KindParts,
98    pub properties: Properties,
99}
100
101#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
102pub struct Details {
103    pub stub: Stub,
104    pub properties: Properties,
105}
106
107impl Default for Details {
108    fn default() -> Self {
109        Self {
110            stub: Default::default(),
111            properties: Default::default(),
112        }
113    }
114}
115
116impl Details {
117    pub fn new(stub: Stub, properties: Properties) -> Self {
118        Self { stub, properties }
119    }
120}
121
122#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
123pub struct Stub {
124    pub point: Point,
125    pub kind: Kind,
126    pub status: Status,
127}
128
129impl Default for Stub {
130    fn default() -> Self {
131        Self {
132            point: Point::root(),
133            kind: Kind::Root,
134            status: Status::Unknown,
135        }
136    }
137}
138
139impl Stub {
140    pub fn point_and_kind(self) -> PointKind {
141        PointKind {
142            point: self.point,
143            kind: self.kind,
144        }
145    }
146}
147
148#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
149pub struct Particle {
150    pub stub: Stub,
151    pub state: Box<Substance>,
152}
153
154#[derive(Debug, Clone, Serialize, Deserialize)]
155pub struct Particle2 {
156    pub stub: Stub,
157    pub state: Substance,
158}
159
160impl Particle2 {
161    pub fn new(stub: Stub, state: Substance) -> Particle2 {
162        Particle2 { stub, state }
163    }
164
165    pub fn point(&self) -> Point {
166        self.stub.point.clone()
167    }
168
169    pub fn state_src(&self) -> Substance {
170        self.state.clone()
171    }
172}
173
174pub mod particle {
175    use std::collections::{HashMap, HashSet};
176    use std::str::FromStr;
177
178    use nom::branch::alt;
179    use nom::bytes::complete::{is_a, tag};
180    use nom::character::complete::{alpha1, digit1};
181    use nom::combinator::{not, recognize};
182    use nom::error::{ErrorKind, ParseError, VerboseError};
183    use nom::sequence::{delimited, tuple};
184    use nom::CompareResult::Incomplete;
185    use nom::Parser;
186    use nom_supreme::error::ErrorTree;
187    use nom_supreme::{parse_from_str, ParserExt};
188    use serde::{Deserialize, Serialize};
189
190    use cosmic_nom::{Res, Span};
191
192    use crate::err::SpaceErr;
193    use crate::kind::{BaseKind, Kind, KindParts};
194    use crate::point::Point;
195    use crate::parse::parse_alpha1_str;
196    use crate::particle::PointKind;
197    use crate::security::Permissions;
198    use crate::substance::{Substance, SubstanceMap};
199
200    /*
201    #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
202    pub struct StatusDetails<C>
203    where
204        C: Condition,
205    {
206        pub status: Status,
207        pub conditions: HashSet<C>,
208    }
209
210    pub trait Condition: ToString {
211        fn status(&self) -> Status;
212        fn desc(&self) -> String;
213    }
214     */
215
216    /*
217    pub fn error_code<I:Span>(input: I) -> Res<I, Code> {
218        let (next, err_code) = delimited(tag("Err("), digit1, tag(")"))(input.clone())?;
219        Ok((
220            next,
221            Code::Error(match err_code.parse() {
222                Ok(i) => i,
223                Err(err) => {
224                    return Err(nom::Err::Error(ErrorTree::from_error_kind(
225                        input,
226                        ErrorKind::Tag,
227                    )))
228                }
229            }),
230        ))
231    }
232
233
234    pub fn code<I:Span>(input: I) -> Res<I, Code> {
235        alt((error_code, ok_code))(input)
236    }
237     */
238}
239
240#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
241pub struct Watch {
242    pub point: Point,
243    pub aspect: Aspect,
244}
245
246#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, strum_macros::Display)]
247pub enum Aspect {
248    Log,
249    State,
250    Property,
251    Child,
252}
253
254pub type PointKind = PointKindDef<Point>;
255pub type PointKindCtx = PointKindDef<PointCtx>;
256pub type PointKindVar = PointKindDef<PointVar>;
257
258#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
259pub struct PointKindDef<Pnt> {
260    pub point: Pnt,
261    pub kind: Kind,
262}
263
264impl ToResolved<PointKindCtx> for PointKindVar {
265    fn to_resolved(self, env: &Env) -> Result<PointKindCtx, SpaceErr> {
266        Ok(PointKindCtx {
267            point: self.point.to_resolved(env)?,
268            kind: self.kind,
269        })
270    }
271}
272
273impl ToResolved<PointKind> for PointKindVar {
274    fn to_resolved(self, env: &Env) -> Result<PointKind, SpaceErr> {
275        Ok(PointKind {
276            point: self.point.to_resolved(env)?,
277            kind: self.kind,
278        })
279    }
280}
281
282impl ToResolved<PointKind> for PointKindCtx {
283    fn to_resolved(self, env: &Env) -> Result<PointKind, SpaceErr> {
284        Ok(PointKind {
285            point: self.point.to_resolved(env)?,
286            kind: self.kind,
287        })
288    }
289}
290
291impl PointKind {
292    pub fn new(point: Point, kind: Kind) -> Self {
293        Self { point, kind }
294    }
295}
296
297impl ToString for PointKind {
298    fn to_string(&self) -> String {
299        format!("{}<{}>", self.point.to_string(), self.kind.to_string())
300    }
301}
302
303impl FromStr for PointKind {
304    type Err = SpaceErr;
305
306    fn from_str(s: &str) -> Result<Self, Self::Err> {
307        let point_and_kind: PointKindVar = result(all_consuming(point_and_kind)(new_span(s)))?;
308        let point_and_kind = point_and_kind.collapse()?;
309        Ok(point_and_kind)
310    }
311}
312
313#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
314pub struct AddressAndType {
315    pub point: Point,
316    pub resource_type: BaseKind,
317}