krpc_core/support/
dubbo.rs1use 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}