1#include <errno.h>
 2#include <time.h>
 3
 4#include "include/pw.h"
 5
 6[[nodiscard]] bool pw_monotonic(PwValuePtr result)
 7{
 8    struct timespec t;
 9    if (clock_gettime(CLOCK_MONOTONIC, &t) == -1) {
10        pw_set_status(PwErrno(errno));
11        return false;
12    }
13    result->type_id = PwTypeId_Timestamp;
14    result->ts_seconds = t.tv_sec;
15    result->ts_nanoseconds = t.tv_nsec;
16    return true;
17}
18
19[[nodiscard]] _PwValue pw_timestamp_sum(PwValuePtr a, PwValuePtr b)
20{
21    pw_assert_timestamp(a);
22    pw_assert_timestamp(b);
23
24    _PwValue sum = PW_TIMESTAMP(
25        a->ts_seconds + b->ts_seconds,
26        a->ts_nanoseconds + b->ts_nanoseconds
27    );
28    if (sum.ts_nanoseconds >= 1000'000'000UL) {
29        sum.ts_nanoseconds -= 1000'000'000UL;
30        sum.ts_seconds++;
31    }
32    return sum;
33}
34
35[[nodiscard]] _PwValue pw_timestamp_diff(PwValuePtr a, PwValuePtr b)
36{
37    pw_assert_timestamp(a);
38    pw_assert_timestamp(b);
39
40    _PwValue diff = PW_TIMESTAMP(
41        a->ts_seconds - b->ts_seconds,
42        a->ts_nanoseconds - b->ts_nanoseconds
43    );
44    if (a->ts_nanoseconds < b->ts_nanoseconds) {
45        diff.ts_seconds--;
46        diff.ts_nanoseconds += 1000'000'000UL;
47    }
48    return diff;
49}
50
51[[nodiscard]] int pw_timestamp_cmp(PwValuePtr a, PwValuePtr b)
52{
53    pw_assert_timestamp(a);
54    pw_assert_timestamp(b);
55
56    if (a->ts_seconds < b->ts_seconds) {
57        return -1;
58    }
59    if (a->ts_seconds > b->ts_seconds) {
60        return 1;
61    }
62    if (a->ts_nanoseconds < b->ts_nanoseconds) {
63        return -1;
64    }
65    if (a->ts_nanoseconds > b->ts_nanoseconds) {
66        return 1;
67    }
68    return 0;
69}