microcad_lang/value/
value_access.rs

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