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;