use std::fmt::Display;
use std::str::FromStr;
use crate::record::Precision;
use crate::ParseError;
#[derive(Debug, Clone, PartialEq)]
pub enum GlobalProperty {
DataSource(String),
DataRecorder(String),
ReferenceTime(String),
RecordingTime(String),
Author(String),
Title(String),
Category(String),
Briefing(String),
Debriefing(String),
Comments(String),
ReferenceLongitude(f64),
ReferenceLatitude(f64),
Unknown(String, String),
}
impl FromStr for GlobalProperty {
type Err = ParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let (name, value) = s.split_once('=').ok_or(ParseError::MissingDelimiter('='))?;
Ok(match name {
"DataSource" => Self::DataSource(value.to_string()),
"DataRecorder" => Self::DataRecorder(value.to_string()),
"ReferenceTime" => Self::ReferenceTime(value.to_string()),
"RecordingTime" => Self::RecordingTime(value.to_string()),
"Author" => Self::Author(value.to_string()),
"Title" => Self::Title(value.to_string()),
"Category" => Self::Category(value.to_string()),
"Briefing" => Self::Briefing(value.to_string()),
"Debriefing" => Self::Debriefing(value.to_string()),
"Comments" => Self::Comments(value.to_string()),
"ReferenceLongitude" => Self::ReferenceLongitude(value.parse()?),
"ReferenceLatitude" => Self::ReferenceLatitude(value.parse()?),
name => Self::Unknown(name.to_string(), value.to_string()),
})
}
}
impl Display for GlobalProperty {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use GlobalProperty::*;
match self {
DataSource(v) => write!(f, "0,DataSource={v}"),
DataRecorder(v) => write!(f, "0,DataRecorder={v}"),
ReferenceTime(v) => write!(f, "0,ReferenceTime={v}"),
RecordingTime(v) => write!(f, "0,RecordingTime={v}"),
Author(v) => write!(f, "0,Author={v}"),
Title(v) => write!(f, "0,Title={v}"),
Category(v) => write!(f, "0,Category={v}"),
Briefing(v) => write!(f, "0,Briefing={v}"),
Debriefing(v) => write!(f, "0,Debriefing={v}"),
Comments(v) => write!(
f,
"0,Comments={}",
v.replace("\r\n", "\\\r\n").replace('\n', "\\\n")
),
ReferenceLongitude(v) => write!(f, "0,ReferenceLongitude={}", v.max_precision(7)),
ReferenceLatitude(v) => write!(f, "0,ReferenceLatitude={}", v.max_precision(7)),
Unknown(v, _) => write!(f, "0,Unknown={v}"),
}
}
}
#[test]
fn test_multi_line_comment() {
let comment = GlobalProperty::Comments(
r#"1
2
3"#
.to_string(),
);
assert_eq!(comment.to_string(), "0,Comments=1\\\n2\\\n3");
}