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