Skip to main content

mockforge_plugin_core/manifest/
loader.rs

1//! Plugin manifest loading utilities
2//!
3//! This module provides functionality for loading and parsing plugin manifests
4//! from files and strings.
5
6use crate::{PluginError, Result};
7use std::path::Path;
8use tracing::warn;
9
10use super::models::PluginManifest;
11
12/// Manifest loader utility
13pub struct ManifestLoader;
14
15impl ManifestLoader {
16    /// Load manifest from file path
17    pub fn load_from_file<P: AsRef<Path>>(path: P) -> Result<PluginManifest> {
18        PluginManifest::from_file(path)
19    }
20
21    /// Load manifest from string content
22    pub fn load_from_string(content: &str) -> Result<PluginManifest> {
23        PluginManifest::parse_from_str(content)
24    }
25
26    /// Load and validate manifest from file
27    pub fn load_and_validate_from_file<P: AsRef<Path>>(path: P) -> Result<PluginManifest> {
28        let manifest = Self::load_from_file(path)?;
29        manifest.validate()?;
30        Ok(manifest)
31    }
32
33    /// Load and validate manifest from string
34    pub fn load_and_validate_from_string(content: &str) -> Result<PluginManifest> {
35        let manifest = Self::load_from_string(content)?;
36        manifest.validate()?;
37        Ok(manifest)
38    }
39
40    /// Load multiple manifests from directory
41    pub fn load_from_directory<P: AsRef<Path>>(dir: P) -> Result<Vec<PluginManifest>> {
42        let mut manifests = Vec::new();
43
44        for entry in std::fs::read_dir(dir)? {
45            let entry = entry?;
46            let path = entry.path();
47
48            if path.extension().is_some_and(|ext| ext == "yaml" || ext == "yml") {
49                match Self::load_from_file(&path) {
50                    Ok(manifest) => manifests.push(manifest),
51                    Err(e) => {
52                        // Log error but continue loading other manifests
53                        warn!("Failed to load manifest from {}: {}", path.display(), e);
54                    }
55                }
56            }
57        }
58
59        Ok(manifests)
60    }
61
62    /// Load and validate multiple manifests from directory
63    pub fn load_and_validate_from_directory<P: AsRef<Path>>(dir: P) -> Result<Vec<PluginManifest>> {
64        let manifests = Self::load_from_directory(dir)?;
65        let mut validated = Vec::new();
66
67        for manifest in manifests {
68            match manifest.validate() {
69                Ok(_) => validated.push(manifest),
70                Err(e) => {
71                    warn!("Failed to validate manifest for plugin {}: {}", manifest.id(), e);
72                }
73            }
74        }
75
76        Ok(validated)
77    }
78}
79
80impl PluginManifest {
81    /// Load manifest from file
82    pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self> {
83        let content = std::fs::read_to_string(path).map_err(|e| {
84            PluginError::config_error(&format!("Failed to read manifest file: {}", e))
85        })?;
86
87        Self::parse_from_str(&content)
88    }
89
90    /// Parse manifest from string
91    pub fn parse_from_str(content: &str) -> Result<Self> {
92        serde_yaml::from_str(content)
93            .map_err(|e| PluginError::config_error(&format!("Failed to parse manifest: {}", e)))
94    }
95}
96
97#[cfg(test)]
98mod tests {
99
100    #[test]
101    fn test_module_compiles() {
102        // Basic compilation test
103    }
104}