shaperail_codegen/
parser.rs1use shaperail_core::ResourceDefinition;
2
3#[derive(Debug, thiserror::Error)]
5pub enum ParseError {
6 #[error("{0}")]
7 Yaml(#[from] serde_yaml::Error),
8
9 #[error("{0}")]
10 Io(#[from] std::io::Error),
11
12 #[error("{0}")]
13 ConfigInterpolation(String),
14}
15
16pub fn parse_resource(yaml: &str) -> Result<ResourceDefinition, ParseError> {
18 let resource: ResourceDefinition = serde_yaml::from_str(yaml)?;
19 Ok(resource)
20}
21
22pub fn parse_resource_file(path: &std::path::Path) -> Result<ResourceDefinition, ParseError> {
24 let content = std::fs::read_to_string(path)?;
25 parse_resource(&content)
26}
27
28#[cfg(test)]
29mod tests {
30 use super::*;
31
32 #[test]
33 fn parse_minimal_resource() {
34 let yaml = r#"
35resource: tags
36version: 1
37schema:
38 id: { type: uuid, primary: true, generated: true }
39 name: { type: string, required: true }
40"#;
41 let rd = parse_resource(yaml).unwrap();
42 assert_eq!(rd.resource, "tags");
43 assert_eq!(rd.version, 1);
44 assert_eq!(rd.schema.len(), 2);
45 assert!(rd.endpoints.is_none());
46 assert!(rd.relations.is_none());
47 assert!(rd.indexes.is_none());
48 }
49
50 #[test]
51 fn parse_full_users_resource() {
52 let yaml = include_str!("../../resources/users.yaml");
53 let rd = parse_resource(yaml).unwrap();
54 assert_eq!(rd.resource, "users");
55 assert_eq!(rd.version, 1);
56 assert_eq!(rd.schema.len(), 9);
57 assert!(rd.endpoints.is_some());
58 assert!(rd.relations.is_some());
59 assert!(rd.indexes.is_some());
60 }
61
62 #[test]
63 fn parse_error_invalid_yaml() {
64 let yaml = "not: [valid: yaml: here";
65 let err = parse_resource(yaml).unwrap_err();
66 assert!(matches!(err, ParseError::Yaml(_)));
67 }
68
69 #[test]
70 fn parse_error_missing_resource_key() {
71 let yaml = r#"
72version: 1
73schema:
74 id: { type: uuid }
75"#;
76 let err = parse_resource(yaml).unwrap_err();
77 assert!(err.to_string().contains("missing field"));
78 }
79
80 #[test]
81 fn parse_error_unknown_top_level_key() {
82 let yaml = r#"
83resource: tags
84version: 1
85schema:
86 id: { type: uuid, primary: true, generated: true }
87unknown: true
88"#;
89 let err = parse_resource(yaml).unwrap_err();
90 assert!(err.to_string().contains("unknown field"));
91 assert!(err.to_string().contains("unknown"));
92 }
93
94 #[test]
95 fn parse_error_unknown_field_key() {
96 let yaml = r#"
97resource: tags
98version: 1
99schema:
100 id: { type: uuid, primary: true, generated: true, searchable: true }
101"#;
102 let err = parse_resource(yaml).unwrap_err();
103 assert!(err.to_string().contains("unknown field"));
104 assert!(err.to_string().contains("searchable"));
105 }
106}