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