use crate::{PluginError, Result};
use std::path::Path;
use tracing::warn;
use super::models::PluginManifest;
pub struct ManifestLoader;
impl ManifestLoader {
pub fn load_from_file<P: AsRef<Path>>(path: P) -> Result<PluginManifest> {
PluginManifest::from_file(path)
}
pub fn load_from_string(content: &str) -> Result<PluginManifest> {
PluginManifest::parse_from_str(content)
}
pub fn load_and_validate_from_file<P: AsRef<Path>>(path: P) -> Result<PluginManifest> {
let manifest = Self::load_from_file(path)?;
manifest.validate()?;
Ok(manifest)
}
pub fn load_and_validate_from_string(content: &str) -> Result<PluginManifest> {
let manifest = Self::load_from_string(content)?;
manifest.validate()?;
Ok(manifest)
}
pub fn load_from_directory<P: AsRef<Path>>(dir: P) -> Result<Vec<PluginManifest>> {
let mut manifests = Vec::new();
for entry in std::fs::read_dir(dir)? {
let entry = entry?;
let path = entry.path();
if path.extension().is_some_and(|ext| ext == "yaml" || ext == "yml") {
match Self::load_from_file(&path) {
Ok(manifest) => manifests.push(manifest),
Err(e) => {
warn!("Failed to load manifest from {}: {}", path.display(), e);
}
}
}
}
Ok(manifests)
}
pub fn load_and_validate_from_directory<P: AsRef<Path>>(dir: P) -> Result<Vec<PluginManifest>> {
let manifests = Self::load_from_directory(dir)?;
let mut validated = Vec::new();
for manifest in manifests {
match manifest.validate() {
Ok(_) => validated.push(manifest),
Err(e) => {
warn!("Failed to validate manifest for plugin {}: {}", manifest.id(), e);
}
}
}
Ok(validated)
}
}
impl PluginManifest {
pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self> {
let content = std::fs::read_to_string(path).map_err(|e| {
PluginError::config_error(&format!("Failed to read manifest file: {}", e))
})?;
Self::parse_from_str(&content)
}
pub fn parse_from_str(content: &str) -> Result<Self> {
serde_yaml::from_str(content)
.map_err(|e| PluginError::config_error(&format!("Failed to parse manifest: {}", e)))
}
}
#[cfg(test)]
mod tests {
#[test]
fn test_module_compiles() {
}
}