linkrs_query/executor/streaming/helpers/
conversion.rs1use linkrs_core::Value;
6use linkrs_core::{Edge, Vertex};
7
8fn vid_raw_string(vid: &Vertex) -> String {
10 if let Some(s) = vid.vid.as_str() {
11 s.to_string()
12 } else if let Some(i) = vid.vid.as_int64() {
13 i.to_string()
14 } else if let Some(u) = vid.vid.as_u64() {
15 u.to_string()
16 } else {
17 format!("{:?}", vid.vid.as_bytes())
18 }
19}
20
21fn edge_raw_string(vid: &linkrs_core::types::storage_ids::VertexId) -> String {
22 if let Some(s) = vid.as_str() {
23 s.to_string()
24 } else if let Some(i) = vid.as_int64() {
25 i.to_string()
26 } else if let Some(u) = vid.as_u64() {
27 u.to_string()
28 } else {
29 format!("{:?}", vid.as_bytes())
30 }
31}
32
33pub fn vertex_to_row(vertex: &Vertex) -> Vec<Value> {
35 let mut row = vec![
36 Value::from(vertex.vid),
37 Value::string(vid_raw_string(vertex)),
38 ];
39
40 row.push(Value::string(vertex.tag.name.clone()));
41
42 for value in vertex.properties().values().take(3) {
45 row.push(value.clone());
46 }
47
48 row
49}
50
51pub fn edge_to_row(edge: &Edge) -> Vec<Value> {
53 let mut row = vec![
54 Value::string(edge_raw_string(&edge.src)),
55 Value::string(edge_raw_string(&edge.dst)),
56 Value::string(edge.edge_type.clone()),
57 Value::BigInt(edge.ranking),
58 ];
59
60 for value in edge.props.values().take(2) {
62 row.push(value.clone());
63 }
64
65 row
66}
67
68pub fn vertices_to_rows(
72 vertices: Vec<Vertex>,
73 partition_range: &std::ops::Range<i64>,
74) -> Vec<Vec<Value>> {
75 vertices
76 .into_iter()
77 .filter(|v| {
78 v.vid
79 .as_int64()
80 .is_some_and(|id| id >= partition_range.start && id < partition_range.end)
81 })
82 .map(|v| vertex_to_row(&v))
83 .collect()
84}
85
86pub fn edges_to_rows(edges: Vec<Edge>, partition_range: &std::ops::Range<i64>) -> Vec<Vec<Value>> {
90 edges
91 .into_iter()
92 .filter(|e| {
93 edge_raw_string(&e.src)
94 .parse::<i64>()
95 .is_ok_and(|id| id >= partition_range.start && id < partition_range.end)
96 })
97 .map(|e| edge_to_row(&e))
98 .collect()
99}
100
101#[cfg(test)]
102mod tests {
103 use super::*;
104 use linkrs_core::types::storage_ids::VertexId;
105 use linkrs_core::vertex_edge_path::Tag;
106 use std::collections::HashMap;
107
108 #[test]
109 fn test_vertex_conversion() {
110 let vertex = Vertex::new(
111 VertexId::try_from_string("vertex_123").expect("valid vertex id"),
112 Tag::new("person".into(), HashMap::new()),
113 );
114
115 let row = vertex_to_row(&vertex);
116
117 assert_eq!(row.len(), 3);
119 assert_eq!(row[2], Value::string("person"));
120 }
121
122 #[test]
123 fn test_edge_conversion() {
124 let edge = Edge {
125 src: VertexId::try_from_string("src_1").expect("valid vertex id"),
126 dst: VertexId::try_from_string("dst_2").expect("valid vertex id"),
127 edge_type: "follows".to_string(),
128 ranking: 42,
129 props: std::collections::HashMap::new(),
130 };
131
132 let row = edge_to_row(&edge);
133
134 assert_eq!(row.len(), 4);
136 assert_eq!(row[2], Value::string("follows"));
137 assert_eq!(row[3], Value::BigInt(42));
138 }
139
140 #[test]
141 fn test_partition_filtering() {
142 let vertices = vec![
143 Vertex::new(
144 VertexId::try_from_int64(10).expect("valid vertex id"),
145 Tag::new(String::new(), HashMap::new()),
146 ),
147 Vertex::new(
148 VertexId::try_from_int64(20).expect("valid vertex id"),
149 Tag::new(String::new(), HashMap::new()),
150 ),
151 Vertex::new(
152 VertexId::try_from_int64(30).expect("valid vertex id"),
153 Tag::new(String::new(), HashMap::new()),
154 ),
155 ];
156
157 let partition_range = std::ops::Range {
159 start: 15i64,
160 end: 35,
161 };
162 let rows = vertices_to_rows(vertices, &partition_range);
163
164 assert_eq!(rows.len(), 2);
166 }
167}