summaryrefslogtreecommitdiff
path: root/src/discord/snowflake.hpp
blob: a5c0e6c2a9f1b04953b7f9b5f2d69d8c8c0dd3a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#pragma once
#include <cstdint>
#include <nlohmann/json.hpp>
#include <glibmm/ustring.h>

struct Snowflake {
    Snowflake();
    Snowflake(uint64_t n);
    Snowflake(const std::string &str);
    Snowflake(const Glib::ustring &str);

    static Snowflake FromNow(); // not thread safe
    static Snowflake FromISO8601(std::string_view ts);

    [[nodiscard]] bool IsValid() const;
    [[nodiscard]] Glib::ustring GetLocalTimestamp() const;

    bool operator==(const Snowflake &s) const noexcept {
        return m_num == s.m_num;
    }

    bool operator<(const Snowflake &s) const noexcept {
        return m_num < s.m_num;
    }

    operator uint64_t() const noexcept {
        return m_num;
    }

    const static Snowflake Invalid;                        // makes sense to me
    const static uint64_t SecondsInterval = 4194304000ULL; // the "difference" between two snowflakes one second apart

    friend void from_json(const nlohmann::json &j, Snowflake &s);
    friend void to_json(nlohmann::json &j, const Snowflake &s);

private:
    friend struct std::hash<Snowflake>;
    friend struct std::less<Snowflake>;
    unsigned long long m_num;
};

namespace std {
template<>
struct hash<Snowflake> {
    std::size_t operator()(const Snowflake &k) const {
        return k.m_num;
    }
};

template<>
struct less<Snowflake> {
    bool operator()(const Snowflake &l, const Snowflake &r) const {
        return l.m_num < r.m_num;
    }
};
} // namespace std