@@ -418,61 +418,71 @@ impl Default for RcDom {
418418 }
419419}
420420
421+ enum SerializeOp {
422+ Open ( Handle ) ,
423+ Close ( QualName )
424+ }
425+
421426impl Serialize for Handle {
422427 fn serialize < S > ( & self , serializer : & mut S , traversal_scope : TraversalScope ) -> io:: Result < ( ) >
423428 where
424429 S : Serializer ,
425430 {
426- match ( & traversal_scope, & self . data ) {
427- (
428- _,
429- & NodeData :: Element {
430- ref name,
431- ref attrs,
432- ..
433- } ,
434- ) => {
435- if traversal_scope == IncludeNode {
436- try!( serializer. start_elem (
437- name. clone ( ) ,
438- attrs. borrow ( ) . iter ( ) . map ( |at| ( & at. name , & at. value [ ..] ) )
439- ) ) ;
440- }
441-
442- for handle in self . children . borrow ( ) . iter ( ) {
443- try!( handle. clone ( ) . serialize ( serializer, IncludeNode ) ) ;
444- }
431+ let mut ops = match traversal_scope {
432+ IncludeNode => vec ! [ SerializeOp :: Open ( self . clone( ) ) ] ,
433+ ChildrenOnly ( _) => self
434+ . children
435+ . borrow ( )
436+ . iter ( )
437+ . map ( |h| SerializeOp :: Open ( h. clone ( ) ) ) . collect ( ) ,
438+ } ;
445439
446- if traversal_scope == IncludeNode {
447- try!( serializer. end_elem ( name. clone ( ) ) ) ;
440+ while !ops. is_empty ( ) {
441+ match ops. remove ( 0 ) {
442+ SerializeOp :: Open ( handle) => {
443+ match & handle. data {
444+ & NodeData :: Element {
445+ ref name,
446+ ref attrs,
447+ ..
448+ } => {
449+ try!( serializer. start_elem (
450+ name. clone ( ) ,
451+ attrs. borrow ( ) . iter ( ) . map ( |at| ( & at. name , & at. value [ ..] ) )
452+ ) ) ;
453+
454+ ops. insert ( 0 , SerializeOp :: Close ( name. clone ( ) ) ) ;
455+
456+ for child in handle. children . borrow ( ) . iter ( ) . rev ( ) {
457+ ops. insert ( 0 , SerializeOp :: Open ( child. clone ( ) ) ) ;
458+ }
459+ }
460+
461+ & NodeData :: Doctype { ref name, .. } => serializer. write_doctype ( & name) ?,
462+
463+ & NodeData :: Text { ref contents } => {
464+ serializer. write_text ( & contents. borrow ( ) ) ?
465+ }
466+
467+ & NodeData :: Comment { ref contents } => {
468+ serializer. write_comment ( & contents) ?
469+ } ,
470+
471+ & NodeData :: ProcessingInstruction {
472+ ref target,
473+ ref contents,
474+ } => serializer. write_processing_instruction ( target, contents) ?,
475+
476+ & NodeData :: Document => panic ! ( "Can't serialize Document node itself" ) ,
477+ }
448478 }
449- Ok ( ( ) )
450- } ,
451479
452- ( & ChildrenOnly ( _) , & NodeData :: Document ) => {
453- for handle in self . children . borrow ( ) . iter ( ) {
454- try!( handle. clone ( ) . serialize ( serializer, IncludeNode ) ) ;
480+ SerializeOp :: Close ( name) => {
481+ try!( serializer. end_elem ( name) ) ;
455482 }
456- Ok ( ( ) )
457- } ,
458-
459- ( & ChildrenOnly ( _) , _) => Ok ( ( ) ) ,
460-
461- ( & IncludeNode , & NodeData :: Doctype { ref name, .. } ) => serializer. write_doctype ( & name) ,
462- ( & IncludeNode , & NodeData :: Text { ref contents } ) => {
463- serializer. write_text ( & contents. borrow ( ) )
464- } ,
465- ( & IncludeNode , & NodeData :: Comment { ref contents } ) => {
466- serializer. write_comment ( & contents)
467- } ,
468- (
469- & IncludeNode ,
470- & NodeData :: ProcessingInstruction {
471- ref target,
472- ref contents,
473- } ,
474- ) => serializer. write_processing_instruction ( target, contents) ,
475- ( & IncludeNode , & NodeData :: Document ) => panic ! ( "Can't serialize Document node itself" ) ,
483+ }
476484 }
485+
486+ Ok ( ( ) )
477487 }
478488}
0 commit comments