Skip to main content

camel_config/
discovery.rs

1//! Route discovery module - finds and loads routes from YAML files using glob patterns.
2
3use camel_core::route::RouteDefinition;
4use glob::glob;
5use std::fs;
6use std::io;
7
8use crate::yaml::parse_yaml;
9
10/// Errors that can occur during route discovery.
11#[derive(Debug, thiserror::Error)]
12pub enum DiscoveryError {
13    /// Invalid glob pattern.
14    #[error("Glob pattern error: {0}")]
15    GlobPattern(#[from] glob::PatternError),
16
17    /// Error accessing file while iterating glob.
18    #[error("Glob error accessing {path}: {source}")]
19    GlobAccess { path: String, source: io::Error },
20
21    /// Error reading a file.
22    #[error("IO error reading {path}: {source}")]
23    Io { path: String, source: io::Error },
24
25    /// Error parsing YAML content.
26    #[error("YAML parse error in {path}: {error}")]
27    Yaml { path: String, error: String },
28}
29
30/// Discovers routes from YAML files matching the given glob patterns.
31///
32/// # Arguments
33/// * `patterns` - Slice of glob patterns to match YAML files
34///
35/// # Returns
36/// A vector of all discovered route definitions, or an error.
37///
38/// # Example
39/// ```ignore
40/// let routes = discover_routes(&["routes/*.yaml".to_string(), "extra/**/*.yaml".to_string()])?;
41/// ```
42pub fn discover_routes(patterns: &[String]) -> Result<Vec<RouteDefinition>, DiscoveryError> {
43    let mut routes = Vec::new();
44
45    for pattern in patterns {
46        // glob returns an iterator over matching paths
47        let entries = glob(pattern)?;
48
49        for entry in entries {
50            let path = entry.map_err(|e| DiscoveryError::GlobAccess {
51                path: e.path().to_string_lossy().to_string(),
52                source: e.into_error(),
53            })?;
54            let path_str = path.to_string_lossy().to_string();
55
56            // Read file content
57            let yaml_content = fs::read_to_string(&path).map_err(|e| DiscoveryError::Io {
58                path: path_str.clone(),
59                source: e,
60            })?;
61
62            // Parse YAML into route definitions
63            let file_routes = parse_yaml(&yaml_content).map_err(|e| DiscoveryError::Yaml {
64                path: path_str,
65                error: e.to_string(),
66            })?;
67
68            routes.extend(file_routes);
69        }
70    }
71
72    Ok(routes)
73}