@@ -906,13 +906,6 @@ impl PartialEq for ReplaceSource {
906906
907907impl Eq for ReplaceSource { }
908908
909- enum IteratorState {
910- ProcessingChunk ,
911- EmittingReplacement ,
912- FinalReplacements ,
913- Done ,
914- }
915-
916909/// Iterator for ReplaceSource rope that applies replacements on the fly
917910pub struct ReplaceSourceRopeIterator < ' a > {
918911 inner_chunks : Box < dyn Iterator < Item = & ' a str > + ' a > ,
@@ -924,15 +917,14 @@ pub struct ReplaceSourceRopeIterator<'a> {
924917 current_chunk : Option < & ' a str > ,
925918 current_chunk_start : usize ,
926919 current_chunk_pos : usize ,
927- state : IteratorState ,
928920}
929921
930922impl < ' a > ReplaceSourceRopeIterator < ' a > {
931923 fn new (
932924 inner_chunks : Box < dyn Iterator < Item = & ' a str > + ' a > ,
933925 replacements : & ' a [ Replacement ] ,
934926 ) -> Self {
935- let mut iter = Self {
927+ Self {
936928 inner_chunks,
937929 replacements,
938930 pos : 0 ,
@@ -942,166 +934,123 @@ impl<'a> ReplaceSourceRopeIterator<'a> {
942934 current_chunk : None ,
943935 current_chunk_start : 0 ,
944936 current_chunk_pos : 0 ,
945- state : IteratorState :: ProcessingChunk ,
946- } ;
947-
948- iter. load_next_chunk ( ) ;
949- iter
950- }
951-
952- fn load_next_chunk ( & mut self ) {
953- self . current_chunk = self . inner_chunks . next ( ) ;
954- self . current_chunk_pos = 0 ;
955- if self . current_chunk . is_some ( ) {
956- self . current_chunk_start = self . pos ;
957- } else {
958- self . state = IteratorState :: FinalReplacements ;
959937 }
960938 }
939+ }
961940
962- fn skip_replaced_content ( & mut self ) -> bool {
963- if let Some ( replacement_end) = self . replacement_end {
964- if replacement_end > self . pos {
965- let chunk_end =
966- self . current_chunk_start + self . current_chunk . unwrap ( ) . len ( ) ;
941+ impl < ' a > Iterator for ReplaceSourceRopeIterator < ' a > {
942+ type Item = & ' a str ;
967943
968- // Skip the entire chunk
969- if replacement_end >= chunk_end {
970- self . pos = chunk_end;
971- self . load_next_chunk ( ) ;
972- return true ;
944+ #[ allow( unsafe_code) ]
945+ fn next ( & mut self ) -> Option < Self :: Item > {
946+ loop {
947+ // Load next chunk (if needed)
948+ if self . current_chunk . is_none ( ) {
949+ self . current_chunk = self . inner_chunks . next ( ) ;
950+ self . current_chunk_pos = 0 ;
951+ if self . current_chunk . is_some ( ) {
952+ self . current_chunk_start = self . pos ;
953+ } else {
954+ // No more chunks, handle remaining replacements
955+ return if self . replacement_idx < self . replacements . len ( ) {
956+ let content = unsafe {
957+ & self
958+ . replacements
959+ . get_unchecked ( self . replacement_idx )
960+ . content
961+ } ;
962+ self . replacement_idx += 1 ;
963+ Some ( content)
964+ } else {
965+ None
966+ } ;
973967 }
974-
975- // Partially skip the chunk
976- let skip_len = replacement_end - self . pos ;
977- self . current_chunk_pos += skip_len;
978- self . pos += skip_len;
979- }
980- }
981- false
982- }
983-
984- fn process_current_chunk ( & mut self ) -> Option < & ' a str > {
985- let chunk = self . current_chunk ?;
986- let chunk_end = self . current_chunk_start + chunk. len ( ) ;
987-
988- // Check if there are replacements in the current chunk
989- while let Some ( next_repl_pos) =
990- self . next_replacement . filter ( |& pos| pos < chunk_end)
991- {
992- if next_repl_pos > self . pos {
993- // Return content before replacement
994- let offset = next_repl_pos - self . pos ;
995- let result =
996- & chunk[ self . current_chunk_pos ..self . current_chunk_pos + offset] ;
997- self . current_chunk_pos += offset;
998- self . pos = next_repl_pos;
999- return Some ( result) ;
1000968 }
1001969
1002- // Prepare to return replacement content
1003- self . state = IteratorState :: EmittingReplacement ;
1004- return None ;
1005- }
1006-
1007- // Return remaining content of the chunk
1008- if self . current_chunk_pos < chunk. len ( ) {
1009- let result = & chunk[ self . current_chunk_pos ..] ;
1010- self . pos = chunk_end;
1011- self . load_next_chunk ( ) ;
1012- Some ( result)
1013- } else {
1014- self . load_next_chunk ( ) ;
1015- None
1016- }
1017- }
1018-
1019- fn emit_replacement ( & mut self ) -> Option < & ' a str > {
1020- let replacement = & self . replacements [ self . replacement_idx ] ;
1021- let content = & replacement. content ;
1022-
1023- // Update replacement state
1024- self . replacement_end = Some (
1025- self
1026- . replacement_end
1027- . map_or ( replacement. end as usize , |end| {
1028- end. max ( replacement. end as usize )
1029- } ) ,
1030- ) ;
1031-
1032- self . replacement_idx += 1 ;
1033- self . next_replacement = self
1034- . replacements
1035- . get ( self . replacement_idx )
1036- . map ( |r| r. start as usize ) ;
970+ let chunk = self . current_chunk . unwrap ( ) ;
971+ let chunk_end = self . current_chunk_start + chunk. len ( ) ;
1037972
1038- // Check if we need to skip replaced content
1039- if let Some ( replacement_end) = self . replacement_end {
1040- if replacement_end > self . pos {
1041- self . pos = replacement_end;
1042-
1043- // If current chunk needs to be skipped, reload it
1044- if let Some ( chunk) = self . current_chunk {
1045- let chunk_end = self . current_chunk_start + chunk. len ( ) ;
973+ // Skip replaced content
974+ if let Some ( replacement_end) = self . replacement_end {
975+ if replacement_end > self . pos {
1046976 if replacement_end >= chunk_end {
1047- self . load_next_chunk ( ) ;
977+ // Skip entire chunk
978+ self . pos = chunk_end;
979+ self . current_chunk = None ;
980+ continue ;
1048981 } else {
1049- self . current_chunk_pos = replacement_end - self . current_chunk_start ;
982+ // Partially skip chunk
983+ let skip_len = replacement_end - self . pos ;
984+ self . current_chunk_pos += skip_len;
985+ self . pos += skip_len;
1050986 }
1051987 }
1052988 }
1053- }
1054-
1055- self . state = IteratorState :: ProcessingChunk ;
1056- Some ( content)
1057- }
1058-
1059- fn emit_final_replacements ( & mut self ) -> Option < & ' a str > {
1060- if self . replacement_idx < self . replacements . len ( ) {
1061- let content = & self . replacements [ self . replacement_idx ] . content ;
1062- self . replacement_idx += 1 ;
1063- Some ( content)
1064- } else {
1065- self . state = IteratorState :: Done ;
1066- None
1067- }
1068- }
1069- }
1070-
1071- impl < ' a > Iterator for ReplaceSourceRopeIterator < ' a > {
1072- type Item = & ' a str ;
1073989
1074- fn next ( & mut self ) -> Option < Self :: Item > {
1075- loop {
1076- match self . state {
1077- IteratorState :: ProcessingChunk => {
1078- if self . skip_replaced_content ( ) {
1079- continue ;
1080- }
990+ // Check if there are replacements in the current chunk
991+ if let Some ( next_repl_pos) =
992+ self . next_replacement . filter ( |& pos| pos < chunk_end)
993+ {
994+ if next_repl_pos > self . pos {
995+ // Return content before replacement
996+ let offset = next_repl_pos - self . pos ;
997+ let result = unsafe {
998+ chunk. get_unchecked (
999+ self . current_chunk_pos ..self . current_chunk_pos + offset,
1000+ )
1001+ } ;
1002+ self . current_chunk_pos += offset;
1003+ self . pos = next_repl_pos;
1004+ return Some ( result) ;
1005+ }
10811006
1082- if let Some ( result) = self . process_current_chunk ( ) {
1083- return Some ( result) ;
1084- }
1007+ // Process replacement
1008+ let replacement =
1009+ unsafe { self . replacements . get_unchecked ( self . replacement_idx ) } ;
1010+ let content = & replacement. content ;
10851011
1086- if self . current_chunk . is_none ( ) {
1087- self . state = IteratorState :: FinalReplacements ;
1088- }
1089- }
1012+ // Move to next replacement
1013+ self . replacement_end = Some (
1014+ self
1015+ . replacement_end
1016+ . map_or ( replacement. end as usize , |end| {
1017+ end. max ( replacement. end as usize )
1018+ } ) ,
1019+ ) ;
10901020
1091- IteratorState :: EmittingReplacement => {
1092- if let Some ( result) = self . emit_replacement ( ) {
1093- return Some ( result) ;
1021+ // Update position (skip replaced content)
1022+ self . replacement_idx += 1 ;
1023+ self . next_replacement = self
1024+ . replacements
1025+ . get ( self . replacement_idx )
1026+ . map ( |r| r. start as usize ) ;
1027+
1028+ // Update position (skip replaced content)
1029+ if let Some ( replacement_end) = self . replacement_end {
1030+ if replacement_end > self . pos {
1031+ self . pos = replacement_end;
1032+ // If current chunk needs to be skipped, reset it
1033+ if replacement_end >= chunk_end {
1034+ self . current_chunk = None ;
1035+ } else {
1036+ self . current_chunk_pos =
1037+ replacement_end - self . current_chunk_start ;
1038+ }
10941039 }
10951040 }
10961041
1097- IteratorState :: FinalReplacements => {
1098- if let Some ( result) = self . emit_final_replacements ( ) {
1099- return Some ( result) ;
1100- }
1101- }
1042+ return Some ( content) ;
1043+ }
11021044
1103- IteratorState :: Done => return None ,
1045+ // Return remaining chunk content
1046+ if self . current_chunk_pos < chunk. len ( ) {
1047+ let result = unsafe { chunk. get_unchecked ( self . current_chunk_pos ..) } ;
1048+ self . pos = chunk_end;
1049+ self . current_chunk = None ;
1050+ return Some ( result) ;
11041051 }
1052+
1053+ self . current_chunk = None ;
11051054 }
11061055 }
11071056}
0 commit comments