1 /// Provides a wrapper around a `mg_local_time`.
2 module memgraph.local_time;
3 
4 import memgraph.mgclient, memgraph.detail, memgraph.value, memgraph.enums;
5 
6 /// Represents local time.
7 ///
8 /// Time is defined with nanoseconds since midnight.
9 struct LocalTime {
10 	/// Create a copy of `other` local time.
11 	this(inout ref LocalTime other) {
12 		this(mg_local_time_copy(other.ptr));
13 	}
14 
15 	/// Create a local time from a Value.
16 	this(inout ref Value value) {
17 		assert(value.type == Type.LocalTime);
18 		this(mg_local_time_copy(mg_value_local_time(value.ptr)));
19 	}
20 
21 	/// Assigns a local time to another. The target of the assignment gets detached from
22 	/// whatever local time it was attached to, and attaches itself to the new local time.
23 	ref LocalTime opAssign(LocalTime rhs) @safe return {
24 		import std.algorithm.mutation : swap;
25 		swap(this, rhs);
26 		return this;
27 	}
28 
29 	/// Return a printable string representation of this local time.
30 	const (string) toString() const {
31 		import std.conv : to;
32 		return to!string(nanoseconds);
33 	}
34 
35 	/// Compares this local time with `other`.
36 	/// Return: true if same, false otherwise.
37 	bool opEquals(const ref LocalTime other) const {
38 		return Detail.areLocalTimesEqual(ptr_, other.ptr);
39 	}
40 
41 	/// Returns nanoseconds since midnight.
42 	const (long) nanoseconds() const { return mg_local_time_nanoseconds(ptr_); }
43 
44 	this(this) {
45 		if (ptr_)
46 			ptr_ = mg_local_time_copy(ptr_);
47 	}
48 
49 	@safe @nogc ~this() {
50 		if (ptr_)
51 			mg_local_time_destroy(ptr_);
52 	}
53 
54 package:
55 	/// Create a LocalTime using the given `mg_local_time`.
56 	this(mg_local_time *ptr) @trusted {
57 		assert(ptr != null);
58 		ptr_ = ptr;
59 	}
60 
61 	/// Create a LocalTime from a copy of the given `mg_local_time`.
62 	this(const mg_local_time *ptr) {
63 		assert(ptr != null);
64 		this(mg_local_time_copy(ptr));
65 	}
66 
67 	const (mg_local_time *) ptr() const { return ptr_; }
68 
69 private:
70 	mg_local_time *ptr_;
71 }
72 
73 unittest {
74 	import std.conv : to;
75 	import memgraph.enums;
76 
77 	auto tm = mg_local_time_alloc(&mg_system_allocator);
78 	assert(tm != null);
79 	tm.nanoseconds = 42;
80 
81 	auto t = LocalTime(tm);
82 	assert(t.nanoseconds == 42);
83 
84 	const t1 = t;
85 	assert(t1 == t);
86 
87 	assert(to!string(t) == "42");
88 
89 	auto t2 = LocalTime(t.ptr);
90 	assert(t2 == t);
91 
92 	const t3 = LocalTime(t2);
93 	assert(t3 == t);
94 
95 	const v = Value(t);
96 	const t4 = LocalTime(v);
97 	assert(t4 == t);
98 	assert(v == t);
99 	assert(to!string(v) == to!string(t));
100 
101 	t2 = t;
102 	assert(t2 == t);
103 
104 	const v1 = Value(t2);
105 	assert(v1.type == Type.LocalTime);
106 	const v2 = Value(t2);
107 	assert(v2.type == Type.LocalTime);
108 
109 	assert(v1 == v2);
110 
111 	const t5 = LocalTime(t3);
112 	assert(t5 == t3);
113 }