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}