@@ -509,7 +509,7 @@ impl<'a> Rope<'a> {
509509 Lines {
510510 iter : match & self . repr {
511511 Repr :: Light ( s) => LinesEnum :: Light ( s) ,
512- Repr :: Full ( data) => LinesEnum :: Complex {
512+ Repr :: Full ( data) => LinesEnum :: Full {
513513 iter : data,
514514 in_chunk_byte_idx : 0 ,
515515 chunk_idx : 0 ,
@@ -554,7 +554,7 @@ impl Hash for Rope<'_> {
554554
555555enum LinesEnum < ' a , ' b > {
556556 Light ( & ' b str ) ,
557- Complex {
557+ Full {
558558 iter : & ' a Vec < ( & ' b str , usize ) > ,
559559 in_chunk_byte_idx : usize ,
560560 chunk_idx : usize ,
@@ -605,7 +605,7 @@ impl<'a> Iterator for Lines<'_, 'a> {
605605 }
606606 Lines {
607607 iter :
608- LinesEnum :: Complex {
608+ LinesEnum :: Full {
609609 iter : chunks,
610610 ref mut in_chunk_byte_idx,
611611 ref mut chunk_idx,
@@ -777,6 +777,39 @@ impl Iterator for CharIndices<'_, '_> {
777777 }
778778 }
779779 }
780+
781+ #[ inline]
782+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
783+ match & self . iter {
784+ CharIndicesEnum :: Light { iter } => iter. size_hint ( ) ,
785+ CharIndicesEnum :: Full {
786+ chunks,
787+ char_indices,
788+ chunk_index,
789+ } => {
790+ if * chunk_index >= chunks. len ( ) {
791+ if char_indices. is_empty ( ) {
792+ return ( 0 , Some ( 0 ) ) ;
793+ }
794+ return ( char_indices. len ( ) , Some ( char_indices. len ( ) ) ) ;
795+ }
796+
797+ let Some ( total) = chunks. last ( ) . map ( |( s, l) | * l + s. len ( ) ) else {
798+ return ( 0 , Some ( 0 ) ) ;
799+ } ;
800+
801+ let ( _, prev) = chunks[ * chunk_index] ;
802+ // SAFETY: The previous length is guaranteed be less than or equal to the latter one.
803+ let remaining = total - prev;
804+
805+ ( 0 , None )
806+ // (
807+ // (remaining + 3) / 4 + char_indices.len(),
808+ // Some(remaining + char_indices.len()),
809+ // )
810+ }
811+ }
812+ }
780813}
781814
782815impl Default for Rope < ' _ > {
@@ -1226,25 +1259,38 @@ mod tests {
12261259
12271260 #[ test]
12281261 fn char_indices ( ) {
1262+ // The algorithm is the same as the one used in `std::str::CharIndices::size_hint`.
1263+ macro_rules! lo {
1264+ ( $expr: expr) => {
1265+ ( $expr + 3 ) / 4
1266+ } ;
1267+ }
1268+
12291269 let mut a = Rope :: new ( ) ;
12301270 a. add ( "abc" ) ;
12311271 a. add ( "def" ) ;
12321272 assert_eq ! (
12331273 a. char_indices( ) . collect:: <Vec <_>>( ) ,
12341274 "abcdef" . char_indices( ) . collect:: <Vec <_>>( )
12351275 ) ;
1276+ let len = "abcdef" . char_indices ( ) . size_hint ( ) . 1 . unwrap ( ) ;
1277+ assert_eq ! ( a. char_indices( ) . size_hint( ) , ( lo!( len) , Some ( len) ) ) ;
12361278
12371279 let mut a = Rope :: new ( ) ;
12381280 a. add ( "こんにちは" ) ;
12391281 assert_eq ! (
12401282 a. char_indices( ) . collect:: <Vec <_>>( ) ,
12411283 "こんにちは" . char_indices( ) . collect:: <Vec <_>>( )
12421284 ) ;
1285+ let len = "こんにちは" . char_indices ( ) . size_hint ( ) . 1 . unwrap ( ) ;
1286+ assert_eq ! ( a. char_indices( ) . size_hint( ) , ( lo!( len) , Some ( len) ) ) ;
12431287 a. add ( "世界" ) ;
12441288 assert_eq ! (
12451289 a. char_indices( ) . collect:: <Vec <_>>( ) ,
12461290 "こんにちは世界" . char_indices( ) . collect:: <Vec <_>>( )
12471291 ) ;
1292+ let len = "こんにちは世界" . char_indices ( ) . size_hint ( ) . 1 . unwrap ( ) ;
1293+ assert_eq ! ( a. char_indices( ) . size_hint( ) , ( lo!( len) , Some ( len) ) ) ;
12481294 }
12491295
12501296 #[ test]
0 commit comments