saito_core/core/consensus/peers/
peer_service.rs1use std::io::{Error, ErrorKind};
2
3use log::{error, warn};
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct PeerService {
8 pub service: String,
9 pub domain: String,
10 pub name: String,
11 }
13
14impl TryFrom<String> for PeerService {
15 type Error = std::io::Error;
16
17 fn try_from(value: String) -> Result<PeerService, std::io::Error> {
18 let values: Vec<&str> = value.split('|').collect();
19 if values.len() != 3 {
20 return Err(Error::from(ErrorKind::InvalidData));
21 }
22 let service = values[0].try_into();
23 let domain = values[1].try_into();
24 let name = values[2].try_into();
25 if service.is_err() {
26 return Err(Error::from(ErrorKind::InvalidData));
27 }
28 if domain.is_err() {
29 return Err(Error::from(ErrorKind::InvalidData));
30 }
31 if name.is_err() {
32 return Err(Error::from(ErrorKind::InvalidData));
33 }
34 Ok(PeerService {
35 service: service.unwrap(),
36 domain: domain.unwrap(),
37 name: name.unwrap(),
38 })
39 }
40}
41
42impl Into<String> for PeerService {
43 fn into(self) -> String {
44 self.service + "|" + self.domain.as_str() + "|" + self.name.as_str()
45 }
46}
47
48impl PeerService {
49 pub fn serialize_services(services: &Vec<PeerService>) -> Vec<u8> {
50 if services.is_empty() {
51 return vec![];
52 }
53 let str: String = services
54 .iter()
55 .map(|service| {
56 let str: String = service.clone().into();
57 str
58 })
59 .collect::<Vec<String>>()
60 .join(";");
61 str.as_bytes().to_vec()
62 }
63 pub fn deserialize_services(buffer: Vec<u8>) -> Result<Vec<PeerService>, Error> {
64 if buffer.is_empty() {
65 return Ok(vec![]);
66 }
67 let str = String::from_utf8(buffer);
68 if str.is_err() {
69 warn!("failed parsing services.");
70 error!("{:?}", str.err().unwrap());
71 return Err(Error::from(ErrorKind::InvalidData));
72 }
73 let str = str.unwrap();
74 let strings = str.split(";");
75 let mut services: Vec<PeerService> = Default::default();
76 for str in strings {
77 if str.is_empty() {
78 continue;
79 }
80 let result = str.try_into();
81 if result.is_err() {
82 warn!("cannot parse services from : {:?}", str);
83 return Err(Error::from(ErrorKind::InvalidData));
84 }
85 let result: String = result.unwrap();
86 let service = result.try_into();
87
88 if service.is_err() {
89 warn!("cannot parse services from : {:?}", str);
90 return Err(Error::from(ErrorKind::InvalidData));
91 }
92
93 services.push(service.unwrap());
94 }
95 Ok(services)
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use crate::core::consensus::peers::peer_service::PeerService;
102
103 #[test]
104 fn test_serialize() {
105 let mut services = vec![];
106 services.push(PeerService {
107 service: "service1".to_string(),
108 domain: "domain1".to_string(),
109 name: "name1".to_string(),
110 });
111 services.push(PeerService {
112 service: "service2".to_string(),
113 domain: "".to_string(),
114 name: "name2".to_string(),
115 });
116 services.push(PeerService {
117 service: "service3".to_string(),
118 domain: "domain3".to_string(),
119 name: "".to_string(),
120 });
121 services.push(PeerService {
122 service: "service4".to_string(),
123 domain: "".to_string(),
124 name: "".to_string(),
125 });
126
127 let buffer = PeerService::serialize_services(&services);
128
129 assert!(buffer.len() > 0);
130
131 let result = PeerService::deserialize_services(buffer);
132 assert!(result.is_ok());
133 let services = result.unwrap();
134 assert_eq!(services.len(), 4);
135
136 let service = services.get(0).unwrap();
137 assert_eq!(service.service, "service1");
138 assert_eq!(service.domain, "domain1");
139 assert_eq!(service.name, "name1");
140
141 let service = services.get(1).unwrap();
142 assert_eq!(service.service, "service2");
143 assert_eq!(service.domain, "");
144 assert_eq!(service.name, "name2");
145
146 let service = services.get(2).unwrap();
147 assert_eq!(service.service, "service3");
148 assert_eq!(service.domain, "domain3");
149 assert_eq!(service.name, "");
150
151 let service = services.get(3).unwrap();
152 assert_eq!(service.service, "service4");
153 assert_eq!(service.domain, "");
154 assert_eq!(service.name, "");
155 }
156}