1 /// Provides a wrapper around a `mg_duration`. 2 module memgraph.duration; 3 4 import memgraph.mgclient, memgraph.detail, memgraph.value, memgraph.enums; 5 6 /// Represents a temporal amount which captures the difference in time 7 /// between two instants. 8 /// 9 /// Duration is defined with months, days, seconds, and nanoseconds. 10 /// Note: Duration can be negative. 11 struct Duration { 12 13 /// Create a copy of `other` duration. 14 this(inout ref Duration other) { 15 this(mg_duration_copy(other.ptr)); 16 } 17 18 /// Create a duration from a Value. 19 this(inout ref Value value) { 20 assert(value.type == Type.Duration); 21 this(mg_duration_copy(mg_value_duration(value.ptr))); 22 } 23 24 /// Assigns a duration to another. The target of the assignment gets detached from 25 /// whatever duration it was attached to, and attaches itself to the new duration. 26 ref Duration opAssign(Duration 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 duration. 33 const (string) toString() const { 34 import std.conv : to; 35 return to!string(months) ~ " " ~ to!string(days) ~ " " ~ to!string(seconds) ~ " " ~ to!string(nanoseconds); 36 } 37 38 /// Compares this duration with `other`. 39 /// Return: true if same, false otherwise. 40 bool opEquals(const ref Duration other) const { 41 return Detail.areDurationsEqual(ptr_, other.ptr); 42 } 43 44 /// Returns the months part of the temporal amount. 45 const (long) months() const { return mg_duration_months(ptr_); } 46 47 /// Returns the days part of the temporal amount. 48 const (long) days() const { return mg_duration_days(ptr_); } 49 50 /// Returns the seconds part of the temporal amount. 51 const (long) seconds() const { return mg_duration_seconds(ptr_); } 52 53 /// Returns the nanoseconds part of the temporal amount. 54 const (long) nanoseconds() const { return mg_duration_nanoseconds(ptr_); } 55 56 this(this) { 57 if (ptr_) 58 ptr_ = mg_duration_copy(ptr_); 59 } 60 61 @safe @nogc ~this() { 62 if (ptr_) 63 mg_duration_destroy(ptr_); 64 } 65 66 package: 67 /// Create a Duration using the given `mg_duration`. 68 this(mg_duration *ptr) @trusted { 69 assert(ptr != null); 70 ptr_ = ptr; 71 } 72 73 /// Create a Duration from a copy of the given `mg_duration`. 74 this(const mg_duration *ptr) { 75 assert(ptr != null); 76 this(mg_duration_copy(ptr)); 77 } 78 79 const (mg_duration *) ptr() const { return ptr_; } 80 81 private: 82 mg_duration *ptr_; 83 } 84 85 unittest { 86 import std.conv : to; 87 import memgraph.enums; 88 89 auto tm = mg_duration_alloc(&mg_system_allocator); 90 assert(tm != null); 91 tm.months = 3; 92 tm.days = 10; 93 tm.seconds = 42; 94 tm.nanoseconds = 23; 95 96 auto t = Duration(tm); 97 assert(t.months == 3); 98 assert(t.days == 10); 99 assert(t.seconds == 42); 100 assert(t.nanoseconds == 23); 101 102 const t1 = t; 103 assert(t1 == t); 104 105 assert(to!string(t) == "3 10 42 23"); 106 107 auto t2 = Duration(t.ptr); 108 assert(t2 == t); 109 110 const t3 = Duration(t2); 111 assert(t3 == t); 112 113 const v = Value(t); 114 const t4 = Duration(v); 115 assert(t4 == t); 116 assert(v == t); 117 assert(to!string(v) == to!string(t)); 118 119 t2 = t; 120 assert(t2 == t); 121 122 const v1 = Value(t2); 123 assert(v1.type == Type.Duration); 124 const v2 = Value(t2); 125 assert(v2.type == Type.Duration); 126 127 assert(v1 == v2); 128 129 const t5 = Duration(t3); 130 assert(t5 == t3); 131 }