1use core::str::FromStr;
2
3use nom::combinator::all_consuming;
4use serde::{Deserialize, Serialize};
5
6use cosmic_macros_primitive::Autobox;
7use cosmic_nom::{new_span, Trace};
8use direct::create::{Create, CreateCtx, CreateVar};
9use direct::delete::{DeleteCtx, DeleteVar};
10use direct::get::{Get, GetCtx, GetVar};
11use direct::read::{Read, ReadCtx, ReadVar};
12use direct::select::{SelectCtx, SelectVar};
13use direct::set::{Set, SetCtx, SetVar};
14use direct::write::{Write, WriteCtx, WriteVar};
15
16use crate::parse::error::result;
17use crate::parse::{command_line, Env};
18use crate::substance::{Bin, ChildSubstance};
19use crate::util::ToResolved;
20use crate::wave::core::cmd::CmdMethod;
21use crate::{Delete, Select, SpaceErr};
22
23pub mod common {
24 use std::collections::hash_map::Iter;
25 use std::collections::HashMap;
26 use std::convert::{TryFrom, TryInto};
27 use std::ops::{Deref, DerefMut};
28
29 use serde::{Deserialize, Serialize};
30
31 use crate::err::SpaceErr;
32 use crate::loc::Variable;
33 use crate::parse::model::Var;
34 use crate::substance::{Substance, SubstanceMap};
35
36 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, strum_macros::Display)]
37 pub enum StateSrcVar {
38 None,
39 FileRef(String),
40 Var(Variable),
41 }
42
43 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, strum_macros::Display)]
44 pub enum StateSrc {
45 None,
46 Substance(Box<Substance>),
47 }
48
49 impl StateSrc {
50 pub fn has_substance(&self) -> bool {
51 match self {
52 StateSrc::None => false,
53 StateSrc::Substance(_) => true,
54 }
55 }
56
57 pub fn get_substance(&self) -> Result<Substance, SpaceErr> {
58 match self {
59 StateSrc::None => Err(SpaceErr::server_error("state has no substance")),
60 StateSrc::Substance(substance) => Ok(*substance.clone()),
61 }
62 }
63 }
64
65 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
66 pub enum PropertyMod {
67 Set {
68 key: String,
69 value: String,
70 lock: bool,
71 },
72 UnSet(String),
73 }
74
75 impl PropertyMod {
76 pub fn set_or<E>(&self, err: E) -> Result<String, E> {
77 match self {
78 Self::Set { key, value, lock } => Ok(value.clone()),
79 Self::UnSet(_) => Err(err),
80 }
81 }
82
83 pub fn opt(&self) -> Option<String> {
84 match self {
85 Self::Set { key, value, lock } => Some(value.clone()),
86 Self::UnSet(_) => None,
87 }
88 }
89 }
90
91 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
92 pub struct SetProperties {
93 pub map: HashMap<String, PropertyMod>,
94 }
95
96 impl Default for SetProperties {
97 fn default() -> Self {
98 Self {
99 map: Default::default(),
100 }
101 }
102 }
103
104 impl SetProperties {
105 pub fn new() -> Self {
106 Self {
107 map: HashMap::new(),
108 }
109 }
110
111 pub fn append(&mut self, properties: SetProperties) {
112 for (_, property) in properties.map.into_iter() {
113 self.push(property);
114 }
115 }
116
117 pub fn push(&mut self, property: PropertyMod) {
118 match &property {
119 PropertyMod::Set { key, value, lock } => {
120 self.map.insert(key.clone(), property);
121 }
122 PropertyMod::UnSet(key) => {
123 self.map.insert(key.clone(), property);
124 }
125 }
126 }
127
128 pub fn iter(&self) -> Iter<'_, String, PropertyMod> {
129 self.map.iter()
130 }
131 }
132
133 impl Deref for SetProperties {
134 type Target = HashMap<String, PropertyMod>;
135
136 fn deref(&self) -> &Self::Target {
137 &self.map
138 }
139 }
140
141 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, strum_macros::Display)]
142 pub enum SetLabel {
143 Set(String),
144 SetValue { key: String, value: String },
145 Unset(String),
146 }
147
148 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
149 pub struct SetRegistry {
150 pub labels: Vec<SetLabel>,
151 }
152
153 impl Deref for SetRegistry {
154 type Target = Vec<SetLabel>;
155
156 fn deref(&self) -> &Self::Target {
157 &self.labels
158 }
159 }
160
161 impl DerefMut for SetRegistry {
162 fn deref_mut(&mut self) -> &mut Self::Target {
163 &mut self.labels
164 }
165 }
166
167 impl Default for SetRegistry {
168 fn default() -> Self {
169 Self {
170 labels: Default::default(),
171 }
172 }
173 }
174}
175
176pub mod direct {
177 use serde::{Deserialize, Serialize};
180
181 use crate::command::direct::create::Create;
182 use crate::command::direct::get::Get;
183 use crate::command::direct::select::Select;
184 use crate::command::direct::set::Set;
185 use crate::command::direct::write::Write;
186 use crate::err::SpaceErr;
187 use crate::fail;
188 use crate::fail::{BadRequest, Fail, NotFound};
189 use crate::kind::{BaseKind, KindParts};
190 use crate::loc::Meta;
191 use crate::point::Point;
192 use crate::selector::KindSelector;
193 use crate::substance::Bin;
194 use crate::substance::{FormErrs, Substance};
195 use crate::util::{ValueMatcher, ValuePattern};
196 use crate::wave::core::ext::ExtMethod;
197 use crate::wave::core::http2::HttpMethod;
198 use crate::wave::core::MethodKind;
199 use crate::wave::core::ReflectedCore;
200
201 #[derive(Debug, Clone, Serialize, Deserialize)]
202 pub enum Cmd {
203 Create(Create),
204 Select(Select),
205 Update(Write),
206 Get(Get),
207 Set(Set),
208 }
209
210 impl PartialEq<Self> for Cmd {
211 fn eq(&self, other: &Self) -> bool {
212 self.get_type() == other.get_type()
213 }
214 }
215
216 impl Eq for Cmd {}
217
218 impl Cmd {
219 pub fn get_type(&self) -> CmdKind {
220 match self {
221 Cmd::Create(_) => CmdKind::Create,
222 Cmd::Select(_) => CmdKind::Select,
223 Cmd::Update(_) => CmdKind::Update,
224 Cmd::Get(_) => CmdKind::Get,
225 Cmd::Set(_) => CmdKind::Set,
226 }
227 }
228 }
229
230 #[derive(
231 Debug,
232 Clone,
233 Eq,
234 PartialEq,
235 strum_macros::Display,
236 strum_macros::EnumString,
237 Serialize,
238 Deserialize,
239 )]
240 pub enum CmdKind {
241 Create,
242 Select,
243 Update,
244 Query,
245 Get,
246 Set,
247 }
248
249 impl ValueMatcher<Cmd> for Cmd {
250 fn is_match(&self, x: &Cmd) -> Result<(), ()> {
251 if self.get_type() == x.get_type() {
252 Ok(())
253 } else {
254 Err(())
255 }
256 }
257 }
258
259 impl ToString for Cmd {
260 fn to_string(&self) -> String {
261 format!("Rc<{}>", self.get_type().to_string())
262 }
263 }
264
265 pub mod set {
266 use serde::{Deserialize, Serialize};
267
268 use crate::command::common::SetProperties;
269 use crate::err::SpaceErr;
270 use crate::parse::Env;
271 use crate::point::{Point, PointCtx, PointVar};
272 use crate::util::ToResolved;
273
274 pub type Set = SetDef<Point>;
275 pub type SetCtx = SetDef<PointCtx>;
276 pub type SetVar = SetDef<PointVar>;
277
278 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
279 pub struct SetDef<Pnt> {
280 pub point: Pnt,
281 pub properties: SetProperties,
282 }
283
284 impl ToResolved<Set> for SetVar {
285 fn to_resolved(self, env: &Env) -> Result<Set, SpaceErr> {
286 let set: SetCtx = self.to_resolved(env)?;
287 set.to_resolved(env)
288 }
289 }
290
291 impl ToResolved<SetCtx> for SetVar {
292 fn to_resolved(self, env: &Env) -> Result<SetCtx, SpaceErr> {
293 Ok(SetCtx {
294 point: self.point.to_resolved(env)?,
295 properties: self.properties,
296 })
297 }
298 }
299
300 impl ToResolved<Set> for SetCtx {
301 fn to_resolved(self, env: &Env) -> Result<Set, SpaceErr> {
302 Ok(Set {
303 point: self.point.to_resolved(env)?,
304 properties: self.properties,
305 })
306 }
307 }
308 }
309
310 pub mod get {
311 use serde::{Deserialize, Serialize};
312
313 use crate::command::common::SetProperties;
314 use crate::err::SpaceErr;
315 use crate::parse::Env;
316 use crate::point::{Point, PointCtx, PointVar};
317 use crate::util::ToResolved;
318
319 pub type Get = GetDef<Point>;
320 pub type GetCtx = GetDef<PointCtx>;
321 pub type GetVar = GetDef<PointVar>;
322
323 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
324 pub struct GetDef<Pnt> {
325 pub point: Pnt,
326 pub op: GetOp,
327 }
328
329 impl ToResolved<Get> for GetVar {
330 fn to_resolved(self, env: &Env) -> Result<Get, SpaceErr> {
331 let set: GetCtx = self.to_resolved(env)?;
332 set.to_resolved(env)
333 }
334 }
335
336 impl ToResolved<GetCtx> for GetVar {
337 fn to_resolved(self, env: &Env) -> Result<GetCtx, SpaceErr> {
338 Ok(GetCtx {
339 point: self.point.to_resolved(env)?,
340 op: self.op,
341 })
342 }
343 }
344
345 impl ToResolved<Get> for GetCtx {
346 fn to_resolved(self, env: &Env) -> Result<Get, SpaceErr> {
347 Ok(Get {
348 point: self.point.to_resolved(env)?,
349 op: self.op,
350 })
351 }
352 }
353
354 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
355 pub enum GetOp {
356 State,
357 Properties(Vec<String>),
358 }
359 }
360
361 pub mod create {
362 use std::convert::TryInto;
363 use std::sync::atomic::{AtomicU64, Ordering};
364 use std::sync::Arc;
365
366 use serde::{Deserialize, Serialize};
367 use tokio::sync::Mutex;
368
369 use crate::command::common::{SetProperties, SetRegistry, StateSrc, StateSrcVar};
370 use crate::command::Command;
371 use crate::err::SpaceErr;
372 use crate::kind::{BaseKind, KindParts};
373 use crate::loc::{HostKey, PointFactory, ToSurface};
374 use crate::parse::model::Subst;
375 use crate::parse::{CamelCase, Env, ResolverErr};
376 use crate::point::{Point, PointCtx, PointSeg, PointVar};
377 use crate::selector::SpecificSelector;
378 use crate::substance::Bin;
379 use crate::substance::Substance;
380 use crate::util::{ConvertFrom, ToResolved};
381 use crate::wave::core::cmd::CmdMethod;
382 use crate::wave::core::ext::ExtMethod;
383 use crate::wave::core::hyp::HypMethod;
384 use crate::wave::core::DirectedCore;
385 use crate::wave::{DirectedProto, Ping, Wave};
386
387 pub enum PointTemplateSeg {
388 ExactSeg(PointSeg),
389 Wildcard(String),
390 }
391
392 impl PointTemplateSeg {
393 pub fn is_wildcard(&self) -> bool {
394 match self {
395 PointTemplateSeg::ExactSeg(_) => false,
396 PointTemplateSeg::Wildcard(_) => true,
397 }
398 }
399 }
400
401 pub type Template = TemplateDef<PointTemplate>;
402 pub type TemplateCtx = TemplateDef<PointTemplateCtx>;
403 pub type TemplateVar = TemplateDef<PointTemplateVar>;
404
405 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
406 pub struct TemplateDef<Pnt> {
407 pub point: Pnt,
408 pub kind: KindTemplate,
409 }
410
411 impl ToResolved<Template> for TemplateVar {
412 fn to_resolved(self, env: &Env) -> Result<Template, SpaceErr> {
413 let template: TemplateCtx = self.to_resolved(env)?;
414 template.to_resolved(env)
415 }
416 }
417
418 impl ToResolved<TemplateCtx> for TemplateVar {
419 fn to_resolved(self, env: &Env) -> Result<TemplateCtx, SpaceErr> {
420 let point: PointTemplateCtx = self.point.to_resolved(env)?;
421
422 let template = TemplateCtx {
423 point,
424 kind: self.kind,
425 };
426 Ok(template)
427 }
428 }
429 impl ToResolved<Template> for TemplateCtx {
430 fn to_resolved(self, env: &Env) -> Result<Template, SpaceErr> {
431 let point = self.point.to_resolved(env)?;
432
433 let template = Template {
434 point,
435 kind: self.kind,
436 };
437 Ok(template)
438 }
439 }
440
441 impl Template {
442 pub fn new(point: PointTemplate, kind: KindTemplate) -> Self {
443 Self { point, kind }
444 }
445 }
446
447 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
448 pub struct KindTemplate {
449 pub base: BaseKind,
450 pub sub: Option<CamelCase>,
451 pub specific: Option<SpecificSelector>,
452 }
453
454 impl ToString for KindTemplate {
455 fn to_string(&self) -> String {
456 if self.sub.is_some() {
457 if self.specific.is_some() {
458 format!(
459 "{}<{}<{}>>",
460 self.base.to_string(),
461 self.sub.as_ref().unwrap().to_string(),
462 self.specific.as_ref().unwrap().to_string()
463 )
464 } else {
465 format!(
466 "{}<{}>",
467 self.base.to_string(),
468 self.sub.as_ref().unwrap().to_string()
469 )
470 }
471 } else {
472 self.base.to_string()
473 }
474 }
475 }
476
477 impl TryInto<KindParts> for KindTemplate {
478 type Error = SpaceErr;
479
480 fn try_into(self) -> Result<KindParts, Self::Error> {
481 if self.specific.is_some() {
482 return Err("cannot create a ResourceKind from a specific pattern when using KindTemplate".into());
483 }
484 Ok(KindParts {
485 base: self.base,
486 sub: self.sub,
487 specific: None,
488 })
489 }
490 }
491
492 #[derive(Debug, Clone, Serialize, Deserialize)]
493 pub enum Require {
494 File(String),
495 Auth(String),
496 }
497
498 #[derive(Debug, Clone, Serialize, Deserialize)]
499 pub enum Fulfillment {
500 File { name: String, content: Bin },
501 Complete,
502 }
503
504 pub type Create = CreateDef<Point, StateSrc>;
505 pub type CreateVar = CreateDef<PointVar, StateSrcVar>;
506 pub type CreateCtx = CreateDef<PointCtx, StateSrc>;
507
508 impl ToResolved<Create> for CreateVar {
509 fn to_resolved(self, env: &Env) -> Result<Create, SpaceErr> {
510 let create: CreateCtx = self.to_resolved(env)?;
511 create.to_resolved(env)
512 }
513 }
514
515 impl ToResolved<CreateCtx> for CreateVar {
516 fn to_resolved(self, env: &Env) -> Result<CreateCtx, SpaceErr> {
517 let template = self.template.to_resolved(env)?;
518 let state = match &self.state {
519 StateSrcVar::None => StateSrc::None,
520 StateSrcVar::FileRef(name) => StateSrc::Substance(Box::new(Substance::Bin(
521 env.file(name)
522 .map_err(|e| match e {
523 ResolverErr::NotAvailable => SpaceErr::server_error(
524 "files are not available in this context",
525 ),
526 ResolverErr::NotFound => {
527 SpaceErr::server_error(format!("cannot find file '{}'", name))
528 }
529 })?
530 .content,
531 ))),
532 StateSrcVar::Var(var) => {
533 let val = env.val(var.name.as_str()).map_err(|e| match e {
534 ResolverErr::NotAvailable => {
535 SpaceErr::server_error("variable are not available in this context")
536 }
537 ResolverErr::NotFound => SpaceErr::server_error(format!(
538 "cannot find variable '{}'",
539 var.name
540 )),
541 })?;
542 StateSrc::Substance(Box::new(Substance::Bin(
543 env.file(val.clone())
544 .map_err(|e| match e {
545 ResolverErr::NotAvailable => SpaceErr::server_error(
546 "files are not available in this context",
547 ),
548 ResolverErr::NotFound => SpaceErr::server_error(format!(
549 "cannot find file '{}'",
550 val.to_text().unwrap_or("err".to_string())
551 )),
552 })?
553 .content,
554 )))
555 }
556 };
557 Ok(CreateCtx {
558 template,
559 properties: self.properties,
560 strategy: self.strategy,
561 state,
562 })
563 }
564 }
565
566 impl ToResolved<Create> for CreateCtx {
567 fn to_resolved(self, env: &Env) -> Result<Create, SpaceErr> {
568 let template = self.template.to_resolved(env)?;
569 Ok(Create {
570 template,
571 properties: self.properties,
572 strategy: self.strategy,
573 state: self.state,
574 })
575 }
576 }
577
578 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
579 pub struct CreateDef<Pnt, StateSrc> {
580 pub template: TemplateDef<PointTemplateDef<Pnt>>,
581 pub properties: SetProperties,
582 pub strategy: Strategy,
583 pub state: StateSrc,
584 }
585
586 impl Create {
587 pub fn fulfillment(mut self, bin: Bin) -> Create {
588 Create {
589 template: self.template,
590 state: StateSrc::Substance(Box::new(Substance::Bin(bin))),
591 properties: self.properties,
592 strategy: self.strategy,
593 }
594 }
595
596 pub fn to_wave_proto(self) -> DirectedProto {
597 let mut wave = DirectedProto::ping();
598 wave.method(CmdMethod::Command);
599 wave.body(Substance::Command(Box::new(Command::Create(self))));
600 wave.to(Point::global_executor());
601 wave
602 }
603 }
604
605 impl Into<DirectedCore> for Create {
606 fn into(self) -> DirectedCore {
607 let mut directed = DirectedCore::ext(ExtMethod::new("Command").unwrap());
608 directed.body = Substance::Command(Box::new(Command::Create(self)));
609 directed
610 }
611 }
612
613 impl Into<DirectedProto> for Create {
614 fn into(self) -> DirectedProto {
615 let mut request =
616 DirectedProto::cmd(Point::global_executor().to_surface(), CmdMethod::Command);
617 request.body(Substance::Command(Box::new(Command::Create(self))));
618 request
619 }
620 }
621
622 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, strum_macros::Display)]
623 pub enum Strategy {
624 Commit,
625 Ensure,
626 Override,
627 }
628
629 pub struct PointFactoryU64 {
630 parent: Point,
631 prefix: String,
632 atomic: Arc<AtomicU64>,
633 }
634
635 impl PointFactoryU64 {
636 pub fn new(parent: Point, prefix: String) -> Self {
637 Self {
638 parent,
639 prefix,
640 atomic: Arc::new(AtomicU64::new(0)),
641 }
642 }
643 }
644
645 #[async_trait]
646 impl PointFactory for PointFactoryU64 {
647 async fn create(&self) -> Result<Point, SpaceErr> {
648 let index = self.atomic.fetch_add(1u64, Ordering::Relaxed);
649 self.parent.push(format!("{}{}", self.prefix, index))
650 }
651 }
652
653 pub type PointTemplate = PointTemplateDef<Point>;
654 pub type PointTemplateCtx = PointTemplateDef<PointCtx>;
655 pub type PointTemplateVar = PointTemplateDef<PointVar>;
656
657 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
658 pub struct PointTemplateDef<Pnt> {
659 pub parent: Pnt,
660 pub child_segment_template: PointSegTemplate,
661 }
662
663 impl ToResolved<PointTemplateCtx> for PointTemplateVar {
664 fn to_resolved(self, env: &Env) -> Result<PointTemplateCtx, SpaceErr> {
665 let parent = self.parent.to_resolved(env)?;
666 Ok(PointTemplateCtx {
667 parent,
668 child_segment_template: self.child_segment_template,
669 })
670 }
671 }
672
673 impl ToResolved<PointTemplate> for PointTemplateCtx {
674 fn to_resolved(self, env: &Env) -> Result<PointTemplate, SpaceErr> {
675 let parent = self.parent.to_resolved(env)?;
676 Ok(PointTemplate {
677 parent,
678 child_segment_template: self.child_segment_template,
679 })
680 }
681 }
682
683 impl ToResolved<PointTemplate> for PointTemplateVar {
684 fn to_resolved(self, env: &Env) -> Result<PointTemplate, SpaceErr> {
685 let ctx: PointTemplateCtx = self.to_resolved(env)?;
686 ctx.to_resolved(env)
687 }
688 }
689
690 #[derive(Debug, Clone, strum_macros::Display, Serialize, Deserialize, Eq, PartialEq)]
691 pub enum PointSegTemplate {
692 Exact(String),
693 Pattern(String), Root,
695 }
696 }
697
698 pub mod select {
699 use std::collections::{HashMap, HashSet};
700 use std::convert::{TryFrom, TryInto};
701 use std::marker::PhantomData;
702
703 use serde::{Deserialize, Serialize};
704
705 use crate::err::SpaceErr;
706 use crate::fail::{BadCoercion, Fail};
707 use crate::point::Point;
708 use crate::parse::Env;
709 use crate::particle::Stub;
710 use crate::selector::{Hop, HopCtx, HopVar, PointHierarchy, Selector, SelectorDef};
711 use crate::substance::{MapPattern, Substance, SubstanceList};
712 use crate::util::{ConvertFrom, ToResolved};
713
714 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
715 pub enum SelectIntoSubstance {
716 Stubs,
717 Points,
718 }
719
720 impl SelectIntoSubstance {
721 pub fn to_primitive(&self, stubs: Vec<Stub>) -> Result<SubstanceList, SpaceErr> {
722 match self {
723 SelectIntoSubstance::Stubs => {
724 let stubs: Vec<Box<Substance>> = stubs
725 .into_iter()
726 .map(|stub| Box::new(Substance::Stub(stub)))
727 .collect();
728 let stubs = SubstanceList { list: stubs };
729 Ok(stubs)
730 }
731 SelectIntoSubstance::Points => {
732 let pointes: Vec<Box<Substance>> = stubs
733 .into_iter()
734 .map(|stub| Box::new(Substance::Point(stub.point)))
735 .collect();
736 let stubs = SubstanceList { list: pointes };
737 Ok(stubs)
738 }
739 }
740 }
741 }
742
743 pub type Select = SelectDef<Hop>;
744 pub type SelectCtx = SelectDef<Hop>;
745 pub type SelectVar = SelectDef<Hop>;
746
747 impl ToResolved<Select> for Select {
748 fn to_resolved(self, env: &Env) -> Result<Select, SpaceErr> {
749 Ok(self)
750 }
751 }
752
753 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
754 pub struct SelectDef<Hop> {
755 pub pattern: SelectorDef<Hop>,
756 pub properties: PropertiesPattern,
757 pub into_substance: SelectIntoSubstance,
758 pub kind: SelectKind,
759 }
760
761 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
762 pub enum SelectKind {
763 Initial,
764 SubSelect {
765 point: Point,
766 hops: Vec<Hop>,
767 hierarchy: PointHierarchy,
768 },
769 }
770
771 impl Select {
772 pub fn sub_select(
773 self,
774 point: Point,
775 hops: Vec<Hop>,
776 hierarchy: PointHierarchy,
777 ) -> SubSelect {
778 SubSelect {
779 point,
780 pattern: self.pattern,
781 properties: self.properties,
782 into_payload: self.into_substance,
783 hops,
784 hierarchy,
785 }
786 }
787 }
788
789 impl TryInto<SubSelect> for Select {
790 type Error = SpaceErr;
791
792 fn try_into(self) -> Result<SubSelect, Self::Error> {
793 if let SelectKind::SubSelect {
794 point,
795 hops,
796 hierarchy,
797 } = self.kind
798 {
799 Ok(SubSelect {
800 point,
801 pattern: self.pattern,
802 properties: self.properties,
803 into_payload: self.into_substance,
804 hops: hops,
805 hierarchy,
806 })
807 } else {
808 Err("Not of kind SubSelector".into())
809 }
810 }
811 }
812
813 #[derive(Debug, Clone)]
814 pub struct SubSelect {
815 pub point: Point,
816 pub pattern: Selector,
817 pub properties: PropertiesPattern,
818 pub into_payload: SelectIntoSubstance,
819 pub hops: Vec<Hop>,
820 pub hierarchy: PointHierarchy,
821 }
822
823 impl Into<Select> for SubSelect {
824 fn into(self) -> Select {
825 Select {
826 pattern: self.pattern,
827 properties: self.properties,
828 into_substance: self.into_payload,
829 kind: SelectKind::SubSelect {
830 point: self.point,
831 hops: self.hops,
832 hierarchy: self.hierarchy,
833 },
834 }
835 }
836 }
837
838 impl SubSelect {
839 pub fn sub_select(
840 &self,
841 point: Point,
842 hops: Vec<Hop>,
843 hierarchy: PointHierarchy,
844 ) -> SubSelect {
845 SubSelect {
846 point,
847 pattern: self.pattern.clone(),
848 properties: self.properties.clone(),
849 into_payload: self.into_payload.clone(),
850 hops,
851 hierarchy,
852 }
853 }
854 }
855
856 impl Select {
857 pub fn new(pattern: Selector) -> Self {
858 Self {
859 pattern,
860 properties: Default::default(),
861 into_substance: SelectIntoSubstance::Stubs,
862 kind: SelectKind::Initial,
863 }
864 }
865 }
866
867 pub type PropertiesPattern = MapPattern;
868 }
869
870 pub mod delete {
871 use serde::{Deserialize, Serialize};
872
873 use crate::command::direct::select::{PropertiesPattern, Select, SelectIntoSubstance};
874 use crate::err::SpaceErr;
875 use crate::parse::Env;
876 use crate::selector::{Hop, SelectorDef};
877 use crate::util::ToResolved;
878
879 pub type Delete = DeleteDef<Hop>;
880 pub type DeleteCtx = DeleteDef<Hop>;
881 pub type DeleteVar = DeleteDef<Hop>;
882
883 impl ToResolved<Delete> for Delete {
884 fn to_resolved(self, env: &Env) -> Result<Delete, SpaceErr> {
885 Ok(self)
886 }
887 }
888
889 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
890 pub struct DeleteDef<Hop> {
891 pub selector: SelectorDef<Hop>,
892 }
893
894 impl Into<Select> for Delete {
895 fn into(self) -> Select {
896 let mut select = Select::new(self.selector);
897 select.into_substance = SelectIntoSubstance::Points;
898 select
899 }
900 }
901 }
902
903 pub mod write {
904 use std::convert::TryInto;
905
906 use serde::{Deserialize, Serialize};
907
908 use crate::command::common::SetProperties;
909 use crate::err::SpaceErr;
910 use crate::parse::Env;
911 use crate::point::{Point, PointCtx, PointVar};
912 use crate::substance::Substance;
913 use crate::util::ToResolved;
914
915 pub type Write = WriteDef<Point>;
916 pub type WriteCtx = WriteDef<PointCtx>;
917 pub type WriteVar = WriteDef<PointVar>;
918
919 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
920 pub struct WriteDef<Pnt> {
921 pub point: Pnt,
922 pub payload: Substance,
923 }
924
925 impl ToResolved<WriteCtx> for WriteVar {
926 fn to_resolved(self, env: &Env) -> Result<WriteCtx, SpaceErr> {
927 Ok(WriteCtx {
928 point: self.point.to_resolved(env)?,
929 payload: self.payload,
930 })
931 }
932 }
933
934 impl ToResolved<Write> for WriteCtx {
935 fn to_resolved(self, env: &Env) -> Result<Write, SpaceErr> {
936 Ok(Write {
937 point: self.point.to_resolved(env)?,
938 payload: self.payload,
939 })
940 }
941 }
942 }
943
944 pub mod read {
945 use serde::{Deserialize, Serialize};
946
947 use crate::err::SpaceErr;
948 use crate::parse::Env;
949 use crate::point::{Point, PointCtx, PointVar};
950 use crate::substance::Substance;
951 use crate::util::ToResolved;
952
953 pub type Read = ReadDef<Point>;
954 pub type ReadCtx = ReadDef<PointCtx>;
955 pub type ReadVar = ReadDef<PointVar>;
956
957 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
958 pub struct ReadDef<Pnt> {
959 pub point: Pnt,
960 pub payload: Substance,
961 }
962
963 impl ToResolved<ReadCtx> for ReadVar {
964 fn to_resolved(self, env: &Env) -> Result<ReadCtx, SpaceErr> {
965 Ok(ReadCtx {
966 point: self.point.to_resolved(env)?,
967 payload: self.payload,
968 })
969 }
970 }
971
972 impl ToResolved<Read> for ReadCtx {
973 fn to_resolved(self, env: &Env) -> Result<Read, SpaceErr> {
974 Ok(Read {
975 point: self.point.to_resolved(env)?,
976 payload: self.payload,
977 })
978 }
979 }
980 }
981
982 pub mod query {
983 use std::convert::TryInto;
984
985 use serde::{Deserialize, Serialize};
986
987 use crate::command::direct::Cmd;
988 use crate::err::SpaceErr;
989 use crate::selector::PointHierarchy;
990
991 #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
992 pub enum Query {
993 PointHierarchy,
994 }
995
996 #[derive(Debug, Clone, Serialize, Deserialize)]
997 pub enum QueryResult {
998 PointHierarchy(PointHierarchy),
999 }
1000
1001 impl TryInto<PointHierarchy> for QueryResult {
1002 type Error = SpaceErr;
1003
1004 fn try_into(self) -> Result<PointHierarchy, SpaceErr> {
1005 match self {
1006 QueryResult::PointHierarchy(hierarchy) => Ok(hierarchy),
1007 }
1008 }
1009 }
1010
1011 impl ToString for QueryResult {
1012 fn to_string(&self) -> String {
1013 match self {
1014 QueryResult::PointHierarchy(hierarchy) => hierarchy.to_string(),
1015 }
1016 }
1017 }
1018 }
1019}
1020
1021#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Autobox)]
1022pub enum Command {
1023 Create(Create),
1024 Delete(Delete),
1025 Select(Select),
1026 Set(Set),
1027 Get(Get),
1028 Write(Write),
1029 Read(Read),
1030}
1031
1032impl ChildSubstance for Command {}
1033
1034impl Command {
1035 pub fn matches(&self, method: &CmdMethod) -> Result<(), ()> {
1036 if match self {
1037 Command::Write(_) => *method == CmdMethod::Update,
1038 Command::Read(_) => *method == CmdMethod::Read,
1039 _ => false,
1040 } {
1041 Ok(())
1042 } else {
1043 Err(())
1044 }
1045 }
1046}
1047
1048pub enum CommandCtx {
1049 Create(CreateCtx),
1050 Delete(DeleteCtx),
1051 Select(SelectCtx),
1052 Set(SetCtx),
1053 Get(GetCtx),
1054 Update(WriteCtx),
1055 Read(ReadCtx),
1056}
1057
1058pub enum CommandVar {
1059 Create(CreateVar),
1060 Delete(DeleteVar),
1061 Select(SelectVar),
1062 Set(SetVar),
1063 Get(GetVar),
1064 Update(WriteVar),
1065 Read(ReadVar),
1066}
1067
1068impl FromStr for CommandVar {
1069 type Err = SpaceErr;
1070
1071 fn from_str(s: &str) -> Result<Self, Self::Err> {
1072 let s = new_span(s);
1073 result(all_consuming(command_line)(s))
1074 }
1075}
1076
1077impl ToResolved<Command> for CommandVar {
1078 fn to_resolved(self, env: &Env) -> Result<Command, SpaceErr> {
1079 let command: CommandCtx = self.to_resolved(env)?;
1080 command.to_resolved(env)
1081 }
1082}
1083
1084impl ToResolved<CommandCtx> for CommandVar {
1085 fn to_resolved(self, env: &Env) -> Result<CommandCtx, SpaceErr> {
1086 Ok(match self {
1087 CommandVar::Create(i) => CommandCtx::Create(i.to_resolved(env)?),
1088 CommandVar::Select(i) => CommandCtx::Select(i.to_resolved(env)?),
1089 CommandVar::Set(i) => CommandCtx::Set(i.to_resolved(env)?),
1090 CommandVar::Get(i) => CommandCtx::Get(i.to_resolved(env)?),
1091 CommandVar::Delete(i) => CommandCtx::Delete(i.to_resolved(env)?),
1092 CommandVar::Update(update) => CommandCtx::Update(update.to_resolved(env)?),
1093 CommandVar::Read(read) => CommandCtx::Read(read.to_resolved(env)?),
1094 })
1095 }
1096}
1097
1098impl ToResolved<Command> for CommandCtx {
1099 fn to_resolved(self, env: &Env) -> Result<Command, SpaceErr> {
1100 Ok(match self {
1101 CommandCtx::Create(i) => Command::Create(i.to_resolved(env)?),
1102 CommandCtx::Select(i) => Command::Select(i.to_resolved(env)?),
1103 CommandCtx::Set(i) => Command::Set(i.to_resolved(env)?),
1104 CommandCtx::Get(i) => Command::Get(i.to_resolved(env)?),
1105 CommandCtx::Delete(i) => Command::Delete(i.to_resolved(env)?),
1106 CommandCtx::Update(update) => Command::Write(update.to_resolved(env)?),
1107 CommandCtx::Read(read) => Command::Read(read.to_resolved(env)?),
1108 })
1109 }
1110}
1111
1112#[derive(Debug, Clone, Serialize, Deserialize)]
1113pub struct CommandTemplate {
1114 pub line: String,
1115 pub transfers: Vec<Trace>,
1116}
1117
1118#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
1119pub struct RawCommand {
1120 pub line: String,
1121 pub transfers: Vec<CmdTransfer>,
1122}
1123
1124impl RawCommand {
1125 pub fn new<S>(line: S) -> Self
1126 where
1127 S: ToString,
1128 {
1129 Self {
1130 line: line.to_string(),
1131 transfers: vec![],
1132 }
1133 }
1134}
1135
1136impl ToString for RawCommand {
1137 fn to_string(&self) -> String {
1138 self.line.clone()
1139 }
1140}
1141
1142#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
1143pub struct CmdTransfer {
1144 pub id: String,
1145 pub content: Bin,
1146}
1147
1148impl CmdTransfer {
1149 pub fn new<N: ToString>(id: N, content: Bin) -> Self {
1150 Self {
1151 id: id.to_string(),
1152 content,
1153 }
1154 }
1155}