1pub fn string_to_adjacency_matrix(graph_str: &str) -> (Vec<f32>, usize) {
23 let bytes = graph_str.as_bytes();
24
25 let size = size_from_bytes(bytes).unwrap_or_else(|err| {
26 panic!("{}", err);
27 });
28
29 let mut bit_vec: Vec<u8> = Vec::new();
30 bytes.iter().skip(1).map(|byte| byte - 63).for_each(|byte| {
31 for shift in (0..6).rev() {
32 if (byte & 1 << shift) > 0 {
33 bit_vec.push(1);
34 } else {
35 bit_vec.push(0);
36 }
37 }
38 });
39
40 let adjusted_bit_vec_len = bit_vec.len() - (bit_vec.len() - (size * (size - 1)) / 2);
41
42 let mut bit_vec_iter = bit_vec[0..adjusted_bit_vec_len].iter();
43
44 let mut adjacency_matrix = vec![0.0; size * size];
45 for i in 1..size {
46 for j in 0..i {
47 if *(bit_vec_iter.next().unwrap()) == 1 {
48 adjacency_matrix[i * size + j] = 1.0;
49 adjacency_matrix[j * size + i] = 1.0;
50 }
51 }
52 }
53
54 (adjacency_matrix, size)
55}
56
57pub fn adjacency_matrix_to_string(adjacency_matrix: &[f32], size: usize) -> String {
75 let mut size_bytes = size_to_bytes(size).unwrap_or_else(|err| {
76 panic!("{}", err);
77 });
78
79 let mut bit_vec = Vec::new();
80 for i in 1..size {
81 for j in 0..i {
82 if adjacency_matrix[i * size + j] == 1.0 {
83 bit_vec.push(1);
84 } else {
85 bit_vec.push(0);
86 }
87 }
88 }
89
90 let mut bytes = bit_vec_to_bytes(bit_vec);
91
92 size_bytes.append(&mut bytes);
93
94 unsafe { String::from_utf8_unchecked(size_bytes) }
95}
96
97fn int_to_bit_vec(mut x: usize) -> Vec<u8> {
99 let mut bit_vec = Vec::new();
100
101 while x != 0 {
102 if x & 1 == 1 {
103 bit_vec.push(1);
104 } else {
105 bit_vec.push(0);
106 }
107
108 x >>= 1;
109 }
110
111 bit_vec.reverse();
112
113 bit_vec
114}
115
116fn bit_vec_to_bytes(mut bit_vec: Vec<u8>) -> Vec<u8> {
118 let next_multiple_of_six = bit_vec.len() - 1 - (bit_vec.len() - 1) % 6 + 6;
120 for _ in 0..(next_multiple_of_six - bit_vec.len()) {
121 bit_vec.push(0);
122 }
123
124 let mut bytes = Vec::new();
125 let mut bit_vec_iter = bit_vec.iter();
126
127 for _ in 0..(bit_vec.len() / 6) {
128 let mut byte: u8 = 0;
129 for shift in (0..6).rev() {
130 byte |= bit_vec_iter.next().unwrap() << shift;
132 }
133 bytes.push(byte);
134 }
135
136 bytes.iter().map(|byte| byte + 63).collect()
137}
138
139fn size_from_bytes(bytes: &[u8]) -> Result<usize, &'static str> {
141 if bytes[0] == 126 {
143 return Err("size is greater than 62");
144 }
145
146 Ok((bytes[0] - 63) as usize)
147}
148
149fn size_to_bytes(size: usize) -> Result<Vec<u8>, &'static str> {
151 match size {
152 s if s <= 62 => Ok(vec![size as u8 + 63]),
153 s if s <= 258047 => {
154 let mut size_bytes = vec![126];
155 size_bytes.append(&mut bit_vec_to_bytes(int_to_bit_vec(size)));
156 Ok(size_bytes)
157 }
158 _ => Err("size is greater than 258,047"),
159 }
160}
161
162#[cfg(test)]
163mod tests {
164 use super::*;
165
166 #[test]
167 fn size_four_graph_to_adjacency_matrix() {
168 let graph_str = String::from("C]");
169
170 let (adjacency_matrix, size) = string_to_adjacency_matrix(&graph_str);
171
172 assert_eq!(
173 adjacency_matrix,
174 vec![0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0]
175 );
176 assert_eq!(size, 4);
177 }
178
179 #[test]
180 fn size_120000_to_bytes() {
181 let size = 120000;
182 let bytes = vec![126, 121, 101, 63];
183
184 assert_eq!(size_to_bytes(size).unwrap(), bytes);
185 }
186}