@@ -537,4 +537,94 @@ impl Iterator for EscapeDefault {
537537 EscapeDefaultState :: Done => ( 0 , Some ( 0 ) ) ,
538538 }
539539 }
540+
541+ fn count ( self ) -> usize {
542+ match self . state {
543+ EscapeDefaultState :: Char ( _) => 1 ,
544+ EscapeDefaultState :: Unicode ( iter) => iter. count ( ) ,
545+ EscapeDefaultState :: Done => 0 ,
546+ EscapeDefaultState :: Backslash ( _) => 2 ,
547+ }
548+ }
549+
550+ fn nth ( & mut self , n : usize ) -> Option < char > {
551+ let ch = match self . state {
552+ EscapeDefaultState :: Backslash ( c) => c,
553+ EscapeDefaultState :: Char ( c) => c,
554+ EscapeDefaultState :: Done => return None ,
555+ EscapeDefaultState :: Unicode ( ref mut i) => return i. nth ( n) ,
556+ } ;
557+
558+ let start = if let Some ( x) = self . get_offset ( ) {
559+ x
560+ } else {
561+ return None ;
562+ } ;
563+ let idx = start + n;
564+
565+ // Update state
566+ self . state = match idx {
567+ 0 => EscapeDefaultState :: Char ( ch) ,
568+ _ => EscapeDefaultState :: Done ,
569+ } ;
570+
571+ match idx {
572+ 0 => Some ( '\\' ) ,
573+ 1 => Some ( ch) ,
574+ _ => None ,
575+ }
576+ }
577+
578+ fn last ( self ) -> Option < char > {
579+ match self . state {
580+ EscapeDefaultState :: Unicode ( iter) => iter. last ( ) ,
581+ EscapeDefaultState :: Done => None ,
582+ EscapeDefaultState :: Backslash ( c) | EscapeDefaultState :: Char ( c) => Some ( c) ,
583+ }
584+ }
585+ }
586+
587+ #[ test]
588+ fn ed_iterator_specializations ( ) {
589+ use super :: EscapeDefault ;
590+
591+ // Check counting
592+ assert_eq ! ( '\n' . escape_default( ) . count( ) , 2 ) ;
593+ assert_eq ! ( 'c' . escape_default( ) . count( ) , 1 ) ;
594+ assert_eq ! ( ' ' . escape_default( ) . count( ) , 1 ) ;
595+ assert_eq ! ( '\\' . escape_default( ) . count( ) , 2 ) ;
596+ assert_eq ! ( '\'' . escape_default( ) . count( ) , 2 ) ;
597+
598+ // Check nth
599+
600+ // Check that OoB is handled correctly
601+ assert_eq ! ( '\n' . escape_default( ) . nth( 2 ) , None ) ;
602+ assert_eq ! ( 'c' . escape_default( ) . nth( 1 ) , None ) ;
603+ assert_eq ! ( ' ' . escape_default( ) . nth( 1 ) , None ) ;
604+ assert_eq ! ( '\\' . escape_default( ) . nth( 2 ) , None ) ;
605+ assert_eq ! ( '\'' . escape_default( ) . nth( 2 ) , None ) ;
606+
607+ // Check the first char
608+ assert_eq ! ( '\n' . escape_default( ) . nth( 0 ) , Some ( '\\' ) ) ;
609+ assert_eq ! ( 'c' . escape_default( ) . nth( 0 ) , Some ( 'c' ) ) ;
610+ assert_eq ! ( ' ' . escape_default( ) . nth( 0 ) , Some ( ' ' ) ) ;
611+ assert_eq ! ( '\\' . escape_default( ) . nth( 0 ) , Some ( '\\' ) ) ;
612+ assert_eq ! ( '\'' . escape_default( ) . nth( 0 ) , Some ( '\\' ) ) ;
613+
614+ // Check the second char
615+ assert_eq ! ( '\n' . escape_default( ) . nth( 1 ) , Some ( 'n' ) ) ;
616+ assert_eq ! ( '\\' . escape_default( ) . nth( 1 ) , Some ( '\\' ) ) ;
617+ assert_eq ! ( '\'' . escape_default( ) . nth( 1 ) , Some ( '\'' ) ) ;
618+ }
619+
620+
621+ impl EscapeDefault {
622+ fn get_offset ( & self ) -> Option < usize > {
623+ match self . state {
624+ EscapeDefaultState :: Backslash ( _) => Some ( 0 ) ,
625+ EscapeDefaultState :: Char ( _) => Some ( 1 ) ,
626+ EscapeDefaultState :: Done => None ,
627+ EscapeDefaultState :: Unicode ( _) => None ,
628+ }
629+ }
540630}
0 commit comments