pforge_config/
parser.rs

1use crate::{ConfigError, ForgeConfig, Result};
2use std::path::Path;
3
4pub fn parse_config(path: &Path) -> Result<ForgeConfig> {
5    let content =
6        std::fs::read_to_string(path).map_err(|e| ConfigError::IoError(path.to_path_buf(), e))?;
7
8    parse_config_from_str(&content)
9}
10
11pub fn parse_config_from_str(yaml: &str) -> Result<ForgeConfig> {
12    serde_yaml::from_str(yaml).map_err(|e| ConfigError::ParseError(e.to_string()))
13}
14
15#[cfg(test)]
16mod tests {
17    use super::*;
18    use crate::*;
19
20    #[test]
21    fn test_parse_config_from_str_minimal() {
22        let yaml = r#"
23forge:
24  name: test-server
25  version: 0.1.0
26  transport: stdio
27
28tools:
29  - type: native
30    name: test_tool
31    description: "Test tool"
32    handler:
33      path: "test::handler"
34    params: {}
35"#;
36        let result = parse_config_from_str(yaml);
37        assert!(result.is_ok());
38        let config = result.unwrap();
39        assert_eq!(config.forge.name, "test-server");
40        assert_eq!(config.forge.version, "0.1.0");
41        assert_eq!(config.tools.len(), 1);
42    }
43
44    #[test]
45    fn test_parse_config_invalid_yaml() {
46        let yaml = "invalid: yaml: structure: [[[";
47        let result = parse_config_from_str(yaml);
48        assert!(result.is_err());
49        assert!(matches!(result.unwrap_err(), ConfigError::ParseError(_)));
50    }
51
52    #[test]
53    fn test_parse_config_from_file_not_found() {
54        let result = parse_config(Path::new("/nonexistent/file.yaml"));
55        assert!(result.is_err());
56        assert!(matches!(result.unwrap_err(), ConfigError::IoError(_, _)));
57    }
58
59    #[test]
60    fn test_parse_config_with_all_tool_types() {
61        let yaml = r#"
62forge:
63  name: multi-tool
64  version: 1.0.0
65  transport: stdio
66
67tools:
68  - type: native
69    name: native_tool
70    description: "Native handler"
71    handler:
72      path: "native::handler"
73    params: {}
74
75  - type: cli
76    name: cli_tool
77    description: "CLI handler"
78    command: "echo"
79    args: ["test"]
80
81  - type: http
82    name: http_tool
83    description: "HTTP handler"
84    endpoint: "https://api.example.com"
85    method: "GET"
86
87  - type: pipeline
88    name: pipeline_tool
89    description: "Pipeline handler"
90    steps:
91      - tool: native_tool
92    params: {}
93"#;
94        let result = parse_config_from_str(yaml);
95        assert!(result.is_ok());
96        let config = result.unwrap();
97        assert_eq!(config.tools.len(), 4);
98    }
99}