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