cot_proto/
lib.rs

1//! Simple Cursor on Target (CoT) (de)serialization library.
2//!
3//! Provides struct definitions and utilities which use
4//! [quick_xml](https://github.com/tafia/quick-xml) to handle conversion to/from XML text.
5//!
6//! The CoT base schema is represented by the [base::Cot] struct. You can either provide your own
7//! type for the detail section of the CoT message, or you can use [detail::parse()] to skip
8//! parsing the section and instead get raw XML text. What we really want is a dynamic type,
9//! analogous to [serde_json::Value](https://docs.rs/serde_json/latest/serde_json/enum.Value.html),
10//! but I haven't found anything similar for XML.
11//!
12
13use thiserror::Error;
14pub mod base;
15pub mod detail;
16pub mod examples;
17#[cfg(feature = "tak")]
18pub mod tak;
19
20#[derive(Debug, Error)]
21pub enum Error {
22    #[error("message field error: {0}")]
23    BadField(&'static str),
24
25    #[error(transparent)]
26    IoError(#[from] std::io::Error),
27    #[error(transparent)]
28    XmlAttr(#[from] quick_xml::events::attributes::AttrError),
29    #[error(transparent)]
30    Xml(#[from] quick_xml::errors::Error),
31    #[error(transparent)]
32    De(#[from] quick_xml::de::DeError),
33}
34
35#[cfg(test)]
36mod test {
37    use quick_xml::events::Event;
38
39    use crate::examples::COT_TRACK_EXAMPLE;
40
41    #[test]
42    fn test_fastxml_extract() {
43        let mut reader = quick_xml::Reader::from_reader(COT_TRACK_EXAMPLE.as_bytes());
44        reader.config_mut().trim_text(true);
45        let mut detail: Vec<String> = vec![];
46        let mut is_detail = false;
47        loop {
48            match reader.read_event() {
49                Ok(Event::Start(ref e)) => {
50                    if e.name().as_ref() == b"detail" {
51                        is_detail = true;
52                    }
53                }
54                Ok(Event::Empty(ref e)) => {
55                    if is_detail {
56                        detail.push(String::from_utf8_lossy(e).to_string());
57                    }
58                }
59                Ok(Event::Text(_e)) => {
60                    //println!("Event::Text: {:?}", e);
61                }
62                Ok(Event::End(ref e)) => {
63                    if e.name().as_ref() == b"detail" {
64                        is_detail = false;
65                    }
66                }
67                Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e),
68                Ok(Event::Eof) => break,
69                _ => println!("Event: {:?}", reader.read_event()),
70            }
71        }
72    }
73}