1use crate::edge::*;
17use crate::memgraph::*;
18use crate::mgp::*;
19use crate::result::*;
20use crate::vertex::*;
21#[double]
23use crate::mgp::ffi;
24use mockall_double::double;
25
26pub struct Path {
27 ptr: *mut mgp_path,
28 memgraph: Memgraph,
29}
30impl Drop for Path {
31 fn drop(&mut self) {
32 unsafe {
33 if !self.ptr.is_null() {
34 ffi::mgp_path_destroy(self.ptr);
35 }
36 }
37 }
38}
39
40impl Path {
41 pub(crate) fn new(ptr: *mut mgp_path, memgraph: &Memgraph) -> Path {
42 #[cfg(not(test))]
43 assert!(
44 !ptr.is_null(),
45 "Unable to create path because the given pointer is null."
46 );
47
48 Path {
49 ptr,
50 memgraph: memgraph.clone(),
51 }
52 }
53
54 pub(crate) unsafe fn mgp_copy(
56 mgp_path: *const mgp_path,
57 memgraph: &Memgraph,
58 ) -> MgpResult<Path> {
59 #[cfg(not(test))]
60 assert!(
61 !mgp_path.is_null(),
62 "Unable to make path copy because the given pointer is null."
63 );
64
65 let mgp_copy = ffi::mgp_path_copy(mgp_path, memgraph.memory_ptr());
66 if mgp_copy.is_null() {
67 return Err(MgpError::UnableToCopyPath);
68 }
69 Ok(Path::new(mgp_copy, &memgraph))
70 }
71
72 pub(crate) fn mgp_ptr(&self) -> *const mgp_path {
74 self.ptr
75 }
76
77 pub fn size(&self) -> u64 {
78 unsafe { ffi::mgp_path_size(self.ptr) }
79 }
80
81 pub fn make_with_start(vertex: &Vertex, memgraph: &Memgraph) -> MgpResult<Path> {
83 unsafe {
84 let mgp_path = ffi::mgp_path_make_with_start(vertex.mgp_ptr(), memgraph.memory_ptr());
85 if mgp_path.is_null() {
86 return Err(MgpError::UnableToCreatePathWithStartVertex);
87 }
88 Ok(Path::new(mgp_path, &memgraph))
89 }
90 }
91
92 pub fn expand(&self, edge: &Edge) -> MgpResult<()> {
95 unsafe {
96 let mgp_result = ffi::mgp_path_expand(self.ptr, edge.mgp_ptr());
97 if mgp_result == 0 {
98 return Err(MgpError::UnableToExpandPath);
99 }
100 Ok(())
101 }
102 }
103
104 pub fn vertex_at(&self, index: u64) -> MgpResult<Vertex> {
105 unsafe {
106 let mgp_vertex = ffi::mgp_path_vertex_at(self.ptr, index);
107 if mgp_vertex.is_null() {
108 return Err(MgpError::OutOfBoundPathVertexIndex);
109 }
110 Vertex::mgp_copy(mgp_vertex, &self.memgraph)
111 }
112 }
113
114 pub fn edge_at(&self, index: u64) -> MgpResult<Edge> {
115 unsafe {
116 let mgp_edge = ffi::mgp_path_edge_at(self.ptr, index);
117 if mgp_edge.is_null() {
118 return Err(MgpError::OutOfBoundPathEdgeIndex);
119 }
120 Edge::mgp_copy(mgp_edge, &self.memgraph)
121 }
122 }
123}
124
125#[cfg(test)]
126mod tests;