1use serde::{Deserialize, Serialize};
11
12#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
14pub struct SpaceInfo {
15 pub id: u64,
16 pub name: String,
17 pub vid_type: String,
18 #[serde(default)]
19 pub comment: Option<String>,
20}
21
22#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
24pub struct TagInfo {
25 pub name: String,
26 #[serde(default)]
27 pub fields: Vec<FieldInfo>,
28}
29
30#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
32pub struct EdgeTypeInfo {
33 pub name: String,
34 #[serde(default)]
35 pub fields: Vec<FieldInfo>,
36}
37
38#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
40pub struct FieldInfo {
41 pub name: String,
42 pub data_type: String,
43 pub nullable: bool,
44 #[serde(default)]
45 pub default_value: Option<String>,
46}
47
48#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
50pub struct PropertyDef {
51 pub name: String,
52 pub data_type: String,
54 #[serde(default)]
55 pub nullable: bool,
56 #[serde(default)]
57 pub default_value: Option<serde_json::Value>,
58 #[serde(default)]
59 pub comment: Option<String>,
60}
61
62impl PropertyDef {
63 pub fn new(name: impl Into<String>, data_type: impl Into<String>) -> Self {
65 Self {
66 name: name.into(),
67 data_type: data_type.into(),
68 nullable: true,
69 default_value: None,
70 comment: None,
71 }
72 }
73
74 pub fn not_null(mut self) -> Self {
76 self.nullable = false;
77 self
78 }
79}
80
81#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
83pub struct CreateSpaceRequest {
84 pub name: String,
85 #[serde(default)]
86 pub vid_type: Option<String>,
87 #[serde(default)]
88 pub comment: Option<String>,
89}
90
91#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
93pub struct CreateTagRequest {
94 pub name: String,
95 #[serde(default)]
96 pub properties: Vec<PropertyDef>,
97}
98
99#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
101pub struct CreateEdgeTypeRequest {
102 pub name: String,
103 #[serde(default)]
104 pub properties: Vec<PropertyDef>,
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110
111 #[test]
112 fn property_def_roundtrip() {
113 let def = PropertyDef {
114 name: "age".to_string(),
115 data_type: "INT".to_string(),
116 nullable: false,
117 default_value: Some(serde_json::json!(18)),
118 comment: Some("years".to_string()),
119 };
120 let json = serde_json::to_string(&def).unwrap();
121 let back: PropertyDef = serde_json::from_str(&json).unwrap();
122 assert_eq!(back.name, "age");
123 assert_eq!(back.data_type, "INT");
124 assert!(!back.nullable);
125 assert_eq!(back.default_value, Some(serde_json::json!(18)));
126 assert_eq!(back.comment.as_deref(), Some("years"));
127 }
128
129 #[test]
130 fn property_def_defaults_absent_fields() {
131 let back: PropertyDef =
132 serde_json::from_str(r#"{"name": "name", "data_type": "STRING"}"#).unwrap();
133 assert!(!back.nullable);
134 assert!(back.default_value.is_none());
135 assert!(back.comment.is_none());
136 }
137
138 #[test]
139 fn space_info_roundtrip() {
140 let info = SpaceInfo {
141 id: 1,
142 name: "space1".to_string(),
143 vid_type: "INT64".to_string(),
144 comment: None,
145 };
146 let json = serde_json::to_string(&info).unwrap();
147 let back: SpaceInfo = serde_json::from_str(&json).unwrap();
148 assert_eq!(back.id, 1);
149 assert_eq!(back.name, "space1");
150 }
151
152 #[test]
153 fn create_space_request_roundtrip() {
154 let request = CreateSpaceRequest {
155 name: "s".to_string(),
156 vid_type: Some("STRING".to_string()),
157 comment: None,
158 };
159 let json = serde_json::to_string(&request).unwrap();
160 let back: CreateSpaceRequest = serde_json::from_str(&json).unwrap();
161 assert_eq!(back.vid_type.as_deref(), Some("STRING"));
162 }
163}