@@ -219,13 +219,13 @@ fn get_object_str<'a>(json: &'a JsonValue, key: &str) -> Option<&'a str> {
219219pub 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 " ;
229229const SHELL_COMPONENT : & str = "shell" ;
230230const DYNAMIC_COMPONENT : & str = "dynamic" ;
231231const 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