pub struct Row { name: String, hut_type: String, path: String, tare: f64, mat_id: String, quantity: f64, lot_id: String, uom: String, lot_status: String, born: chrono::DateTime, expire: chrono::DateTime, } impl Row { const DF: &str = "%Y-%m-%d %H:%M"; pub fn new( name: &str, hut_type: &str, path: &str, tare: f64, mat_id: &str, quantity: f64, uom: &str, lot_status: &str, checksum: bool, ) -> Self { let born = chrono::Local::now(); let expire = born .checked_add_days(chrono::Days::new(365)) .expect("A valid date time"); let name = match checksum { true => make_checksum(), false => name.to_ascii_uppercase(), }; Self { name: name.clone(), hut_type: hut_type.to_ascii_uppercase(), path: path.to_ascii_uppercase(), tare, mat_id: mat_id.to_ascii_uppercase(), quantity, lot_id: format!("{}-{}", name, mat_id).to_ascii_uppercase(), uom: uom.to_ascii_uppercase(), lot_status: lot_status.to_ascii_uppercase(), born, expire, } } } fn make_checksum() -> String { let base = rand::random_range(10000..99999).to_string(); let expect = "a valid character in the base checksum"; let split = format!( "{}{}{}{}{}", base.chars().next().expect(expect), base.chars().nth(2).expect(expect), base.chars().nth(4).expect(expect), base.chars().nth(1).expect(expect), base.chars().nth(3).expect(expect) ) .repeat(2); let sum: u32 = split .chars() .map(|c| c.to_digit(10).expect("a valid integer value")) .sum(); let last = (10 - (sum % 10)) % 10; format!("{}{}", base, last) } impl std::fmt::Display for Row { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, "{},{},{},{},{},N,{},{},{},{},{},{},{},{}", self.name, self.name, self.hut_type, self.path, self.tare, self.mat_id, self.quantity, self.lot_id, self.uom, self.lot_status, self.born.format(Self::DF), self.born.format(Self::DF), self.expire.format(Self::DF), ) } }