mockforge_plugin_sdk/
builders.rs1use mockforge_plugin_core::*;
7
8pub struct ManifestBuilder {
24 manifest: PluginManifest,
25}
26
27impl ManifestBuilder {
28 pub fn new(id: &str, version: &str) -> Self {
30 let version = PluginVersion::parse(version).unwrap_or_else(|_| PluginVersion::new(0, 1, 0));
31 let info = PluginInfo {
32 id: PluginId::new(id),
33 version,
34 name: String::new(),
35 description: String::new(),
36 author: PluginAuthor::new("Unknown"),
37 };
38
39 Self {
40 manifest: PluginManifest::new(info),
41 }
42 }
43
44 pub fn name(mut self, name: &str) -> Self {
46 self.manifest.info.name = name.to_string();
47 self
48 }
49
50 pub fn description(mut self, description: &str) -> Self {
52 self.manifest.info.description = description.to_string();
53 self
54 }
55
56 pub fn author(mut self, name: &str, email: &str) -> Self {
58 self.manifest.info.author = PluginAuthor::with_email(name, email);
59 self
60 }
61
62 pub fn author_name(mut self, name: &str) -> Self {
64 self.manifest.info.author = PluginAuthor::new(name);
65 self
66 }
67
68 pub fn capability(mut self, capability: &str) -> Self {
72 self.manifest.capabilities.push(capability.to_string());
73 self
74 }
75
76 pub fn capabilities(mut self, capabilities: &[&str]) -> Self {
78 for cap in capabilities {
79 self.manifest.capabilities.push(cap.to_string());
80 }
81 self
82 }
83
84 pub fn dependency(mut self, plugin_id: &str, version: &str) -> Self {
86 if let Ok(parsed_version) = PluginVersion::parse(version) {
87 self.manifest.dependencies.insert(PluginId::new(plugin_id), parsed_version);
88 }
89 self
90 }
91
92 pub fn build(self) -> PluginManifest {
94 self.manifest
95 }
96
97 pub fn build_and_save(self, path: &str) -> std::result::Result<PluginManifest, std::io::Error> {
99 let manifest = self.manifest;
100 let yaml = serde_yaml::to_string(&manifest)
101 .map_err(|e| std::io::Error::other(format!("YAML error: {}", e)))?;
102 std::fs::write(path, yaml)?;
103 Ok(manifest)
104 }
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110
111 #[test]
112 fn test_manifest_builder() {
113 let manifest = ManifestBuilder::new("test-plugin", "1.0.0")
114 .name("Test Plugin")
115 .description("A test plugin")
116 .author("Test Author", "test@example.com")
117 .capability("network")
118 .capability("filesystem.read")
119 .build();
120
121 assert_eq!(manifest.info.id, PluginId::new("test-plugin"));
122 assert_eq!(manifest.info.name, "Test Plugin");
123 assert_eq!(manifest.info.description, "A test plugin");
124 assert_eq!(manifest.capabilities.len(), 2);
125 assert!(manifest.capabilities.contains(&"network".to_string()));
126 assert!(manifest.capabilities.contains(&"filesystem.read".to_string()));
127 }
128
129 #[test]
130 fn test_manifest_with_dependencies() {
131 let manifest = ManifestBuilder::new("test-plugin", "2.0.0")
132 .name("Test Plugin")
133 .dependency("dep1", "1.0.0")
134 .dependency("dep2", "1.5.0")
135 .build();
136
137 assert_eq!(manifest.dependencies.len(), 2);
138 }
139
140 #[test]
141 fn test_manifest_save() {
142 use tempfile::NamedTempFile;
143
144 let manifest = ManifestBuilder::new("test-plugin", "1.0.0")
145 .name("Test Plugin")
146 .description("A test plugin")
147 .author("Test", "test@example.com")
148 .build();
149
150 let temp_file = NamedTempFile::new().unwrap();
151 let path = temp_file.path().to_str().unwrap();
152
153 let yaml = serde_yaml::to_string(&manifest).unwrap();
154 std::fs::write(path, yaml).unwrap();
155
156 let loaded = PluginManifest::from_file(path).unwrap();
157 assert_eq!(loaded.info.id, manifest.info.id);
158 assert_eq!(loaded.info.name, manifest.info.name);
159 }
160}