use std::fmt;
#[derive(Debug, Default, PartialEq)]
pub struct Metadata {
pub redcode: Option<String>,
pub name: Option<String>,
pub author: Option<String>,
pub date: Option<String>,
pub version: Option<String>,
pub strategy: Option<String>,
pub assertion: Option<String>,
}
impl Metadata {
pub fn parse_line(&mut self, line: &str) -> String {
let split_line: Vec<&str> = line.splitn(2, ';').map(|p| p.trim()).collect();
if split_line.len() > 1 {
let split_comment: Vec<&str> = split_line[1].splitn(2, char::is_whitespace).collect();
let value = Some(
split_comment
.get(1)
.map_or_else(String::new, |s| s.trim().to_owned()),
);
let directive = split_comment[0].to_lowercase();
match directive.as_ref() {
"redcode" => self.redcode = value,
"name" => self.name = value,
"author" => self.author = value,
"date" => self.date = value,
"version" => self.version = value,
"strategy" => self.strategy = value,
"assert" => self.assertion = value,
_ => (),
}
}
split_line[0].trim().to_string()
}
}
impl fmt::Display for Metadata {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
for (field, name) in &[
(&self.redcode, "redcode"),
(&self.name, "name"),
(&self.author, "author"),
(&self.version, "version"),
(&self.date, "date"),
(&self.strategy, "strategy"),
(&self.assertion, "assert"),
] {
if let Some(value) = field.as_deref() {
if value.is_empty() {
writeln!(formatter, ";{}", name)?;
} else {
writeln!(formatter, ";{} {}", name, value)?;
}
}
}
Ok(())
}
}