wtx 0.44.2

A collection of different transport implementations and related tools focused primarily on web technologies.
Documentation
use crate::calendar::{Duration, Hour, Sixty, Time, nanosecond::Nanosecond};

fn _8_48_05_234_445_009() -> Time {
  Time::from_hms_ns(Hour::N8, Sixty::N48, Sixty::N5, Nanosecond::from_num(234_445_009).unwrap())
}

fn _14_20_30() -> Time {
  Time::from_hms(Hour::N14, Sixty::N20, Sixty::N30)
}

#[test]
fn hour() {
  assert_eq!(Time::ZERO.hour().num(), 0);
  assert_eq!(Time::MAX.hour().num(), 23);
  assert_eq!(_8_48_05_234_445_009().hour().num(), 8);
  assert_eq!(_14_20_30().hour().num(), 14);
}

#[test]
fn iso8601() {
  assert_eq!(Time::ZERO.iso8601().as_str(), "00:00:00");
  assert_eq!(Time::MAX.iso8601().as_str(), "23:59:59.999999999");
  assert_eq!(_8_48_05_234_445_009().iso8601().as_str(), "08:48:05.234445009");
  assert_eq!(_14_20_30().iso8601().as_str(), "14:20:30");

  let valid = [
    "09:08:07",
    "09:08:07.1",
    "09:08:07.12",
    "09:08:07.123",
    "09:08:07.123",
    "09:08:07.1234",
    "09:08:07.12345",
    "09:08:07.123456",
    "09:08:07.1234567",
    "09:08:07.12345678",
    "09:08:07.123456789",
  ];
  for str in valid {
    let time = Time::from_iso8601(str.as_bytes()).unwrap();
    let time_str = time.iso8601();
    assert_eq!(time, Time::from_iso8601(time_str.as_bytes()).unwrap());
  }

  let invalid = [
    "",
    "x",
    "15",
    "15:8:",
    "15:8:x",
    "15:8:9x",
    "23:59:61",
    "23:54:35 GMT",
    "23:54:35 +0000",
    "1441497364.649",
    "+1441497364.649",
    "+1441497364",
    "001:02:03",
    "01:002:03",
    "01:02:003",
    "12:34:56.x",
    "12:34:56. 0",
    "09:08:00000000007",
  ];
  for str in invalid {
    assert!(Time::from_iso8601(str.as_bytes()).is_err());
  }
}

#[test]
fn minute() {
  assert_eq!(Time::ZERO.minute().num(), 0);
  assert_eq!(Time::MAX.minute().num(), 59);
  assert_eq!(_8_48_05_234_445_009().minute().num(), 48);
  assert_eq!(_14_20_30().minute().num(), 20);
}

#[test]
fn nanosecond() {
  assert_eq!(Time::ZERO.nanosecond().num(), 0);
  assert_eq!(Time::MAX.nanosecond().num(), 999_999_999);
  assert_eq!(_8_48_05_234_445_009().nanosecond().num(), 234_445_009);
  assert_eq!(_14_20_30().nanosecond().num(), 0);
}

#[test]
fn overflowing_add_and_sub() {
  macro_rules! test {
    ($lhs:expr, $rhs:expr, $rslt:expr) => {{
      let (this, rem) = $rslt;
      assert_eq!($lhs.overflowing_add($rhs), (this, rem));
      assert_eq!($lhs.overflowing_sub($rhs.neg()), (this, -rem));
    }};
  }

  test!(
    instance(0, 0, 0, 0),
    Duration::from_milliseconds(-990),
    (instance(23, 59, 59, 10), -86_400)
  );
  test!(
    instance(0, 0, 0, 0),
    Duration::from_milliseconds(-9990),
    (instance(23, 59, 50, 10), -86_400)
  );
  test!(
    instance(3, 4, 5, 678),
    Duration::from_hours(-7).unwrap(),
    (instance(20, 4, 5, 678), -86_400)
  );
  test!(instance(3, 4, 5, 678), Duration::from_hours(11).unwrap(), (instance(14, 4, 5, 678), 0));
  test!(
    instance(3, 4, 5, 678),
    Duration::from_hours(23).unwrap(),
    (instance(2, 4, 5, 678), 86_400)
  );
  test!(
    instance(3, 5, 59, 900),
    Duration::from_days(12345).unwrap(),
    (instance(3, 5, 59, 900), 1_066_608_000)
  );
  test!(instance(3, 5, 59, 900), Duration::from_milliseconds(100), (instance(3, 6, 0, 0), 0));
  test!(
    instance(3, 5, 59, 900),
    Duration::from_seconds(-86399).unwrap(),
    (instance(3, 6, 0, 900), -86_400)
  );
  test!(
    instance(3, 5, 59, 900),
    Duration::from_seconds(86399).unwrap(),
    (instance(3, 5, 58, 900), 86_400)
  );
  test!(instance(3, 5, 59, 900), Duration::ZERO, (instance(3, 5, 59, 900), 0));
}

#[test]
fn second() {
  assert_eq!(Time::ZERO.second().num(), 0);
  assert_eq!(Time::MAX.second().num(), 59);
  assert_eq!(_8_48_05_234_445_009().second().num(), 5);
  assert_eq!(_14_20_30().second().num(), 30);
}

#[test]
fn seconds_from_mn() {
  assert_eq!(Time::ZERO.seconds_since_mn(), 0);
  assert_eq!(Time::MAX.seconds_since_mn(), 86_399);
  assert_eq!(_8_48_05_234_445_009().seconds_since_mn(), 28800 + 2880 + 5);
  assert_eq!(_14_20_30().seconds_since_mn(), 50400 + 1200 + 30);
}

fn instance(h: u8, m: u8, s: u8, ms: u16) -> Time {
  Time::from_hms_ms(
    h.try_into().unwrap(),
    m.try_into().unwrap(),
    s.try_into().unwrap(),
    ms.try_into().unwrap(),
  )
}