Skip to content

Commit

Permalink
feat: add precision to time and chrono
Browse files Browse the repository at this point in the history
  • Loading branch information
saiintbrisson committed Aug 22, 2023
1 parent e29d173 commit c1c2324
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 0 deletions.
49 changes: 49 additions & 0 deletions fake/src/impls/chrono/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,52 @@ impl Dummy<Faker> for NaiveDateTime {
NaiveDateTime::new(date, time)
}
}

pub struct Precision<const N: usize>;

trait AllowedPrecision {
const SCALE: i64;

fn to_scale(nanos: i64) -> i64 {
if nanos != 0 {
nanos / Self::SCALE * Self::SCALE
} else {
nanos
}
}
}
macro_rules! allow_precision {
($($precision:expr),*) => {
$(impl AllowedPrecision for Precision<$precision> {
const SCALE: i64 = 10i64.pow(9 - $precision);
})*
};
}
allow_precision!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);

impl<const N: usize> Dummy<Precision<N>> for NaiveTime
where
Precision<N>: AllowedPrecision,
{
fn dummy_with_rng<R: Rng + ?Sized>(_: &Precision<N>, rng: &mut R) -> Self {
let hour = (0..24).fake_with_rng(rng);
let min = (0..60).fake_with_rng(rng);
let sec = (0..60).fake_with_rng(rng);
let nanos: i64 = (0..1_000_000_000).fake_with_rng(rng);
let nanos = Precision::<N>::to_scale(nanos) as u32;
NaiveTime::from_hms_nano_opt(hour, min, sec, nanos).expect("failed to create time")
}
}

impl<Tz, const N: usize> Dummy<Precision<N>> for DateTime<Tz>
where
Tz: TimeZone + Dummy<Faker>,
Precision<N>: AllowedPrecision,
{
fn dummy_with_rng<R: Rng + ?Sized>(_: &Precision<N>, rng: &mut R) -> Self {
let nanos: i64 = Faker.fake_with_rng(rng);
let utc: DateTime<Utc> = Utc.timestamp_nanos(Precision::<N>::to_scale(nanos));
let tz: Tz = Faker.fake_with_rng(rng);
utc.with_timezone(&tz)
}
}
58 changes: 58 additions & 0 deletions fake/src/impls/time/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,61 @@ impl Dummy<Faker> for PrimitiveDateTime {
PrimitiveDateTime::new(date, time)
}
}

pub struct Precision<const N: usize>;

trait AllowedPrecision {
const SCALE: i128;

fn to_scale(nanos: i128) -> i128 {
if nanos != 0 {
nanos / Self::SCALE * Self::SCALE
} else {
nanos
}
}
}
macro_rules! allow_precision {
($($precision:expr),*) => {
$(impl AllowedPrecision for Precision<$precision> {
const SCALE: i128 = 10i128.pow(9 - $precision);
})*
};
}
allow_precision!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);

impl<const N: usize> Dummy<Precision<N>> for Time
where
Precision<N>: AllowedPrecision,
{
fn dummy_with_rng<R: Rng + ?Sized>(_: &Precision<N>, rng: &mut R) -> Self {
let hour = (0..24).fake_with_rng(rng);
let min = (0..60).fake_with_rng(rng);
let sec = (0..60).fake_with_rng(rng);
let nanos: i128 = (0..1_000_000_000).fake_with_rng(rng);
let nanos = Precision::<N>::to_scale(nanos) as u32;
Time::from_hms_nano(hour, min, sec, nanos).expect("failed to create time")
}
}

impl<const N: usize> Dummy<Precision<N>> for PrimitiveDateTime
where
Precision<N>: AllowedPrecision,
{
fn dummy_with_rng<R: Rng + ?Sized>(_: &Precision<N>, rng: &mut R) -> Self {
let date = Faker.fake_with_rng(rng);
let time = Precision::<N>.fake_with_rng(rng);
PrimitiveDateTime::new(date, time)
}
}

impl<const N: usize> Dummy<Precision<N>> for OffsetDateTime
where
Precision<N>: AllowedPrecision,
{
fn dummy_with_rng<R: Rng + ?Sized>(_: &Precision<N>, rng: &mut R) -> Self {
let nanos = (MIN_NANOS..MAX_NANOS).fake_with_rng(rng);
let nanos = Precision::<N>::to_scale(nanos);
OffsetDateTime::from_unix_timestamp_nanos(nanos).unwrap()
}
}

0 comments on commit c1c2324

Please sign in to comment.