worldinterface_core/
descriptor.rs1use serde::{Deserialize, Serialize};
8use serde_json::Value;
9
10#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
12pub struct Descriptor {
13 pub name: String,
15 pub display_name: String,
17 pub description: String,
19 pub category: ConnectorCategory,
21 #[serde(default, skip_serializing_if = "Option::is_none")]
23 pub input_schema: Option<Value>,
24 #[serde(default, skip_serializing_if = "Option::is_none")]
26 pub output_schema: Option<Value>,
27 pub idempotent: bool,
29 pub side_effects: bool,
31}
32
33#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
35#[serde(rename_all = "snake_case")]
36pub enum ConnectorCategory {
37 Http,
38 FileSystem,
39 Delay,
40 Transform,
41 Custom(String),
42}
43
44#[cfg(test)]
45mod tests {
46 use serde_json::json;
47
48 use super::*;
49
50 fn sample_descriptor() -> Descriptor {
51 Descriptor {
52 name: "http.request".into(),
53 display_name: "HTTP Request".into(),
54 description: "Makes an HTTP request to an external URL.".into(),
55 category: ConnectorCategory::Http,
56 input_schema: Some(json!({
57 "type": "object",
58 "properties": {
59 "url": { "type": "string" },
60 "method": { "type": "string" }
61 }
62 })),
63 output_schema: Some(json!({
64 "type": "object",
65 "properties": {
66 "status": { "type": "integer" },
67 "body": { "type": "string" }
68 }
69 })),
70 idempotent: false,
71 side_effects: true,
72 }
73 }
74
75 #[test]
76 fn descriptor_json_roundtrip() {
77 let desc = sample_descriptor();
78 let json = serde_json::to_string(&desc).unwrap();
79 let back: Descriptor = serde_json::from_str(&json).unwrap();
80 assert_eq!(desc, back);
81 }
82
83 #[test]
84 fn category_variants_roundtrip() {
85 let categories = vec![
86 ConnectorCategory::Http,
87 ConnectorCategory::FileSystem,
88 ConnectorCategory::Delay,
89 ConnectorCategory::Transform,
90 ConnectorCategory::Custom("my_plugin".into()),
91 ];
92 for cat in categories {
93 let json = serde_json::to_string(&cat).unwrap();
94 let back: ConnectorCategory = serde_json::from_str(&json).unwrap();
95 assert_eq!(cat, back);
96 }
97 }
98
99 #[test]
100 fn descriptor_with_no_schemas() {
101 let desc = Descriptor {
102 name: "delay".into(),
103 display_name: "Delay".into(),
104 description: "Waits for a specified duration.".into(),
105 category: ConnectorCategory::Delay,
106 input_schema: None,
107 output_schema: None,
108 idempotent: true,
109 side_effects: false,
110 };
111 let json = serde_json::to_string(&desc).unwrap();
112 let back: Descriptor = serde_json::from_str(&json).unwrap();
113 assert_eq!(desc, back);
114 assert!(!json.contains("input_schema"));
116 assert!(!json.contains("output_schema"));
117 }
118}