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