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}