use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Descriptor {
pub name: String,
pub display_name: String,
pub description: String,
pub category: ConnectorCategory,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub input_schema: Option<Value>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub output_schema: Option<Value>,
pub idempotent: bool,
pub side_effects: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ConnectorCategory {
Http,
FileSystem,
Delay,
Transform,
Custom(String),
}
#[cfg(test)]
mod tests {
use serde_json::json;
use super::*;
fn sample_descriptor() -> Descriptor {
Descriptor {
name: "http.request".into(),
display_name: "HTTP Request".into(),
description: "Makes an HTTP request to an external URL.".into(),
category: ConnectorCategory::Http,
input_schema: Some(json!({
"type": "object",
"properties": {
"url": { "type": "string" },
"method": { "type": "string" }
}
})),
output_schema: Some(json!({
"type": "object",
"properties": {
"status": { "type": "integer" },
"body": { "type": "string" }
}
})),
idempotent: false,
side_effects: true,
}
}
#[test]
fn descriptor_json_roundtrip() {
let desc = sample_descriptor();
let json = serde_json::to_string(&desc).unwrap();
let back: Descriptor = serde_json::from_str(&json).unwrap();
assert_eq!(desc, back);
}
#[test]
fn category_variants_roundtrip() {
let categories = vec![
ConnectorCategory::Http,
ConnectorCategory::FileSystem,
ConnectorCategory::Delay,
ConnectorCategory::Transform,
ConnectorCategory::Custom("my_plugin".into()),
];
for cat in categories {
let json = serde_json::to_string(&cat).unwrap();
let back: ConnectorCategory = serde_json::from_str(&json).unwrap();
assert_eq!(cat, back);
}
}
#[test]
fn descriptor_with_no_schemas() {
let desc = Descriptor {
name: "delay".into(),
display_name: "Delay".into(),
description: "Waits for a specified duration.".into(),
category: ConnectorCategory::Delay,
input_schema: None,
output_schema: None,
idempotent: true,
side_effects: false,
};
let json = serde_json::to_string(&desc).unwrap();
let back: Descriptor = serde_json::from_str(&json).unwrap();
assert_eq!(desc, back);
assert!(!json.contains("input_schema"));
assert!(!json.contains("output_schema"));
}
}