1use std::sync::Arc;
16
17use sim_cookbook::EmbeddedDir;
18use sim_kernel::{CodecId, Lib};
19
20use crate::catalog::LibCatalog;
21use crate::config::{ConfigProvider, LoadableLibResolver, ResolvedLoadable, built_in_config};
22use crate::loadable::LoadableLibList;
23
24pub struct SeededLibCatalog {
26 libs: Vec<Box<dyn Lib>>,
27}
28
29impl SeededLibCatalog {
30 pub fn standard() -> Self {
36 let libs: Vec<Box<dyn Lib>> = vec![
37 Box::new(sim_lib_numbers_i64::I64NumbersLib::new()),
38 Box::new(sim_lib_numbers_arith::NumbersArithmeticLib::new()),
39 Box::new(sim_lib_numbers_bigint::BigIntNumbersLib::new()),
40 Box::new(sim_lib_numbers_bool::BoolNumbersLib::new()),
41 Box::new(sim_lib_numbers_f64::F64NumbersLib::new()),
42 Box::new(sim_lib_numbers_rational::RationalNumbersLib::new()),
43 Box::new(sim_lib_numbers_complex::ComplexNumbersLib::new()),
44 Box::new(sim_lib_numbers_func::FuncNumbersLib::new()),
45 Box::new(sim_lib_numbers_cas::CasNumbersLib::new()),
46 Box::new(sim_lib_numbers_tensor::TensorNumbersLib::new()),
47 Box::new(sim_lib_numbers_tensor_bcast::TensorBroadcastLib::new()),
51 Box::new(sim_lib_discrete::DiscreteLib),
52 Box::new(sim_lib_binding::BindingLib),
56 Box::new(sim_lib_control::ControlLib),
57 Box::new(sim_lib_sequence::SequenceLib),
58 Box::new(sim_lib_pattern::PatternLib),
59 Box::new(sim_codec_algol::AlgolCodecLib::new(CodecId(201))),
66 Box::new(sim_lib_lang_scheme::SchemeCodecLib::new(CodecId(202))),
67 Box::new(sim_lib_midi_core::MidiDigestLib),
70 ];
71 Self { libs }
72 }
73
74 pub fn loadable_libs() -> LoadableLibList {
76 let resolver = BuiltInLoadableResolver;
77 let provider = ConfigProvider::new(built_in_config(), &resolver);
78 let (directory, diagnostics) = provider.loadable_libs();
79 debug_assert!(diagnostics.is_empty(), "{diagnostics:?}");
80 directory
81 }
82}
83
84impl LibCatalog for SeededLibCatalog {
85 fn resolve(&self, name: &str) -> Option<&dyn Lib> {
86 self.libs
87 .iter()
88 .find(|lib| {
89 let id = lib.manifest().id;
90 id.as_qualified_str() == name || id.name.as_ref() == name
91 })
92 .map(|lib| lib.as_ref())
93 }
94}
95
96pub struct BuiltInLoadableResolver;
98
99impl LoadableLibResolver for BuiltInLoadableResolver {
100 fn resolve(&self, source: &str, _id: &str) -> Option<ResolvedLoadable> {
101 match source {
102 "symbol:numbers/i64" => Some(resolved(
103 "I64 numbers",
104 Some(sim_lib_numbers_i64::RECIPES),
105 || Box::new(sim_lib_numbers_i64::I64NumbersLib::new()),
106 )),
107 "symbol:numbers/arith" => Some(resolved(
108 "Arithmetic numbers",
109 Some(sim_lib_numbers_arith::RECIPES),
110 || Box::new(sim_lib_numbers_arith::NumbersArithmeticLib::new()),
111 )),
112 "symbol:numbers/bigint" => Some(resolved(
113 "Big integer numbers",
114 Some(sim_lib_numbers_bigint::RECIPES),
115 || Box::new(sim_lib_numbers_bigint::BigIntNumbersLib::new()),
116 )),
117 "symbol:numbers/bool" => Some(resolved(
118 "Boolean numbers",
119 Some(sim_lib_numbers_bool::RECIPES),
120 || Box::new(sim_lib_numbers_bool::BoolNumbersLib::new()),
121 )),
122 "symbol:numbers/f64" => Some(resolved(
123 "F64 numbers",
124 Some(sim_lib_numbers_f64::RECIPES),
125 || Box::new(sim_lib_numbers_f64::F64NumbersLib::new()),
126 )),
127 "symbol:numbers/rational" => Some(resolved(
128 "Rational numbers",
129 Some(sim_lib_numbers_rational::RECIPES),
130 || Box::new(sim_lib_numbers_rational::RationalNumbersLib::new()),
131 )),
132 "symbol:numbers/complex" => Some(resolved(
133 "Complex numbers",
134 Some(sim_lib_numbers_complex::RECIPES),
135 || Box::new(sim_lib_numbers_complex::ComplexNumbersLib::new()),
136 )),
137 "symbol:numbers/func" => Some(resolved(
138 "Function numbers",
139 Some(sim_lib_numbers_func::RECIPES),
140 || Box::new(sim_lib_numbers_func::FuncNumbersLib::new()),
141 )),
142 "symbol:numbers/cas" => Some(resolved(
143 "CAS numbers",
144 Some(sim_lib_numbers_cas::RECIPES),
145 || Box::new(sim_lib_numbers_cas::CasNumbersLib::new()),
146 )),
147 "symbol:numbers/tensor" => Some(resolved(
148 "Tensor numbers",
149 Some(sim_lib_numbers_tensor::RECIPES),
150 || Box::new(sim_lib_numbers_tensor::TensorNumbersLib::new()),
151 )),
152 "symbol:numbers/tensor-bcast" => {
153 Some(resolved("Tensor broadcast numbers", None, || {
154 Box::new(sim_lib_numbers_tensor_bcast::TensorBroadcastLib::new())
155 }))
156 }
157 "symbol:discrete" => Some(resolved(
158 "Discrete math",
159 Some(sim_lib_discrete::RECIPES),
160 || Box::new(sim_lib_discrete::DiscreteLib),
161 )),
162 "symbol:organ/binding" => Some(resolved(
163 "Binding organ",
164 Some(sim_lib_binding::RECIPES),
165 || Box::new(sim_lib_binding::BindingLib),
166 )),
167 "symbol:organ/control" => Some(resolved(
168 "Control organ",
169 Some(sim_lib_control::RECIPES),
170 || Box::new(sim_lib_control::ControlLib),
171 )),
172 "symbol:organ/sequence" => Some(resolved(
173 "Sequence organ",
174 Some(sim_lib_sequence::RECIPES),
175 || Box::new(sim_lib_sequence::SequenceLib),
176 )),
177 "symbol:organ/pattern" => Some(resolved(
178 "Pattern organ",
179 Some(sim_lib_pattern::RECIPES),
180 || Box::new(sim_lib_pattern::PatternLib),
181 )),
182 "symbol:codec/algol" => Some(resolved(
183 "Algol codec",
184 Some(sim_codec_algol::RECIPES),
185 || Box::new(sim_codec_algol::AlgolCodecLib::new(CodecId(201))),
186 )),
187 "symbol:codec/scheme-r7rs-small" => Some(resolved(
188 "Scheme codec",
189 Some(sim_lib_lang_scheme::RECIPES),
190 || Box::new(sim_lib_lang_scheme::SchemeCodecLib::new(CodecId(202))),
191 )),
192 "symbol:midi/digest" => Some(resolved(
193 "MIDI digest",
194 Some(sim_lib_midi_core::RECIPES),
195 || Box::new(sim_lib_midi_core::MidiDigestLib),
196 )),
197 _ => None,
198 }
199 }
200}
201
202fn resolved<F>(title: &str, recipes: Option<EmbeddedDir>, make: F) -> ResolvedLoadable
203where
204 F: Fn() -> Box<dyn Lib + Send + Sync> + Send + Sync + 'static,
205{
206 ResolvedLoadable {
207 title: title.to_owned(),
208 recipes,
209 factory: Arc::new(make),
210 }
211}