melodium_loader/package/
package.rs

1use crate::Loader;
2use core::fmt::Debug;
3use melodium_common::descriptor::{
4    Collection, Identifier, IdentifierRequirement, LoadingResult, PackageRequirement,
5};
6use semver::Version;
7use std::{collections::HashMap, sync::Arc};
8
9#[derive(Debug)]
10pub enum Package {
11    Core(super::CorePackage),
12    Raw(super::RawPackage),
13    Map(super::MappedPackage),
14    #[cfg(feature = "filesystem")]
15    Fs(super::FsPackage),
16    #[cfg(feature = "jeu")]
17    Jeu(super::JeuPackage),
18}
19
20impl PackageInfo for Package {
21    fn name(&self) -> &str {
22        match self {
23            Package::Core(pkg) => pkg.name(),
24            Package::Raw(pkg) => pkg.name(),
25            Package::Map(pkg) => pkg.name(),
26            #[cfg(feature = "filesystem")]
27            Package::Fs(pkg) => pkg.name(),
28            #[cfg(feature = "jeu")]
29            Package::Jeu(pkg) => pkg.name(),
30        }
31    }
32
33    fn version(&self) -> &Version {
34        match self {
35            Package::Core(pkg) => pkg.version(),
36            Package::Raw(pkg) => pkg.version(),
37            Package::Map(pkg) => pkg.version(),
38            #[cfg(feature = "filesystem")]
39            Package::Fs(pkg) => pkg.version(),
40            #[cfg(feature = "jeu")]
41            Package::Jeu(pkg) => pkg.version(),
42        }
43    }
44
45    fn requirements(&self) -> &Vec<PackageRequirement> {
46        match self {
47            Package::Core(pkg) => pkg.requirements(),
48            Package::Raw(pkg) => pkg.requirements(),
49            Package::Map(pkg) => pkg.requirements(),
50            #[cfg(feature = "filesystem")]
51            Package::Fs(pkg) => pkg.requirements(),
52            #[cfg(feature = "jeu")]
53            Package::Jeu(pkg) => pkg.requirements(),
54        }
55    }
56
57    fn entrypoints(&self) -> &HashMap<String, Identifier> {
58        match self {
59            Package::Core(pkg) => pkg.entrypoints(),
60            Package::Raw(pkg) => pkg.entrypoints(),
61            Package::Map(pkg) => pkg.entrypoints(),
62            #[cfg(feature = "filesystem")]
63            Package::Fs(pkg) => pkg.entrypoints(),
64            #[cfg(feature = "jeu")]
65            Package::Jeu(pkg) => pkg.entrypoints(),
66        }
67    }
68}
69
70impl PackageTrait for Package {
71    fn embedded_collection(&self, loader: &Loader) -> LoadingResult<Collection> {
72        match self {
73            Package::Core(pkg) => pkg.embedded_collection(loader),
74            Package::Raw(pkg) => pkg.embedded_collection(loader),
75            Package::Map(pkg) => pkg.embedded_collection(loader),
76            #[cfg(feature = "filesystem")]
77            Package::Fs(pkg) => pkg.embedded_collection(loader),
78            #[cfg(feature = "jeu")]
79            Package::Jeu(pkg) => pkg.embedded_collection(loader),
80        }
81    }
82
83    fn full_collection(&self, loader: &Loader) -> LoadingResult<Collection> {
84        match self {
85            Package::Core(pkg) => pkg.full_collection(loader),
86            Package::Raw(pkg) => pkg.full_collection(loader),
87            Package::Map(pkg) => pkg.full_collection(loader),
88            #[cfg(feature = "filesystem")]
89            Package::Fs(pkg) => pkg.full_collection(loader),
90            #[cfg(feature = "jeu")]
91            Package::Jeu(pkg) => pkg.full_collection(loader),
92        }
93    }
94
95    fn all_identifiers(&self, loader: &Loader) -> LoadingResult<Vec<Identifier>> {
96        match self {
97            Package::Core(pkg) => pkg.all_identifiers(loader),
98            Package::Raw(pkg) => pkg.all_identifiers(loader),
99            Package::Map(pkg) => pkg.all_identifiers(loader),
100            #[cfg(feature = "filesystem")]
101            Package::Fs(pkg) => pkg.all_identifiers(loader),
102            #[cfg(feature = "jeu")]
103            Package::Jeu(pkg) => pkg.all_identifiers(loader),
104        }
105    }
106
107    fn element(
108        &self,
109        loader: &Loader,
110        identifier_requirement: &IdentifierRequirement,
111    ) -> LoadingResult<Collection> {
112        match self {
113            Package::Core(pkg) => pkg.element(loader, identifier_requirement),
114            Package::Raw(pkg) => pkg.element(loader, identifier_requirement),
115            Package::Map(pkg) => pkg.element(loader, identifier_requirement),
116            #[cfg(feature = "filesystem")]
117            Package::Fs(pkg) => pkg.element(loader, identifier_requirement),
118            #[cfg(feature = "jeu")]
119            Package::Jeu(pkg) => pkg.element(loader, identifier_requirement),
120        }
121    }
122
123    fn make_building(&self, collection: &Arc<Collection>) -> LoadingResult<()> {
124        match self {
125            Package::Core(pkg) => pkg.make_building(collection),
126            Package::Raw(pkg) => pkg.make_building(collection),
127            Package::Map(pkg) => pkg.make_building(collection),
128            #[cfg(feature = "filesystem")]
129            Package::Fs(pkg) => pkg.make_building(collection),
130            #[cfg(feature = "jeu")]
131            Package::Jeu(pkg) => pkg.make_building(collection),
132        }
133    }
134}
135
136pub trait PackageInfo: Debug {
137    fn name(&self) -> &str;
138    fn version(&self) -> &Version;
139    fn requirements(&self) -> &Vec<PackageRequirement>;
140    fn entrypoints(&self) -> &HashMap<String, Identifier>;
141}
142
143pub trait PackageTrait: Debug + PackageInfo {
144    /**
145     * Gives all elements that are ready to use as soon as package is loaded in memory.
146     *
147     * Those elements are basically the built-in ones, call to this function is relatively cheap.
148     */
149    fn embedded_collection(&self, loader: &Loader) -> LoadingResult<Collection>;
150    /**
151     * Gives all elements that are contained in the package.
152     *
153     * This call trigger disk access and parsing of all the elements, which might be costly.
154     * It should be used only when other functions in that trait don't fit for usage.
155     */
156    fn full_collection(&self, loader: &Loader) -> LoadingResult<Collection>;
157    /**
158     * Gives identifiers of all the existing elements in the package.
159     *
160     * Call to this function is cheaper than to `full_collection`, but still require some work.
161     */
162    fn all_identifiers(&self, loader: &Loader) -> LoadingResult<Vec<Identifier>>;
163    /**
164     * Gives the identified element, and the whole other ones it depends on to work.
165     *
166     * This function fits for most of the usages, and is the most optimized one for getting functionnal stuff.
167     * It loads and build all but only the required elements within the package, wether built-in or to-build elements.
168     */
169    fn element(
170        &self,
171        loader: &Loader,
172        identifier_requirement: &IdentifierRequirement,
173    ) -> LoadingResult<Collection>;
174    /**
175     * Make the final build of all elements that depends on this package within the given collection.
176     *
177     * Only after a successful call to this function the elements given by the package are guaranteed to work.
178     */
179    fn make_building(&self, collection: &Arc<Collection>) -> LoadingResult<()>;
180}