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