Skip to main content

melodium_share/
collection.rs

1use crate::{Context, Data, Function, Identifier, Model, Treatment};
2use itertools::Itertools;
3use melodium_common::descriptor::{
4    Collection as CommonCollection, Entry, Identified, Identifier as CommonIdentifier,
5};
6use serde::{Deserialize, Serialize};
7use std::collections::VecDeque;
8
9#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
10#[serde(rename_all = "snake_case")]
11#[cfg_attr(feature = "webassembly", derive(tsify::Tsify))]
12#[cfg_attr(feature = "webassembly", tsify(into_wasm_abi, from_wasm_abi))]
13pub enum Element {
14    Context(Context),
15    Data(Data),
16    Function(Function),
17    Model(Model),
18    Treatment(Treatment),
19}
20
21impl Element {
22    pub fn identifier(&self) -> &Identifier {
23        match self {
24            Element::Context(c) => &c.identifier,
25            Element::Data(d) => &d.identifier,
26            Element::Function(f) => &f.identifier,
27            Element::Model(m) => &m.identifier,
28            Element::Treatment(t) => &t.identifier,
29        }
30    }
31
32    pub fn is_compiled(&self) -> bool {
33        match self {
34            Element::Context(_) => true,
35            Element::Data(_) => true,
36            Element::Function(_) => true,
37            Element::Model(m) => m.implementation_kind.is_compiled(),
38            Element::Treatment(t) => t.implementation_kind.is_compiled(),
39        }
40    }
41}
42
43impl From<&Entry> for Element {
44    fn from(value: &Entry) -> Self {
45        match value {
46            Entry::Context(c) => Element::Context(c.as_ref().into()),
47            Entry::Data(d) => Element::Data(d.as_ref().into()),
48            Entry::Function(f) => Element::Function(f.as_ref().into()),
49            Entry::Model(m) => Element::Model(m.into()),
50            Entry::Treatment(t) => Element::Treatment(t.into()),
51        }
52    }
53}
54
55#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
56#[cfg_attr(feature = "webassembly", derive(tsify::Tsify))]
57#[cfg_attr(feature = "webassembly", tsify(into_wasm_abi, from_wasm_abi))]
58pub struct Collection {
59    elements: Vec<Element>,
60}
61
62impl Collection {
63    pub fn elements(&self) -> &Vec<Element> {
64        &self.elements
65    }
66
67    pub fn to_elements(self) -> Vec<Element> {
68        self.elements
69    }
70
71    pub fn from_entrypoint(collection: &CommonCollection, entrypoint: &CommonIdentifier) -> Self {
72        let mut identifiers: VecDeque<CommonIdentifier> = VecDeque::new();
73
74        if let Some(element) = collection.get(&entrypoint.into()) {
75            let mut prepending_identifiers = element.uses();
76            while !prepending_identifiers.is_empty() {
77                prepending_identifiers
78                    .iter()
79                    .rev()
80                    .for_each(|id| identifiers.push_front(id.clone()));
81
82                let mut new_identifiers = Vec::new();
83                for id in &prepending_identifiers {
84                    if let Some(element) = collection.get(&id.into()) {
85                        new_identifiers.extend(element.uses());
86                    }
87                }
88
89                prepending_identifiers = new_identifiers;
90            }
91        }
92
93        identifiers.push_back(entrypoint.clone());
94
95        let elements = identifiers
96            .iter()
97            .unique()
98            .filter_map(|identifier| collection.get(&identifier.into()).map(|entry| entry.into()))
99            .collect();
100
101        Self { elements }
102    }
103}
104
105impl From<&CommonCollection> for Collection {
106    fn from(collection: &CommonCollection) -> Self {
107        Self {
108            elements: collection
109                .identifiers()
110                .iter()
111                .filter_map(|identifier| {
112                    collection
113                        .get(&(identifier.into()))
114                        .map(|entry| entry.into())
115                })
116                .collect(),
117        }
118    }
119}