Skip to main content

pidgin_lang/validator/
syntax.rs

1use crate::ast::{Directive, FieldValue, PgnPacket};
2use super::ValidationError;
3
4pub fn validate_syntax(packet: &PgnPacket) -> Vec<ValidationError> {
5    let mut errors = Vec::new();
6
7    match packet.directive {
8        Directive::Run => {
9            require_field(packet, "wf", &mut errors);
10            require_field(packet, "mode", &mut errors);
11            require_list_field(packet, "in", &mut errors);
12            require_list_field(packet, "out", &mut errors);
13        }
14        Directive::Result => {
15            require_field(packet, "wf", &mut errors);
16            require_list_field(packet, "out", &mut errors);
17            require_field(packet, "status", &mut errors);
18        }
19        Directive::Approval => {
20            require_field(packet, "status", &mut errors);
21        }
22        Directive::Context => {
23            require_field(packet, "wf", &mut errors);
24            require_list_field(packet, "in", &mut errors);
25        }
26    }
27
28    errors
29}
30
31fn require_field(packet: &PgnPacket, field: &str, errors: &mut Vec<ValidationError>) {
32    if !packet.fields.contains_key(field) {
33        errors.push(ValidationError {
34            code: "PGN_E001".to_string(),
35            message: format!("missing required field: {}", field),
36        });
37    }
38}
39
40fn require_list_field(packet: &PgnPacket, field: &str, errors: &mut Vec<ValidationError>) {
41    match packet.fields.get(field) {
42        None => {
43            errors.push(ValidationError {
44                code: "PGN_E001".to_string(),
45                message: format!("missing required field: {}", field),
46            });
47        }
48        Some(value) => {
49            if !matches!(value, FieldValue::List(_)) {
50                errors.push(ValidationError {
51                    code: "PGN_E016".to_string(),
52                    message: format!("field '{}' must be a list, got scalar", field),
53                });
54            }
55        }
56    }
57}