doris_rs/record/
formatting.rs1use crate::{
2 error::FormattingError,
3 prelude::{EpochFlag, Header, Record},
4};
5
6use itertools::Itertools;
7
8use std::io::{BufWriter, Write};
9
10impl Record {
11 pub fn format<W: Write>(
14 &self,
15 writer: &mut BufWriter<W>,
16 header: &Header,
17 ) -> Result<(), FormattingError> {
18 let num_observables = header.observables.len();
19
20 for (key, measurement) in self.measurements.iter() {
22 let (year, month, day, hours, mins, secs, nanos) =
23 key.epoch.to_gregorian(key.epoch.time_scale);
24
25 write!(
26 writer,
27 "> {:04} {:02} {:02} {:02} {:02} {:02}.{:09} {}",
28 year, month, day, hours, mins, secs, nanos, key.flag
29 )?;
30
31 let num_stations = measurement
33 .observations
34 .keys()
35 .map(|k| k.station.code)
36 .unique()
37 .count();
38
39 write!(writer, "{:3}", num_stations)?;
40
41 if let Some(clock_offset) = measurement.satellite_clock_offset {
43 write!(
44 writer,
45 " {:.9} {}\n",
46 clock_offset.offset.to_seconds(),
47 clock_offset.extrapolated as u8
48 )?;
49 } else {
50 write!(writer, "\n")?;
51 }
52
53 match key.flag {
54 EpochFlag::OK | EpochFlag::PowerFailure => {
55 for station_id in measurement
56 .observations
57 .keys()
58 .map(|k| k.station.code)
59 .unique()
60 .sorted()
61 {
62 write!(writer, "D{:02}", station_id)?;
63
64 for (nth_observable, observable) in header.observables.iter().enumerate() {
66 if let Some(observation) = measurement
67 .observations
68 .iter()
69 .filter_map(|(k, v)| {
70 if k.station.code == station_id && k.observable == *observable {
71 Some(v)
72 } else {
73 None
74 }
75 })
76 .reduce(|k, _| k)
77 {
78 write!(writer, "{:14.3} ", observation.value)?;
79 } else {
80 write!(writer, " ")?;
81 }
82
83 if nth_observable == num_observables - 1 {
84 write!(writer, "\n")?;
85 } else {
86 if (nth_observable % 5) == 4 {
87 write!(writer, "\n ")?;
88 }
89 }
90 }
91 }
92 },
93 _ => {
94 },
96 }
97 }
98
99 Ok(())
100 }
101}