use super::FormatError;
use std::io::{BufRead, BufReader, Read};
use std::path::Path;
#[derive(Debug, Default, Clone, PartialEq)]
pub struct VgosDbHeader {
pub session_code: String,
pub start_epoch: String,
pub stations: Vec<String>,
}
pub fn read_vgosdb(_path: &Path) -> Result<VgosDbHeader, FormatError> {
Err(FormatError::Unsupported(
"vgosDB binary NetCDF reader is out of scope for siderust core; use the text side-car path"
.to_string(),
))
}
pub fn read_vgosdb_sidecar<R: Read>(reader: R) -> Result<VgosDbHeader, FormatError> {
let mut buf = BufReader::new(reader);
let mut line = String::new();
let mut out = VgosDbHeader::default();
let mut line_no = 0usize;
while {
line.clear();
buf.read_line(&mut line)? > 0
} {
line_no += 1;
let l = line.trim();
if l.is_empty() || l.starts_with('#') {
continue;
}
let (k, v) = l
.split_once('=')
.ok_or_else(|| FormatError::Format(format!("line {line_no}: expected key=value")))?;
match k.trim() {
"session_code" => out.session_code = v.trim().to_string(),
"start_epoch" => out.start_epoch = v.trim().to_string(),
"stations" => {
out.stations = v
.split(',')
.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())
.collect()
}
other => {
return Err(FormatError::Format(format!(
"line {line_no}: unknown key `{other}`"
)))
}
}
}
Ok(out)
}
pub type VgosDb = VgosDbHeader;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn read_vgosdb_returns_unsupported() {
assert!(matches!(
read_vgosdb(Path::new("/none")),
Err(FormatError::Unsupported(_))
));
}
#[test]
fn sidecar_parses_session_block() {
let buf = b"# header\nsession_code=R1100\nstart_epoch=2024-01-01T00:00:00\nstations=KOKEE, WETTZELL\n";
let h = read_vgosdb_sidecar(&buf[..]).unwrap();
assert_eq!(h.session_code, "R1100");
assert_eq!(h.start_epoch, "2024-01-01T00:00:00");
assert_eq!(
h.stations,
vec!["KOKEE".to_string(), "WETTZELL".to_string()]
);
}
#[test]
fn sidecar_rejects_malformed_lines() {
let buf = b"no_equals_here\n";
assert!(matches!(
read_vgosdb_sidecar(&buf[..]),
Err(FormatError::Format(_))
));
}
#[test]
fn sidecar_rejects_unknown_keys() {
let buf = b"some_other_key=value\n";
assert!(matches!(
read_vgosdb_sidecar(&buf[..]),
Err(FormatError::Format(_))
));
}
}