cosmic_space/wave/core/
ext.rs1use std::ops::Deref;
2
3use nom::combinator::all_consuming;
4use regex::Regex;
5use serde::{Deserialize, Serialize};
6
7use cosmic_nom::new_span;
8
9use crate::err::SpaceErr;
10use crate::loc::Meta;
11use crate::parse::camel_case_chars;
12use crate::parse::error::result;
13use crate::parse::model::MethodScopeSelector;
14use crate::substance::{FormErrs, Substance};
15use crate::util::{ValueMatcher, ValuePattern};
16use crate::wave::core::http2::StatusCode;
17use crate::wave::core::{DirectedCore, HeaderMap, Method, ReflectedCore};
18use url::Url;
19
20#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
21pub struct ExtMethod {
22 string: String,
23}
24
25impl ExtMethod {
26 pub fn new<S: ToString>(string: S) -> Result<Self, SpaceErr> {
27 let tmp = string.to_string();
28 let string = result(all_consuming(camel_case_chars)(new_span(tmp.as_str())))?.to_string();
29 Ok(Self { string })
30 }
31}
32
33impl ToString for ExtMethod {
34 fn to_string(&self) -> String {
35 self.string.clone()
36 }
37}
38
39impl ValueMatcher<ExtMethod> for ExtMethod {
40 fn is_match(&self, x: &ExtMethod) -> Result<(), ()> {
41 if *self == *x {
42 Ok(())
43 } else {
44 Err(())
45 }
46 }
47}
48
49impl Into<MethodScopeSelector> for ExtMethod {
50 fn into(self) -> MethodScopeSelector {
51 MethodScopeSelector::new(
52 ValuePattern::Pattern(Method::Ext(self)),
53 Regex::new(".*").unwrap(),
54 )
55 }
56}
57
58impl TryFrom<String> for ExtMethod {
59 type Error = SpaceErr;
60
61 fn try_from(value: String) -> Result<Self, Self::Error> {
62 Self::new(value)
63 }
64}
65
66impl TryFrom<&str> for ExtMethod {
67 type Error = SpaceErr;
68
69 fn try_from(value: &str) -> Result<Self, Self::Error> {
70 Self::new(value)
71 }
72}
73
74impl Deref for ExtMethod {
75 type Target = String;
76
77 fn deref(&self) -> &Self::Target {
78 &self.string
79 }
80}
81
82impl Default for ExtMethod {
83 fn default() -> Self {
84 Self {
85 string: "Def".to_string(),
86 }
87 }
88}
89
90#[derive(Debug, Clone, Serialize, Deserialize)]
91pub struct ExtDirected {
92 pub method: ExtMethod,
93
94 pub headers: HeaderMap,
95
96 pub uri: Url,
97 pub body: Substance,
98}
99
100impl Default for ExtDirected {
101 fn default() -> Self {
102 Self {
103 method: Default::default(),
104 headers: Default::default(),
105 uri: Url::parse("http:://localhost/").unwrap(),
106 body: Default::default(),
107 }
108 }
109}
110
111impl ExtDirected {
112 pub fn new<M>(method: M) -> Result<Self, SpaceErr>
113 where
114 M: TryInto<ExtMethod, Error = SpaceErr>,
115 {
116 Ok(ExtDirected {
117 method: method.try_into()?,
118 ..Default::default()
119 })
120 }
121
122 pub fn with_body(mut self, body: Substance) -> Self {
123 self.body = body;
124 self
125 }
126
127 pub fn ok(&self, payload: Substance) -> ReflectedCore {
128 ReflectedCore {
129 headers: Default::default(),
130 status: StatusCode::from_u16(200u16).unwrap(),
131 body: payload,
132 }
133 }
134
135 pub fn fail(&self, error: &str) -> ReflectedCore {
136 let errors = FormErrs::default(error);
137 ReflectedCore {
138 headers: Default::default(),
139 status: StatusCode::from_u16(500u16).unwrap(),
140 body: Substance::FormErrs(errors),
141 }
142 }
143}
144
145impl TryFrom<DirectedCore> for ExtDirected {
146 type Error = SpaceErr;
147
148 fn try_from(core: DirectedCore) -> Result<Self, Self::Error> {
149 if let Method::Ext(action) = core.method {
150 Ok(Self {
151 method: action,
152 headers: core.headers,
153 uri: core.uri,
154 body: core.body,
155 })
156 } else {
157 Err("expected Ext".into())
158 }
159 }
160}