summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--include/erebos/storage.h15
-rw-r--r--src/storage.cpp37
3 files changed, 53 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c7685ae..ccb2527 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -10,5 +10,6 @@ find_package(Threads REQUIRED)
find_package(ZLIB REQUIRED)
find_package(OpenSSL REQUIRED)
find_library(B2_LIBRARY b2 REQUIRED)
+find_library(UUID_LIBRARY uuid REQUIRED)
add_subdirectory(src)
diff --git a/include/erebos/storage.h b/include/erebos/storage.h
index 5812783..0859dc8 100644
--- a/include/erebos/storage.h
+++ b/include/erebos/storage.h
@@ -9,6 +9,8 @@
#include <variant>
#include <vector>
+#include <uuid/uuid.h>
+
namespace erebos {
class Storage;
@@ -154,6 +156,17 @@ protected:
Ref(const std::shared_ptr<const Priv> p): PartialRef(p) {}
};
+struct UUID
+{
+ explicit UUID(std::string);
+ explicit operator std::string() const;
+
+ bool operator==(const UUID &) const;
+ bool operator!=(const UUID &) const;
+
+ uuid_t uuid;
+};
+
template<class S>
class RecordT
{
@@ -171,6 +184,7 @@ public:
int,
std::string,
std::vector<uint8_t>,
+ UUID,
typename S::Ref,
UnknownType> Variant;
@@ -190,6 +204,7 @@ public:
std::optional<int> asInteger() const;
std::optional<std::string> asText() const;
std::optional<std::vector<uint8_t>> asBinary() const;
+ std::optional<UUID> asUUID() const;
std::optional<typename S::Ref> asRef() const;
std::optional<UnknownType> asUnknown() const;
diff --git a/src/storage.cpp b/src/storage.cpp
index 07fef51..e0819d4 100644
--- a/src/storage.cpp
+++ b/src/storage.cpp
@@ -536,6 +536,30 @@ const Storage & Ref::storage() const
}
+UUID::UUID(string str)
+{
+ if (uuid_parse(str.c_str(), uuid) != 0)
+ throw runtime_error("invalid UUID");
+}
+
+UUID::operator string() const
+{
+ string str(UUID_STR_LEN - 1, '\0');
+ uuid_unparse_lower(uuid, str.data());
+ return str;
+}
+
+bool UUID::operator==(const UUID & other) const
+{
+ return std::equal(std::begin(uuid), std::end(uuid), std::begin(other.uuid));
+}
+
+bool UUID::operator!=(const UUID & other) const
+{
+ return !(*this == other);
+}
+
+
template<class S>
RecordT<S>::Item::operator bool() const
{
@@ -567,6 +591,14 @@ optional<vector<uint8_t>> RecordT<S>::Item::asBinary() const
}
template<class S>
+optional<UUID> RecordT<S>::Item::asUUID() const
+{
+ if (holds_alternative<UUID>(value))
+ return std::get<UUID>(value);
+ return nullopt;
+}
+
+template<class S>
optional<typename S::Ref> RecordT<S>::Item::asRef() const
{
if (holds_alternative<typename S::Ref>(value))
@@ -623,6 +655,8 @@ optional<RecordT<S>> RecordT<S>::decode(const S & st,
items->emplace_back(name, value);
else if (type == "b")
items->emplace_back(name, base64::decode(value));
+ else if (type == "u")
+ items->emplace_back(name, UUID(value));
else if (type == "r.b2") {
if constexpr (is_same_v<S, Storage>) {
if (auto ref = st.ref(Digest(value)))
@@ -702,6 +736,9 @@ vector<uint8_t> RecordT<S>::encodeInner() const
} else if (auto x = item.asBinary()) {
type = "b";
value = base64::encode(*x);
+ } else if (auto x = item.asUUID()) {
+ type = "u";
+ value = string(*x);
} else if (auto x = item.asRef()) {
type = "r.b2";
value = string(x->digest());