Skip to main content

sdml_generate/
lib.rs

1/*!
2This package provides a set of generators, or transformations, from the in-memory model to either other representations
3as well as actions that can be performed on modules.
4
5This package also provides a pair of traits used to define *generators*, types that convert one or more modules into
6other artifacts.
7
8# Example
9
10The following shows common usage of the `GenerateToWriter` trait in this case to write a text-tree representation of a
11modules transitive dependencies.
12
13```rust
14use sdml_core::store::InMemoryModuleCache;
15use sdml_core::model::modules::Module;
16use sdml_generate::Generator;
17use sdml_generate::actions::deps::{
18    DependencyViewGenerator, DependencyViewOptions,
19};
20use std::io::stdout;
21# use sdml_core::model::identifiers::Identifier;
22# fn load_module() -> (Module, InMemoryModuleCache) { (Module::empty(Identifier::new_unchecked("example")), InMemoryModuleCache::default()) }
23
24let (module, cache) = load_module();
25
26let mut generator = DependencyViewGenerator::default();
27let options = DependencyViewOptions::default().as_text_tree();
28generator.generate_with_options(&module, &cache, options, None, &mut stdout())
29         .expect("write to stdout failed");
30```
31
32*/
33
34#![warn(
35    unknown_lints,
36    // ---------- Stylistic
37    absolute_paths_not_starting_with_crate,
38    elided_lifetimes_in_paths,
39    explicit_outlives_requirements,
40    macro_use_extern_crate,
41    nonstandard_style, /* group */
42    noop_method_call,
43    rust_2018_idioms,
44    single_use_lifetimes,
45    trivial_casts,
46    trivial_numeric_casts,
47    // ---------- Future
48    future_incompatible, /* group */
49    rust_2021_compatibility, /* group */
50    // ---------- Public
51    missing_debug_implementations,
52    // missing_docs,
53    unreachable_pub,
54    // ---------- Unsafe
55    unsafe_code,
56    unsafe_op_in_unsafe_fn,
57    // ---------- Unused
58    unused, /* group */
59)]
60#![deny(
61    // ---------- Public
62    exported_private_dependencies,
63    // ---------- Deprecated
64    anonymous_parameters,
65    bare_trait_objects,
66    ellipsis_inclusive_range_patterns,
67    // ---------- Unsafe
68    deref_nullptr,
69    drop_bounds,
70    dyn_drop,
71)]
72
73use sdml_core::{error::Error, model::modules::Module, store::ModuleStore};
74use std::{fmt::Debug, fs::OpenOptions, io::Cursor, io::Write, path::PathBuf};
75
76// ------------------------------------------------------------------------------------------------
77// Public Types
78// ------------------------------------------------------------------------------------------------
79
80///
81/// This trait denotes a type that generates content from a module.
82///
83/// The type `Options` denotes some type that contains any settings that affect the behavior of
84/// the generator. If no settings are required `Options` may be set to `()`. Given that options
85/// are provided at the method level it is recommended that generators are constructed using
86/// `Default::default()`.
87///
88pub trait Generator: Default {
89    type Options: Default + Debug;
90
91    // --------------------------------------------------------------------------------------------
92    // Write to ❱ implementation of `Write`
93    // --------------------------------------------------------------------------------------------
94
95    ///
96    /// Generate from the given module into the provided writer. Note that this calls
97    /// `generate_with_options` using `Self::Options::default()`.
98    ///
99    fn generate<W>(
100        &mut self,
101        module: &Module,
102        cache: &impl ModuleStore,
103        path: Option<PathBuf>,
104        writer: &mut W,
105    ) -> Result<(), Error>
106    where
107        W: Write + Sized,
108    {
109        self.generate_with_options(module, cache, Default::default(), path, writer)
110    }
111
112    ///
113    /// Generate from the given module into a string.
114    ///
115    fn generate_to_string(
116        &mut self,
117        module: &Module,
118        cache: &impl ModuleStore,
119        options: Self::Options,
120        path: Option<PathBuf>,
121    ) -> Result<String, Error> {
122        let mut buffer = Cursor::new(Vec::new());
123        self.generate_with_options(module, cache, options, path, &mut buffer)?;
124        Ok(String::from_utf8(buffer.into_inner())?)
125    }
126
127    ///
128    /// Generate from the given module into a file.
129    ///
130    /// Note: The referenced file will be created if it does not exist, and replaced if it does.
131    ///
132    fn generate_to_file(
133        &mut self,
134        module: &Module,
135        cache: &impl ModuleStore,
136        options: Self::Options,
137        path: &PathBuf,
138    ) -> Result<(), Error> {
139        let mut file = OpenOptions::new()
140            .create(true)
141            .truncate(true)
142            .write(true)
143            .open(path)?;
144        self.generate_with_options(module, cache, options, Some(path.clone()), &mut file)
145    }
146
147    ///
148    /// Generate from the given module into the provided writer.
149    ///
150    fn generate_with_options<W>(
151        &mut self,
152        module: &Module,
153        cache: &impl ModuleStore,
154        options: Self::Options,
155        path: Option<PathBuf>,
156        writer: &mut W,
157    ) -> Result<(), Error>
158    where
159        W: Write + Sized;
160}
161
162// ------------------------------------------------------------------------------------------------
163// Modules
164// ------------------------------------------------------------------------------------------------
165
166#[macro_use]
167mod macros;
168
169mod errors;
170
171mod exec;
172
173pub mod color;
174
175pub mod actions;
176
177pub mod convert;
178
179pub mod draw;