1use std::{
2 borrow::Cow,
3 cmp::{Ordering, min},
4 fmt,
5 io::{BufRead, Read, Result as IoResult, Write},
6 mem,
7 ops::{AddAssign, Deref},
8 pin::Pin,
9 task::{Context as TaskContext, Poll},
10};
11
12use RopeElem::{Local, Shared};
13use anyhow::{Context, Result};
14use bytes::{Buf, Bytes};
15use futures::Stream;
16use serde::{Deserialize, Deserializer, Serialize, Serializer};
17use serde_bytes::ByteBuf;
18use tokio::io::{AsyncRead, ReadBuf};
19use triomphe::Arc;
20use turbo_tasks_hash::{DeterministicHash, DeterministicHasher};
21use unsize::{CoerceUnsize, Coercion};
22
23static EMPTY_BUF: &[u8] = &[];
24
25#[turbo_tasks::value(shared, serialization = "custom", eq = "manual", operation)]
32#[derive(Clone, Debug, Default)]
33pub struct Rope {
34 length: usize,
36
37 #[turbo_tasks(debug_ignore, trace_ignore)]
39 data: InnerRope,
40}
41
42#[derive(Clone, Debug)]
45struct InnerRope(Arc<[RopeElem]>);
46
47#[derive(Clone, Debug)]
49enum RopeElem {
50 Local(Bytes),
52
53 Shared(InnerRope),
55}
56
57#[derive(Default, Debug)]
61pub struct RopeBuilder {
62 length: usize,
64
65 committed: Vec<RopeElem>,
68
69 uncommitted: Uncommitted,
74}
75
76#[derive(Default)]
80enum Uncommitted {
81 #[default]
82 None,
83
84 Static(&'static [u8]),
89
90 Owned(Vec<u8>),
95}
96
97impl Rope {
98 pub fn len(&self) -> usize {
99 self.length
100 }
101
102 pub fn is_empty(&self) -> bool {
103 self.length == 0
104 }
105
106 pub fn read(&self) -> RopeReader {
108 RopeReader::new(&self.data, 0)
109 }
110
111 pub fn to_str(&self) -> Result<Cow<'_, str>> {
113 self.data.to_str(self.length)
114 }
115
116 pub fn to_bytes(&self) -> Result<Cow<'_, [u8]>> {
118 self.data.to_bytes(self.length)
119 }
120}
121
122impl From<Vec<u8>> for Rope {
123 fn from(mut bytes: Vec<u8>) -> Self {
124 bytes.shrink_to_fit();
125 Rope::from(Bytes::from(bytes))
126 }
127}
128
129impl From<String> for Rope {
130 fn from(mut bytes: String) -> Self {
131 bytes.shrink_to_fit();
132 Rope::from(Bytes::from(bytes))
133 }
134}
135
136impl<T: Into<Bytes>> From<T> for Rope {
137 default fn from(bytes: T) -> Self {
138 let bytes = bytes.into();
139 if bytes.is_empty() {
141 Default::default()
142 } else {
143 Rope {
144 length: bytes.len(),
145 data: InnerRope(Arc::from([Local(bytes)]).unsize(Coercion::to_slice())),
146 }
147 }
148 }
149}
150
151impl RopeBuilder {
152 pub fn push_bytes(&mut self, bytes: &[u8]) {
157 if bytes.is_empty() {
158 return;
159 }
160
161 self.uncommitted.push_bytes(bytes);
162 }
163
164 pub fn push_static_bytes(&mut self, bytes: &'static [u8]) {
169 if bytes.is_empty() {
170 return;
171 }
172
173 if bytes.len() < mem::size_of::<Bytes>() {
177 return self.uncommitted.push_static_bytes(bytes);
178 }
179
180 self.finish();
182
183 self.length += bytes.len();
184 self.committed.push(Local(Bytes::from_static(bytes)));
185 }
186
187 pub fn concat(&mut self, other: &Rope) {
192 if other.is_empty() {
193 return;
194 }
195
196 self.finish();
198
199 self.length += other.len();
200 self.committed.push(Shared(other.data.clone()));
201 }
202
203 fn finish(&mut self) {
208 if let Some(b) = self.uncommitted.finish() {
209 debug_assert!(!b.is_empty(), "must not have empty uncommitted bytes");
210 self.length += b.len();
211 self.committed.push(Local(b));
212 }
213 }
214
215 pub fn len(&self) -> usize {
216 self.length + self.uncommitted.len()
217 }
218
219 pub fn is_empty(&self) -> bool {
220 self.len() == 0
221 }
222
223 pub fn build(mut self) -> Rope {
225 self.finish();
226 Rope {
227 length: self.length,
228 data: InnerRope::from(self.committed),
229 }
230 }
231}
232
233impl From<&'static str> for RopeBuilder {
234 default fn from(bytes: &'static str) -> Self {
235 let mut r = RopeBuilder::default();
236 r += bytes;
237 r
238 }
239}
240
241impl From<Vec<u8>> for RopeBuilder {
242 fn from(bytes: Vec<u8>) -> Self {
243 RopeBuilder {
244 uncommitted: Uncommitted::from(bytes),
246 ..Default::default()
247 }
248 }
249}
250
251impl Write for RopeBuilder {
252 fn write(&mut self, bytes: &[u8]) -> IoResult<usize> {
253 self.push_bytes(bytes);
254 Ok(bytes.len())
255 }
256
257 fn flush(&mut self) -> IoResult<()> {
258 self.finish();
259 Ok(())
260 }
261}
262
263impl AddAssign<&'static str> for RopeBuilder {
264 fn add_assign(&mut self, rhs: &'static str) {
269 self.push_static_bytes(rhs.as_bytes());
270 }
271}
272
273impl AddAssign<&Rope> for RopeBuilder {
274 fn add_assign(&mut self, rhs: &Rope) {
275 self.concat(rhs);
276 }
277}
278
279impl Uncommitted {
280 fn len(&self) -> usize {
281 match self {
282 Uncommitted::None => 0,
283 Uncommitted::Static(s) => s.len(),
284 Uncommitted::Owned(v) => v.len(),
285 }
286 }
287
288 fn push_bytes(&mut self, bytes: &[u8]) {
291 debug_assert!(!bytes.is_empty(), "must not push empty uncommitted bytes");
292 match self {
293 Self::None => *self = Self::Owned(bytes.to_vec()),
294 Self::Static(s) => {
295 let v = [s, bytes].concat();
299 *self = Self::Owned(v);
300 }
301 Self::Owned(v) => v.extend(bytes),
302 }
303 }
304
305 fn push_static_bytes(&mut self, bytes: &'static [u8]) {
308 debug_assert!(!bytes.is_empty(), "must not push empty uncommitted bytes");
309 match self {
310 Self::None => *self = Self::Static(bytes),
317 _ => self.push_bytes(bytes),
318 }
319 }
320
321 fn finish(&mut self) -> Option<Bytes> {
324 match mem::take(self) {
325 Self::None => None,
326 Self::Static(s) => Some(Bytes::from_static(s)),
327 Self::Owned(mut v) => {
328 v.shrink_to_fit();
329 Some(v.into())
330 }
331 }
332 }
333}
334
335impl fmt::Debug for Uncommitted {
336 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
337 match self {
338 Uncommitted::None => f.write_str("None"),
339 Uncommitted::Static(s) => f
340 .debug_tuple("Static")
341 .field(&Bytes::from_static(s))
342 .finish(),
343 Uncommitted::Owned(v) => f
344 .debug_tuple("Owned")
345 .field(&Bytes::from(v.clone()))
346 .finish(),
347 }
348 }
349}
350
351impl DeterministicHash for Rope {
352 fn deterministic_hash<H: DeterministicHasher>(&self, state: &mut H) {
355 state.write_usize(self.len());
356 self.data.deterministic_hash(state);
357 }
358}
359
360impl Serialize for Rope {
361 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
365 use serde::ser::Error;
366 let bytes = self.to_bytes().map_err(Error::custom)?;
367 match bytes {
368 Cow::Borrowed(b) => serde_bytes::Bytes::new(b).serialize(serializer),
369 Cow::Owned(b) => ByteBuf::from(b).serialize(serializer),
370 }
371 }
372}
373
374impl<'de> Deserialize<'de> for Rope {
375 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
377 let bytes = ByteBuf::deserialize(deserializer)?.into_vec();
378 Ok(Rope::from(bytes))
379 }
380}
381
382pub mod ser_as_string {
383 use serde::{Serializer, ser::Error};
384
385 use super::Rope;
386
387 pub fn serialize<S: Serializer>(rope: &Rope, serializer: S) -> Result<S::Ok, S::Error> {
389 let s = rope.to_str().map_err(Error::custom)?;
390 serializer.serialize_str(&s)
391 }
392}
393
394pub mod ser_option_as_string {
395 use serde::{Serializer, ser::Error};
396
397 use super::Rope;
398
399 pub fn serialize<S: Serializer>(rope: &Option<Rope>, serializer: S) -> Result<S::Ok, S::Error> {
401 if let Some(rope) = rope {
402 let s = rope.to_str().map_err(Error::custom)?;
403 serializer.serialize_some(&s)
404 } else {
405 serializer.serialize_none()
406 }
407 }
408}
409
410impl PartialEq for Rope {
411 fn eq(&self, other: &Self) -> bool {
413 if self.len() != other.len() {
414 return false;
415 }
416 self.cmp(other) == Ordering::Equal
417 }
418}
419
420impl Eq for Rope {}
421
422impl Ord for Rope {
423 fn cmp(&self, other: &Self) -> Ordering {
424 if Arc::ptr_eq(&self.data, &other.data) {
425 return Ordering::Equal;
426 }
427
428 let left = &self.data;
431 let right = &other.data;
432 let len = min(left.len(), right.len());
433 let mut index = 0;
434 while index < len {
435 let a = &left[index];
436 let b = &right[index];
437
438 match a.maybe_cmp(b) {
439 Some(Ordering::Equal) => index += 1,
441 Some(ordering) => return ordering,
443 None => break,
445 }
446 }
447 if index == len {
450 return left.len().cmp(&right.len());
453 }
454
455 let mut left = RopeReader::new(left, index);
458 let mut right = RopeReader::new(right, index);
459 loop {
460 match (left.fill_buf(), right.fill_buf()) {
461 (Ok(a), Ok(b)) => {
464 let len = min(a.len(), b.len());
465
466 if len == 0 {
468 return a.len().cmp(&b.len());
469 }
470
471 match a[0..len].cmp(&b[0..len]) {
472 Ordering::Equal => {
473 left.consume(len);
474 right.consume(len);
475 }
476 ordering => return ordering,
477 }
478 }
479
480 _ => unreachable!(),
483 }
484 }
485 }
486}
487
488impl PartialOrd for Rope {
489 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
490 Some(self.cmp(other))
491 }
492}
493
494impl From<Vec<u8>> for Uncommitted {
495 fn from(bytes: Vec<u8>) -> Self {
496 if bytes.is_empty() {
497 Uncommitted::None
498 } else {
499 Uncommitted::Owned(bytes)
500 }
501 }
502}
503
504impl InnerRope {
505 fn to_str(&self, len: usize) -> Result<Cow<'_, str>> {
507 match &self[..] {
508 [] => Ok(Cow::Borrowed("")),
509 [Shared(inner)] => inner.to_str(len),
510 [Local(bytes)] => {
511 let utf8 = std::str::from_utf8(bytes);
512 utf8.context("failed to convert rope into string")
513 .map(Cow::Borrowed)
514 }
515 _ => {
516 let mut read = RopeReader::new(self, 0);
517 let mut string = String::with_capacity(len);
518 let res = read.read_to_string(&mut string);
519 res.context("failed to convert rope into string")?;
520 Ok(Cow::Owned(string))
521 }
522 }
523 }
524
525 fn to_bytes(&self, len: usize) -> Result<Cow<'_, [u8]>> {
527 match &self[..] {
528 [] => Ok(Cow::Borrowed(EMPTY_BUF)),
529 [Shared(inner)] => inner.to_bytes(len),
530 [Local(bytes)] => Ok(Cow::Borrowed(bytes)),
531 _ => {
532 let mut read = RopeReader::new(self, 0);
533 let mut buf = Vec::with_capacity(len);
534 read.read_to_end(&mut buf)?;
535 Ok(Cow::Owned(buf))
536 }
537 }
538 }
539}
540
541impl Default for InnerRope {
542 fn default() -> Self {
543 InnerRope(Arc::new([]).unsize(Coercion::to_slice()))
544 }
545}
546
547impl DeterministicHash for InnerRope {
548 fn deterministic_hash<H: DeterministicHasher>(&self, state: &mut H) {
553 for v in self.0.iter() {
554 v.deterministic_hash(state);
555 }
556 }
557}
558
559impl From<Vec<RopeElem>> for InnerRope {
560 fn from(mut els: Vec<RopeElem>) -> Self {
561 if cfg!(debug_assertions) {
562 for el in els.iter() {
564 match el {
565 Local(b) => debug_assert!(!b.is_empty(), "must not have empty Bytes"),
566 Shared(s) => {
567 debug_assert!(!s.is_empty(), "must not have empty InnerRope");
572 }
573 }
574 }
575 }
576 els.shrink_to_fit();
577 InnerRope(Arc::from(els))
578 }
579}
580
581impl Deref for InnerRope {
582 type Target = Arc<[RopeElem]>;
583
584 fn deref(&self) -> &Self::Target {
585 &self.0
586 }
587}
588
589impl RopeElem {
590 fn maybe_cmp(&self, other: &Self) -> Option<Ordering> {
591 match (self, other) {
592 (Local(a), Local(b)) => {
593 if a.len() == b.len() {
594 return Some(a.cmp(b));
595 }
596
597 None
600 }
601 (Shared(a), Shared(b)) => {
602 if Arc::ptr_eq(&a.0, &b.0) {
603 return Some(Ordering::Equal);
604 }
605
606 None
609 }
610 _ => None,
611 }
612 }
613}
614
615impl DeterministicHash for RopeElem {
616 fn deterministic_hash<H: DeterministicHasher>(&self, state: &mut H) {
620 match self {
621 Local(bytes) => state.write_bytes(bytes),
622 Shared(inner) => inner.deterministic_hash(state),
623 }
624 }
625}
626
627#[derive(Debug, Default)]
628pub struct RopeReader {
630 stack: Vec<StackElem>,
633}
634
635#[derive(Debug)]
639enum StackElem {
640 Local(Bytes),
641 Shared(InnerRope, usize),
642}
643
644impl RopeReader {
645 fn new(inner: &InnerRope, index: usize) -> Self {
646 if index >= inner.len() {
647 Default::default()
648 } else {
649 RopeReader {
650 stack: vec![StackElem::Shared(inner.clone(), index)],
651 }
652 }
653 }
654
655 fn read_internal(&mut self, want: usize, buf: &mut ReadBuf<'_>) -> usize {
658 let mut remaining = want;
659
660 while remaining > 0 {
661 let mut bytes = match self.next() {
662 None => break,
663 Some(b) => b,
664 };
665
666 let amount = min(bytes.len(), remaining);
667
668 buf.put_slice(&bytes[0..amount]);
669
670 if amount < bytes.len() {
671 bytes.advance(amount);
672 self.stack.push(StackElem::Local(bytes))
673 }
674 remaining -= amount;
675 }
676
677 want - remaining
678 }
679}
680
681impl Iterator for RopeReader {
682 type Item = Bytes;
683
684 fn next(&mut self) -> Option<Self::Item> {
685 loop {
688 let (inner, mut index) = match self.stack.pop() {
689 None => return None,
690 Some(StackElem::Local(b)) => {
691 debug_assert!(!b.is_empty(), "must not have empty Bytes section");
692 return Some(b);
693 }
694 Some(StackElem::Shared(r, i)) => (r, i),
695 };
696
697 let el = inner[index].clone();
698 index += 1;
699 if index < inner.len() {
700 self.stack.push(StackElem::Shared(inner, index));
701 }
702
703 self.stack.push(StackElem::from(el));
704 }
705 }
706}
707
708impl Read for RopeReader {
709 fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
710 Ok(self.read_internal(buf.len(), &mut ReadBuf::new(buf)))
711 }
712}
713
714impl AsyncRead for RopeReader {
715 fn poll_read(
716 self: Pin<&mut Self>,
717 _cx: &mut TaskContext<'_>,
718 buf: &mut ReadBuf<'_>,
719 ) -> Poll<IoResult<()>> {
720 let this = self.get_mut();
721 this.read_internal(buf.remaining(), buf);
722 Poll::Ready(Ok(()))
723 }
724}
725
726impl BufRead for RopeReader {
727 fn fill_buf(&mut self) -> IoResult<&[u8]> {
728 let bytes = match self.next() {
731 None => return Ok(EMPTY_BUF),
732 Some(b) => b,
733 };
734
735 self.stack.push(StackElem::Local(bytes));
739 let Some(StackElem::Local(bytes)) = self.stack.last() else {
740 unreachable!()
741 };
742
743 Ok(bytes)
744 }
745
746 fn consume(&mut self, amt: usize) {
747 if let Some(StackElem::Local(b)) = self.stack.last_mut() {
748 if amt == b.len() {
749 self.stack.pop();
750 } else {
751 b.advance(amt);
754 }
755 }
756 }
757}
758
759impl Stream for RopeReader {
760 type Item = Result<Bytes>;
763
764 fn poll_next(self: Pin<&mut Self>, _cx: &mut TaskContext<'_>) -> Poll<Option<Self::Item>> {
767 let this = self.get_mut();
768 Poll::Ready(this.next().map(Ok))
769 }
770}
771
772impl From<RopeElem> for StackElem {
773 fn from(el: RopeElem) -> Self {
774 match el {
775 Local(bytes) => Self::Local(bytes),
776 Shared(inner) => Self::Shared(inner, 0),
777 }
778 }
779}
780
781#[cfg(test)]
782mod test {
783 use std::{
784 borrow::Cow,
785 cmp::min,
786 io::{BufRead, Read},
787 };
788
789 use anyhow::Result;
790
791 use super::{InnerRope, Rope, RopeBuilder, RopeElem};
792
793 impl From<&str> for RopeElem {
796 fn from(value: &str) -> Self {
797 RopeElem::Local(value.to_string().into())
798 }
799 }
800 impl From<Vec<RopeElem>> for RopeElem {
801 fn from(value: Vec<RopeElem>) -> Self {
802 RopeElem::Shared(InnerRope::from(value))
803 }
804 }
805 impl From<Rope> for RopeElem {
806 fn from(value: Rope) -> Self {
807 RopeElem::Shared(value.data)
808 }
809 }
810 impl Rope {
811 fn new(value: Vec<RopeElem>) -> Self {
812 let data = InnerRope::from(value);
813 Rope {
814 length: data.len(),
815 data,
816 }
817 }
818 }
819 impl InnerRope {
820 fn len(&self) -> usize {
821 self.iter().map(|v| v.len()).sum()
822 }
823 }
824 impl RopeElem {
825 fn len(&self) -> usize {
826 match self {
827 RopeElem::Local(b) => b.len(),
828 RopeElem::Shared(r) => r.len(),
829 }
830 }
831 }
832
833 #[test]
834 fn empty_build_without_pushes() {
835 let empty = RopeBuilder::default().build();
836 let mut reader = empty.read();
837 assert!(reader.next().is_none());
838 }
839
840 #[test]
841 fn empty_build_with_empty_static_push() {
842 let mut builder = RopeBuilder::default();
843 builder += "";
844
845 let empty = builder.build();
846 let mut reader = empty.read();
847 assert!(reader.next().is_none());
848 }
849
850 #[test]
851 fn empty_build_with_empty_bytes_push() {
852 let mut builder = RopeBuilder::default();
853 builder.push_bytes(&[]);
854
855 let empty = builder.build();
856 let mut reader = empty.read();
857 assert!(reader.next().is_none());
858 }
859
860 #[test]
861 fn empty_build_with_empty_concat() {
862 let mut builder = RopeBuilder::default();
863 builder += &RopeBuilder::default().build();
864
865 let empty = builder.build();
866 let mut reader = empty.read();
867 assert!(reader.next().is_none());
868 }
869
870 #[test]
871 fn empty_from_empty_static_str() {
872 let empty = Rope::from("");
873 let mut reader = empty.read();
874 assert!(reader.next().is_none());
875 }
876
877 #[test]
878 fn empty_from_empty_string() {
879 let empty = Rope::from("".to_string());
880 let mut reader = empty.read();
881 assert!(reader.next().is_none());
882 }
883
884 #[test]
885 fn empty_equality() {
886 let a = Rope::from("");
887 let b = Rope::from("");
888
889 assert_eq!(a, b);
890 }
891
892 #[test]
893 fn cloned_equality() {
894 let a = Rope::from("abc");
895 let b = a.clone();
896
897 assert_eq!(a, b);
898 }
899
900 #[test]
901 fn value_equality() {
902 let a = Rope::from("abc".to_string());
903 let b = Rope::from("abc".to_string());
904
905 assert_eq!(a, b);
906 }
907
908 #[test]
909 fn value_inequality() {
910 let a = Rope::from("abc".to_string());
911 let b = Rope::from("def".to_string());
912
913 assert_ne!(a, b);
914 }
915
916 #[test]
917 fn value_equality_shared_1() {
918 let shared = Rope::from("def");
919 let a = Rope::new(vec!["abc".into(), shared.clone().into(), "ghi".into()]);
920 let b = Rope::new(vec!["abc".into(), shared.into(), "ghi".into()]);
921
922 assert_eq!(a, b);
923 }
924
925 #[test]
926 fn value_equality_shared_2() {
927 let a = Rope::new(vec!["abc".into(), vec!["def".into()].into(), "ghi".into()]);
928 let b = Rope::new(vec!["abc".into(), vec!["def".into()].into(), "ghi".into()]);
929
930 assert_eq!(a, b);
931 }
932
933 #[test]
934 fn value_equality_splits_1() {
935 let a = Rope::new(vec!["a".into(), "aa".into()]);
936 let b = Rope::new(vec!["aa".into(), "a".into()]);
937
938 assert_eq!(a, b);
939 }
940
941 #[test]
942 fn value_equality_splits_2() {
943 let a = Rope::new(vec![vec!["a".into()].into(), "aa".into()]);
944 let b = Rope::new(vec![vec!["aa".into()].into(), "a".into()]);
945
946 assert_eq!(a, b);
947 }
948
949 #[test]
950 fn value_inequality_shared_1() {
951 let shared = Rope::from("def");
952 let a = Rope::new(vec!["aaa".into(), shared.clone().into(), "ghi".into()]);
953 let b = Rope::new(vec!["bbb".into(), shared.into(), "ghi".into()]);
954
955 assert_ne!(a, b);
956 }
957
958 #[test]
959 fn value_inequality_shared_2() {
960 let a = Rope::new(vec!["abc".into(), vec!["ddd".into()].into(), "ghi".into()]);
961 let b = Rope::new(vec!["abc".into(), vec!["eee".into()].into(), "ghi".into()]);
962
963 assert_ne!(a, b);
964 }
965
966 #[test]
967 fn value_inequality_shared_3() {
968 let shared = Rope::from("def");
969 let a = Rope::new(vec!["abc".into(), shared.clone().into(), "ggg".into()]);
970 let b = Rope::new(vec!["abc".into(), shared.into(), "hhh".into()]);
971
972 assert_ne!(a, b);
973 }
974
975 #[test]
976 fn iteration() {
977 let shared = Rope::from("def");
978 let rope = Rope::new(vec!["abc".into(), shared.into(), "ghi".into()]);
979
980 let chunks = rope.read().collect::<Vec<_>>();
981
982 assert_eq!(chunks, vec!["abc", "def", "ghi"]);
983 }
984
985 #[test]
986 fn read() {
987 let shared = Rope::from("def");
988 let rope = Rope::new(vec!["abc".into(), shared.into(), "ghi".into()]);
989
990 let mut chunks = vec![];
991 let mut buf = [0_u8; 2];
992 let mut reader = rope.read();
993 loop {
994 let amt = reader.read(&mut buf).unwrap();
995 if amt == 0 {
996 break;
997 }
998 chunks.push(Vec::from(&buf[0..amt]));
999 }
1000
1001 assert_eq!(
1002 chunks,
1003 vec![
1004 Vec::from(*b"ab"),
1005 Vec::from(*b"cd"),
1006 Vec::from(*b"ef"),
1007 Vec::from(*b"gh"),
1008 Vec::from(*b"i")
1009 ]
1010 );
1011 }
1012
1013 #[test]
1014 fn fill_buf() {
1015 let shared = Rope::from("def");
1016 let rope = Rope::new(vec!["abc".into(), shared.into(), "ghi".into()]);
1017
1018 let mut chunks = vec![];
1019 let mut reader = rope.read();
1020 loop {
1021 let buf = reader.fill_buf().unwrap();
1022 if buf.is_empty() {
1023 break;
1024 }
1025 let c = min(2, buf.len());
1026 chunks.push(Vec::from(buf));
1027 reader.consume(c);
1028 }
1029
1030 assert_eq!(
1031 chunks,
1032 vec![
1035 Vec::from(*b"abc"),
1036 Vec::from(*b"c"),
1037 Vec::from(*b"def"),
1038 Vec::from(*b"f"),
1039 Vec::from(*b"ghi"),
1040 Vec::from(*b"i")
1041 ]
1042 );
1043 }
1044
1045 #[test]
1046 fn test_to_bytes() -> Result<()> {
1047 let rope = Rope::from("abc");
1048 assert_eq!(rope.to_bytes()?, Cow::Borrowed::<[u8]>(&[0x61, 0x62, 0x63]));
1049 Ok(())
1050 }
1051}