datex_core/datex_values/primitives/
endpoint.rs1use regex::Regex;
2
3use crate::{utils::{buffers::{self, append_u8, append_u16, read_u8, read_slice, read_u16}, color::Color}};
4
5#[derive(Debug, Clone, PartialEq)]
6pub enum EndpointType {
7 Id,
8 PersonAlias,
9 InstitutionAlias
10}
11
12
13#[derive(Debug, Clone, PartialEq)]
14pub struct Endpoint {
15 name: String,
16 endpoint_type: EndpointType,
17 instance: u16,
18 binary: Vec<u8> }
20
21impl Endpoint {
22
23 pub const ANY_INSTANCE:u16 = 0;
24
25 pub fn new(name_binary:&Vec<u8>, instance: u16) -> Endpoint {
27 let mut name = buffers::buffer_to_hex(name_binary.to_vec());
28 name = Regex::new(r"(00)*$").unwrap().replace_all(&name, "").to_string();
29 if name == "" { name = "local".to_string() }
30 else if name == "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" { name = "any".to_string() }
31
32 Endpoint {
33 name,
34 endpoint_type: EndpointType::Id,
35 instance,
36 binary: Self::to_binary(EndpointType::Id, name_binary, instance)
37 }
38 }
39
40 pub fn new_person(name:&str, instance: u16) -> Endpoint {
42 Endpoint {
43 name: name.trim_matches(char::from(0)).to_string(),
44 endpoint_type: EndpointType::PersonAlias,
45 instance,
46 binary: Self::to_binary(EndpointType::PersonAlias, &Self::encode_name_binary(name.to_string()), instance)
47 }
48 }
49
50 pub fn new_institution(name:&str, instance: u16) -> Endpoint {
52 Endpoint {
53 name: name.trim_matches(char::from(0)).to_string(),
54 endpoint_type: EndpointType::InstitutionAlias,
55 instance,
56 binary: Self::to_binary(EndpointType::InstitutionAlias, &Self::encode_name_binary(name.to_string()), instance)
57 }
58 }
59
60 pub fn new_from_binary(binary:&Vec<u8>) -> Endpoint {
61 let index = &mut 0;
62 let endpoint_type_bin = read_u8(binary, index);
63 let endpoint_type = match endpoint_type_bin {
64 2 => EndpointType::InstitutionAlias,
65 1 => EndpointType::PersonAlias,
66 _ => EndpointType::Id
67 };
68
69 let name = &read_slice(binary, index, 18);
70 let instance = read_u16(binary, index);
71
72 match endpoint_type {
73 EndpointType::InstitutionAlias => Self::new_institution(&Self::decode_name_binary(name), instance),
74 EndpointType::PersonAlias => Self::new_person(&Self::decode_name_binary(name), instance),
75 EndpointType::Id => Self::new(name, instance)
76 }
77
78 }
79
80
81 fn encode_name_binary(name: String) -> Vec<u8> {
83 if name.len()>18 {
84 panic!("Endpoint name exceeds maximum of 18 bytes");
85 }
86 return String::into_bytes(name);
88 }
89
90 fn decode_name_binary(name_binary: &Vec<u8>) -> String {
92 if name_binary.len()>18 {
93 panic!("Endpoint name exceeds maximum of 18 bytes");
94 }
95
96 let name_utf8 = String::from_utf8(name_binary.to_vec()).expect("could not read endpoint name");
97 return name_utf8.trim_matches(char::from(0)).to_string();
99 }
100
101
102 fn to_binary(endpoint_type: EndpointType, name_binary:&Vec<u8>, instance: u16) -> Vec<u8> {
105 if name_binary.len()>18 { panic!("Endpoint name exceeds maximum of 18 bytes");
107 }
108 let name_sized = &mut name_binary.to_vec();
109 name_sized.resize(18, 0);
110 let binary = &mut Vec::<u8>::with_capacity(21);
111
112 append_u8(binary, endpoint_type as u8);
113 binary.extend_from_slice(name_sized);
114 append_u16(binary, instance);
115
116 return binary.to_vec()
117 }
118
119
120 pub fn get_binary(&self) -> &Vec<u8>{
121 return &self.binary;
122 }
123
124 pub fn get_type(&self) -> &EndpointType {
125 return &self.endpoint_type;
126 }
127
128 pub fn get_instance(&self) -> u16 {
129 return self.instance;
130 }
131
132 pub fn to_string(&self, colorized:bool) -> String {
133 let mut main = match self.endpoint_type {
134 EndpointType::Id => format!("{}@@{}", (if colorized {Color::ENDPOINT.as_ansi_rgb()} else {"".to_string()}), self.name),
135 EndpointType::PersonAlias => format!("{}@{}", (if colorized {Color::EndpointPerson.as_ansi_rgb()} else {"".to_string()}), self.name),
136 EndpointType::InstitutionAlias => format!("{}@+{}", (if colorized {Color::EndpointInstitution.as_ansi_rgb()} else {"".to_string()}), self.name)
137 };
138 if self.instance != Endpoint::ANY_INSTANCE {
148 main += &format!("/{:04X}", self.instance);
149 }
150
151 return main;
152 }
153
154}