graph6_rs/
write.rs

1use crate::{utils::upper_triangle, GraphConversion};
2
3/// Trait to write graphs into graph 6 formatted strings
4pub trait WriteGraph: GraphConversion {
5    fn write_graph(&self) -> String {
6        write_graph6(self.bit_vec().to_vec(), self.size(), self.is_directed())
7    }
8}
9
10fn write_header(repr: &mut String, is_directed: bool) {
11    if is_directed {
12        repr.push('&');
13    }
14}
15
16fn write_size(repr: &mut String, size: usize) {
17    let size_char = char::from_u32(size as u32 + 63).unwrap();
18    repr.push(size_char);
19}
20
21fn pad_bitvector(bit_vec: &mut Vec<usize>) {
22    if bit_vec.len() % 6 != 0 {
23        (0..6 - (bit_vec.len() % 6)).for_each(|_| bit_vec.push(0));
24    }
25}
26
27fn parse_bitvector(bit_vec: &[usize], repr: &mut String) {
28    for chunk in bit_vec.chunks(6) {
29        let mut sum = 0;
30        for (i, bit) in chunk.iter().rev().enumerate() {
31            sum += bit * 2usize.pow(i as u32);
32        }
33        let char = char::from_u32(sum as u32 + 63).unwrap();
34        repr.push(char);
35    }
36}
37
38pub fn write_graph6(bit_vec: Vec<usize>, n: usize, is_directed: bool) -> String {
39    let mut repr = String::new();
40    let mut bit_vec = if is_directed {
41        bit_vec
42    } else {
43        upper_triangle(&bit_vec, n)
44    };
45    write_header(&mut repr, is_directed);
46    write_size(&mut repr, n);
47    pad_bitvector(&mut bit_vec);
48    parse_bitvector(&bit_vec, &mut repr);
49    repr
50}
51
52#[cfg(test)]
53mod testing {
54
55    #[test]
56    fn test_write_undirected_n2() {
57        let bit_vec = vec![0, 1, 1, 0];
58        let repr = super::write_graph6(bit_vec, 2, false);
59        assert_eq!(repr, "A_");
60    }
61
62    #[test]
63    fn test_write_directed_n2_mirror() {
64        let bit_vec = vec![0, 1, 1, 0];
65        let repr = super::write_graph6(bit_vec, 2, true);
66        assert_eq!(repr, "&AW");
67    }
68
69    #[test]
70    fn test_write_directed_n2_unmirrored() {
71        let bit_vec = vec![0, 0, 1, 0];
72        let repr = super::write_graph6(bit_vec, 2, true);
73        assert_eq!(repr, "&AG");
74    }
75}