1use crate::codec::{RawDecode, RawEncode, RawEncodePurpose, RawFixedBytes};
2use crate::*;
3use std::fmt::{Display, Formatter};
4use std::str::FromStr;
5#[derive(Eq, PartialEq, Clone, Debug)]
8pub struct Area {
9 pub country: u16,
10 pub carrier: u8,
11 pub city: u16,
12 pub inner: u8, }
20
21impl Area {
22 pub fn new(country: u16, carrier: u8, city: u16, inner: u8) -> Self {
23 assert!(country <= 0x1FF);
24 assert!(city <= 0x1FFF);
25 assert!(carrier <= 0xF);
26 Area {
27 country,
28 carrier,
29 city,
30 inner,
31 }
32 }
33}
34
35impl FromStr for Area {
36 type Err = BuckyError;
37
38 fn from_str(s: &str) -> Result<Self, Self::Err> {
39 let values = s.split(":");
40 let mut array: Vec<u16> = vec![];
41 for value in values {
42 match value.parse::<u16>() {
43 Ok(num) => array.push(num),
44 Err(_) => {
45 return Err(BuckyError::new(
46 BuckyErrorCode::InvalidFormat,
47 "decode area err",
48 ))
49 }
50 }
51 }
52 if array.len() != 4 {
53 return Err(BuckyError::new(
54 BuckyErrorCode::InvalidFormat,
55 "decode area err",
56 ));
57 }
58 if array[0] > 0x1FF || array[2] > 0x1FFF || array[1] > 0xF {
59 return Err(BuckyError::new(
60 BuckyErrorCode::InvalidFormat,
61 "decode area err",
62 ));
63 }
64
65 Ok(Area {
66 country: array[0],
67 carrier: array[1] as u8,
68 city: array[2],
69 inner: array[3] as u8,
70 })
71 }
72}
73
74impl Display for Area {
75 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
76 write!(
77 f,
78 "{}:{}:{}:{}",
79 self.country, self.carrier, self.city, self.inner
80 )
81 }
82}
83
84impl Default for Area {
85 fn default() -> Self {
86 Area {
87 country: 0,
88 carrier: 0,
89 city: 0,
90 inner: 0,
91 }
92 }
93}
94
95impl RawFixedBytes for Area {
96 fn raw_bytes() -> Option<usize> {
97 Some(5)
98 }
99}
100
101impl RawEncode for Area {
102 fn raw_measure(&self, _purpose: &Option<RawEncodePurpose>) -> Result<usize, BuckyError> {
103 Ok(5)
104 }
105
106 fn raw_encode<'a>(
107 &self,
108 buf: &'a mut [u8],
109 _purpose: &Option<RawEncodePurpose>,
110 ) -> Result<&'a mut [u8], BuckyError> {
111 let bytes = Self::raw_bytes().unwrap();
112 if buf.len() < bytes {
113 let msg = format!(
114 "not enough buffer for encode Area, except={}, got={}",
115 bytes,
116 buf.len()
117 );
118 error!("{}", msg);
119
120 return Err(BuckyError::new(BuckyErrorCode::OutOfLimit, msg));
121 }
122
123 buf[0] = self.country as u8;
126 buf[1] = self.carrier;
127 buf[2] = (self.city >> 8) as u8 | (self.country >> 8 << 7) as u8;
128 buf[3] = (self.city << 8 >> 8) as u8;
129 buf[4] = self.inner;
130
131 Ok(&mut buf[5..])
132 }
133}
134
135impl<'de> RawDecode<'de> for Area {
136 fn raw_decode(buf: &'de [u8]) -> Result<(Self, &'de [u8]), BuckyError> {
137 let bytes = Self::raw_bytes().unwrap();
138 if buf.len() < bytes {
139 let msg = format!(
140 "not enough buffer for decode Area, except={}, got={}",
141 bytes,
142 buf.len()
143 );
144 error!("{}", msg);
145
146 return Err(BuckyError::new(BuckyErrorCode::OutOfLimit, msg));
147 }
148
149 let mut area_code = Self::default();
150 area_code.country = buf[0] as u16 | (buf[2] as u16 >> 7 << 8);
151 area_code.carrier = buf[1];
152 area_code.city = ((buf[2] as u16) << 9 >> 1) | (buf[3] as u16);
153 area_code.inner = buf[4];
154
155 Ok((area_code, &buf[5..]))
156 }
157}
158
159#[cfg(test)]
160mod test_area {
161 use crate::*;
162 use std::str::FromStr;
163
164 #[test]
165 fn test() {
166 let area = Area::new(333, 14, 3345, 32);
167 let buf = area.to_vec().unwrap();
168 let tmp_area = Area::clone_from_slice(buf.as_slice()).unwrap();
169
170 assert_eq!(333, tmp_area.country);
171 assert_eq!(14, tmp_area.carrier);
172 assert_eq!(3345, tmp_area.city);
173 assert_eq!(32, tmp_area.inner);
174 assert_eq!(area.country, tmp_area.country);
175 assert_eq!(area.carrier, tmp_area.carrier);
176 assert_eq!(area.city, tmp_area.city);
177 assert_eq!(area.inner, tmp_area.inner);
178
179 let area = Area::new(33, 14, 3345, 32);
180 let buf = area.to_vec().unwrap();
181 let tmp_area = Area::clone_from_slice(buf.as_slice()).unwrap();
182
183 assert_eq!(33, tmp_area.country);
184 assert_eq!(14, tmp_area.carrier);
185 assert_eq!(3345, tmp_area.city);
186 assert_eq!(32, tmp_area.inner);
187 assert_eq!(area.country, tmp_area.country);
188 assert_eq!(area.carrier, tmp_area.carrier);
189 assert_eq!(area.city, tmp_area.city);
190 assert_eq!(area.inner, tmp_area.inner);
191 }
192
193 #[test]
194 fn test_str() {
195 let area = Area::from_str("333:14:3345:32").unwrap();
196 let buf = area.to_vec().unwrap();
197 let tmp_area = Area::clone_from_slice(buf.as_slice()).unwrap();
198
199 assert_eq!(333, tmp_area.country);
200 assert_eq!(14, tmp_area.carrier);
201 assert_eq!(3345, tmp_area.city);
202 assert_eq!(32, tmp_area.inner);
203 assert_eq!(area.country, tmp_area.country);
204 assert_eq!(area.carrier, tmp_area.carrier);
205 assert_eq!(area.city, tmp_area.city);
206 assert_eq!(area.inner, tmp_area.inner);
207 }
208
209 #[test]
210 fn test_object_id() {
211 let area = Area::from_str("334:15:3345:32").unwrap();
212 let private_key = PrivateKey::generate_rsa(1024).unwrap();
213 let people: People = People::new(
214 None,
215 Vec::new(),
216 private_key.public(),
217 Some(area.clone()),
218 None,
219 None,
220 )
221 .build();
222 let people_id = people.desc().calculate_id();
223 let people_data = people.to_vec().unwrap();
224 let new_people = People::clone_from_slice(people_data.as_slice()).unwrap();
225 let new_people_id = new_people.desc().calculate_id();
226 assert_eq!(people_id, new_people_id);
227 let id_info = people_id.info();
228 if let ObjectIdInfo::Standard(obj) = id_info {
229 let tmp_area = obj.area.unwrap();
230 assert_eq!(334, tmp_area.country);
231 assert_eq!(15, tmp_area.carrier);
232 assert_eq!(3345, tmp_area.city);
233 assert_eq!(32, tmp_area.inner);
234 assert_eq!(area.country, tmp_area.country);
235 assert_eq!(area.carrier, tmp_area.carrier);
236 assert_eq!(area.city, tmp_area.city);
237 assert_eq!(area.inner, tmp_area.inner);
238 } else {
239 assert!(false);
240 }
241
242 let area = Area::from_str("3333:10:3345:32");
243 assert!(area.is_err());
244 let area = Area::from_str("333:17:3345:32");
245 assert!(area.is_err());
246 let area = Area::from_str("333:15:8192:32");
247 assert!(area.is_err());
248 let area = Area::from_str("333:15:133345:256");
249 assert!(area.is_err());
250 }
251}