cosmic_space/wave/core/
ext.rs

1use 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}