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