1use crate::error::Converter;
2use crate::Result;
3use roxmltree::Node;
4
5#[derive(Clone, Debug)]
7pub struct DateTime {
8    pub gps_time: f64,
10    pub atomic_reference: bool,
12}
13
14impl DateTime {
15    pub(crate) fn from_node(node: &Node) -> Result<Option<Self>> {
16        let gps_time_text = node
17            .children()
18            .find(|n| n.has_tag_name("dateTimeValue") && n.attribute("type") == Some("Float"))
19            .invalid_err("Unable to find XML tag 'dateTimeValue' with type 'Float'")?
20            .text();
21        let gps_time = if let Some(text) = gps_time_text {
22            text.parse::<f64>()
23                .invalid_err("Failed to parse inner text of XML tag 'dateTimeValue' as double")?
24        } else {
25            return Ok(None);
26        };
27
28        let atomic_reference_node = node.children().find(|n| {
29            n.has_tag_name("isAtomicClockReferenced") && n.attribute("type") == Some("Integer")
30        });
31        let atomic_reference = if let Some(node) = atomic_reference_node {
32            node.text().unwrap_or("0").trim() == "1"
33        } else {
34            return Ok(None);
35        };
36
37        Ok(Some(Self {
38            gps_time,
39            atomic_reference,
40        }))
41    }
42
43    pub(crate) fn xml_string(&self, tag_name: &str) -> String {
44        let mut xml = String::new();
45        xml += &format!("<{tag_name} type=\"Structure\">\n");
46        xml += &format!(
47            "<dateTimeValue type=\"Float\">{}</dateTimeValue>\n",
48            self.gps_time
49        );
50        xml += &format!(
51            "<isAtomicClockReferenced type=\"Integer\">{}</isAtomicClockReferenced>\n",
52            if self.atomic_reference { "1" } else { "0" }
53        );
54        xml += &format!("</{tag_name}>\n");
55        xml
56    }
57}