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};
21
22static EMPTY_BUF: &[u8] = &[];
23
24#[turbo_tasks::value(shared, serialization = "custom", eq = "manual", operation)]
31#[derive(Clone, Debug, Default)]
32pub struct Rope {
33 length: usize,
35
36 #[turbo_tasks(debug_ignore, trace_ignore)]
38 data: InnerRope,
39}
40
41#[derive(Clone, Debug)]
44struct InnerRope(Arc<Vec<RopeElem>>);
45
46#[derive(Clone, Debug)]
48enum RopeElem {
49 Local(Bytes),
51
52 Shared(InnerRope),
54}
55
56#[derive(Default, Debug)]
60pub struct RopeBuilder {
61 length: usize,
63
64 committed: Vec<RopeElem>,
67
68 uncommitted: Uncommitted,
73}
74
75#[derive(Default)]
79enum Uncommitted {
80 #[default]
81 None,
82
83 Static(&'static [u8]),
88
89 Owned(Vec<u8>),
94}
95
96impl Rope {
97 pub fn len(&self) -> usize {
98 self.length
99 }
100
101 pub fn is_empty(&self) -> bool {
102 self.length == 0
103 }
104
105 pub fn read(&self) -> RopeReader {
107 RopeReader::new(&self.data, 0)
108 }
109
110 pub fn to_str(&self) -> Result<Cow<'_, str>> {
112 self.data.to_str(self.length)
113 }
114
115 pub fn to_bytes(&self) -> Cow<'_, [u8]> {
117 self.data.to_bytes(self.length)
118 }
119
120 pub fn into_bytes(self) -> Bytes {
121 self.data.into_bytes(self.length)
122 }
123}
124
125impl From<Vec<u8>> for Rope {
126 fn from(mut bytes: Vec<u8>) -> Self {
127 bytes.shrink_to_fit();
128 Rope::from(Bytes::from(bytes))
129 }
130}
131
132impl From<String> for Rope {
133 fn from(mut bytes: String) -> Self {
134 bytes.shrink_to_fit();
135 Rope::from(Bytes::from(bytes))
136 }
137}
138
139impl<T: Into<Bytes>> From<T> for Rope {
140 default fn from(bytes: T) -> Self {
141 let bytes = bytes.into();
142 if bytes.is_empty() {
144 Default::default()
145 } else {
146 Rope {
147 length: bytes.len(),
148 data: InnerRope(Arc::from(vec![Local(bytes)])),
149 }
150 }
151 }
152}
153
154impl RopeBuilder {
155 pub fn push_bytes(&mut self, bytes: &[u8]) {
160 if bytes.is_empty() {
161 return;
162 }
163
164 self.uncommitted.push_bytes(bytes);
165 }
166
167 pub fn push_static_bytes(&mut self, bytes: &'static [u8]) {
172 if bytes.is_empty() {
173 return;
174 }
175
176 if bytes.len() < mem::size_of::<Bytes>() {
180 return self.uncommitted.push_static_bytes(bytes);
181 }
182
183 self.finish();
185
186 self.length += bytes.len();
187 self.committed.push(Local(Bytes::from_static(bytes)));
188 }
189
190 pub fn concat(&mut self, other: &Rope) {
195 if other.is_empty() {
196 return;
197 }
198
199 self.finish();
201
202 self.length += other.len();
203 self.committed.push(Shared(other.data.clone()));
204 }
205
206 fn finish(&mut self) {
211 if let Some(b) = self.uncommitted.finish() {
212 debug_assert!(!b.is_empty(), "must not have empty uncommitted bytes");
213 self.length += b.len();
214 self.committed.push(Local(b));
215 }
216 }
217
218 pub fn len(&self) -> usize {
219 self.length + self.uncommitted.len()
220 }
221
222 pub fn is_empty(&self) -> bool {
223 self.len() == 0
224 }
225
226 pub fn build(mut self) -> Rope {
228 self.finish();
229 Rope {
230 length: self.length,
231 data: InnerRope::from(self.committed),
232 }
233 }
234}
235
236impl From<&'static str> for RopeBuilder {
237 default fn from(bytes: &'static str) -> Self {
238 let mut r = RopeBuilder::default();
239 r += bytes;
240 r
241 }
242}
243
244impl From<Vec<u8>> for RopeBuilder {
245 fn from(bytes: Vec<u8>) -> Self {
246 RopeBuilder {
247 uncommitted: Uncommitted::from(bytes),
249 ..Default::default()
250 }
251 }
252}
253
254impl Write for RopeBuilder {
255 fn write(&mut self, bytes: &[u8]) -> IoResult<usize> {
256 self.push_bytes(bytes);
257 Ok(bytes.len())
258 }
259
260 fn flush(&mut self) -> IoResult<()> {
261 self.finish();
262 Ok(())
263 }
264}
265
266impl AddAssign<&'static str> for RopeBuilder {
267 fn add_assign(&mut self, rhs: &'static str) {
272 self.push_static_bytes(rhs.as_bytes());
273 }
274}
275
276impl AddAssign<&Rope> for RopeBuilder {
277 fn add_assign(&mut self, rhs: &Rope) {
278 self.concat(rhs);
279 }
280}
281
282impl Uncommitted {
283 fn len(&self) -> usize {
284 match self {
285 Uncommitted::None => 0,
286 Uncommitted::Static(s) => s.len(),
287 Uncommitted::Owned(v) => v.len(),
288 }
289 }
290
291 fn push_bytes(&mut self, bytes: &[u8]) {
294 debug_assert!(!bytes.is_empty(), "must not push empty uncommitted bytes");
295 match self {
296 Self::None => *self = Self::Owned(bytes.to_vec()),
297 Self::Static(s) => {
298 let v = [s, bytes].concat();
302 *self = Self::Owned(v);
303 }
304 Self::Owned(v) => v.extend(bytes),
305 }
306 }
307
308 fn push_static_bytes(&mut self, bytes: &'static [u8]) {
311 debug_assert!(!bytes.is_empty(), "must not push empty uncommitted bytes");
312 match self {
313 Self::None => *self = Self::Static(bytes),
320 _ => self.push_bytes(bytes),
321 }
322 }
323
324 fn finish(&mut self) -> Option<Bytes> {
327 match mem::take(self) {
328 Self::None => None,
329 Self::Static(s) => Some(Bytes::from_static(s)),
330 Self::Owned(mut v) => {
331 v.shrink_to_fit();
332 Some(v.into())
333 }
334 }
335 }
336}
337
338impl fmt::Debug for Uncommitted {
339 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
340 match self {
341 Uncommitted::None => f.write_str("None"),
342 Uncommitted::Static(s) => f
343 .debug_tuple("Static")
344 .field(&Bytes::from_static(s))
345 .finish(),
346 Uncommitted::Owned(v) => f
347 .debug_tuple("Owned")
348 .field(&Bytes::from(v.clone()))
349 .finish(),
350 }
351 }
352}
353
354impl DeterministicHash for Rope {
355 fn deterministic_hash<H: DeterministicHasher>(&self, state: &mut H) {
358 state.write_usize(self.len());
359 self.data.deterministic_hash(state);
360 }
361}
362
363impl Serialize for Rope {
364 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
368 let bytes = self.to_bytes();
369 match bytes {
370 Cow::Borrowed(b) => serde_bytes::Bytes::new(b).serialize(serializer),
371 Cow::Owned(b) => ByteBuf::from(b).serialize(serializer),
372 }
373 }
374}
375
376impl<'de> Deserialize<'de> for Rope {
377 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
379 let bytes = ByteBuf::deserialize(deserializer)?.into_vec();
380 Ok(Rope::from(bytes))
381 }
382}
383
384pub mod ser_as_string {
385 use serde::{Serializer, ser::Error};
386
387 use super::Rope;
388
389 pub fn serialize<S: Serializer>(rope: &Rope, serializer: S) -> Result<S::Ok, S::Error> {
391 let s = rope.to_str().map_err(Error::custom)?;
392 serializer.serialize_str(&s)
393 }
394}
395
396pub mod ser_option_as_string {
397 use serde::{Serializer, ser::Error};
398
399 use super::Rope;
400
401 pub fn serialize<S: Serializer>(rope: &Option<Rope>, serializer: S) -> Result<S::Ok, S::Error> {
403 if let Some(rope) = rope {
404 let s = rope.to_str().map_err(Error::custom)?;
405 serializer.serialize_some(&s)
406 } else {
407 serializer.serialize_none()
408 }
409 }
410}
411
412impl PartialEq for Rope {
413 fn eq(&self, other: &Self) -> bool {
415 if self.len() != other.len() {
416 return false;
417 }
418 self.cmp(other) == Ordering::Equal
419 }
420}
421
422impl Eq for Rope {}
423
424impl Ord for Rope {
425 fn cmp(&self, other: &Self) -> Ordering {
426 if Arc::ptr_eq(&self.data, &other.data) {
427 return Ordering::Equal;
428 }
429
430 let left = &self.data;
433 let right = &other.data;
434 let len = min(left.len(), right.len());
435 let mut index = 0;
436 while index < len {
437 let a = &left[index];
438 let b = &right[index];
439
440 match a.maybe_cmp(b) {
441 Some(Ordering::Equal) => index += 1,
443 Some(ordering) => return ordering,
445 None => break,
447 }
448 }
449 if index == len {
452 return left.len().cmp(&right.len());
455 }
456
457 let mut left = RopeReader::new(left, index);
460 let mut right = RopeReader::new(right, index);
461 loop {
462 match (left.fill_buf(), right.fill_buf()) {
463 (Ok(a), Ok(b)) => {
466 let len = min(a.len(), b.len());
467
468 if len == 0 {
470 return a.len().cmp(&b.len());
471 }
472
473 match a[0..len].cmp(&b[0..len]) {
474 Ordering::Equal => {
475 left.consume(len);
476 right.consume(len);
477 }
478 ordering => return ordering,
479 }
480 }
481
482 _ => unreachable!(),
485 }
486 }
487 }
488}
489
490impl PartialOrd for Rope {
491 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
492 Some(self.cmp(other))
493 }
494}
495
496impl From<Vec<u8>> for Uncommitted {
497 fn from(bytes: Vec<u8>) -> Self {
498 if bytes.is_empty() {
499 Uncommitted::None
500 } else {
501 Uncommitted::Owned(bytes)
502 }
503 }
504}
505
506impl InnerRope {
507 fn to_str(&self, len: usize) -> Result<Cow<'_, str>> {
509 match &self[..] {
510 [] => Ok(Cow::Borrowed("")),
511 [Shared(inner)] => inner.to_str(len),
512 [Local(bytes)] => {
513 let utf8 = std::str::from_utf8(bytes);
514 utf8.context("failed to convert rope into string")
515 .map(Cow::Borrowed)
516 }
517 _ => {
518 let mut read = RopeReader::new(self, 0);
519 let mut string = String::with_capacity(len);
520 let res = read.read_to_string(&mut string);
521 res.context("failed to convert rope into string")?;
522 Ok(Cow::Owned(string))
523 }
524 }
525 }
526
527 fn to_bytes(&self, len: usize) -> Cow<'_, [u8]> {
529 match &self[..] {
530 [] => Cow::Borrowed(EMPTY_BUF),
531 [Shared(inner)] => inner.to_bytes(len),
532 [Local(bytes)] => Cow::Borrowed(bytes),
533 _ => {
534 let mut read = RopeReader::new(self, 0);
535 let mut buf = Vec::with_capacity(len);
536 read.read_to_end(&mut buf)
537 .expect("rope reader should not fail");
538 buf.into()
539 }
540 }
541 }
542
543 fn into_bytes(mut self, len: usize) -> Bytes {
544 if self.0.is_empty() {
545 return Bytes::default();
546 } else if self.0.len() == 1 {
547 let data = Arc::try_unwrap(self.0);
548 match data {
549 Ok(data) => {
550 return data.into_iter().next().unwrap().into_bytes(len);
551 }
552 Err(data) => {
553 if let Local(bytes) = &data[0] {
555 return bytes.clone();
556 }
557 self.0 = data;
558 }
559 }
560 }
561
562 let mut read = RopeReader::new(&self, 0);
563 let mut buf = Vec::with_capacity(len);
564 read.read_to_end(&mut buf)
565 .expect("read of rope cannot fail");
566 buf.into()
567 }
568}
569
570impl Default for InnerRope {
571 fn default() -> Self {
572 InnerRope(Arc::new(vec![]))
573 }
574}
575
576impl DeterministicHash for InnerRope {
577 fn deterministic_hash<H: DeterministicHasher>(&self, state: &mut H) {
582 for v in self.0.iter() {
583 v.deterministic_hash(state);
584 }
585 }
586}
587
588impl From<Vec<RopeElem>> for InnerRope {
589 fn from(mut els: Vec<RopeElem>) -> Self {
590 if cfg!(debug_assertions) {
591 for el in els.iter() {
593 match el {
594 Local(b) => debug_assert!(!b.is_empty(), "must not have empty Bytes"),
595 Shared(s) => {
596 debug_assert!(!s.is_empty(), "must not have empty InnerRope");
601 }
602 }
603 }
604 }
605 els.shrink_to_fit();
606 InnerRope(Arc::from(els))
607 }
608}
609
610impl Deref for InnerRope {
611 type Target = Arc<Vec<RopeElem>>;
612
613 fn deref(&self) -> &Self::Target {
614 &self.0
615 }
616}
617
618impl RopeElem {
619 fn maybe_cmp(&self, other: &Self) -> Option<Ordering> {
620 match (self, other) {
621 (Local(a), Local(b)) => {
622 if a.len() == b.len() {
623 return Some(a.cmp(b));
624 }
625
626 None
629 }
630 (Shared(a), Shared(b)) => {
631 if Arc::ptr_eq(&a.0, &b.0) {
632 return Some(Ordering::Equal);
633 }
634
635 None
638 }
639 _ => None,
640 }
641 }
642
643 fn into_bytes(self, len: usize) -> Bytes {
644 match self {
645 Local(bytes) => bytes,
646 Shared(inner) => inner.into_bytes(len),
647 }
648 }
649}
650
651impl DeterministicHash for RopeElem {
652 fn deterministic_hash<H: DeterministicHasher>(&self, state: &mut H) {
656 match self {
657 Local(bytes) => state.write_bytes(bytes),
658 Shared(inner) => inner.deterministic_hash(state),
659 }
660 }
661}
662
663#[derive(Debug, Default)]
664pub struct RopeReader {
666 stack: Vec<StackElem>,
669}
670
671#[derive(Debug)]
675enum StackElem {
676 Local(Bytes),
677 Shared(InnerRope, usize),
678}
679
680impl RopeReader {
681 fn new(inner: &InnerRope, index: usize) -> Self {
682 if index >= inner.len() {
683 Default::default()
684 } else {
685 RopeReader {
686 stack: vec![StackElem::Shared(inner.clone(), index)],
687 }
688 }
689 }
690
691 fn read_internal(&mut self, want: usize, buf: &mut ReadBuf<'_>) -> usize {
694 let mut remaining = want;
695
696 while remaining > 0 {
697 let mut bytes = match self.next() {
698 None => break,
699 Some(b) => b,
700 };
701
702 let amount = min(bytes.len(), remaining);
703
704 buf.put_slice(&bytes[0..amount]);
705
706 if amount < bytes.len() {
707 bytes.advance(amount);
708 self.stack.push(StackElem::Local(bytes))
709 }
710 remaining -= amount;
711 }
712
713 want - remaining
714 }
715}
716
717impl Iterator for RopeReader {
718 type Item = Bytes;
719
720 fn next(&mut self) -> Option<Self::Item> {
721 loop {
724 let (inner, mut index) = match self.stack.pop() {
725 None => return None,
726 Some(StackElem::Local(b)) => {
727 debug_assert!(!b.is_empty(), "must not have empty Bytes section");
728 return Some(b);
729 }
730 Some(StackElem::Shared(r, i)) => (r, i),
731 };
732
733 let el = inner[index].clone();
734 index += 1;
735 if index < inner.len() {
736 self.stack.push(StackElem::Shared(inner, index));
737 }
738
739 self.stack.push(StackElem::from(el));
740 }
741 }
742}
743
744impl Read for RopeReader {
745 fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
746 Ok(self.read_internal(buf.len(), &mut ReadBuf::new(buf)))
747 }
748}
749
750impl AsyncRead for RopeReader {
751 fn poll_read(
752 self: Pin<&mut Self>,
753 _cx: &mut TaskContext<'_>,
754 buf: &mut ReadBuf<'_>,
755 ) -> Poll<IoResult<()>> {
756 let this = self.get_mut();
757 this.read_internal(buf.remaining(), buf);
758 Poll::Ready(Ok(()))
759 }
760}
761
762impl BufRead for RopeReader {
763 fn fill_buf(&mut self) -> IoResult<&[u8]> {
764 let bytes = match self.next() {
767 None => return Ok(EMPTY_BUF),
768 Some(b) => b,
769 };
770
771 self.stack.push(StackElem::Local(bytes));
775 let Some(StackElem::Local(bytes)) = self.stack.last() else {
776 unreachable!()
777 };
778
779 Ok(bytes)
780 }
781
782 fn consume(&mut self, amt: usize) {
783 if let Some(StackElem::Local(b)) = self.stack.last_mut() {
784 if amt == b.len() {
785 self.stack.pop();
786 } else {
787 b.advance(amt);
790 }
791 }
792 }
793}
794
795impl Stream for RopeReader {
796 type Item = Result<Bytes>;
799
800 fn poll_next(self: Pin<&mut Self>, _cx: &mut TaskContext<'_>) -> Poll<Option<Self::Item>> {
803 let this = self.get_mut();
804 Poll::Ready(this.next().map(Ok))
805 }
806}
807
808impl From<RopeElem> for StackElem {
809 fn from(el: RopeElem) -> Self {
810 match el {
811 Local(bytes) => Self::Local(bytes),
812 Shared(inner) => Self::Shared(inner, 0),
813 }
814 }
815}
816
817#[cfg(test)]
818mod test {
819 use std::{
820 borrow::Cow,
821 cmp::min,
822 io::{BufRead, Read},
823 };
824
825 use anyhow::Result;
826
827 use super::{InnerRope, Rope, RopeBuilder, RopeElem};
828
829 impl From<&str> for RopeElem {
832 fn from(value: &str) -> Self {
833 RopeElem::Local(value.to_string().into())
834 }
835 }
836 impl From<Vec<RopeElem>> for RopeElem {
837 fn from(value: Vec<RopeElem>) -> Self {
838 RopeElem::Shared(InnerRope::from(value))
839 }
840 }
841 impl From<Rope> for RopeElem {
842 fn from(value: Rope) -> Self {
843 RopeElem::Shared(value.data)
844 }
845 }
846 impl Rope {
847 fn new(value: Vec<RopeElem>) -> Self {
848 let data = InnerRope::from(value);
849 Rope {
850 length: data.len(),
851 data,
852 }
853 }
854 }
855 impl InnerRope {
856 fn len(&self) -> usize {
857 self.iter().map(|v| v.len()).sum()
858 }
859 }
860 impl RopeElem {
861 fn len(&self) -> usize {
862 match self {
863 RopeElem::Local(b) => b.len(),
864 RopeElem::Shared(r) => r.len(),
865 }
866 }
867 }
868
869 #[test]
870 fn empty_build_without_pushes() {
871 let empty = RopeBuilder::default().build();
872 let mut reader = empty.read();
873 assert!(reader.next().is_none());
874 }
875
876 #[test]
877 fn empty_build_with_empty_static_push() {
878 let mut builder = RopeBuilder::default();
879 builder += "";
880
881 let empty = builder.build();
882 let mut reader = empty.read();
883 assert!(reader.next().is_none());
884 }
885
886 #[test]
887 fn empty_build_with_empty_bytes_push() {
888 let mut builder = RopeBuilder::default();
889 builder.push_bytes(&[]);
890
891 let empty = builder.build();
892 let mut reader = empty.read();
893 assert!(reader.next().is_none());
894 }
895
896 #[test]
897 fn empty_build_with_empty_concat() {
898 let mut builder = RopeBuilder::default();
899 builder += &RopeBuilder::default().build();
900
901 let empty = builder.build();
902 let mut reader = empty.read();
903 assert!(reader.next().is_none());
904 }
905
906 #[test]
907 fn empty_from_empty_static_str() {
908 let empty = Rope::from("");
909 let mut reader = empty.read();
910 assert!(reader.next().is_none());
911 }
912
913 #[test]
914 fn empty_from_empty_string() {
915 let empty = Rope::from("".to_string());
916 let mut reader = empty.read();
917 assert!(reader.next().is_none());
918 }
919
920 #[test]
921 fn empty_equality() {
922 let a = Rope::from("");
923 let b = Rope::from("");
924
925 assert_eq!(a, b);
926 }
927
928 #[test]
929 fn cloned_equality() {
930 let a = Rope::from("abc");
931 let b = a.clone();
932
933 assert_eq!(a, b);
934 }
935
936 #[test]
937 fn value_equality() {
938 let a = Rope::from("abc".to_string());
939 let b = Rope::from("abc".to_string());
940
941 assert_eq!(a, b);
942 }
943
944 #[test]
945 fn value_inequality() {
946 let a = Rope::from("abc".to_string());
947 let b = Rope::from("def".to_string());
948
949 assert_ne!(a, b);
950 }
951
952 #[test]
953 fn value_equality_shared_1() {
954 let shared = Rope::from("def");
955 let a = Rope::new(vec!["abc".into(), shared.clone().into(), "ghi".into()]);
956 let b = Rope::new(vec!["abc".into(), shared.into(), "ghi".into()]);
957
958 assert_eq!(a, b);
959 }
960
961 #[test]
962 fn value_equality_shared_2() {
963 let a = Rope::new(vec!["abc".into(), vec!["def".into()].into(), "ghi".into()]);
964 let b = Rope::new(vec!["abc".into(), vec!["def".into()].into(), "ghi".into()]);
965
966 assert_eq!(a, b);
967 }
968
969 #[test]
970 fn value_equality_splits_1() {
971 let a = Rope::new(vec!["a".into(), "aa".into()]);
972 let b = Rope::new(vec!["aa".into(), "a".into()]);
973
974 assert_eq!(a, b);
975 }
976
977 #[test]
978 fn value_equality_splits_2() {
979 let a = Rope::new(vec![vec!["a".into()].into(), "aa".into()]);
980 let b = Rope::new(vec![vec!["aa".into()].into(), "a".into()]);
981
982 assert_eq!(a, b);
983 }
984
985 #[test]
986 fn value_inequality_shared_1() {
987 let shared = Rope::from("def");
988 let a = Rope::new(vec!["aaa".into(), shared.clone().into(), "ghi".into()]);
989 let b = Rope::new(vec!["bbb".into(), shared.into(), "ghi".into()]);
990
991 assert_ne!(a, b);
992 }
993
994 #[test]
995 fn value_inequality_shared_2() {
996 let a = Rope::new(vec!["abc".into(), vec!["ddd".into()].into(), "ghi".into()]);
997 let b = Rope::new(vec!["abc".into(), vec!["eee".into()].into(), "ghi".into()]);
998
999 assert_ne!(a, b);
1000 }
1001
1002 #[test]
1003 fn value_inequality_shared_3() {
1004 let shared = Rope::from("def");
1005 let a = Rope::new(vec!["abc".into(), shared.clone().into(), "ggg".into()]);
1006 let b = Rope::new(vec!["abc".into(), shared.into(), "hhh".into()]);
1007
1008 assert_ne!(a, b);
1009 }
1010
1011 #[test]
1012 fn iteration() {
1013 let shared = Rope::from("def");
1014 let rope = Rope::new(vec!["abc".into(), shared.into(), "ghi".into()]);
1015
1016 let chunks = rope.read().collect::<Vec<_>>();
1017
1018 assert_eq!(chunks, vec!["abc", "def", "ghi"]);
1019 }
1020
1021 #[test]
1022 fn read() {
1023 let shared = Rope::from("def");
1024 let rope = Rope::new(vec!["abc".into(), shared.into(), "ghi".into()]);
1025
1026 let mut chunks = vec![];
1027 let mut buf = [0_u8; 2];
1028 let mut reader = rope.read();
1029 loop {
1030 let amt = reader.read(&mut buf).unwrap();
1031 if amt == 0 {
1032 break;
1033 }
1034 chunks.push(Vec::from(&buf[0..amt]));
1035 }
1036
1037 assert_eq!(
1038 chunks,
1039 vec![
1040 Vec::from(*b"ab"),
1041 Vec::from(*b"cd"),
1042 Vec::from(*b"ef"),
1043 Vec::from(*b"gh"),
1044 Vec::from(*b"i")
1045 ]
1046 );
1047 }
1048
1049 #[test]
1050 fn fill_buf() {
1051 let shared = Rope::from("def");
1052 let rope = Rope::new(vec!["abc".into(), shared.into(), "ghi".into()]);
1053
1054 let mut chunks = vec![];
1055 let mut reader = rope.read();
1056 loop {
1057 let buf = reader.fill_buf().unwrap();
1058 if buf.is_empty() {
1059 break;
1060 }
1061 let c = min(2, buf.len());
1062 chunks.push(Vec::from(buf));
1063 reader.consume(c);
1064 }
1065
1066 assert_eq!(
1067 chunks,
1068 vec![
1071 Vec::from(*b"abc"),
1072 Vec::from(*b"c"),
1073 Vec::from(*b"def"),
1074 Vec::from(*b"f"),
1075 Vec::from(*b"ghi"),
1076 Vec::from(*b"i")
1077 ]
1078 );
1079 }
1080
1081 #[test]
1082 fn test_to_bytes() -> Result<()> {
1083 let rope = Rope::from("abc");
1084 assert_eq!(rope.to_bytes(), Cow::Borrowed::<[u8]>(&[0x61, 0x62, 0x63]));
1085 Ok(())
1086 }
1087}