cosmic_space/
util.rs

1use alloc::string::{String, ToString};
2use core::marker::Sized;
3use core::option::Option;
4use core::option::Option::{None, Some};
5use core::result::Result;
6use core::result::Result::{Err, Ok};
7
8use serde::{Deserialize, Serialize};
9
10use crate::err::SpaceErr;
11use crate::loc;
12use crate::loc::Uuid;
13use crate::parse::Env;
14use crate::wasm::{cosmic_timestamp, cosmic_uuid, Timestamp};
15use crate::wave::core::http2::HttpMethod;
16
17#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
18pub enum HttpMethodPattern {
19    Any,
20    None,
21    Pattern(HttpMethod),
22}
23
24impl HttpMethodPattern {
25    pub fn is_match(&self, x: &HttpMethod) -> Result<(), ()> {
26        match self {
27            Self::Any => Ok(()),
28            Self::Pattern(exact) => exact.is_match(x),
29            Self::None => Err(()),
30        }
31    }
32
33    pub fn is_match_opt(&self, x: Option<&HttpMethod>) -> Result<(), ()> {
34        match self {
35            Self::Any => Ok(()),
36            Self::Pattern(exact) => match x {
37                None => Err(()),
38                Some(x) => self.is_match(x),
39            },
40            Self::None => Err(()),
41        }
42    }
43}
44
45impl ToString for HttpMethodPattern {
46    fn to_string(&self) -> String {
47        match self {
48            Self::Any => "*".to_string(),
49            Self::None => "!".to_string(),
50            Self::Pattern(pattern) => pattern.to_string(),
51        }
52    }
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
56pub enum ValuePattern<T> {
57    Any,
58    None,
59    Pattern(T),
60}
61
62impl<T> ValuePattern<T>
63where
64    T: ToString,
65{
66    pub fn stringify(self) -> ValuePattern<String> {
67        match self {
68            ValuePattern::Any => ValuePattern::Any,
69            ValuePattern::None => ValuePattern::None,
70            ValuePattern::Pattern(t) => ValuePattern::Pattern(t.to_string()),
71        }
72    }
73}
74
75impl<T> ToString for ValuePattern<T>
76where
77    T: ToString,
78{
79    fn to_string(&self) -> String {
80        match self {
81            ValuePattern::Any => "*".to_string(),
82            ValuePattern::None => "!".to_string(),
83            ValuePattern::Pattern(pattern) => pattern.to_string(),
84        }
85    }
86}
87
88impl<T> ValuePattern<T> {
89    pub fn modify<X, F>(self, mut f: F) -> Result<ValuePattern<X>, SpaceErr>
90    where
91        F: FnMut(T) -> Result<X, SpaceErr>,
92    {
93        Ok(match self {
94            ValuePattern::Any => ValuePattern::Any,
95            ValuePattern::None => ValuePattern::None,
96            ValuePattern::Pattern(from) => ValuePattern::Pattern(f(from)?),
97        })
98    }
99
100    pub fn wrap<X>(self, x: X) -> ValuePattern<X> {
101        match self {
102            ValuePattern::Any => ValuePattern::Any,
103            ValuePattern::None => ValuePattern::None,
104            ValuePattern::Pattern(_) => ValuePattern::Pattern(x),
105        }
106    }
107
108    pub fn is_match<X>(&self, x: &X) -> Result<(), ()>
109    where
110        T: ValueMatcher<X>,
111    {
112        match self {
113            ValuePattern::Any => Ok(()),
114            ValuePattern::Pattern(exact) => exact.is_match(x),
115            ValuePattern::None => Err(()),
116        }
117    }
118
119    pub fn is_match_opt<X>(&self, x: Option<&X>) -> Result<(), ()>
120    where
121        T: ValueMatcher<X>,
122    {
123        match self {
124            ValuePattern::Any => Ok(()),
125            ValuePattern::Pattern(exact) => match x {
126                None => Err(()),
127                Some(x) => self.is_match(x),
128            },
129            ValuePattern::None => Err(()),
130        }
131    }
132}
133
134pub trait ValueMatcher<X> {
135    fn is_match(&self, x: &X) -> Result<(), ()>;
136}
137
138pub struct RegexMatcher {
139    pub pattern: String,
140}
141
142impl ToString for RegexMatcher {
143    fn to_string(&self) -> String {
144        self.pattern.clone()
145    }
146}
147
148impl RegexMatcher {
149    pub fn new(string: String) -> Self {
150        Self { pattern: string }
151    }
152}
153
154impl ValueMatcher<String> for RegexMatcher {
155    fn is_match(&self, x: &String) -> Result<(), ()> {
156        let matches = x.matches(x);
157        if matches.count() > 0 {
158            Ok(())
159        } else {
160            Err(())
161        }
162    }
163}
164
165#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
166pub struct StringMatcher {
167    pub pattern: String,
168}
169
170impl ToString for StringMatcher {
171    fn to_string(&self) -> String {
172        self.pattern.clone()
173    }
174}
175
176impl StringMatcher {
177    pub fn new(string: String) -> Self {
178        Self { pattern: string }
179    }
180}
181
182impl ValueMatcher<String> for StringMatcher {
183    fn is_match(&self, x: &String) -> Result<(), ()> {
184        if self.pattern == *x {
185            Ok(())
186        } else {
187            Err(())
188        }
189    }
190}
191
192pub trait Convert<A> {
193    fn convert(self) -> Result<A, SpaceErr>;
194}
195
196pub trait ConvertFrom<A>
197where
198    Self: Sized,
199{
200    fn convert_from(a: A) -> Result<Self, SpaceErr>;
201}
202
203pub fn uuid() -> Uuid {
204    unsafe { cosmic_uuid() }
205}
206
207pub fn timestamp() -> Timestamp {
208    unsafe { cosmic_timestamp() }
209}
210
211pub trait ToResolved<R>
212where
213    Self: Sized,
214{
215    fn collapse(self) -> Result<R, SpaceErr> {
216        self.to_resolved(&Env::no_point())
217    }
218
219    fn to_resolved(self, env: &Env) -> Result<R, SpaceErr>;
220}
221
222pub fn log<R>(result: Result<R, SpaceErr>) -> Result<R, SpaceErr> {
223    match result {
224        Ok(r) => Ok(r),
225        Err(err) => {
226            err.print();
227            Err(err)
228        }
229    }
230}