use crate::{error::ParsingError, fmt_doris, prelude::FormattingError};
use std::{
io::{BufWriter, Write},
str::FromStr,
};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Default, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Receiver {
pub model: String,
pub serial_number: String,
pub firmware: String,
}
impl Receiver {
pub(crate) fn format<W: Write>(&self, w: &mut BufWriter<W>) -> Result<(), FormattingError> {
writeln!(
w,
"{}",
fmt_doris(
&format!(
"{:<20}{:<20}{}",
self.serial_number, self.model, self.firmware
),
"REC # / TYPE / VERS"
)
)?;
Ok(())
}
pub fn with_model(&self, model: &str) -> Self {
let mut s = self.clone();
s.model = model.to_string();
s
}
pub fn with_serial_number(&self, serial_number: &str) -> Self {
let mut s = self.clone();
s.serial_number = serial_number.to_string();
s
}
pub fn with_firmware(&self, firmware: &str) -> Self {
let mut s = self.clone();
s.firmware = firmware.to_string();
s
}
}
impl FromStr for Receiver {
type Err = ParsingError;
fn from_str(line: &str) -> Result<Self, Self::Err> {
if line.len() < 60 {
return Err(ParsingError::Receiver);
}
let (sn, rem) = line.split_at(20);
let (model, rem) = rem.split_at(20);
let (version, _) = rem.split_at(20);
Ok(Receiver {
serial_number: sn.trim().to_string(),
model: model.trim().to_string(),
firmware: version.trim().to_string(),
})
}
}
#[cfg(test)]
mod test {
use super::*;
use std::str::FromStr;
#[test]
fn receiver_parsing() {
let content = "2090088 LEICA GR50 4.51 ";
let rcvr = Receiver::from_str(content).unwrap();
assert_eq!(rcvr.model, "LEICA GR50");
assert_eq!(rcvr.firmware, "4.51");
assert_eq!(rcvr.serial_number, "2090088");
}
}