rainier_framework/
facades.rs1use std::sync::Arc;
22
23use rainier_container::facade;
24use rainier_view::ViewEngine;
25
26#[derive(Clone)]
32pub struct Views(pub Arc<dyn ViewEngine>);
33
34impl Views {
35 pub fn new(engine: Arc<dyn ViewEngine>) -> Self {
37 Self(engine)
38 }
39
40 pub fn engine(&self) -> &Arc<dyn ViewEngine> {
42 &self.0
43 }
44
45 pub fn render(&self, name: &str, data: &serde_json::Value) -> rainier_support::Result<String> {
47 self.0.render(name, data)
48 }
49
50 pub fn render_view(&self, view: &rainier_view::View) -> rainier_support::Result<String> {
52 self.0.render_view(view)
53 }
54}
55
56impl std::fmt::Debug for Views {
57 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58 f.write_str("Views(..)")
59 }
60}
61
62facade!(
63 Config => rainier_config::Config
65);
66
67facade!(
68 Event => rainier_events::Dispatcher
70);
71
72facade!(
73 DB => rainier_database::Database
75);
76
77facade!(
78 Queue => rainier_queue::QueueManager
80);
81
82facade!(
83 Mail => rainier_mail::Mailer
85);
86
87facade!(
88 View => Views
90);
91
92facade!(
93 Url => rainier_routing::UrlGenerator
95);
96
97facade!(
98 Middleware => rainier_middleware::MiddlewareRegistry
100);
101
102facade!(
103 Crypt => rainier_crypt::Encryption
105);
106
107facade!(
108 Notify => rainier_notify::Notifier
110);
111
112facade!(
113 Broadcast => rainier_broadcast::Broadcasting
115);
116
117facade!(
118 Cache => rainier_cache::CacheManager
120);
121
122facade!(
123 Storage => rainier_filesystem::Storage
125);
126
127facade!(
128 Session => rainier_session::SessionManager
139);
140
141#[cfg(test)]
153mod tests {
154 use super::*;
155 use rainier_container::{
156 clear_facade_application, set_facade_application, Application, Facade,
157 };
158 use rainier_view::MemoryEngine;
159
160 static SERIAL: std::sync::Mutex<()> = std::sync::Mutex::new(());
162
163 fn install(build: impl FnOnce(&Application)) -> std::sync::MutexGuard<'static, ()> {
164 let guard = SERIAL.lock().unwrap_or_else(|e| e.into_inner());
165 let app = Application::new(".");
166 build(&app);
167 set_facade_application(Arc::new(app));
168 guard
169 }
170
171 #[test]
172 fn the_config_facade_reads_through_the_container() {
173 let _guard = install(|app| {
174 let config = rainier_config::Config::new();
175 config.set("app.name", "Rainier").unwrap();
176 app.instance(config);
177 });
178
179 assert_eq!(Config::instance().string("app.name").as_deref(), Some("Rainier"));
180 clear_facade_application();
181 }
182
183 #[test]
184 fn the_view_facade_renders() {
185 let _guard = install(|app| {
186 app.instance(Views::new(Arc::new(
187 MemoryEngine::new().with("greeting", "Hi {{ name }}"),
188 )));
189 });
190
191 let rendered =
192 View::instance().render("greeting", &serde_json::json!({ "name": "Ada" })).unwrap();
193 assert_eq!(rendered, "Hi Ada");
194 clear_facade_application();
195 }
196
197 #[test]
198 fn rebinding_swaps_what_every_call_sees() {
199 let _guard = install(|app| {
200 app.instance(Views::new(Arc::new(MemoryEngine::new().with("t", "first"))));
201 });
202 assert_eq!(View::instance().render("t", &serde_json::json!({})).unwrap(), "first");
203
204 rainier_container::facade_application()
205 .instance(Views::new(Arc::new(MemoryEngine::new().with("t", "second"))));
206 assert_eq!(View::instance().render("t", &serde_json::json!({})).unwrap(), "second");
207
208 clear_facade_application();
209 }
210
211 #[test]
212 fn an_unbound_facade_reads_as_none_rather_than_panicking_through_try() {
213 let _guard = install(|_| {});
214 assert!(DB::try_instance().is_none());
215 clear_facade_application();
216 }
217}