microcad_lang/syntax/
init_definition.rs

1// Copyright © 2024-2025 The µcad authors <info@ucad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4//! Initialization definition syntax element
5
6use crate::{src_ref::*, syntax::*};
7
8/// Workbench *initializer* definition
9///
10/// Example:
11///
12/// ```uCAD
13/// part A(a: Length) {
14///     init(b: Length) { a = 2.0*b; } // The init definition
15/// }
16/// ```
17#[derive(Clone, Debug)]
18pub struct InitDefinition {
19    /// Parameter list for this init definition
20    pub parameters: ParameterList,
21    /// Body if the init definition
22    pub body: Body,
23    /// Source reference
24    pub src_ref: SrcRef,
25}
26
27impl SrcReferrer for InitDefinition {
28    fn src_ref(&self) -> SrcRef {
29        self.src_ref.clone()
30    }
31}
32
33impl std::fmt::Display for InitDefinition {
34    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35        write!(f, "init({parameters}) ", parameters = self.parameters)?;
36        write!(f, "{body}", body = self.body)
37    }
38}
39
40impl TreeDisplay for InitDefinition {
41    fn tree_print(&self, f: &mut std::fmt::Formatter, mut depth: TreeState) -> std::fmt::Result {
42        writeln!(f, "{:depth$}InitDefinition:", "")?;
43        depth.indent();
44        self.parameters.tree_print(f, depth)?;
45        self.body.tree_print(f, depth)
46    }
47}
48
49/// Iterator over part's *initializers*.
50pub struct Inits<'a>(std::slice::Iter<'a, Statement>);
51
52/// Interface for elements which have *initializers*.
53pub trait Initialized<'a> {
54    /// return iterator of body statements.
55    fn statements(&'a self) -> std::slice::Iter<'a, Statement>;
56
57    /// Return iterator over all initializers.
58    fn inits(&'a self) -> Inits<'a>
59    where
60        Self: std::marker::Sized,
61    {
62        Inits::new(self)
63    }
64}
65
66impl<'a> Inits<'a> {
67    /// Create new init for a part.
68    pub fn new(def: &'a impl Initialized<'a>) -> Self {
69        Self(def.statements())
70    }
71}
72
73impl<'a> Iterator for Inits<'a> {
74    type Item = &'a InitDefinition;
75
76    fn next(&mut self) -> Option<Self::Item> {
77        for statement in self.0.by_ref() {
78            match statement {
79                Statement::Init(init_definition) => {
80                    return Some(init_definition);
81                }
82                _ => continue,
83            }
84        }
85
86        None
87    }
88}