microcad_lang/parse/
parameter.rs

1// Copyright © 2025 The µcad authors <info@ucad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4use crate::{ord_map::*, parse::*, parser::*};
5
6/// Short cut to create a `ParameterList` instance
7impl Parse for Parameter {
8    fn parse(pair: Pair) -> ParseResult<Self> {
9        let mut name = Identifier::default();
10        let mut specified_type = None;
11        let mut default_value = None;
12
13        for pair in pair.inner() {
14            match pair.as_rule() {
15                Rule::identifier => {
16                    name = Identifier::parse(pair)?;
17                }
18                Rule::r#type => {
19                    specified_type = Some(TypeAnnotation::parse(pair)?);
20                }
21                Rule::expression => {
22                    default_value = Some(Expression::parse(pair)?);
23                }
24                rule => {
25                    unreachable!(
26                        "Unexpected token in parameter: {:?} {:?}",
27                        rule,
28                        pair.as_span().as_str()
29                    );
30                }
31            }
32        }
33
34        if specified_type.is_none() && default_value.is_none() {
35            return Err(ParseError::ParameterMissingTypeOrValue(name.clone()));
36        }
37
38        Ok(Self {
39            id: name,
40            specified_type,
41            default_value,
42            src_ref: pair.into(),
43        })
44    }
45}
46
47impl Parse for ParameterList {
48    fn parse(pair: Pair) -> ParseResult<Self> {
49        Parser::ensure_rule(&pair, Rule::parameter_list);
50
51        let mut parameters: OrdMap<_, _> = Default::default();
52
53        for pair in pair.inner().filter(|p| p.as_rule() == Rule::parameter) {
54            parameters
55                .try_push(Parameter::parse(pair)?)
56                .map_err(ParseError::DuplicateIdentifier)?;
57        }
58
59        Ok(ParameterList(Refer::new(parameters, pair.src_ref())))
60    }
61}