1use arrow::datatypes::{DataType, Field, Schema};
17use std::sync::Arc;
18
19pub mod crate_node_col {
23 pub const ID: usize = 0;
24 pub const VERSION: usize = 1;
25 pub const WORKSPACE_MEMBER: usize = 2;
26 pub const DESCRIPTION: usize = 3;
27 pub const EDITION: usize = 4;
28}
29
30pub mod crate_edge_col {
34 pub const SOURCE: usize = 0;
35 pub const TARGET: usize = 1;
36 pub const VERSION_REQ: usize = 2;
37 pub const OPTIONAL: usize = 3;
38 pub const DEV_DEP: usize = 4;
39 pub const BUILD_DEP: usize = 5;
40 pub const SOURCE_KIND: usize = 6;
41}
42
43pub fn crate_node_schema() -> Arc<Schema> {
54 Arc::new(Schema::new(vec![
55 Field::new("id", DataType::Utf8, false),
56 Field::new("version", DataType::Utf8, false),
57 Field::new("workspace_member", DataType::Boolean, false),
58 Field::new("description", DataType::Utf8, true),
59 Field::new("edition", DataType::Utf8, false),
60 ]))
61}
62
63pub fn crate_edge_schema() -> Arc<Schema> {
74 Arc::new(Schema::new(vec![
75 Field::new("source", DataType::Utf8, false),
76 Field::new("target", DataType::Utf8, false),
77 Field::new("version_req", DataType::Utf8, false),
78 Field::new("optional", DataType::Boolean, false),
79 Field::new("dev_dep", DataType::Boolean, false),
80 Field::new("build_dep", DataType::Boolean, false),
81 Field::new("source_kind", DataType::Utf8, false),
82 ]))
83}
84
85#[cfg(test)]
88mod tests {
89 use super::*;
90
91 #[test]
92 fn test_crate_node_schema_field_count() {
93 let schema = crate_node_schema();
94 assert_eq!(
95 schema.fields().len(),
96 5,
97 "CrateNode schema should have 5 fields"
98 );
99 }
100
101 #[test]
102 fn test_crate_edge_schema_field_count() {
103 let schema = crate_edge_schema();
104 assert_eq!(
105 schema.fields().len(),
106 7,
107 "CrateEdge schema should have 7 fields"
108 );
109 }
110
111 #[test]
112 fn test_crate_node_schema_field_names() {
113 let schema = crate_node_schema();
114 let names: Vec<&str> = schema.fields().iter().map(|f| f.name().as_str()).collect();
115 assert_eq!(
116 names,
117 vec![
118 "id",
119 "version",
120 "workspace_member",
121 "description",
122 "edition"
123 ]
124 );
125 }
126
127 #[test]
128 fn test_crate_edge_schema_field_names() {
129 let schema = crate_edge_schema();
130 let names: Vec<&str> = schema.fields().iter().map(|f| f.name().as_str()).collect();
131 assert_eq!(
132 names,
133 vec![
134 "source",
135 "target",
136 "version_req",
137 "optional",
138 "dev_dep",
139 "build_dep",
140 "source_kind"
141 ]
142 );
143 }
144
145 #[test]
146 fn test_crate_node_schema_nullability() {
147 let schema = crate_node_schema();
148 for name in &["id", "version", "edition"] {
150 let field = schema.field_with_name(name).expect(name);
151 assert!(!field.is_nullable(), "{name} should be non-nullable");
152 }
153 let wm = schema.field_with_name("workspace_member").unwrap();
155 assert!(!wm.is_nullable(), "workspace_member should be non-nullable");
156 let desc = schema.field_with_name("description").unwrap();
158 assert!(desc.is_nullable(), "description should be nullable");
159 }
160
161 #[test]
162 fn test_crate_edge_schema_nullability() {
163 let schema = crate_edge_schema();
164 let non_null = ["source", "target", "version_req", "source_kind"];
165 for name in &non_null {
166 let field = schema.field_with_name(name).expect(name);
167 assert!(!field.is_nullable(), "{name} should be non-nullable");
168 }
169 let bool_cols = ["optional", "dev_dep", "build_dep"];
170 for name in &bool_cols {
171 let field = schema.field_with_name(name).expect(name);
172 assert!(
173 !field.is_nullable(),
174 "{name} bool col should be non-nullable"
175 );
176 }
177 }
178
179 #[test]
180 fn test_crate_node_col_constants_match_schema() {
181 let schema = crate_node_schema();
182 let check = |idx: usize, expected: &str| {
183 let actual = schema.field(idx).name();
184 assert_eq!(
185 actual, expected,
186 "crate_node_col[{idx}] expected {expected}, got {actual}"
187 );
188 };
189 check(crate_node_col::ID, "id");
190 check(crate_node_col::VERSION, "version");
191 check(crate_node_col::WORKSPACE_MEMBER, "workspace_member");
192 check(crate_node_col::DESCRIPTION, "description");
193 check(crate_node_col::EDITION, "edition");
194 }
195
196 #[test]
197 fn test_crate_edge_col_constants_match_schema() {
198 let schema = crate_edge_schema();
199 let check = |idx: usize, expected: &str| {
200 let actual = schema.field(idx).name();
201 assert_eq!(
202 actual, expected,
203 "crate_edge_col[{idx}] expected {expected}, got {actual}"
204 );
205 };
206 check(crate_edge_col::SOURCE, "source");
207 check(crate_edge_col::TARGET, "target");
208 check(crate_edge_col::VERSION_REQ, "version_req");
209 check(crate_edge_col::OPTIONAL, "optional");
210 check(crate_edge_col::DEV_DEP, "dev_dep");
211 check(crate_edge_col::BUILD_DEP, "build_dep");
212 check(crate_edge_col::SOURCE_KIND, "source_kind");
213 }
214
215 #[test]
216 fn test_crate_node_schema_types() {
217 let schema = crate_node_schema();
218 assert_eq!(
219 *schema.field(crate_node_col::ID).data_type(),
220 DataType::Utf8
221 );
222 assert_eq!(
223 *schema.field(crate_node_col::VERSION).data_type(),
224 DataType::Utf8
225 );
226 assert_eq!(
227 *schema.field(crate_node_col::WORKSPACE_MEMBER).data_type(),
228 DataType::Boolean
229 );
230 assert_eq!(
231 *schema.field(crate_node_col::DESCRIPTION).data_type(),
232 DataType::Utf8
233 );
234 assert_eq!(
235 *schema.field(crate_node_col::EDITION).data_type(),
236 DataType::Utf8
237 );
238 }
239
240 #[test]
241 fn test_crate_edge_schema_types() {
242 let schema = crate_edge_schema();
243 for col in &[
244 crate_edge_col::SOURCE,
245 crate_edge_col::TARGET,
246 crate_edge_col::VERSION_REQ,
247 crate_edge_col::SOURCE_KIND,
248 ] {
249 assert_eq!(*schema.field(*col).data_type(), DataType::Utf8);
250 }
251 for col in &[
252 crate_edge_col::OPTIONAL,
253 crate_edge_col::DEV_DEP,
254 crate_edge_col::BUILD_DEP,
255 ] {
256 assert_eq!(*schema.field(*col).data_type(), DataType::Boolean);
257 }
258 }
259}