sdml_core/load.rs
1/*!
2This module provides the traits for loading modules from some source.
3
4The goal of the traits [`ModuleResolver`] and [`ModuleLoader`] is to provide the ability to load
5a module into memory from some resource.
6
7# Example
8
9```
10use sdml_core::model::identifiers::Identifier;
11use sdml_core::load::ModuleLoader;
12use sdml_core::store::ModuleStore;
13
14fn module_found(
15 module: &Identifier,
16 loader: &mut impl ModuleLoader,
17 cache: &mut impl ModuleStore
18) -> bool {
19 loader.load(module, None, cache, false).is_ok()
20}
21```
22
23 */
24
25use crate::{model::identifiers::Identifier, store::ModuleStore};
26use sdml_errors::{
27 diagnostics::{reporter::ReportCounters, SeverityFilter},
28 Diagnostic, FileId, Source,
29};
30use url::Url;
31
32// ------------------------------------------------------------------------------------------------
33// Public Types
34// ------------------------------------------------------------------------------------------------
35
36///
37/// A resolver implementation is responsible for determining the resource identifier (URL) for
38/// a module named `name`. The additional parameter `from` identifies the module source making
39/// the request.
40///
41pub trait ModuleResolver: Default {
42 ///
43 /// Return a URL given the module name `name`.
44 ///
45 fn name_to_resource(
46 &self,
47 name: &Identifier,
48 from: Option<FileId>,
49 ) -> Result<Url, sdml_errors::Error>;
50}
51
52///
53/// A loader instance is responsible for resolving a module into a resource URL and parsing it into
54/// memory. Note that the loader does not return the module instance itself but rather the module's
55/// name parsed from the resource, the module itself is inserted into the `cache`.
56///
57pub trait ModuleLoader: Default {
58 ///
59 /// Resolve `name` into a resource identifier (URL) and parse into memory. The loader will check
60 /// the `store` first to see if the module is already loaded, and will add the module into the
61 /// store after parsing. The value of `recursive` tells the loader whether to also load
62 /// the module's dependencies as well.
63 ///
64 fn load(
65 &mut self,
66 name: &Identifier,
67 from: Option<FileId>,
68 store: &mut impl ModuleStore,
69 recursive: bool,
70 ) -> Result<Identifier, sdml_errors::Error>;
71
72 ///
73 /// Returns the instance of [`ModuleResolver`] used by this loader.
74 ///
75 fn resolver(&self) -> &impl ModuleResolver;
76
77 fn get_file_id(&self, name: &Identifier) -> Option<FileId>;
78
79 fn get_source_by_name(&self, name: &Identifier) -> Option<Source> {
80 self.get_file_id(name).and_then(|id| self.get_source(id))
81 }
82
83 fn has_source(&self, file_id: FileId) -> bool {
84 self.get_source(file_id).is_some()
85 }
86
87 fn get_source(&self, file_id: FileId) -> Option<Source>;
88
89 fn report(&self, diagnostic: &Diagnostic) -> Result<(), sdml_errors::Error>;
90 fn reporter_done(
91 &self,
92 top_module_name: Option<String>,
93 ) -> Result<ReportCounters, sdml_errors::Error>;
94
95 fn set_severity_filter(&mut self, filter: SeverityFilter);
96}