krpc_core/support/
dubbo.rs

1use std::vec;
2use crate::register::{Info, Resource};
3
4pub fn decode_url(url: &str) -> Result<Resource, String> {
5    let mut url = &krpc_common::url_util::decode_url(url)?[..];
6    if url.starts_with("tri://") {
7        url = &url[6..];
8        return Ok(Resource::Server(get_info(url)));
9    } else if url.starts_with("consumer://") {
10        url = &url[11..];
11        return Ok(Resource::Client(get_info(url)));
12    }
13    return Err("decode err".to_string());
14}
15
16pub fn encode_url(resource: &Resource) -> String {
17    let mut url = String::new();
18    match resource {
19        Resource::Client(info) => {
20            url.push_str("consumer://");
21            url.push_str(&(get_path(info) + &"/"));
22            url.push_str(&(info.server_name.clone() + &"?"));
23            url.push_str(&("interface=".to_owned() + &info.server_name));
24            url.push_str(&get_field_url("&methods", &info.methods));
25            if let Some(version) = &info.version {
26                let value = vec![version.clone()];
27                url.push_str(&get_field_url("&version", &value));
28            }
29            url.push_str("&dubbo=2.0.2&release=3.3.0-beta.1&side=consumer");
30        }
31        Resource::Server(info) => {
32            url.push_str("tri://");
33            url.push_str(&(get_path(info) + &"/"));
34            url.push_str(&(info.server_name.clone() + &"?"));
35            url.push_str(&("interface=".to_owned() + &info.server_name));
36            url.push_str(&get_field_url("&methods", &info.methods));
37            if let Some(version) = &info.version {
38                let value = vec![version.clone()];
39                url.push_str(&get_field_url("&version", &value));
40            }
41            url.push_str(
42                "&dubbo=2.0.2&prefer.serialization=fastjson&release=3.3.0-beta.1&side=provider",
43            );
44        }
45    }
46    return "/".to_string() + &krpc_common::url_util::encode_url(&url);
47}
48
49fn get_ip(path: &str) -> (String, Option<String>) {
50    let path: Vec<&str> = path.split(":").collect();
51    let mut port = None;
52    if path.len() > 1 {
53        let _ = port.insert(path[1].to_string());
54    }
55    return (path[0].to_string(), port);
56}
57
58fn get_path(info: &Info) -> String {
59    let mut ip = info.ip.clone();
60    if let Some(port) = info.port.clone() {
61        ip.push_str(":");
62        ip.push_str(&port);
63    }
64    return ip.to_string();
65}
66
67fn get_info(url: &str) -> Info {
68    let info: Vec<&str> = url.split("/").collect();
69    let path = get_ip(info[0]);
70    let info: Vec<&str> = info[1].split("?").collect();
71    let server_name = info[0].to_string();
72    let vision = get_field_values(info[1], "version");
73    let mut revision = None;
74    if !vision.is_empty(){
75        let _ = revision.insert(vision[0].clone());
76    }
77    let info = Info {
78        server_name,
79        version: revision,
80        methods: get_field_values(info[1], "methods"),
81        ip: path.0,
82        port: path.1,
83    };
84    return info;
85}
86
87fn get_field_values(str: &str, key: &str) -> Vec<String> {
88    let fields: Vec<&str> = str.split("&").collect();
89    let mut res = vec![];
90    for field in fields {
91        let field: Vec<&str> = field.split("=").collect();
92        if field[0] == key {
93            let velues: Vec<&str> = field[1].split(",").collect();
94            res = velues.iter().fold(res, |mut res, &e| {
95                res.push(e.to_string());
96                res
97            });
98            break;
99        }
100    }
101    return res;
102}
103
104fn get_field_url(key: &str, values: &Vec<String>) -> String {
105    if values.is_empty() {
106        return String::new();
107    }
108    let mut res = String::new();
109    for value in values {
110        res.push_str(&(value.to_owned() + ","));
111    }
112    return key.to_string() + "=" + &res[..res.len() - 1];
113}