melodium_core/descriptor/
context.rs

1use core::fmt::{Display, Formatter, Result};
2use melodium_common::descriptor::{
3    Attribuable, Attributes, Context as ContextDescriptor, DataType, DescribedType, Documented,
4    Identified, Identifier,
5};
6use std::collections::HashMap;
7use std::iter::FromIterator;
8use std::sync::Arc;
9
10#[derive(Debug)]
11pub struct Context {
12    identifier: Identifier,
13    values: HashMap<String, DataType>,
14    #[cfg(feature = "doc")]
15    documentation: String,
16    attributes: Attributes,
17}
18
19impl Context {
20    pub fn new(
21        identifier: Identifier,
22        values: Vec<(&str, DataType)>,
23        #[cfg(feature = "doc")] documentation: String,
24        #[cfg(not(feature = "doc"))] _documentation: String,
25        attributes: Attributes,
26    ) -> Arc<Self> {
27        Arc::new(Self {
28            identifier,
29            values: HashMap::from_iter(values.into_iter().map(|v| (v.0.to_string(), v.1))),
30            #[cfg(feature = "doc")]
31            documentation,
32            attributes,
33        })
34    }
35}
36
37impl Attribuable for Context {
38    fn attributes(&self) -> &Attributes {
39        &self.attributes
40    }
41}
42
43impl ContextDescriptor for Context {
44    fn name(&self) -> &str {
45        &self.identifier.name()
46    }
47
48    fn values(&self) -> &HashMap<String, DataType> {
49        &self.values
50    }
51}
52
53impl Documented for Context {
54    fn documentation(&self) -> &str {
55        #[cfg(feature = "doc")]
56        {
57            &self.documentation
58        }
59        #[cfg(not(feature = "doc"))]
60        {
61            &""
62        }
63    }
64}
65
66impl Identified for Context {
67    fn identifier(&self) -> &Identifier {
68        &self.identifier
69    }
70
71    fn make_use(&self, identifier: &Identifier) -> bool {
72        self.values.values().any(|val| {
73            DescribedType::from(val)
74                .final_type()
75                .data()
76                .map(|data| data.identifier() == identifier || data.make_use(identifier))
77                .unwrap_or(false)
78        })
79    }
80
81    fn uses(&self) -> Vec<Identifier> {
82        self.values
83            .values()
84            .filter_map(|val| {
85                DescribedType::from(val).final_type().data().map(|data| {
86                    let mut uses = vec![data.identifier().clone()];
87                    uses.extend(data.uses());
88                    uses
89                })
90            })
91            .flatten()
92            .collect()
93    }
94}
95
96impl Display for Context {
97    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
98        write!(f, "context {}", self.identifier.to_string())?;
99
100        for (name, dt) in &self.values {
101            write!(f, "{}: {}", name, dt)?
102        }
103
104        Ok(())
105    }
106}