fusen_common/
lib.rs

1use bytes::{Bytes, BytesMut};
2use codec::CodecType;
3use error::FusenError;
4use fusen_procedural_macro::Data;
5use http::{HeaderMap, HeaderValue};
6use register::Type;
7use serde::{Deserialize, Serialize};
8use std::collections::{hash_map::Iter, HashMap};
9pub type Error = Box<dyn std::error::Error + Send + Sync>;
10pub type Result<T> = std::result::Result<T, Error>;
11pub type Response<T> = std::result::Result<T, String>;
12pub type FusenFuture<T> = std::pin::Pin<Box<dyn std::future::Future<Output = T> + Send>>;
13pub type FusenResult<T> = std::result::Result<T, FusenError>;
14pub mod codec;
15pub mod config;
16pub mod date_util;
17pub mod error;
18pub mod logs;
19pub mod r#macro;
20pub mod net;
21pub mod register;
22pub mod server;
23pub mod trie;
24pub mod url;
25
26#[derive(Debug, Data)]
27pub struct MetaData {
28    inner: HashMap<String, String>,
29}
30
31impl MetaData {
32    pub fn get_codec(&self) -> CodecType {
33        let content_type = self.get_value("content-type");
34        if let Some(str) = content_type {
35            if str.to_lowercase().contains("grpc") {
36                return CodecType::GRPC;
37            }
38        }
39        CodecType::JSON
40    }
41    pub fn into_inner(self) -> HashMap<String, String> {
42        self.inner
43    }
44    pub fn get_value(&self, key: &str) -> Option<&String> {
45        self.inner.get(key)
46    }
47
48    pub fn get_iter(&self) -> Iter<String, String> {
49        self.inner.iter()
50    }
51    pub fn clone_map(&self) -> HashMap<String, String> {
52        self.inner.clone()
53    }
54
55    pub fn insert(&mut self, key: String, value: String) -> Option<String> {
56        self.inner.insert(key, value)
57    }
58    pub fn remove(&mut self, key: &str) -> Option<String> {
59        self.inner.remove(key)
60    }
61}
62
63impl From<&HeaderMap<HeaderValue>> for MetaData {
64    fn from(value: &HeaderMap<HeaderValue>) -> MetaData {
65        value.iter().fold(MetaData::new(), |mut meta, e| {
66            meta.inner
67                .insert(e.0.to_string(), e.1.to_str().unwrap().to_string());
68            meta
69        })
70    }
71}
72
73impl MetaData {
74    pub fn new() -> Self {
75        MetaData::default()
76    }
77}
78
79impl Default for MetaData {
80    fn default() -> Self {
81        let mut inner = HashMap::new();
82        inner.insert("prefer.serialization".to_owned(), "fastjson".to_owned());
83        inner.insert(
84            "preserved.register.source".to_owned(),
85            "SPRING_CLOUD".to_owned(),
86        );
87        inner.insert("protocol".to_owned(), "tri".to_owned());
88        Self { inner }
89    }
90}
91
92#[derive(Debug, Default, Data)]
93pub struct ContextInfo {
94    path: Path,
95    class_name: String,
96    method_name: String,
97    version: Option<String>,
98    group: Option<String>,
99}
100
101impl ContextInfo {
102    pub fn new(
103        path: Path,
104        class_name: String,
105        method_name: String,
106        version: Option<String>,
107        group: Option<String>,
108    ) -> Self {
109        ContextInfo {
110            path,
111            class_name,
112            method_name,
113            version,
114            group,
115        }
116    }
117    pub fn get_handler_key(&self) -> String {
118        let mut key = self.class_name.clone();
119        if let Some(version) = &self.version {
120            key.push(':');
121            key.push_str(version);
122        }
123        key
124    }
125}
126
127#[derive(Debug, Data)]
128pub struct FusenRequest {
129    method: String,
130    headers: HashMap<String, String>,
131    query_fields: HashMap<String, String>,
132    body: Bytes,
133}
134
135impl FusenRequest {
136    pub fn new_for_client(method: &str, fields_ty: Vec<String>, bodys: Vec<String>) -> Self {
137        let mut query_fields = HashMap::new();
138        let mut bytes = BytesMut::new();
139        if method.to_lowercase().as_str() != "post" {
140            for (idx, body) in bodys.into_iter().enumerate() {
141                let mut pre = 0;
142                if fields_ty[idx].starts_with("r#") {
143                    pre = 2;
144                }
145                query_fields.insert(fields_ty[idx][pre..].to_owned(), body.replace('\"', ""));
146            }
147        } else if bodys.len() == 1 {
148            bytes.extend_from_slice(bodys[0].as_bytes());
149        } else {
150            bytes.extend_from_slice(serde_json::to_string(&bodys).unwrap().as_bytes());
151        }
152        FusenRequest {
153            method: method.to_ascii_lowercase(),
154            headers: Default::default(),
155            query_fields,
156            body: bytes.into(),
157        }
158    }
159    pub fn new(method: &str, query_fields: HashMap<String, String>, body: Bytes) -> Self {
160        FusenRequest {
161            method: method.to_ascii_lowercase(),
162            headers: Default::default(),
163            query_fields,
164            body,
165        }
166    }
167    pub fn get_fields(
168        &mut self,
169        temp_fields_name: Vec<&str>,
170        temp_fields_ty: Vec<&str>,
171    ) -> Result<Vec<String>> {
172        let mut new_fields = vec![];
173        if self.method != "post" {
174            let hash_map = &self.query_fields;
175            for item in temp_fields_name.iter().enumerate() {
176                let mut pre = 0;
177                if item.1.starts_with("r#") {
178                    pre = 2;
179                };
180                match hash_map.get(&item.1[pre..]) {
181                    Some(fields) => {
182                        let mut temp = String::new();
183                        if "String" == temp_fields_ty[item.0] {
184                            temp.push('\"');
185                            temp.push_str(fields);
186                            temp.push('\"');
187                        } else {
188                            temp.push_str(fields);
189                        }
190                        new_fields.push(temp);
191                    }
192                    None => {
193                        new_fields.push("null".to_owned());
194                    }
195                }
196            }
197        } else if self.body.starts_with(b"[") {
198            new_fields = serde_json::from_slice(&self.body)?;
199        } else {
200            new_fields.push(String::from_utf8(self.body.to_vec())?);
201        }
202        Ok(new_fields)
203    }
204}
205
206#[derive(Debug, Data)]
207pub struct FusenResponse {
208    headers: HashMap<String, String>,
209    response: std::result::Result<Bytes, FusenError>,
210    response_ty: Option<&'static str>,
211}
212
213impl Default for FusenResponse {
214    fn default() -> Self {
215        Self {
216            headers: Default::default(),
217            response: Err(FusenError::Null),
218            response_ty: Default::default(),
219        }
220    }
221}
222
223impl FusenResponse {
224    pub fn insert_return_ty(&mut self, ty: &'static str) {
225        let _ = self.response_ty.insert(ty);
226    }
227    pub fn into_response(self) -> std::result::Result<Bytes, FusenError> {
228        self.response
229    }
230}
231
232#[derive(Debug, Data)]
233pub struct FusenContext {
234    unique_identifier: String,
235    server_type: Type,
236    meta_data: MetaData,
237    context_info: ContextInfo,
238    request: FusenRequest,
239    response: FusenResponse,
240}
241
242impl FusenContext {
243    pub fn new(
244        unique_identifier: String,
245        context_info: ContextInfo,
246        request: FusenRequest,
247        meta_data: MetaData,
248    ) -> FusenContext {
249        FusenContext {
250            unique_identifier,
251            context_info,
252            server_type: Type::Fusen,
253            meta_data,
254            request,
255            response: Default::default(),
256        }
257    }
258    pub fn insert_server_type(&mut self, server_tyep: Type) {
259        self.server_type = server_tyep
260    }
261    pub fn into_response(self) -> FusenResponse {
262        self.response
263    }
264    pub fn get_return_ty(&self) -> Option<&'static str> {
265        self.response.response_ty
266    }
267}
268
269#[derive(Clone, Debug, Serialize, Deserialize)]
270pub struct MethodResource {
271    name: String,
272    path: String,
273    method: String,
274}
275
276#[derive(Debug, Clone)]
277pub enum Path {
278    GET(String),
279    PUT(String),
280    DELETE(String),
281    POST(String),
282}
283
284impl Default for Path {
285    fn default() -> Self {
286        Path::GET(Default::default())
287    }
288}
289
290impl Path {
291    pub fn get_key(&self) -> String {
292        let mut key = String::new();
293        match self {
294            Path::GET(path) => {
295                key.push_str("get:");
296                key.push_str(path);
297            }
298            Path::POST(path) => {
299                key.push_str("post:");
300                key.push_str(path);
301            }
302            Path::PUT(path) => {
303                key.push_str("put:");
304                key.push_str(path);
305            }
306            Path::DELETE(path) => {
307                key.push_str("delete:");
308                key.push_str(path);
309            }
310        };
311        key
312    }
313
314    pub fn update_path(&mut self, new_path: String) {
315        match self {
316            Path::GET(path) => *path = new_path,
317            Path::POST(path) => *path = new_path,
318            Path::PUT(path) => *path = new_path,
319            Path::DELETE(path) => *path = new_path,
320        }
321    }
322
323    pub fn get_path(&self) -> String {
324        match self {
325            Path::GET(path) => path,
326            Path::POST(path) => path,
327            Path::PUT(path) => path,
328            Path::DELETE(path) => path,
329        }
330        .clone()
331    }
332
333    pub fn new(method: &str, path: String) -> Self {
334        match method.to_lowercase().as_str() {
335            "get" => Self::GET(path),
336            "put" => Self::PUT(path),
337            "delete" => Self::DELETE(path),
338            _ => Self::POST(path),
339        }
340    }
341}
342
343impl MethodResource {
344    pub fn get_name(&self) -> String {
345        self.name.to_string()
346    }
347    pub fn get_path(&self) -> String {
348        self.path.to_string()
349    }
350    pub fn get_method(&self) -> String {
351        self.method.to_string()
352    }
353    pub fn new(name: String, path: String, method: String) -> Self {
354        Self { name, path, method }
355    }
356    pub fn new_macro(method_str: &str) -> Self {
357        let method: Vec<String> = serde_json::from_str(method_str).unwrap();
358        Self {
359            name: method[0].to_string(),
360            path: method[1].to_string(),
361            method: method[2].to_string(),
362        }
363    }
364    pub fn form_json_str(str: &str) -> Self {
365        serde_json::from_str(str).unwrap()
366    }
367    pub fn to_json_str(&self) -> String {
368        serde_json::to_string(self).unwrap()
369    }
370}