melodium_lang/semantic/
assigned_generic.rs

1//! Module dedicated to AssignedGeneric semantic analysis.
2
3use super::common::Node;
4use super::DeclarativeElement;
5use super::Type;
6use super::TypeFlow;
7use crate::error::ScriptError;
8use crate::text::Generic as TextGeneric;
9use crate::ScriptResult;
10use std::sync::{Arc, RwLock, Weak};
11
12/// Structure managing and describing semantic of an assigned generic.
13///
14/// It owns the whole [text parameter](TextParameter).
15#[derive(Debug)]
16pub struct AssignedGeneric {
17    pub text: TextGeneric,
18
19    pub scope: Weak<RwLock<dyn DeclarativeElement>>,
20
21    pub r#type: Arc<RwLock<Type>>,
22}
23
24impl AssignedGeneric {
25    /// Create a new semantic assignation of generic, based on textual generic.
26    ///
27    /// * `parent`: the parent element owning this assignation.
28    /// * `text`: the textual generic.
29    ///
30    /// # Note
31    /// Only parent-child relationships are made at this step. Other references can be made afterwards using the [Node trait](Node).
32    ///
33    pub fn new(
34        scope: Arc<RwLock<dyn DeclarativeElement>>,
35        text: TextGeneric,
36    ) -> ScriptResult<Arc<RwLock<Self>>> {
37        let result = ScriptResult::new_success(());
38
39        result
40            .and_then(|_| {
41                if !text.traits.is_empty() {
42                    ScriptResult::new_failure(ScriptError::invalid_generic(
43                        178,
44                        text.r#type.name.clone(),
45                    ))
46                } else {
47                    ScriptResult::new_success(())
48                }
49            })
50            .and_then(|_| Type::new(Arc::clone(&scope), text.r#type.clone()))
51            .and_then(|assigned_type| {
52                if assigned_type.flow != TypeFlow::Block {
53                    ScriptResult::new_failure(ScriptError::flow_forbidden(168, text.r#type.name))
54                } else {
55                    ScriptResult::new_success(Arc::new(RwLock::new(Self {
56                        text,
57                        r#type: Arc::new(RwLock::new(assigned_type)),
58                        scope: Arc::downgrade(&scope),
59                    })))
60                }
61            })
62    }
63}
64
65impl Node for AssignedGeneric {
66    fn children(&self) -> Vec<Arc<RwLock<dyn Node>>> {
67        vec![Arc::clone(&self.r#type) as Arc<RwLock<dyn Node>>]
68    }
69}