Skip to content

Commit fa5aef6

Browse files
committed
avoid instanciating the default component when not needed
1 parent 9d4c8c1 commit fa5aef6

File tree

1 file changed

+43
-26
lines changed

1 file changed

+43
-26
lines changed

src/render.rs

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -219,13 +219,13 @@ fn get_object_str<'a>(json: &'a JsonValue, key: &str) -> Option<&'a str> {
219219
pub struct RenderContext<W: std::io::Write> {
220220
app_state: Arc<AppState>,
221221
pub writer: W,
222-
current_component: SplitTemplateRenderer,
222+
current_component: Option<SplitTemplateRenderer>,
223223
shell_renderer: SplitTemplateRenderer,
224224
recursion_depth: usize,
225225
current_statement: usize,
226226
}
227227

228-
const DEFAULT_COMPONENT: &str = "default";
228+
const DEFAULT_COMPONENT: &str = "debug";
229229
const SHELL_COMPONENT: &str = "shell";
230230
const DYNAMIC_COMPONENT: &str = "dynamic";
231231
const MAX_RECURSION_DEPTH: usize = 256;
@@ -241,7 +241,8 @@ impl<W: std::io::Write> RenderContext<W> {
241241
.await
242242
.with_context(|| "The shell component should always exist")?;
243243

244-
let mut initial_component = get_object_str(&initial_row, "component");
244+
let mut initial_component =
245+
Some(get_object_str(&initial_row, "component").unwrap_or(DEFAULT_COMPONENT));
245246
let mut shell_properties = JsonValue::Null;
246247
match initial_component {
247248
Some(SHELL_COMPONENT) => {
@@ -266,14 +267,10 @@ impl<W: std::io::Write> RenderContext<W> {
266267
log::debug!("Rendering the shell with properties: {shell_properties}");
267268
shell_renderer.render_start(&mut writer, shell_properties)?;
268269

269-
let current_component = Self::create_renderer(DEFAULT_COMPONENT, Arc::clone(&app_state))
270-
.await
271-
.with_context(|| format!("Unable to open the rendering context because opening the {DEFAULT_COMPONENT} component failed"))?;
272-
273270
let mut initial_context = RenderContext {
274271
app_state,
275272
writer,
276-
current_component,
273+
current_component: None,
277274
shell_renderer,
278275
recursion_depth: 0,
279276
current_statement: 1,
@@ -287,14 +284,21 @@ impl<W: std::io::Write> RenderContext<W> {
287284
Ok(initial_context)
288285
}
289286

287+
async fn current_component(&mut self) -> anyhow::Result<&mut SplitTemplateRenderer> {
288+
if self.current_component.is_none() {
289+
let _old = self.set_current_component(DEFAULT_COMPONENT).await?;
290+
}
291+
Ok(self.current_component.as_mut().unwrap())
292+
}
293+
290294
#[async_recursion(? Send)]
291295
pub async fn handle_row(&mut self, data: &JsonValue) -> anyhow::Result<()> {
292296
log::debug!(
293297
"<- Processing database row: {}",
294298
serde_json::to_string(&data).unwrap_or_else(|e| e.to_string())
295299
);
296300
let new_component = get_object_str(data, "component");
297-
let current_component = SplitTemplateRenderer::name(&self.current_component);
301+
let current_component = self.current_component().await?.name();
298302
match (current_component, new_component) {
299303
(_current_component, Some(DYNAMIC_COMPONENT)) => {
300304
self.render_dynamic(data).await.with_context(|| {
@@ -309,7 +313,7 @@ impl<W: std::io::Write> RenderContext<W> {
309313
self.open_component_with_data(new_component, &data).await?;
310314
}
311315
(_, _) => {
312-
self.render_current_template_with_data(&data)?;
316+
self.render_current_template_with_data(&data).await?;
313317
}
314318
}
315319
Ok(())
@@ -374,7 +378,8 @@ impl<W: std::io::Write> RenderContext<W> {
374378
"query_number": self.current_statement,
375379
"description": description,
376380
"backtrace": backtrace
377-
}))?;
381+
}))
382+
.await?;
378383
self.close_component()?;
379384
self.current_component = saved_component;
380385
Ok(())
@@ -394,15 +399,26 @@ impl<W: std::io::Write> RenderContext<W> {
394399
}
395400
}
396401

397-
fn render_current_template_with_data<T: Serialize>(&mut self, data: &T) -> anyhow::Result<()> {
402+
async fn render_current_template_with_data<T: Serialize>(
403+
&mut self,
404+
data: &T,
405+
) -> anyhow::Result<()> {
406+
if self.current_component.is_none() {
407+
self.set_current_component(DEFAULT_COMPONENT).await?;
408+
}
398409
self.current_component
410+
.as_mut()
411+
.expect("just set the current component")
399412
.render_item(&mut self.writer, json!(data))?;
400413
self.shell_renderer
401414
.render_item(&mut self.writer, JsonValue::Null)?;
402415
Ok(())
403416
}
404417

405-
async fn open_component(&mut self, component: &str) -> anyhow::Result<SplitTemplateRenderer> {
418+
async fn open_component(
419+
&mut self,
420+
component: &str,
421+
) -> anyhow::Result<Option<SplitTemplateRenderer>> {
406422
self.open_component_with_data(component, &json!(null)).await
407423
}
408424

@@ -421,38 +437,39 @@ impl<W: std::io::Write> RenderContext<W> {
421437
async fn set_current_component(
422438
&mut self,
423439
component: &str,
424-
) -> anyhow::Result<SplitTemplateRenderer> {
440+
) -> anyhow::Result<Option<SplitTemplateRenderer>> {
425441
let new_component = Self::create_renderer(component, Arc::clone(&self.app_state)).await?;
426-
Ok(std::mem::replace(
427-
&mut self.current_component,
428-
new_component,
429-
))
442+
Ok(self.current_component.replace(new_component))
430443
}
431444

432445
async fn open_component_with_data<T: Serialize>(
433446
&mut self,
434447
component: &str,
435448
data: &T,
436-
) -> anyhow::Result<SplitTemplateRenderer> {
449+
) -> anyhow::Result<Option<SplitTemplateRenderer>> {
437450
self.close_component()?;
438451
let old_component = self.set_current_component(component).await?;
439452
self.current_component
453+
.as_mut()
454+
.expect("just set the current component")
440455
.render_start(&mut self.writer, json!(data))?;
441456
Ok(old_component)
442457
}
443458

444459
fn close_component(&mut self) -> anyhow::Result<()> {
445-
self.current_component.render_end(&mut self.writer)?;
460+
if let Some(old_component) = self.current_component.as_mut().take() {
461+
old_component.render_end(&mut self.writer)?;
462+
}
446463
Ok(())
447464
}
448465

449466
pub async fn close(mut self) -> W {
450-
let res = self
451-
.current_component
452-
.render_end(&mut self.writer)
453-
.map_err(|e| format_err!("Unable to render the component closing: {e}"));
454-
self.handle_result_and_log(&res).await;
455-
467+
if let Some(old_component) = self.current_component.as_mut().take() {
468+
let res = old_component
469+
.render_end(&mut self.writer)
470+
.map_err(|e| format_err!("Unable to render the component closing: {e}"));
471+
self.handle_result_and_log(&res).await;
472+
}
456473
let res = self
457474
.shell_renderer
458475
.render_end(&mut self.writer)

0 commit comments

Comments
 (0)