use nom::bytes::complete::take;
use nom::IResult;
use rand::Rng;
use std::fmt::Display;
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
pub struct Bsb {
pub first: String,
pub sep: String,
pub second: String,
}
impl Bsb {
pub fn deserialise(i: &str) -> IResult<&str, Self> {
let (i, first) = take(3u8)(i)?;
let (i, sep) = take(1u8)(i)?;
let (i, second) = take(3u8)(i)?;
let bsb = Self {
first: first.to_string(),
sep: sep.to_string(),
second: second.to_string(),
};
Ok((i, bsb))
}
}
impl Display for Bsb {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "{}{}{}", self.first, self.sep, self.second)
}
}
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
pub struct TwoDigitYears {
pub day: String,
pub month: String,
pub year: String,
}
impl TwoDigitYears {
pub fn deserialise(i: &str) -> IResult<&str, String> {
let mut rng = rand::thread_rng();
let (i, day) = take(2u8)(i)?;
let (i, month) = take(2u8)(i)?;
let (i, year) = take(2u8)(i)?;
Ok((
i,
format!(
"{}{}{}{}{}",
day,
month,
rng.gen_range(1i32..=9i32),
rng.gen_range(1i32..=9i32),
year
),
))
}
}
impl Display for TwoDigitYears {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "{}{}{}", self.day, self.month, self.year)
}
}
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
pub struct TotalField {
pub total: String,
pub credit: String,
pub debit: String,
}
impl TotalField {
pub fn deserialise(i: &str) -> IResult<&str, Self> {
let (i, total) = take(10u8)(i)?;
let (i, credit) = take(10u8)(i)?;
let (i, debit) = take(10u8)(i)?;
let total_field = Self {
total: total.to_string(),
credit: credit.to_string(),
debit: debit.to_string(),
};
Ok((i, total_field))
}
}
impl Display for TotalField {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "{}{}{}", self.total, self.credit, self.debit)
}
}
#[test]
fn test_bsb() {
let bsb: &str = "063-000";
let (_, result) = Bsb::deserialise(&bsb).unwrap();
assert_eq!(result.first, "063");
}
#[test]
fn test_2dy() {
let date: &str = "280222";
let (_, result) = TwoDigitYears::deserialise(&date).unwrap();
let (first, second) = result.split_at(4);
let (_, last) = second.split_at(2);
assert_eq!(first, "2802");
assert_eq!(last, "22");
}
#[test]
fn test_total_field() {
let total: &str = "000312924700031292470000000000";
let (_, result) = TotalField::deserialise(&total).unwrap();
assert_eq!(result.total, "0003129247");
}