honeycomb_core/cmap/dim3/
serialize.rs

1use crate::{
2    cmap::{CMap3, DartIdType},
3    geometry::CoordsFloat,
4};
5
6/// **Serialization methods**
7impl<T: CoordsFloat> CMap3<T> {
8    // --- Custom
9
10    /// Serialize the map under a custom format.
11    ///
12    /// The format specification is described in the [user guide]().
13    ///
14    /// # Panics
15    ///
16    /// This method may panic if there was an error trying to open / write to the file.
17    pub fn serialize(&self, mut writer: impl std::fmt::Write) {
18        let n_darts = self.n_darts();
19
20        writeln!(writer, "[META]").expect("E: couldn't write to file");
21        writeln!(
22            writer,
23            "{} {} {}",
24            env!("CARGO_PKG_VERSION"), // indicates which version was used to generate the file
25            3,
26            n_darts - 1
27        )
28        .expect("E: couldn't write to file");
29        writeln!(writer).expect("E: couldn't write to file"); // not required, but nice
30
31        writeln!(writer, "[BETAS]").expect("E: couldn't write to file");
32        let width = n_darts.to_string().len();
33        let mut b0 = String::with_capacity(self.n_darts() * 2);
34        let mut b1 = String::with_capacity(self.n_darts() * 2);
35        let mut b2 = String::with_capacity(self.n_darts() * 2);
36        let mut b3 = String::with_capacity(self.n_darts() * 2);
37        std::thread::scope(|s| {
38            s.spawn(|| {
39                // convoluted bc this prevents ephemeral allocs
40                use std::fmt::Write;
41                let mut buf = String::new();
42                (0..n_darts as DartIdType).for_each(|d| {
43                    write!(&mut buf, "{:>width$} ", self.beta::<0>(d)).unwrap();
44                    b0.push_str(buf.as_str());
45                    buf.clear();
46                });
47            });
48            s.spawn(|| {
49                // convoluted bc this prevents ephemeral allocs
50                use std::fmt::Write;
51                let mut buf = String::new();
52                (0..n_darts as DartIdType).for_each(|d| {
53                    write!(&mut buf, "{:>width$} ", self.beta::<1>(d)).unwrap();
54                    b1.push_str(buf.as_str());
55                    buf.clear();
56                });
57            });
58            s.spawn(|| {
59                // convoluted bc this prevents ephemeral allocs
60                use std::fmt::Write;
61                let mut buf = String::new();
62                (0..n_darts as DartIdType).for_each(|d| {
63                    write!(&mut buf, "{:>width$} ", self.beta::<2>(d)).unwrap();
64                    b2.push_str(buf.as_str());
65                    buf.clear();
66                });
67            });
68            s.spawn(|| {
69                // convoluted bc this prevents ephemeral allocs
70                use std::fmt::Write;
71                let mut buf = String::new();
72                (0..n_darts as DartIdType).for_each(|d| {
73                    write!(&mut buf, "{:>width$} ", self.beta::<3>(d)).unwrap();
74                    b3.push_str(buf.as_str());
75                    buf.clear();
76                });
77            });
78        });
79        writeln!(writer, "{}", b0.trim()).expect("E: couldn't write to file");
80        writeln!(writer, "{}", b1.trim()).expect("E: couldn't write to file");
81        writeln!(writer, "{}", b2.trim()).expect("E: couldn't write to file");
82        writeln!(writer, "{}", b3.trim()).expect("E: couldn't write to file");
83        writeln!(writer).expect("E: couldn't write to file"); // not required, but nice
84
85        writeln!(writer, "[UNUSED]").expect("E: couldn't write to file");
86        self.unused_darts
87            .iter()
88            .enumerate()
89            .filter(|(_, v)| v.read_atomic())
90            .for_each(|(i, _)| {
91                write!(writer, "{i} ").unwrap();
92            });
93        writeln!(writer).expect("E: couldn't write to file"); // required
94        writeln!(writer).expect("E: couldn't write to file"); // not required, but nice
95
96        writeln!(writer, "[VERTICES]").expect("E: couldn't write to file");
97        self.iter_vertices().for_each(|v| {
98            if let Some(val) = self.force_read_vertex(v) {
99                writeln!(
100                    writer,
101                    "{v} {} {} {}",
102                    val.0
103                        .to_f64()
104                        .expect("E: unreachable, unless experimenting with f128"),
105                    val.1
106                        .to_f64()
107                        .expect("E: unreachable, unless experimenting with f128"),
108                    val.2
109                        .to_f64()
110                        .expect("E: unreachable, unless experimenting with f128"),
111                )
112                .expect("E: couldn't write to file");
113            }
114        });
115    }
116}