1use std::{
2 borrow::Cow,
3 cmp::{Ordering, min},
4 fmt,
5 hash::{Hash, Hasher},
6 io::{BufRead, Read, Result as IoResult, Write},
7 mem,
8 ops::{AddAssign, Deref},
9 pin::Pin,
10 task::{Context as TaskContext, Poll},
11};
12
13use RopeElem::{Local, Shared};
14use anyhow::{Context, Result};
15use bincode::{
16 Decode, Encode,
17 de::{Decoder, read::Reader as _},
18 enc::{Encoder, write::Writer as _},
19 error::{DecodeError, EncodeError},
20 impl_borrow_decode,
21};
22use bytes::Bytes;
23use futures::Stream;
24use tokio::io::{AsyncRead, ReadBuf};
25use triomphe::Arc;
26use turbo_tasks_hash::{DeterministicHash, DeterministicHasher, hash_xxh3_hash64};
27
28static EMPTY_BUF: &[u8] = &[];
29
30#[turbo_tasks::value(shared, serialization = "custom", eq = "manual", operation)]
37#[derive(Clone, Debug, Default)]
38pub struct Rope {
39 length: usize,
41
42 #[turbo_tasks(debug_ignore, trace_ignore)]
44 data: InnerRope,
45}
46
47#[derive(Clone, Debug)]
50struct InnerRope(Arc<Vec<RopeElem>>);
51
52#[derive(Clone, Debug)]
54enum RopeElem {
55 Local(Bytes),
57
58 Shared(InnerRope),
60}
61
62#[derive(Default, Debug)]
66pub struct RopeBuilder {
67 length: usize,
69
70 committed: Vec<RopeElem>,
73
74 uncommitted: Uncommitted,
79}
80
81#[derive(Default)]
85enum Uncommitted {
86 #[default]
87 None,
88
89 Static(&'static [u8]),
94
95 Owned(Vec<u8>),
100}
101
102impl Rope {
103 pub fn len(&self) -> usize {
104 self.length
105 }
106
107 pub fn is_empty(&self) -> bool {
108 self.length == 0
109 }
110
111 pub fn read(&self) -> RopeReader<'_> {
113 RopeReader::new(&self.data, 0)
114 }
115
116 pub fn to_str(&self) -> Result<Cow<'_, str>> {
118 self.data.to_str(self.length)
119 }
120
121 pub fn to_bytes(&self) -> Cow<'_, [u8]> {
123 self.data.to_bytes(self.length)
124 }
125
126 pub fn into_bytes(self) -> Bytes {
127 self.data.into_bytes(self.length)
128 }
129}
130
131impl From<Vec<u8>> for Rope {
132 fn from(mut bytes: Vec<u8>) -> Self {
133 bytes.shrink_to_fit();
134 Rope::from(Bytes::from(bytes))
135 }
136}
137
138impl From<String> for Rope {
139 fn from(mut bytes: String) -> Self {
140 bytes.shrink_to_fit();
141 Rope::from(Bytes::from(bytes))
142 }
143}
144
145impl<T: Into<Bytes>> From<T> for Rope {
146 default fn from(bytes: T) -> Self {
147 let bytes = bytes.into();
148 if bytes.is_empty() {
150 Default::default()
151 } else {
152 Rope {
153 length: bytes.len(),
154 data: InnerRope(Arc::from(vec![Local(bytes)])),
155 }
156 }
157 }
158}
159
160impl RopeBuilder {
161 pub fn push_bytes(&mut self, bytes: &[u8]) {
166 if bytes.is_empty() {
167 return;
168 }
169
170 self.uncommitted.push_bytes(bytes);
171 }
172
173 pub fn reserve_bytes(&mut self, additional: usize) {
178 self.uncommitted.reserve_bytes(additional);
179 }
180
181 pub fn push_static_bytes(&mut self, bytes: &'static [u8]) {
186 if bytes.is_empty() {
187 return;
188 }
189
190 if bytes.len() < mem::size_of::<Bytes>() {
194 return self.uncommitted.push_static_bytes(bytes);
195 }
196
197 self.finish();
199
200 self.length += bytes.len();
201 self.committed.push(Local(Bytes::from_static(bytes)));
202 }
203
204 pub fn concat(&mut self, other: &Rope) {
209 if other.is_empty() {
210 return;
211 }
212
213 self.finish();
215
216 self.length += other.len();
217 self.committed.push(Shared(other.data.clone()));
218 }
219
220 fn finish(&mut self) {
225 if let Some(b) = self.uncommitted.finish() {
226 debug_assert!(!b.is_empty(), "must not have empty uncommitted bytes");
227 self.length += b.len();
228 self.committed.push(Local(b));
229 }
230 }
231
232 pub fn len(&self) -> usize {
233 self.length + self.uncommitted.len()
234 }
235
236 pub fn is_empty(&self) -> bool {
237 self.len() == 0
238 }
239
240 pub fn build(mut self) -> Rope {
242 self.finish();
243 Rope {
244 length: self.length,
245 data: InnerRope::from(self.committed),
246 }
247 }
248}
249
250impl From<&'static str> for RopeBuilder {
251 default fn from(bytes: &'static str) -> Self {
252 let mut r = RopeBuilder::default();
253 r += bytes;
254 r
255 }
256}
257
258impl From<Vec<u8>> for RopeBuilder {
259 fn from(bytes: Vec<u8>) -> Self {
260 RopeBuilder {
261 uncommitted: Uncommitted::from(bytes),
263 ..Default::default()
264 }
265 }
266}
267
268impl Write for RopeBuilder {
269 fn write(&mut self, bytes: &[u8]) -> IoResult<usize> {
270 self.push_bytes(bytes);
271 Ok(bytes.len())
272 }
273
274 fn flush(&mut self) -> IoResult<()> {
275 self.finish();
276 Ok(())
277 }
278}
279
280impl AddAssign<&'static str> for RopeBuilder {
281 fn add_assign(&mut self, rhs: &'static str) {
286 self.push_static_bytes(rhs.as_bytes());
287 }
288}
289
290impl AddAssign<&Rope> for RopeBuilder {
291 fn add_assign(&mut self, rhs: &Rope) {
292 self.concat(rhs);
293 }
294}
295
296impl Uncommitted {
297 fn len(&self) -> usize {
298 match self {
299 Uncommitted::None => 0,
300 Uncommitted::Static(s) => s.len(),
301 Uncommitted::Owned(v) => v.len(),
302 }
303 }
304
305 fn push_bytes(&mut self, bytes: &[u8]) {
308 debug_assert!(!bytes.is_empty(), "must not push empty uncommitted bytes");
309 match self {
310 Self::None => *self = Self::Owned(bytes.to_vec()),
311 Self::Static(s) => {
312 let v = [s, bytes].concat();
316 *self = Self::Owned(v);
317 }
318 Self::Owned(v) => v.extend(bytes),
319 }
320 }
321
322 fn reserve_bytes(&mut self, additional: usize) {
325 match self {
326 Self::None => {
327 *self = Self::Owned(Vec::with_capacity(additional));
328 }
329 Self::Static(s) => {
330 let mut v = Vec::with_capacity(s.len() + additional);
331 v.extend_from_slice(s);
332 *self = Self::Owned(v);
333 }
334 Self::Owned(v) => {
335 v.reserve(additional);
336 }
337 }
338 }
339
340 fn push_static_bytes(&mut self, bytes: &'static [u8]) {
343 debug_assert!(!bytes.is_empty(), "must not push empty uncommitted bytes");
344 match self {
345 Self::None => *self = Self::Static(bytes),
352 _ => self.push_bytes(bytes),
353 }
354 }
355
356 fn finish(&mut self) -> Option<Bytes> {
359 match mem::take(self) {
360 Self::None => None,
361 Self::Static(s) => Some(Bytes::from_static(s)),
362 Self::Owned(mut v) => {
363 v.shrink_to_fit();
364 Some(v.into())
365 }
366 }
367 }
368}
369
370impl fmt::Debug for Uncommitted {
371 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
372 match self {
373 Uncommitted::None => f.write_str("None"),
374 Uncommitted::Static(s) => f
375 .debug_tuple("Static")
376 .field(&Bytes::from_static(s))
377 .finish(),
378 Uncommitted::Owned(v) => f
379 .debug_tuple("Owned")
380 .field(&Bytes::from(v.clone()))
381 .finish(),
382 }
383 }
384}
385
386impl DeterministicHash for Rope {
387 fn deterministic_hash<H: DeterministicHasher>(&self, state: &mut H) {
390 state.write_usize(self.len());
391 self.data.deterministic_hash(state);
392 }
393}
394
395impl Rope {
396 pub fn content_hash(&self) -> impl DeterministicHash + '_ {
404 RopeBytesOnlyHash(self)
405 }
406}
407pub struct RopeBytesOnlyHash<'a>(&'a Rope);
408impl DeterministicHash for RopeBytesOnlyHash<'_> {
409 fn deterministic_hash<H: DeterministicHasher>(&self, state: &mut H) {
410 self.0.data.deterministic_hash(state);
411 }
412}
413
414impl Encode for Rope {
420 fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
421 self.length.encode(encoder)?;
422 let mut reader = self.read();
423 for chunk in &mut reader {
424 encoder.writer().write(chunk)?;
425 }
426
427 Ok(())
428 }
429}
430
431impl<Context> Decode<Context> for Rope {
432 #[allow(clippy::uninit_vec)]
433 fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
434 let length = usize::decode(decoder)?;
435 let mut bytes = Vec::with_capacity(length);
436
437 unsafe {
443 bytes.set_len(length);
444 }
445 decoder.claim_bytes_read(length)?;
447 decoder.reader().read(&mut bytes)?;
448
449 Ok(Rope::from(bytes))
450 }
451}
452
453impl_borrow_decode!(Rope);
454
455pub mod ser_as_string {
456 use serde::{Serializer, ser::Error};
457
458 use super::Rope;
459
460 pub fn serialize<S: Serializer>(rope: &Rope, serializer: S) -> Result<S::Ok, S::Error> {
462 let s = rope.to_str().map_err(Error::custom)?;
463 serializer.serialize_str(&s)
464 }
465}
466
467pub mod ser_option_as_string {
468 use serde::{Serializer, ser::Error};
469
470 use super::Rope;
471
472 pub fn serialize<S: Serializer>(rope: &Option<Rope>, serializer: S) -> Result<S::Ok, S::Error> {
474 if let Some(rope) = rope {
475 let s = rope.to_str().map_err(Error::custom)?;
476 serializer.serialize_some(&s)
477 } else {
478 serializer.serialize_none()
479 }
480 }
481}
482
483impl PartialEq for Rope {
484 fn eq(&self, other: &Self) -> bool {
486 if self.len() != other.len() {
487 return false;
488 }
489 self.cmp(other) == Ordering::Equal
490 }
491}
492
493impl Eq for Rope {}
494
495impl Hash for Rope {
496 fn hash<H: Hasher>(&self, state: &mut H) {
497 hash_xxh3_hash64(self.content_hash()).hash(state);
498 }
499}
500
501impl Ord for Rope {
502 fn cmp(&self, other: &Self) -> Ordering {
503 if Arc::ptr_eq(&self.data, &other.data) {
504 return Ordering::Equal;
505 }
506
507 let left = &self.data;
510 let right = &other.data;
511 let len = min(left.len(), right.len());
512 let mut index = 0;
513 while index < len {
514 let a = &left[index];
515 let b = &right[index];
516
517 match a.maybe_cmp(b) {
518 Some(Ordering::Equal) => index += 1,
520 Some(ordering) => return ordering,
522 None => break,
524 }
525 }
526 if index == len {
529 return left.len().cmp(&right.len());
532 }
533
534 let mut left = RopeReader::new(left, index);
537 let mut right = RopeReader::new(right, index);
538 loop {
539 match (left.fill_buf(), right.fill_buf()) {
540 (Ok(a), Ok(b)) => {
543 let len = min(a.len(), b.len());
544
545 if len == 0 {
547 return a.len().cmp(&b.len());
548 }
549
550 match a[0..len].cmp(&b[0..len]) {
551 Ordering::Equal => {
552 left.consume(len);
553 right.consume(len);
554 }
555 ordering => return ordering,
556 }
557 }
558
559 _ => unreachable!(),
562 }
563 }
564 }
565}
566
567impl PartialOrd for Rope {
568 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
569 Some(self.cmp(other))
570 }
571}
572
573impl From<Vec<u8>> for Uncommitted {
574 fn from(bytes: Vec<u8>) -> Self {
575 if bytes.is_empty() {
576 Uncommitted::None
577 } else {
578 Uncommitted::Owned(bytes)
579 }
580 }
581}
582
583impl InnerRope {
584 fn to_str(&self, len: usize) -> Result<Cow<'_, str>> {
586 match &self[..] {
587 [] => Ok(Cow::Borrowed("")),
588 [Shared(inner)] => inner.to_str(len),
589 [Local(bytes)] => {
590 let utf8 = std::str::from_utf8(bytes);
591 utf8.context("failed to convert rope into string")
592 .map(Cow::Borrowed)
593 }
594 _ => {
595 let mut read = RopeReader::new(self, 0);
596 let mut string = String::with_capacity(len);
597 let res = read.read_to_string(&mut string);
598 res.context("failed to convert rope into string")?;
599 Ok(Cow::Owned(string))
600 }
601 }
602 }
603
604 fn to_bytes(&self, len: usize) -> Cow<'_, [u8]> {
606 match &self[..] {
607 [] => Cow::Borrowed(EMPTY_BUF),
608 [Shared(inner)] => inner.to_bytes(len),
609 [Local(bytes)] => Cow::Borrowed(bytes),
610 _ => {
611 let mut read = RopeReader::new(self, 0);
612 let mut buf = Vec::with_capacity(len);
613 read.read_to_end(&mut buf)
614 .expect("rope reader should not fail");
615 buf.into()
616 }
617 }
618 }
619
620 fn into_bytes(mut self, len: usize) -> Bytes {
621 if self.0.is_empty() {
622 return Bytes::default();
623 } else if self.0.len() == 1 {
624 let data = Arc::try_unwrap(self.0);
625 match data {
626 Ok(data) => {
627 return data.into_iter().next().unwrap().into_bytes(len);
628 }
629 Err(data) => {
630 if let Local(bytes) = &data[0] {
632 return bytes.clone();
633 }
634 self.0 = data;
635 }
636 }
637 }
638
639 let mut read = RopeReader::new(&self, 0);
640 let mut buf = Vec::with_capacity(len);
641 read.read_to_end(&mut buf)
642 .expect("read of rope cannot fail");
643 buf.into()
644 }
645}
646
647impl Default for InnerRope {
648 fn default() -> Self {
649 InnerRope(Arc::new(vec![]))
650 }
651}
652
653impl DeterministicHash for InnerRope {
654 fn deterministic_hash<H: DeterministicHasher>(&self, state: &mut H) {
659 for v in self.0.iter() {
660 v.deterministic_hash(state);
661 }
662 }
663}
664
665impl From<Vec<RopeElem>> for InnerRope {
666 fn from(mut els: Vec<RopeElem>) -> Self {
667 if cfg!(debug_assertions) {
668 for el in els.iter() {
670 match el {
671 Local(b) => debug_assert!(!b.is_empty(), "must not have empty Bytes"),
672 Shared(s) => {
673 debug_assert!(!s.is_empty(), "must not have empty InnerRope");
678 }
679 }
680 }
681 }
682 els.shrink_to_fit();
683 InnerRope(Arc::from(els))
684 }
685}
686
687impl Deref for InnerRope {
688 type Target = Arc<Vec<RopeElem>>;
689
690 fn deref(&self) -> &Self::Target {
691 &self.0
692 }
693}
694
695impl RopeElem {
696 fn maybe_cmp(&self, other: &Self) -> Option<Ordering> {
697 match (self, other) {
698 (Local(a), Local(b)) => {
699 if a.len() == b.len() {
700 return Some(a.cmp(b));
701 }
702
703 None
706 }
707 (Shared(a), Shared(b)) => {
708 if Arc::ptr_eq(&a.0, &b.0) {
709 return Some(Ordering::Equal);
710 }
711
712 None
715 }
716 _ => None,
717 }
718 }
719
720 fn into_bytes(self, len: usize) -> Bytes {
721 match self {
722 Local(bytes) => bytes,
723 Shared(inner) => inner.into_bytes(len),
724 }
725 }
726}
727
728impl DeterministicHash for RopeElem {
729 fn deterministic_hash<H: DeterministicHasher>(&self, state: &mut H) {
733 match self {
734 Local(bytes) => state.write_bytes(bytes),
735 Shared(inner) => inner.deterministic_hash(state),
736 }
737 }
738}
739
740#[derive(Debug, Default)]
741pub struct RopeReader<'a> {
743 stack: Vec<StackElem<'a>>,
745 offset: usize,
747}
748
749#[derive(Debug)]
753enum StackElem<'a> {
754 Local(&'a Bytes),
755 Shared(&'a InnerRope, usize),
756}
757
758impl<'a> RopeReader<'a> {
759 fn new(inner: &'a InnerRope, index: usize) -> Self {
760 if index >= inner.len() {
761 Default::default()
762 } else {
763 RopeReader {
764 stack: vec![StackElem::Shared(inner, index)],
765 offset: 0,
766 }
767 }
768 }
769
770 fn read_internal(&mut self, want: usize, buf: &mut ReadBuf<'_>) -> usize {
773 let mut remaining = want;
774
775 while remaining > 0 {
776 let bytes = match self.next_internal() {
777 None => break,
778 Some(b) => b,
779 };
780
781 let lower = self.offset;
782 let upper = min(bytes.len(), lower + remaining);
783
784 buf.put_slice(&bytes[self.offset..upper]);
785
786 if upper < bytes.len() {
787 self.offset = upper;
788 self.stack.push(StackElem::Local(bytes))
789 } else {
790 self.offset = 0;
791 }
792 remaining -= upper - lower;
793 }
794
795 want - remaining
796 }
797
798 fn next_internal(&mut self) -> Option<&'a Bytes> {
800 loop {
803 let (inner, mut index) = match self.stack.pop() {
804 None => return None,
805 Some(StackElem::Local(b)) => {
806 debug_assert!(!b.is_empty(), "must not have empty Bytes section");
807 return Some(b);
808 }
809 Some(StackElem::Shared(r, i)) => (r, i),
810 };
811
812 let el = &inner[index];
813 index += 1;
814 if index < inner.len() {
815 self.stack.push(StackElem::Shared(inner, index));
816 }
817
818 self.stack.push(StackElem::from(el));
819 }
820 }
821}
822
823impl<'a> Iterator for RopeReader<'a> {
824 type Item = &'a Bytes;
825
826 fn next(&mut self) -> Option<Self::Item> {
827 self.offset = 0;
828 self.next_internal()
829 }
830}
831
832impl Read for RopeReader<'_> {
833 fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
834 Ok(self.read_internal(buf.len(), &mut ReadBuf::new(buf)))
835 }
836}
837
838impl AsyncRead for RopeReader<'_> {
839 fn poll_read(
840 self: Pin<&mut Self>,
841 _cx: &mut TaskContext<'_>,
842 buf: &mut ReadBuf<'_>,
843 ) -> Poll<IoResult<()>> {
844 let this = self.get_mut();
845 this.read_internal(buf.remaining(), buf);
846 Poll::Ready(Ok(()))
847 }
848}
849
850impl BufRead for RopeReader<'_> {
851 fn fill_buf(&mut self) -> IoResult<&[u8]> {
853 let bytes = match self.next_internal() {
856 None => return Ok(EMPTY_BUF),
857 Some(b) => b,
858 };
859
860 self.stack.push(StackElem::Local(bytes));
864 let Some(StackElem::Local(bytes)) = self.stack.last() else {
865 unreachable!()
866 };
867
868 Ok(&bytes[self.offset..])
869 }
870
871 fn consume(&mut self, amt: usize) {
872 if let Some(StackElem::Local(b)) = self.stack.last_mut() {
873 debug_assert!(
875 self.offset + amt <= b.len(),
876 "It is a logic error if `amount` exceeds the number of unread bytes in the \
877 internal buffer, which is returned by `fill_buf`."
878 );
879 self.offset += amt;
882 if self.offset == b.len() {
883 self.stack.pop();
885 self.offset = 0;
886 }
887 }
888 }
889}
890
891impl<'a> Stream for RopeReader<'a> {
892 type Item = Result<&'a Bytes>;
895
896 fn poll_next(self: Pin<&mut Self>, _cx: &mut TaskContext<'_>) -> Poll<Option<Self::Item>> {
899 let this = self.get_mut();
900 Poll::Ready(this.next().map(Ok))
901 }
902}
903
904impl<'a> From<&'a RopeElem> for StackElem<'a> {
905 fn from(el: &'a RopeElem) -> Self {
906 match el {
907 Local(bytes) => Self::Local(bytes),
908 Shared(inner) => Self::Shared(inner, 0),
909 }
910 }
911}
912
913#[cfg(test)]
914mod test {
915 use std::{
916 borrow::Cow,
917 cmp::min,
918 io::{BufRead, Read},
919 };
920
921 use anyhow::Result;
922 use turbo_tasks_hash::{DeterministicHasher, Xxh3Hash64Hasher, hash_xxh3_hash64};
923
924 use super::{InnerRope, Rope, RopeBuilder, RopeElem};
925
926 impl From<&str> for RopeElem {
929 fn from(value: &str) -> Self {
930 RopeElem::Local(value.to_string().into())
931 }
932 }
933 impl From<Vec<RopeElem>> for RopeElem {
934 fn from(value: Vec<RopeElem>) -> Self {
935 RopeElem::Shared(InnerRope::from(value))
936 }
937 }
938 impl From<Rope> for RopeElem {
939 fn from(value: Rope) -> Self {
940 RopeElem::Shared(value.data)
941 }
942 }
943 impl Rope {
944 fn new(value: Vec<RopeElem>) -> Self {
945 let data = InnerRope::from(value);
946 Rope {
947 length: data.len(),
948 data,
949 }
950 }
951 }
952 impl InnerRope {
953 fn len(&self) -> usize {
954 self.iter().map(|v| v.len()).sum()
955 }
956 }
957 impl RopeElem {
958 fn len(&self) -> usize {
959 match self {
960 RopeElem::Local(b) => b.len(),
961 RopeElem::Shared(r) => r.len(),
962 }
963 }
964 }
965
966 #[test]
967 fn empty_build_without_pushes() {
968 let empty = RopeBuilder::default().build();
969 let mut reader = empty.read();
970 assert!(reader.next().is_none());
971 }
972
973 #[test]
974 fn empty_build_with_empty_static_push() {
975 let mut builder = RopeBuilder::default();
976 builder += "";
977
978 let empty = builder.build();
979 let mut reader = empty.read();
980 assert!(reader.next().is_none());
981 }
982
983 #[test]
984 fn empty_build_with_empty_bytes_push() {
985 let mut builder = RopeBuilder::default();
986 builder.push_bytes(&[]);
987
988 let empty = builder.build();
989 let mut reader = empty.read();
990 assert!(reader.next().is_none());
991 }
992
993 #[test]
994 fn empty_build_with_empty_concat() {
995 let mut builder = RopeBuilder::default();
996 builder += &RopeBuilder::default().build();
997
998 let empty = builder.build();
999 let mut reader = empty.read();
1000 assert!(reader.next().is_none());
1001 }
1002
1003 #[test]
1004 fn empty_from_empty_static_str() {
1005 let empty = Rope::from("");
1006 let mut reader = empty.read();
1007 assert!(reader.next().is_none());
1008 }
1009
1010 #[test]
1011 fn empty_from_empty_string() {
1012 let empty = Rope::from("".to_string());
1013 let mut reader = empty.read();
1014 assert!(reader.next().is_none());
1015 }
1016
1017 #[test]
1018 fn empty_equality() {
1019 let a = Rope::from("");
1020 let b = Rope::from("");
1021
1022 assert_eq!(a, b);
1023 }
1024
1025 #[test]
1026 fn cloned_equality() {
1027 let a = Rope::from("abc");
1028 let b = a.clone();
1029
1030 assert_eq!(a, b);
1031 }
1032
1033 #[test]
1034 fn value_equality() {
1035 let a = Rope::from("abc".to_string());
1036 let b = Rope::from("abc".to_string());
1037
1038 assert_eq!(a, b);
1039 }
1040
1041 #[test]
1042 fn value_inequality() {
1043 let a = Rope::from("abc".to_string());
1044 let b = Rope::from("def".to_string());
1045
1046 assert_ne!(a, b);
1047 }
1048
1049 #[test]
1050 fn value_equality_shared_1() {
1051 let shared = Rope::from("def");
1052 let a = Rope::new(vec!["abc".into(), shared.clone().into(), "ghi".into()]);
1053 let b = Rope::new(vec!["abc".into(), shared.into(), "ghi".into()]);
1054
1055 assert_eq!(a, b);
1056 }
1057
1058 #[test]
1059 fn value_equality_shared_2() {
1060 let a = Rope::new(vec!["abc".into(), vec!["def".into()].into(), "ghi".into()]);
1061 let b = Rope::new(vec!["abc".into(), vec!["def".into()].into(), "ghi".into()]);
1062
1063 assert_eq!(a, b);
1064 }
1065
1066 #[test]
1067 fn value_equality_splits_1() {
1068 let a = Rope::new(vec!["a".into(), "aa".into()]);
1069 let b = Rope::new(vec!["aa".into(), "a".into()]);
1070
1071 assert_eq!(a, b);
1072 }
1073
1074 #[test]
1075 fn value_equality_splits_2() {
1076 let a = Rope::new(vec![vec!["a".into()].into(), "aa".into()]);
1077 let b = Rope::new(vec![vec!["aa".into()].into(), "a".into()]);
1078
1079 assert_eq!(a, b);
1080 }
1081
1082 #[test]
1083 fn value_inequality_shared_1() {
1084 let shared = Rope::from("def");
1085 let a = Rope::new(vec!["aaa".into(), shared.clone().into(), "ghi".into()]);
1086 let b = Rope::new(vec!["bbb".into(), shared.into(), "ghi".into()]);
1087
1088 assert_ne!(a, b);
1089 }
1090
1091 #[test]
1092 fn value_inequality_shared_2() {
1093 let a = Rope::new(vec!["abc".into(), vec!["ddd".into()].into(), "ghi".into()]);
1094 let b = Rope::new(vec!["abc".into(), vec!["eee".into()].into(), "ghi".into()]);
1095
1096 assert_ne!(a, b);
1097 }
1098
1099 #[test]
1100 fn value_inequality_shared_3() {
1101 let shared = Rope::from("def");
1102 let a = Rope::new(vec!["abc".into(), shared.clone().into(), "ggg".into()]);
1103 let b = Rope::new(vec!["abc".into(), shared.into(), "hhh".into()]);
1104
1105 assert_ne!(a, b);
1106 }
1107
1108 #[test]
1109 fn hash_structure_invariance() {
1110 let shared = Rope::from("def");
1111 let a = Rope::new(vec!["abc".into(), shared.clone().into(), "ggg".into()]);
1112 let b = Rope::new(vec![
1113 "ab".into(),
1114 "c".into(),
1115 shared.into(),
1116 "g".into(),
1117 "gg".into(),
1118 ]);
1119
1120 assert_eq!(hash_xxh3_hash64(a), hash_xxh3_hash64(b));
1121 }
1122
1123 #[test]
1124 fn content_hash() {
1125 let rope = Rope::new(vec!["abc".into(), "def".into()]);
1126
1127 let string = "abcdef";
1128 let mut hasher = Xxh3Hash64Hasher::default();
1129 hasher.write_bytes(string.as_bytes());
1130
1131 assert_eq!(hash_xxh3_hash64(rope.content_hash()), hasher.finish());
1132 }
1133
1134 #[test]
1135 fn standard_hash_uses_content() {
1136 use std::{
1137 collections::hash_map::DefaultHasher,
1138 hash::{Hash, Hasher},
1139 };
1140
1141 let original = Rope::from("same content");
1142 let copied = Rope::from(original.to_bytes().into_owned());
1143 let mut original_hasher = DefaultHasher::new();
1144 let mut copied_hasher = DefaultHasher::new();
1145 original.hash(&mut original_hasher);
1146 copied.hash(&mut copied_hasher);
1147
1148 assert_eq!(original, copied);
1149 assert_eq!(original_hasher.finish(), copied_hasher.finish());
1150 }
1151
1152 #[test]
1153 fn iteration() {
1154 let shared = Rope::from("def");
1155 let rope = Rope::new(vec!["abc".into(), shared.into(), "ghi".into()]);
1156
1157 let chunks = rope.read().collect::<Vec<_>>();
1158
1159 assert_eq!(chunks, vec!["abc", "def", "ghi"]);
1160 }
1161
1162 #[test]
1163 fn read() {
1164 let shared = Rope::from("def");
1165 let rope = Rope::new(vec!["abc".into(), shared.into(), "ghi".into()]);
1166
1167 let mut chunks = vec![];
1168 let mut buf = [0_u8; 2];
1169 let mut reader = rope.read();
1170 loop {
1171 let amt = reader.read(&mut buf).unwrap();
1172 if amt == 0 {
1173 break;
1174 }
1175 chunks.push(Vec::from(&buf[0..amt]));
1176 }
1177
1178 assert_eq!(
1179 chunks,
1180 vec![
1181 Vec::from(*b"ab"),
1182 Vec::from(*b"cd"),
1183 Vec::from(*b"ef"),
1184 Vec::from(*b"gh"),
1185 Vec::from(*b"i")
1186 ]
1187 );
1188 }
1189
1190 #[test]
1191 fn fill_buf() {
1192 let shared = Rope::from("def");
1193 let rope = Rope::new(vec!["abc".into(), shared.into(), "ghi".into()]);
1194
1195 let mut chunks = vec![];
1196 let mut reader = rope.read();
1197 loop {
1198 let buf = reader.fill_buf().unwrap();
1199 if buf.is_empty() {
1200 break;
1201 }
1202 let c = min(2, buf.len());
1203 chunks.push(Vec::from(buf));
1204 reader.consume(c);
1205 }
1206
1207 assert_eq!(
1208 chunks,
1209 vec![
1212 Vec::from(*b"abc"),
1213 Vec::from(*b"c"),
1214 Vec::from(*b"def"),
1215 Vec::from(*b"f"),
1216 Vec::from(*b"ghi"),
1217 Vec::from(*b"i")
1218 ]
1219 );
1220 }
1221
1222 #[test]
1223 fn test_to_bytes() -> Result<()> {
1224 let rope = Rope::from("abc");
1225 assert_eq!(rope.to_bytes(), Cow::Borrowed::<[u8]>(&[0x61, 0x62, 0x63]));
1226 Ok(())
1227 }
1228}