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