microcad_lang/syntax/call/
argument.rs

1// Copyright © 2024-2025 The µcad authors <info@ucad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4//! A single argument
5
6use crate::{ord_map::*, src_ref::*, syntax::*};
7
8/// Argument in a [`Call`].
9#[derive(Clone, PartialEq)]
10pub struct Argument {
11    /// Name of the argument
12    pub id: Option<Identifier>,
13    /// Value of the argument
14    pub expression: Expression,
15    /// Source code reference
16    pub src_ref: SrcRef,
17}
18
19impl Argument {
20    /// Returns the name, if self.name is some. If self.name is None, try to extract the name from the expression
21    pub fn derived_name(&self) -> Option<Identifier> {
22        match &self.id {
23            Some(name) => Some(name.clone()),
24            None => self.expression.single_identifier().cloned(),
25        }
26    }
27}
28
29impl SrcReferrer for Argument {
30    fn src_ref(&self) -> SrcRef {
31        self.src_ref.clone()
32    }
33}
34
35impl OrdMapValue<Identifier> for Argument {
36    fn key(&self) -> Option<Identifier> {
37        self.id.clone()
38    }
39}
40
41impl std::fmt::Display for Argument {
42    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
43        match self.id {
44            Some(ref id) => write!(f, "{id} = {}", self.expression),
45            None => write!(f, "{}", self.expression),
46        }
47    }
48}
49
50impl std::fmt::Debug for Argument {
51    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
52        match self.id {
53            Some(ref id) => write!(f, "{id:?} = {:?}", self.expression),
54            None => write!(f, "{:?}", self.expression),
55        }
56    }
57}
58
59impl TreeDisplay for Argument {
60    fn tree_print(&self, f: &mut std::fmt::Formatter, mut depth: TreeState) -> std::fmt::Result {
61        match self.id {
62            Some(ref id) => writeln!(f, "{:depth$}Argument '{id:?}':", "")?,
63            None => writeln!(f, "{:depth$}Argument:", "")?,
64        };
65        depth.indent();
66        self.expression.tree_print(f, depth)
67    }
68}
69
70#[test]
71fn test_argument_debug() {
72    let arg1 = Argument {
73        id: Some("id1".into()),
74        expression: Expression::QualifiedName("my::name1".into()),
75        src_ref: SrcRef(None),
76    };
77
78    let arg2 = Argument {
79        id: None,
80        expression: Expression::QualifiedName("my::name2".into()),
81        src_ref: SrcRef(None),
82    };
83
84    let arg3 = Argument {
85        id: Some(Identifier::none()),
86        expression: Expression::QualifiedName("my::name2".into()),
87        src_ref: SrcRef(None),
88    };
89
90    let mut args = ArgumentList::default();
91
92    args.try_push(arg1).expect("test error");
93    args.try_push(arg2).expect("test error");
94    args.try_push(arg3).expect("test error");
95
96    log::info!("{args}");
97    log::info!("{args:?}");
98}