microcad_lang/value/
parameter_value.rs

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