use crate::project::{ProjectComponent, ProjectError};
use std::path::Path;
pub trait ProjectComponentProvider: Send + Sync {
fn scan_path(&self, path: &Path) -> Result<Option<ProjectComponent>, ProjectError>;
}
pub struct ProjectProviderRegistry {
providers: Vec<Box<dyn ProjectComponentProvider>>,
}
impl ProjectProviderRegistry {
pub fn new() -> Self {
Self {
providers: Vec::new(),
}
}
pub fn with_provider(mut self, provider: Box<dyn ProjectComponentProvider>) -> Self {
self.providers.push(provider);
self
}
pub fn scan_directory(&self, path: &Path) -> Result<Option<ProjectComponent>, ProjectError> {
for provider in &self.providers {
match provider.scan_path(path)? {
Some(component) => return Ok(Some(component)),
None => continue,
}
}
Ok(None)
}
}
impl Default for ProjectProviderRegistry {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[allow(dead_code)]
struct MockProvider {
name: String,
}
impl ProjectComponentProvider for MockProvider {
fn scan_path(&self, _path: &Path) -> Result<Option<ProjectComponent>, ProjectError> {
Ok(None)
}
}
#[allow(dead_code)]
impl MockProvider {
fn new(name: &str) -> Self {
Self {
name: name.to_string(),
}
}
}
}