1 /// Provides a wrapper around a `mg_point_3d`.
2 module memgraph.point3d;
3 
4 import memgraph.mgclient, memgraph.detail, memgraph.value, memgraph.enums;
5 
6 /// Represents a single location in 3-dimensional space.
7 ///
8 /// Contains SRID along with its x, y and z coordinates.
9 struct Point3d {
10   /// Create a shallow copy of `other` point 3d.
11   @nogc this(inout ref Point3d other) {
12     this(other.ptr);
13   }
14 
15   /// Create a point 3d from a Value.
16   this(inout ref Value value) {
17     assert(value.type == Type.Point3d);
18     this(mg_value_point_3d(value.ptr));
19   }
20 
21   /// Return a printable string representation of this time.
22   string toString() const {
23     import std.format : format;
24     return format!("{srid:%s, x:%s, y:%s, z:%s}")(srid, x, y, z);
25   }
26 
27   /// Compares this point 3d with `other`.
28   /// Return: true if same, false otherwise.
29   @nogc auto opEquals(const ref Point3d other) const {
30     return Detail.arePoint3dsEqual(ptr_, other.ptr);
31   }
32 
33   /// Return the hash code for this point 3d.
34   size_t toHash() const nothrow @safe {
35     return cast(ulong)ptr_;
36   }
37 
38   /// Returns SRID of the 3D point.
39   @nogc auto srid() const { return mg_point_3d_srid(ptr_); }
40   /// Returns the x coordinate of the 3D point.
41   @nogc auto x() const { return mg_point_3d_x(ptr_); }
42   /// Returns the y coordinate of the 3D point.
43   @nogc auto y() const { return mg_point_3d_y(ptr_); }
44   /// Returns the z coordinate of the 3D point.
45   @nogc auto z() const { return mg_point_3d_z(ptr_); }
46 
47 package:
48   /// Create a Point3d using the given `mg_point_3d` pointer.
49   @nogc this(const mg_point_3d *ptr) @trusted {
50     assert(ptr != null);
51     ptr_ = ptr;
52   }
53 
54   /// Return pointer to internal `mg_point_3d`.
55   @nogc auto ptr() const {
56     return ptr_;
57   }
58 
59 private:
60   const mg_point_3d *ptr_;
61 } // struct Point3d
62 
63 unittest {
64   import std.conv : to;
65   import memgraph.enums;
66 
67   auto tm = mg_point_3d_alloc(&mg_system_allocator);
68   assert(tm != null);
69   tm.srid = 42;
70   tm.x = 2;
71   tm.y = 3;
72   tm.z = 7;
73 
74   auto t = Point3d(tm);
75   assert(t.srid == 42);
76   assert(t.x == 2);
77   assert(t.y == 3);
78   assert(t.z == 7);
79 
80   const t1 = t;
81   assert(t1 == t);
82 
83   assert(to!string(t) == "{srid:42, x:2, y:3, z:7}", to!string(t));
84 
85   auto t2 = Point3d(mg_point_3d_copy(t.ptr));
86   assert(t2 == t);
87 
88   const t3 = Point3d(t2);
89   assert(t3 == t);
90 
91   const t5 = Point3d(t3);
92   assert(t5 == t3);
93 
94   // only for coverage atm
95   auto v1 = Value(mg_value_make_point_3d(mg_point_3d_copy(t.ptr)));
96   auto p1 = Point3d(v1);
97   assert(v1 == p1);
98 
99   assert(to!string(v1) == to!string(p1), to!string(v1));
100 
101   assert(cast(ulong)t.ptr == t.toHash);
102 }