Skip to main content

microcad_lang/value/
value_access.rs

1// Copyright © 2025-2026 The µcad authors <info@microcad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4//! Value access trait
5
6use crate::value::*;
7
8use microcad_lang_base::Identifier;
9
10/// Trait for Value Lists
11pub trait ValueAccess {
12    /// Find named value by identifier.
13    fn by_id(&self, id: &Identifier) -> Option<&Value>;
14
15    /// Find unnamed value by type.
16    fn by_ty(&self, ty: &Type) -> Option<&Value>;
17
18    /// Helper function to fetch an argument by string.
19    fn by_str<'a, T>(&'a self, id: &str) -> ValueResult<T>
20    where
21        T: std::convert::TryFrom<&'a Value>,
22        T::Error: std::fmt::Debug,
23    {
24        let id = &Identifier::no_ref(id);
25        if let Some(val) = self.by_id(id) {
26            if let Ok(val) = TryInto::try_into(val) {
27                Ok(val)
28            } else {
29                Err(ValueError::CannotConvert(
30                    val.to_string(),
31                    std::any::type_name::<T>().into(),
32                ))
33            }
34        } else {
35            Err(ValueError::IdNotFound(id.clone()))
36        }
37    }
38
39    /// Fetch an argument value by name as `&str`.
40    fn get<'a, T>(&'a self, id: &str) -> T
41    where
42        T: std::convert::TryFrom<&'a Value>,
43        T::Error: std::fmt::Debug,
44    {
45        self.by_str(id).expect("No error")
46    }
47
48    /// Fetch an argument value by name as `&str`.
49    ///
50    /// Panics if `id ` cannot be found.`
51    fn get_value(&self, id: &str) -> ValueResult<&Value> {
52        let id = Identifier::no_ref(id);
53        if let Some(value) = self.by_id(&id) {
54            Ok(value)
55        } else {
56            Err(ValueError::IdNotFound(id))
57        }
58    }
59
60    /// Return `true`, if tuple contains a value with that name
61    fn contains_id(&self, id: &Identifier) -> bool {
62        self.by_id(id).is_some()
63    }
64}