Skip to main content

microcad_lang/value/
parameter_value.rs

1// Copyright © 2024-2026 The µcad authors <info@microcad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4//! Parameter value evaluation entity
5
6use microcad_lang_base::SrcReferrer;
7
8use crate::{ty::*, value::*};
9
10/// Parameter value is the result of evaluating a parameter
11#[derive(Clone, Default)]
12pub struct ParameterValue {
13    /// Parameter type
14    pub specified_type: Option<Type>,
15    /// Parameter default
16    pub default_value: Option<Value>,
17    /// Source code reference
18    pub src_ref: SrcRef,
19}
20
21impl ParameterValue {
22    /// Creates an invalid parameter value, in case an error occurred during evaluation
23    pub fn invalid(src_ref: SrcRef) -> Self {
24        Self {
25            specified_type: None,
26            default_value: None,
27            src_ref,
28        }
29    }
30
31    /// Check if type of this parameter value matches the given one
32    pub fn type_matches(&self, ty: &Type) -> bool {
33        match &self.specified_type {
34            Some(t) => t == ty,
35            None => true, // Accept any type if none is specified
36        }
37    }
38}
39
40impl Ty for ParameterValue {
41    /// Return effective type
42    ///
43    /// Returns any `specified_type` or the type of the `default_value`.
44    /// Panics if neither of both is available.
45    fn ty(&self) -> Type {
46        if let Some(ty) = &self.specified_type {
47            ty.clone()
48        } else if let Some(def) = &self.default_value {
49            def.ty()
50        } else {
51            Type::Invalid
52        }
53    }
54}
55
56impl std::fmt::Display for ParameterValue {
57    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58        if let Some(def) = &self.default_value {
59            write!(f, "{} = {def}", def.ty())?;
60        } else if let Some(ty) = &self.specified_type {
61            write!(f, "= {ty}")?;
62        }
63        Ok(())
64    }
65}
66impl std::fmt::Debug for ParameterValue {
67    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68        if let Some(def) = &self.default_value {
69            write!(f, ": {ty:?} = {def:?}", ty = def.ty())?;
70        } else if let Some(ty) = &self.specified_type {
71            write!(f, "= {ty:?}")?;
72        }
73        Ok(())
74    }
75}
76
77impl SrcReferrer for ParameterValue {
78    fn src_ref(&self) -> SrcRef {
79        self.src_ref.clone()
80    }
81}
82
83#[test]
84fn test_is_list_of() {
85    assert!(
86        Type::Array(Box::new(QuantityType::Scalar.into()))
87            .is_array_of(&QuantityType::Scalar.into())
88    );
89}