1use std::borrow::Borrow;
8use std::cell::{Cell, UnsafeCell};
9use std::cmp::Ordering;
10use std::default::Default;
11use std::fmt as strfmt;
12use std::iter::FromIterator;
13use std::marker::PhantomData;
14use std::num::NonZeroUsize;
15use std::ops::{Deref, DerefMut};
16use std::sync::atomic::Ordering as AtomicOrdering;
17use std::sync::atomic::{self, AtomicUsize};
18use std::{hash, io, mem, ptr, str};
19
20use crate::buf32::{self, Buf32};
21use crate::fmt::imp::Fixup;
22use crate::fmt::{self, Slice, ASCII, UTF8};
23use crate::util::{
24 copy_and_advance, copy_lifetime, copy_lifetime_mut, unsafe_slice, unsafe_slice_mut,
25};
26use crate::OFLOW;
27
28const MAX_INLINE_LEN: usize = 8;
29const MAX_INLINE_TAG: usize = 0xF;
30const EMPTY_TAG: usize = 0xF;
31
32#[inline(always)]
33fn inline_tag(len: u32) -> NonZeroUsize {
34 debug_assert!(len <= MAX_INLINE_LEN as u32);
35 unsafe { NonZeroUsize::new_unchecked(if len == 0 { EMPTY_TAG } else { len as usize }) }
36}
37
38pub unsafe trait Atomicity: 'static {
51 #[doc(hidden)]
52 fn new() -> Self;
53
54 #[doc(hidden)]
55 fn increment(&self) -> usize;
56
57 #[doc(hidden)]
58 fn decrement(&self) -> usize;
59
60 #[doc(hidden)]
61 fn fence_acquire();
62}
63
64#[repr(C)]
71pub struct NonAtomic(Cell<usize>);
72
73unsafe impl Atomicity for NonAtomic {
74 #[inline]
75 fn new() -> Self {
76 NonAtomic(Cell::new(1))
77 }
78
79 #[inline]
80 fn increment(&self) -> usize {
81 let value = self.0.get();
82 self.0.set(value.checked_add(1).expect(OFLOW));
83 value
84 }
85
86 #[inline]
87 fn decrement(&self) -> usize {
88 let value = self.0.get();
89 self.0.set(value - 1);
90 value
91 }
92
93 #[inline]
94 fn fence_acquire() {}
95}
96
97pub struct Atomic(AtomicUsize);
104
105unsafe impl Atomicity for Atomic {
106 #[inline]
107 fn new() -> Self {
108 Atomic(AtomicUsize::new(1))
109 }
110
111 #[inline]
112 fn increment(&self) -> usize {
113 self.0.fetch_add(1, AtomicOrdering::Relaxed)
115 }
116
117 #[inline]
118 fn decrement(&self) -> usize {
119 self.0.fetch_sub(1, AtomicOrdering::Release)
120 }
121
122 #[inline]
123 fn fence_acquire() {
124 atomic::fence(AtomicOrdering::Acquire);
125 }
126}
127
128#[repr(C)] struct Header<A: Atomicity> {
130 refcount: A,
131 cap: u32,
132}
133
134impl<A> Header<A>
135where
136 A: Atomicity,
137{
138 #[inline(always)]
139 unsafe fn new() -> Header<A> {
140 Header {
141 refcount: A::new(),
142 cap: 0,
143 }
144 }
145}
146
147#[derive(Copy, Clone, Hash, Debug, PartialEq, Eq)]
149pub enum SubtendrilError {
150 OutOfBounds,
151 ValidationFailed,
152}
153
154#[repr(C)]
183pub struct Tendril<F, A = NonAtomic>
184where
185 F: fmt::Format,
186 A: Atomicity,
187{
188 ptr: Cell<NonZeroUsize>,
189 buf: UnsafeCell<Buffer>,
190 marker: PhantomData<*mut F>,
191 refcount_marker: PhantomData<A>,
192}
193
194#[repr(C)]
195union Buffer {
196 heap: Heap,
197 inline: [u8; 8],
198}
199
200#[derive(Copy, Clone)]
201#[repr(C)]
202struct Heap {
203 len: u32,
204 aux: u32,
205}
206
207unsafe impl<F, A> Send for Tendril<F, A>
208where
209 F: fmt::Format,
210 A: Atomicity + Sync,
211{
212}
213
214pub type StrTendril = Tendril<fmt::UTF8>;
216
217pub type ByteTendril = Tendril<fmt::Bytes>;
219
220impl<F, A> Clone for Tendril<F, A>
221where
222 F: fmt::Format,
223 A: Atomicity,
224{
225 #[inline]
226 fn clone(&self) -> Tendril<F, A> {
227 unsafe {
228 if self.ptr.get().get() > MAX_INLINE_TAG {
229 self.make_buf_shared();
230 self.incref();
231 }
232
233 ptr::read(self)
234 }
235 }
236}
237
238impl<F, A> Drop for Tendril<F, A>
239where
240 F: fmt::Format,
241 A: Atomicity,
242{
243 #[inline]
244 fn drop(&mut self) {
245 unsafe {
246 let p = self.ptr.get().get();
247 if p <= MAX_INLINE_TAG {
248 return;
249 }
250
251 let (buf, shared, _) = self.assume_buf();
252 if shared {
253 let header = self.header();
254 if (*header).refcount.decrement() == 1 {
255 A::fence_acquire();
256 buf.destroy();
257 }
258 } else {
259 buf.destroy();
260 }
261 }
262 }
263}
264
265macro_rules! from_iter_method {
266 ($ty:ty) => {
267 #[inline]
268 fn from_iter<I>(iterable: I) -> Self
269 where
270 I: IntoIterator<Item = $ty>,
271 {
272 let mut output = Self::new();
273 output.extend(iterable);
274 output
275 }
276 };
277}
278
279impl<A> Extend<char> for Tendril<fmt::UTF8, A>
280where
281 A: Atomicity,
282{
283 #[inline]
284 fn extend<I>(&mut self, iterable: I)
285 where
286 I: IntoIterator<Item = char>,
287 {
288 let iterator = iterable.into_iter();
289 self.force_reserve(iterator.size_hint().0 as u32);
290 for c in iterator {
291 self.push_char(c);
292 }
293 }
294}
295
296impl<A> FromIterator<char> for Tendril<fmt::UTF8, A>
297where
298 A: Atomicity,
299{
300 from_iter_method!(char);
301}
302
303impl<A> Extend<u8> for Tendril<fmt::Bytes, A>
304where
305 A: Atomicity,
306{
307 #[inline]
308 fn extend<I>(&mut self, iterable: I)
309 where
310 I: IntoIterator<Item = u8>,
311 {
312 let iterator = iterable.into_iter();
313 self.force_reserve(iterator.size_hint().0 as u32);
314 for b in iterator {
315 self.push_slice(&[b]);
316 }
317 }
318}
319
320impl<A> FromIterator<u8> for Tendril<fmt::Bytes, A>
321where
322 A: Atomicity,
323{
324 from_iter_method!(u8);
325}
326
327impl<'a, A> Extend<&'a u8> for Tendril<fmt::Bytes, A>
328where
329 A: Atomicity,
330{
331 #[inline]
332 fn extend<I>(&mut self, iterable: I)
333 where
334 I: IntoIterator<Item = &'a u8>,
335 {
336 let iterator = iterable.into_iter();
337 self.force_reserve(iterator.size_hint().0 as u32);
338 for &b in iterator {
339 self.push_slice(&[b]);
340 }
341 }
342}
343
344impl<'a, A> FromIterator<&'a u8> for Tendril<fmt::Bytes, A>
345where
346 A: Atomicity,
347{
348 from_iter_method!(&'a u8);
349}
350
351impl<'a, A> Extend<&'a str> for Tendril<fmt::UTF8, A>
352where
353 A: Atomicity,
354{
355 #[inline]
356 fn extend<I>(&mut self, iterable: I)
357 where
358 I: IntoIterator<Item = &'a str>,
359 {
360 for s in iterable {
361 self.push_slice(s);
362 }
363 }
364}
365
366impl<'a, A> FromIterator<&'a str> for Tendril<fmt::UTF8, A>
367where
368 A: Atomicity,
369{
370 from_iter_method!(&'a str);
371}
372
373impl<'a, A> Extend<&'a [u8]> for Tendril<fmt::Bytes, A>
374where
375 A: Atomicity,
376{
377 #[inline]
378 fn extend<I>(&mut self, iterable: I)
379 where
380 I: IntoIterator<Item = &'a [u8]>,
381 {
382 for s in iterable {
383 self.push_slice(s);
384 }
385 }
386}
387
388impl<'a, A> FromIterator<&'a [u8]> for Tendril<fmt::Bytes, A>
389where
390 A: Atomicity,
391{
392 from_iter_method!(&'a [u8]);
393}
394
395impl<'a, F, A> Extend<&'a Tendril<F, A>> for Tendril<F, A>
396where
397 F: fmt::Format + 'a,
398 A: Atomicity,
399{
400 #[inline]
401 fn extend<I>(&mut self, iterable: I)
402 where
403 I: IntoIterator<Item = &'a Tendril<F, A>>,
404 {
405 for t in iterable {
406 self.push_tendril(t);
407 }
408 }
409}
410
411impl<'a, F, A> FromIterator<&'a Tendril<F, A>> for Tendril<F, A>
412where
413 F: fmt::Format + 'a,
414 A: Atomicity,
415{
416 from_iter_method!(&'a Tendril<F, A>);
417}
418
419impl<F, A> Deref for Tendril<F, A>
420where
421 F: fmt::SliceFormat,
422 A: Atomicity,
423{
424 type Target = F::Slice;
425
426 #[inline]
427 fn deref(&self) -> &F::Slice {
428 unsafe { F::Slice::from_bytes(self.as_byte_slice()) }
429 }
430}
431
432impl<F, A> DerefMut for Tendril<F, A>
433where
434 F: fmt::SliceFormat,
435 A: Atomicity,
436{
437 #[inline]
438 fn deref_mut(&mut self) -> &mut F::Slice {
439 unsafe { F::Slice::from_mut_bytes(self.as_mut_byte_slice()) }
440 }
441}
442
443impl<F, A> Borrow<[u8]> for Tendril<F, A>
444where
445 F: fmt::SliceFormat,
446 A: Atomicity,
447{
448 fn borrow(&self) -> &[u8] {
449 self.as_byte_slice()
450 }
451}
452
453impl<F, A> PartialEq for Tendril<F, A>
458where
459 F: fmt::Format,
460 A: Atomicity,
461{
462 #[inline]
463 fn eq(&self, other: &Self) -> bool {
464 self.as_byte_slice() == other.as_byte_slice()
465 }
466}
467
468impl<A: Atomicity> PartialEq<str> for Tendril<ASCII, A> {
469 #[inline]
470 fn eq(&self, other: &str) -> bool {
471 self.as_byte_slice() == other.as_bytes()
472 }
473}
474
475impl<A: Atomicity> PartialEq<str> for Tendril<UTF8, A> {
476 #[inline]
477 fn eq(&self, other: &str) -> bool {
478 self.as_byte_slice() == other.as_bytes()
479 }
480}
481
482impl<F, A> Eq for Tendril<F, A>
483where
484 F: fmt::Format,
485 A: Atomicity,
486{
487}
488
489impl<F, A> PartialOrd for Tendril<F, A>
490where
491 F: fmt::SliceFormat,
492 <F as fmt::SliceFormat>::Slice: PartialOrd,
493 A: Atomicity,
494{
495 #[inline]
496 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
497 PartialOrd::partial_cmp(&**self, &**other)
498 }
499}
500
501impl<F, A> Ord for Tendril<F, A>
502where
503 F: fmt::SliceFormat,
504 <F as fmt::SliceFormat>::Slice: Ord,
505 A: Atomicity,
506{
507 #[inline]
508 fn cmp(&self, other: &Self) -> Ordering {
509 Ord::cmp(&**self, &**other)
510 }
511}
512
513impl<F, A> Default for Tendril<F, A>
514where
515 F: fmt::Format,
516 A: Atomicity,
517{
518 #[inline(always)]
519 fn default() -> Tendril<F, A> {
520 Tendril::new()
521 }
522}
523
524impl<F, A> strfmt::Debug for Tendril<F, A>
525where
526 F: fmt::SliceFormat + Default + strfmt::Debug,
527 <F as fmt::SliceFormat>::Slice: strfmt::Debug,
528 A: Atomicity,
529{
530 #[inline]
531 fn fmt(&self, f: &mut strfmt::Formatter) -> strfmt::Result {
532 let kind = match self.ptr.get().get() {
533 p if p <= MAX_INLINE_TAG => "inline",
534 p if p & 1 == 1 => "shared",
535 _ => "owned",
536 };
537
538 write!(f, "Tendril<{:?}>({}: ", <F as Default>::default(), kind)?;
539 <<F as fmt::SliceFormat>::Slice as strfmt::Debug>::fmt(&**self, f)?;
540 write!(f, ")")
541 }
542}
543
544impl<F, A> hash::Hash for Tendril<F, A>
545where
546 F: fmt::Format,
547 A: Atomicity,
548{
549 #[inline]
550 fn hash<H: hash::Hasher>(&self, hasher: &mut H) {
551 self.as_byte_slice().hash(hasher)
552 }
553}
554
555impl<F, A> Tendril<F, A>
556where
557 F: fmt::Format,
558 A: Atomicity,
559{
560 #[inline(always)]
562 pub fn new() -> Tendril<F, A> {
563 unsafe { Tendril::inline(&[]) }
564 }
565
566 #[inline]
568 pub fn with_capacity(capacity: u32) -> Tendril<F, A> {
569 let mut t: Tendril<F, A> = Tendril::new();
570 if capacity > MAX_INLINE_LEN as u32 {
571 unsafe {
572 t.make_owned_with_capacity(capacity);
573 }
574 }
575 t
576 }
577
578 #[inline]
583 pub fn reserve(&mut self, additional: u32) {
584 if !self.is_shared() {
585 self.force_reserve(additional);
588 }
589 }
590
591 #[inline]
593 fn force_reserve(&mut self, additional: u32) {
594 let new_len = self.len32().checked_add(additional).expect(OFLOW);
595 if new_len > MAX_INLINE_LEN as u32 {
596 unsafe {
597 self.make_owned_with_capacity(new_len);
598 }
599 }
600 }
601
602 #[inline(always)]
607 pub fn len32(&self) -> u32 {
608 match self.ptr.get().get() {
609 EMPTY_TAG => 0,
610 n if n <= MAX_INLINE_LEN => n as u32,
611 _ => unsafe { self.raw_len() },
612 }
613 }
614
615 #[inline]
617 pub fn is_shared(&self) -> bool {
618 let n = self.ptr.get().get();
619
620 (n > MAX_INLINE_TAG) && ((n & 1) == 1)
621 }
622
623 #[inline]
625 pub fn is_shared_with(&self, other: &Tendril<F, A>) -> bool {
626 let n = self.ptr.get().get();
627
628 (n > MAX_INLINE_TAG) && (n == other.ptr.get().get())
629 }
630
631 #[inline]
633 pub fn clear(&mut self) {
634 if self.ptr.get().get() <= MAX_INLINE_TAG {
635 self.ptr
636 .set(unsafe { NonZeroUsize::new_unchecked(EMPTY_TAG) });
637 } else {
638 let (_, shared, _) = unsafe { self.assume_buf() };
639 if shared {
640 *self = Tendril::new();
642 } else {
643 unsafe { self.set_len(0) };
644 }
645 }
646 }
647
648 #[inline]
650 pub fn try_from_byte_slice(x: &[u8]) -> Result<Tendril<F, A>, ()> {
651 match F::validate(x) {
652 true => Ok(unsafe { Tendril::from_byte_slice_without_validating(x) }),
653 false => Err(()),
654 }
655 }
656
657 #[inline(always)]
659 pub fn as_bytes(&self) -> &Tendril<fmt::Bytes, A> {
660 unsafe { mem::transmute(self) }
661 }
662
663 #[inline(always)]
665 pub fn into_bytes(self) -> Tendril<fmt::Bytes, A> {
666 unsafe { mem::transmute(self) }
667 }
668
669 #[inline]
674 pub fn into_send(mut self) -> SendTendril<F> {
675 self.make_owned();
676 SendTendril {
677 tendril: unsafe { mem::transmute(self) },
680 }
681 }
682
683 #[inline(always)]
685 pub fn as_superset<Super>(&self) -> &Tendril<Super, A>
686 where
687 F: fmt::SubsetOf<Super>,
688 Super: fmt::Format,
689 {
690 unsafe { mem::transmute(self) }
691 }
692
693 #[inline(always)]
695 pub fn into_superset<Super>(self) -> Tendril<Super, A>
696 where
697 F: fmt::SubsetOf<Super>,
698 Super: fmt::Format,
699 {
700 unsafe { mem::transmute(self) }
701 }
702
703 #[inline]
705 pub fn try_as_subset<Sub>(&self) -> Result<&Tendril<Sub, A>, ()>
706 where
707 Sub: fmt::SubsetOf<F>,
708 {
709 match Sub::revalidate_subset(self.as_byte_slice()) {
710 true => Ok(unsafe { mem::transmute(self) }),
711 false => Err(()),
712 }
713 }
714
715 #[inline]
717 pub fn try_into_subset<Sub>(self) -> Result<Tendril<Sub, A>, Self>
718 where
719 Sub: fmt::SubsetOf<F>,
720 {
721 match Sub::revalidate_subset(self.as_byte_slice()) {
722 true => Ok(unsafe { mem::transmute(self) }),
723 false => Err(self),
724 }
725 }
726
727 #[inline]
730 pub fn try_reinterpret_view<Other>(&self) -> Result<&Tendril<Other, A>, ()>
731 where
732 Other: fmt::Format,
733 {
734 match Other::validate(self.as_byte_slice()) {
735 true => Ok(unsafe { mem::transmute(self) }),
736 false => Err(()),
737 }
738 }
739
740 #[inline]
747 pub fn try_reinterpret<Other>(self) -> Result<Tendril<Other, A>, Self>
748 where
749 Other: fmt::Format,
750 {
751 match Other::validate(self.as_byte_slice()) {
752 true => Ok(unsafe { mem::transmute(self) }),
753 false => Err(self),
754 }
755 }
756
757 #[inline]
760 pub fn try_push_bytes(&mut self, buf: &[u8]) -> Result<(), ()> {
761 match F::validate(buf) {
762 true => unsafe {
763 self.push_bytes_without_validating(buf);
764 Ok(())
765 },
766 false => Err(()),
767 }
768 }
769
770 #[inline]
772 pub fn push_tendril(&mut self, other: &Tendril<F, A>) {
773 let new_len = self.len32().checked_add(other.len32()).expect(OFLOW);
774
775 unsafe {
776 if (self.ptr.get().get() > MAX_INLINE_TAG) && (other.ptr.get().get() > MAX_INLINE_TAG) {
777 let (self_buf, self_shared, _) = self.assume_buf();
778 let (other_buf, other_shared, _) = other.assume_buf();
779
780 if self_shared
781 && other_shared
782 && (self_buf.data_ptr() == other_buf.data_ptr())
783 && other.aux() == self.aux() + self.raw_len()
784 {
785 self.set_len(new_len);
786 return;
787 }
788 }
789
790 self.push_bytes_without_validating(other.as_byte_slice())
791 }
792 }
793
794 #[inline]
803 pub fn try_subtendril(
804 &self,
805 offset: u32,
806 length: u32,
807 ) -> Result<Tendril<F, A>, SubtendrilError> {
808 let self_len = self.len32();
809 if offset > self_len || length > (self_len - offset) {
810 return Err(SubtendrilError::OutOfBounds);
811 }
812
813 unsafe {
814 let byte_slice = unsafe_slice(self.as_byte_slice(), offset as usize, length as usize);
815 if !F::validate_subseq(byte_slice) {
816 return Err(SubtendrilError::ValidationFailed);
817 }
818
819 Ok(self.unsafe_subtendril(offset, length))
820 }
821 }
822
823 #[inline]
827 pub fn subtendril(&self, offset: u32, length: u32) -> Tendril<F, A> {
828 self.try_subtendril(offset, length).unwrap()
829 }
830
831 #[inline]
836 pub fn try_pop_front(&mut self, n: u32) -> Result<(), SubtendrilError> {
837 if n == 0 {
838 return Ok(());
839 }
840 let old_len = self.len32();
841 if n > old_len {
842 return Err(SubtendrilError::OutOfBounds);
843 }
844 let new_len = old_len - n;
845
846 unsafe {
847 if !F::validate_suffix(unsafe_slice(
848 self.as_byte_slice(),
849 n as usize,
850 new_len as usize,
851 )) {
852 return Err(SubtendrilError::ValidationFailed);
853 }
854
855 self.unsafe_pop_front(n);
856 Ok(())
857 }
858 }
859
860 #[inline]
865 pub fn pop_front(&mut self, n: u32) {
866 self.try_pop_front(n).unwrap()
867 }
868
869 #[inline]
874 pub fn try_pop_back(&mut self, n: u32) -> Result<(), SubtendrilError> {
875 if n == 0 {
876 return Ok(());
877 }
878 let old_len = self.len32();
879 if n > old_len {
880 return Err(SubtendrilError::OutOfBounds);
881 }
882 let new_len = old_len - n;
883
884 unsafe {
885 if !F::validate_prefix(unsafe_slice(self.as_byte_slice(), 0, new_len as usize)) {
886 return Err(SubtendrilError::ValidationFailed);
887 }
888
889 self.unsafe_pop_back(n);
890 Ok(())
891 }
892 }
893
894 #[inline]
899 pub fn pop_back(&mut self, n: u32) {
900 self.try_pop_back(n).unwrap()
901 }
902
903 #[inline(always)]
905 pub unsafe fn reinterpret_view_without_validating<Other>(&self) -> &Tendril<Other, A>
906 where
907 Other: fmt::Format,
908 {
909 mem::transmute(self)
910 }
911
912 #[inline(always)]
914 pub unsafe fn reinterpret_without_validating<Other>(self) -> Tendril<Other, A>
915 where
916 Other: fmt::Format,
917 {
918 mem::transmute(self)
919 }
920
921 #[inline]
923 pub unsafe fn from_byte_slice_without_validating(x: &[u8]) -> Tendril<F, A> {
924 assert!(x.len() <= buf32::MAX_LEN);
925 if x.len() <= MAX_INLINE_LEN {
926 Tendril::inline(x)
927 } else {
928 Tendril::owned_copy(x)
929 }
930 }
931
932 #[inline]
934 pub unsafe fn push_bytes_without_validating(&mut self, buf: &[u8]) {
935 assert!(buf.len() <= buf32::MAX_LEN);
936
937 let Fixup {
938 drop_left,
939 drop_right,
940 insert_len,
941 insert_bytes,
942 } = F::fixup(self.as_byte_slice(), buf);
943
944 let adj_len = self.len32() + insert_len - drop_left;
946
947 let new_len = adj_len.checked_add(buf.len() as u32).expect(OFLOW) - drop_right;
948
949 let drop_left = drop_left as usize;
950 let drop_right = drop_right as usize;
951
952 if new_len <= MAX_INLINE_LEN as u32 {
953 let mut tmp = [0_u8; MAX_INLINE_LEN];
954 {
955 let old = self.as_byte_slice();
956 let mut dest = tmp.as_mut_ptr();
957 copy_and_advance(&mut dest, unsafe_slice(old, 0, old.len() - drop_left));
958 copy_and_advance(
959 &mut dest,
960 unsafe_slice(&insert_bytes, 0, insert_len as usize),
961 );
962 copy_and_advance(
963 &mut dest,
964 unsafe_slice(buf, drop_right, buf.len() - drop_right),
965 );
966 }
967 *self = Tendril::inline(&tmp[..new_len as usize]);
968 } else {
969 self.make_owned_with_capacity(new_len);
970 let (owned, _, _) = self.assume_buf();
971 let mut dest = owned.data_ptr().add(owned.len as usize - drop_left);
972 copy_and_advance(
973 &mut dest,
974 unsafe_slice(&insert_bytes, 0, insert_len as usize),
975 );
976 copy_and_advance(
977 &mut dest,
978 unsafe_slice(buf, drop_right, buf.len() - drop_right),
979 );
980 self.set_len(new_len);
981 }
982 }
983
984 #[inline]
988 pub unsafe fn unsafe_subtendril(&self, offset: u32, length: u32) -> Tendril<F, A> {
989 if length <= MAX_INLINE_LEN as u32 {
990 Tendril::inline(unsafe_slice(
991 self.as_byte_slice(),
992 offset as usize,
993 length as usize,
994 ))
995 } else {
996 self.make_buf_shared();
997 self.incref();
998 let (buf, _, _) = self.assume_buf();
999 Tendril::shared(buf, self.aux() + offset, length)
1000 }
1001 }
1002
1003 #[inline]
1007 pub unsafe fn unsafe_pop_front(&mut self, n: u32) {
1008 let new_len = self.len32() - n;
1009 if new_len <= MAX_INLINE_LEN as u32 {
1010 *self = Tendril::inline(unsafe_slice(
1011 self.as_byte_slice(),
1012 n as usize,
1013 new_len as usize,
1014 ));
1015 } else {
1016 self.make_buf_shared();
1017 self.set_aux(self.aux() + n);
1018 let len = self.raw_len();
1019 self.set_len(len - n);
1020 }
1021 }
1022
1023 #[inline]
1027 pub unsafe fn unsafe_pop_back(&mut self, n: u32) {
1028 let new_len = self.len32() - n;
1029 if new_len <= MAX_INLINE_LEN as u32 {
1030 *self = Tendril::inline(unsafe_slice(self.as_byte_slice(), 0, new_len as usize));
1031 } else {
1032 self.make_buf_shared();
1033 let len = self.raw_len();
1034 self.set_len(len - n);
1035 }
1036 }
1037
1038 #[inline]
1039 unsafe fn incref(&self) {
1040 (*self.header()).refcount.increment();
1041 }
1042
1043 #[inline]
1044 unsafe fn make_buf_shared(&self) {
1045 let p = self.ptr.get().get();
1046 if p & 1 == 0 {
1047 let header = p as *mut Header<A>;
1048 (*header).cap = self.aux();
1049
1050 self.ptr.set(NonZeroUsize::new_unchecked(p | 1));
1051 self.set_aux(0);
1052 }
1053 }
1054
1055 #[inline]
1059 fn make_owned(&mut self) {
1060 unsafe {
1061 let ptr = self.ptr.get().get();
1062 if ptr <= MAX_INLINE_TAG || (ptr & 1) == 1 {
1063 *self = Tendril::owned_copy(self.as_byte_slice());
1064 }
1065 }
1066 }
1067
1068 #[inline]
1069 unsafe fn make_owned_with_capacity(&mut self, cap: u32) {
1070 self.make_owned();
1071 let mut buf = self.assume_buf().0;
1072 buf.grow(cap);
1073 self.ptr.set(NonZeroUsize::new_unchecked(buf.ptr as usize));
1074 self.set_aux(buf.cap);
1075 }
1076
1077 #[inline(always)]
1078 unsafe fn header(&self) -> *mut Header<A> {
1079 (self.ptr.get().get() & !1) as *mut Header<A>
1080 }
1081
1082 #[inline]
1083 unsafe fn assume_buf(&self) -> (Buf32<Header<A>>, bool, u32) {
1084 let ptr = self.ptr.get().get();
1085 let header = self.header();
1086 let shared = (ptr & 1) == 1;
1087 let (cap, offset) = match shared {
1088 true => ((*header).cap, self.aux()),
1089 false => (self.aux(), 0),
1090 };
1091
1092 (
1093 Buf32 {
1094 ptr: header,
1095 len: offset + self.len32(),
1096 cap,
1097 },
1098 shared,
1099 offset,
1100 )
1101 }
1102
1103 #[inline]
1104 unsafe fn inline(x: &[u8]) -> Tendril<F, A> {
1105 let len = x.len();
1106 let t = Tendril {
1107 ptr: Cell::new(inline_tag(len as u32)),
1108 buf: UnsafeCell::new(Buffer { inline: [0; 8] }),
1109 marker: PhantomData,
1110 refcount_marker: PhantomData,
1111 };
1112 ptr::copy_nonoverlapping(x.as_ptr(), (*t.buf.get()).inline.as_mut_ptr(), len);
1113 t
1114 }
1115
1116 #[inline]
1117 unsafe fn owned(x: Buf32<Header<A>>) -> Tendril<F, A> {
1118 Tendril {
1119 ptr: Cell::new(NonZeroUsize::new_unchecked(x.ptr as usize)),
1120 buf: UnsafeCell::new(Buffer {
1121 heap: Heap {
1122 len: x.len,
1123 aux: x.cap,
1124 },
1125 }),
1126 marker: PhantomData,
1127 refcount_marker: PhantomData,
1128 }
1129 }
1130
1131 #[inline]
1132 unsafe fn owned_copy(x: &[u8]) -> Tendril<F, A> {
1133 let len32 = x.len() as u32;
1134 let mut b = Buf32::with_capacity(len32, Header::new());
1135 ptr::copy_nonoverlapping(x.as_ptr(), b.data_ptr(), x.len());
1136 b.len = len32;
1137 Tendril::owned(b)
1138 }
1139
1140 #[inline]
1141 unsafe fn shared(buf: Buf32<Header<A>>, off: u32, len: u32) -> Tendril<F, A> {
1142 Tendril {
1143 ptr: Cell::new(NonZeroUsize::new_unchecked((buf.ptr as usize) | 1)),
1144 buf: UnsafeCell::new(Buffer {
1145 heap: Heap { len, aux: off },
1146 }),
1147 marker: PhantomData,
1148 refcount_marker: PhantomData,
1149 }
1150 }
1151
1152 #[inline]
1153 fn as_byte_slice(&self) -> &[u8] {
1154 unsafe {
1155 match self.ptr.get().get() {
1156 EMPTY_TAG => &[],
1157 n if n <= MAX_INLINE_LEN => (*self.buf.get()).inline.get_unchecked(..n),
1158 _ => {
1159 let (buf, _, offset) = self.assume_buf();
1160 copy_lifetime(
1161 self,
1162 unsafe_slice(buf.data(), offset as usize, self.len32() as usize),
1163 )
1164 },
1165 }
1166 }
1167 }
1168
1169 #[inline]
1172 fn as_mut_byte_slice(&mut self) -> &mut [u8] {
1173 unsafe {
1174 match self.ptr.get().get() {
1175 EMPTY_TAG => &mut [],
1176 n if n <= MAX_INLINE_LEN => (*self.buf.get()).inline.get_unchecked_mut(..n),
1177 _ => {
1178 self.make_owned();
1179 let (mut buf, _, offset) = self.assume_buf();
1180 let len = self.len32() as usize;
1181 copy_lifetime_mut(self, unsafe_slice_mut(buf.data_mut(), offset as usize, len))
1182 },
1183 }
1184 }
1185 }
1186
1187 unsafe fn raw_len(&self) -> u32 {
1188 (*self.buf.get()).heap.len
1189 }
1190
1191 unsafe fn set_len(&mut self, len: u32) {
1192 (*self.buf.get()).heap.len = len;
1193 }
1194
1195 unsafe fn aux(&self) -> u32 {
1196 (*self.buf.get()).heap.aux
1197 }
1198
1199 unsafe fn set_aux(&self, aux: u32) {
1200 (*self.buf.get()).heap.aux = aux;
1201 }
1202}
1203
1204impl<F, A> Tendril<F, A>
1205where
1206 F: fmt::SliceFormat,
1207 A: Atomicity,
1208{
1209 #[inline]
1211 pub fn from_slice(x: &F::Slice) -> Tendril<F, A> {
1212 unsafe { Tendril::from_byte_slice_without_validating(x.as_bytes()) }
1213 }
1214
1215 #[inline]
1217 pub fn push_slice(&mut self, x: &F::Slice) {
1218 unsafe { self.push_bytes_without_validating(x.as_bytes()) }
1219 }
1220}
1221
1222#[derive(Clone)]
1232pub struct SendTendril<F>
1233where
1234 F: fmt::Format,
1235{
1236 tendril: Tendril<F>,
1237}
1238
1239unsafe impl<F> Send for SendTendril<F> where F: fmt::Format {}
1240
1241impl<F, A> From<Tendril<F, A>> for SendTendril<F>
1242where
1243 F: fmt::Format,
1244 A: Atomicity,
1245{
1246 #[inline]
1247 fn from(tendril: Tendril<F, A>) -> SendTendril<F> {
1248 tendril.into_send()
1249 }
1250}
1251
1252impl<F, A> From<SendTendril<F>> for Tendril<F, A>
1253where
1254 F: fmt::Format,
1255 A: Atomicity,
1256{
1257 #[inline]
1258 fn from(send: SendTendril<F>) -> Tendril<F, A> {
1259 unsafe { mem::transmute(send.tendril) }
1260 }
1264}
1265
1266pub trait SliceExt<F>: fmt::Slice
1268where
1269 F: fmt::SliceFormat<Slice = Self>,
1270{
1271 #[inline]
1273 fn to_tendril(&self) -> Tendril<F> {
1274 Tendril::from_slice(self)
1279 }
1280}
1281
1282impl SliceExt<fmt::UTF8> for str {}
1283impl SliceExt<fmt::Bytes> for [u8] {}
1284
1285impl<F, A> Tendril<F, A>
1286where
1287 F: for<'a> fmt::CharFormat<'a>,
1288 A: Atomicity,
1289{
1290 #[inline]
1292 pub fn pop_front_char(&mut self) -> Option<char> {
1293 unsafe {
1294 let next_char; let mut skip = 0; {
1298 let mut iter = F::char_indices(self.as_byte_slice());
1304 match iter.next() {
1305 Some((_, c)) => {
1306 next_char = Some(c);
1307 if let Some((n, _)) = iter.next() {
1308 skip = n as u32;
1309 }
1310 },
1311 None => {
1312 next_char = None;
1313 },
1314 }
1315 }
1316
1317 if skip != 0 {
1318 self.unsafe_pop_front(skip);
1319 } else {
1320 self.clear();
1321 }
1322
1323 next_char
1324 }
1325 }
1326
1327 #[inline]
1332 pub fn pop_front_char_run<C, R>(&mut self, mut classify: C) -> Option<(Tendril<F, A>, R)>
1333 where
1334 C: FnMut(char) -> R,
1335 R: PartialEq,
1336 {
1337 let (class, first_mismatch);
1338 {
1339 let mut chars = unsafe { F::char_indices(self.as_byte_slice()) };
1340 let (_, first) = chars.next()?;
1341 class = classify(first);
1342 first_mismatch = chars.find(|&(_, ch)| classify(ch) != class);
1343 }
1344
1345 match first_mismatch {
1346 Some((idx, _)) => unsafe {
1347 let t = self.unsafe_subtendril(0, idx as u32);
1348 self.unsafe_pop_front(idx as u32);
1349 Some((t, class))
1350 },
1351 None => {
1352 let t = self.clone();
1353 self.clear();
1354 Some((t, class))
1355 },
1356 }
1357 }
1358
1359 #[inline]
1361 pub fn try_push_char(&mut self, c: char) -> Result<(), ()> {
1362 F::encode_char(c, |b| unsafe {
1363 self.push_bytes_without_validating(b);
1364 })
1365 }
1366}
1367
1368pub trait ReadExt: io::Read {
1370 fn read_to_tendril<A>(&mut self, buf: &mut Tendril<fmt::Bytes, A>) -> io::Result<usize>
1371 where
1372 A: Atomicity;
1373}
1374
1375impl<T> ReadExt for T
1376where
1377 T: io::Read,
1378{
1379 fn read_to_tendril<A>(&mut self, buf: &mut Tendril<fmt::Bytes, A>) -> io::Result<usize>
1381 where
1382 A: Atomicity,
1383 {
1384 const DEFAULT_BUF_SIZE: u32 = 64 * 1024;
1386
1387 let start_len = buf.len();
1388 let mut len = start_len;
1389 let mut new_write_size = 16;
1390 let ret;
1391 loop {
1392 if len == buf.len() {
1393 if new_write_size < DEFAULT_BUF_SIZE {
1394 new_write_size *= 2;
1395 }
1396 unsafe {
1401 buf.push_uninitialized(new_write_size);
1402 }
1403 }
1404
1405 match self.read(&mut buf[len..]) {
1406 Ok(0) => {
1407 ret = Ok(len - start_len);
1408 break;
1409 },
1410 Ok(n) => len += n,
1411 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {},
1412 Err(e) => {
1413 ret = Err(e);
1414 break;
1415 },
1416 }
1417 }
1418
1419 let buf_len = buf.len32();
1420 buf.pop_back(buf_len - (len as u32));
1421 ret
1422 }
1423}
1424
1425impl<A> io::Write for Tendril<fmt::Bytes, A>
1426where
1427 A: Atomicity,
1428{
1429 #[inline]
1430 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1431 self.push_slice(buf);
1432 Ok(buf.len())
1433 }
1434
1435 #[inline]
1436 fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
1437 self.push_slice(buf);
1438 Ok(())
1439 }
1440
1441 #[inline(always)]
1442 fn flush(&mut self) -> io::Result<()> {
1443 Ok(())
1444 }
1445}
1446
1447impl<F, A> Tendril<F, A>
1448where
1449 A: Atomicity,
1450 F: fmt::SliceFormat<Slice = [u8]>,
1451{
1452 #[inline]
1458 pub unsafe fn push_uninitialized(&mut self, n: u32) {
1459 let new_len = self.len32().checked_add(n).expect(OFLOW);
1460 if new_len <= MAX_INLINE_LEN as u32 && self.ptr.get().get() <= MAX_INLINE_TAG {
1461 self.ptr.set(inline_tag(new_len))
1462 } else {
1463 self.make_owned_with_capacity(new_len);
1464 self.set_len(new_len);
1465 }
1466 }
1467}
1468
1469impl<A> strfmt::Display for Tendril<fmt::UTF8, A>
1470where
1471 A: Atomicity,
1472{
1473 #[inline]
1474 fn fmt(&self, f: &mut strfmt::Formatter) -> strfmt::Result {
1475 <str as strfmt::Display>::fmt(&**self, f)
1476 }
1477}
1478
1479impl<A> str::FromStr for Tendril<fmt::UTF8, A>
1480where
1481 A: Atomicity,
1482{
1483 type Err = ();
1484
1485 #[inline]
1486 fn from_str(s: &str) -> Result<Self, ()> {
1487 Ok(Tendril::from_slice(s))
1488 }
1489}
1490
1491impl<A> strfmt::Write for Tendril<fmt::UTF8, A>
1492where
1493 A: Atomicity,
1494{
1495 #[inline]
1496 fn write_str(&mut self, s: &str) -> strfmt::Result {
1497 self.push_slice(s);
1498 Ok(())
1499 }
1500}
1501
1502impl<A> Tendril<fmt::UTF8, A>
1503where
1504 A: Atomicity,
1505{
1506 #[inline]
1508 pub fn push_char(&mut self, c: char) {
1509 unsafe {
1510 self.push_bytes_without_validating(c.encode_utf8(&mut [0_u8; 4]).as_bytes());
1511 }
1512 }
1513
1514 #[inline]
1516 pub fn from_char(c: char) -> Tendril<fmt::UTF8, A> {
1517 let mut t: Tendril<fmt::UTF8, A> = Tendril::new();
1518 t.push_char(c);
1519 t
1520 }
1521
1522 #[inline]
1524 pub fn format(args: strfmt::Arguments) -> Tendril<fmt::UTF8, A> {
1525 use std::fmt::Write;
1526 let mut output: Tendril<fmt::UTF8, A> = Tendril::new();
1527 let _ = write!(&mut output, "{}", args);
1528 output
1529 }
1530}
1531
1532#[macro_export]
1536macro_rules! format_tendril {
1537 ($($arg:tt)*) => ($crate::StrTendril::format(format_args!($($arg)*)))
1538}
1539
1540impl<F, A> From<&F::Slice> for Tendril<F, A>
1541where
1542 F: fmt::SliceFormat,
1543 A: Atomicity,
1544{
1545 #[inline]
1546 fn from(input: &F::Slice) -> Tendril<F, A> {
1547 Tendril::from_slice(input)
1548 }
1549}
1550
1551impl<A> From<String> for Tendril<fmt::UTF8, A>
1552where
1553 A: Atomicity,
1554{
1555 #[inline]
1556 fn from(input: String) -> Tendril<fmt::UTF8, A> {
1557 Tendril::from_slice(&*input)
1558 }
1559}
1560
1561impl<F, A> AsRef<F::Slice> for Tendril<F, A>
1562where
1563 F: fmt::SliceFormat,
1564 A: Atomicity,
1565{
1566 #[inline]
1567 fn as_ref(&self) -> &F::Slice {
1568 self
1569 }
1570}
1571
1572impl<A> From<Tendril<fmt::UTF8, A>> for String
1573where
1574 A: Atomicity,
1575{
1576 #[inline]
1577 fn from(input: Tendril<fmt::UTF8, A>) -> String {
1578 String::from(&*input)
1579 }
1580}
1581
1582impl<'a, A> From<&'a Tendril<fmt::UTF8, A>> for String
1583where
1584 A: Atomicity,
1585{
1586 #[inline]
1587 fn from(input: &'a Tendril<fmt::UTF8, A>) -> String {
1588 String::from(&**input)
1589 }
1590}
1591
1592#[cfg(test)]
1593mod test {
1594 use super::{
1595 Atomic, ByteTendril, Header, NonAtomic, ReadExt, SendTendril, SliceExt, StrTendril, Tendril,
1596 };
1597 use crate::fmt;
1598 use std::iter;
1599 use std::thread;
1600
1601 fn assert_send<T: Send>() {}
1602
1603 #[test]
1604 fn smoke_test() {
1605 assert_eq!("", &*"".to_tendril());
1606 assert_eq!("abc", &*"abc".to_tendril());
1607 assert_eq!("Hello, world!", &*"Hello, world!".to_tendril());
1608
1609 assert_eq!(b"", &*b"".to_tendril());
1610 assert_eq!(b"abc", &*b"abc".to_tendril());
1611 assert_eq!(b"Hello, world!", &*b"Hello, world!".to_tendril());
1612 }
1613
1614 #[test]
1615 fn assert_sizes() {
1616 use std::mem;
1617 struct EmptyWithDrop;
1618 impl Drop for EmptyWithDrop {
1619 fn drop(&mut self) {}
1620 }
1621 let compiler_uses_inline_drop_flags = mem::size_of::<EmptyWithDrop>() > 0;
1622
1623 let correct = mem::size_of::<*const ()>()
1624 + 8
1625 + if compiler_uses_inline_drop_flags {
1626 1
1627 } else {
1628 0
1629 };
1630
1631 assert_eq!(correct, mem::size_of::<ByteTendril>());
1632 assert_eq!(correct, mem::size_of::<StrTendril>());
1633
1634 assert_eq!(
1639 mem::size_of::<*const ()>() * 2,
1640 mem::size_of::<Header<Atomic>>(),
1641 );
1642 assert_eq!(
1643 mem::size_of::<Header<Atomic>>(),
1644 mem::size_of::<Header<NonAtomic>>(),
1645 );
1646 }
1647
1648 #[test]
1649 fn validate_utf8() {
1650 assert!(ByteTendril::try_from_byte_slice(b"\xFF").is_ok());
1651 assert!(StrTendril::try_from_byte_slice(b"\xFF").is_err());
1652 assert!(StrTendril::try_from_byte_slice(b"\xEA\x99\xFF").is_err());
1653 assert!(StrTendril::try_from_byte_slice(b"\xEA\x99").is_err());
1654 assert!(StrTendril::try_from_byte_slice(b"\xEA\x99\xAE\xEA").is_err());
1655 assert_eq!(
1656 "\u{a66e}",
1657 &*StrTendril::try_from_byte_slice(b"\xEA\x99\xAE").unwrap()
1658 );
1659
1660 let mut t = StrTendril::new();
1661 assert!(t.try_push_bytes(b"\xEA\x99").is_err());
1662 assert!(t.try_push_bytes(b"\xAE").is_err());
1663 assert!(t.try_push_bytes(b"\xEA\x99\xAE").is_ok());
1664 assert_eq!("\u{a66e}", &*t);
1665 }
1666
1667 #[test]
1668 fn share_and_unshare() {
1669 let s = b"foobarbaz".to_tendril();
1670 assert_eq!(b"foobarbaz", &*s);
1671 assert!(!s.is_shared());
1672
1673 let mut t = s.clone();
1674 assert_eq!(s.as_ptr(), t.as_ptr());
1675 assert!(s.is_shared());
1676 assert!(t.is_shared());
1677
1678 t.push_slice(b"quux");
1679 assert_eq!(b"foobarbaz", &*s);
1680 assert_eq!(b"foobarbazquux", &*t);
1681 assert!(s.as_ptr() != t.as_ptr());
1682 assert!(!t.is_shared());
1683 }
1684
1685 #[test]
1686 fn format_display() {
1687 assert_eq!("foobar", &*format!("{}", "foobar".to_tendril()));
1688
1689 let mut s = "foo".to_tendril();
1690 assert_eq!("foo", &*format!("{}", s));
1691
1692 let t = s.clone();
1693 assert_eq!("foo", &*format!("{}", s));
1694 assert_eq!("foo", &*format!("{}", t));
1695
1696 s.push_slice("barbaz!");
1697 assert_eq!("foobarbaz!", &*format!("{}", s));
1698 assert_eq!("foo", &*format!("{}", t));
1699 }
1700
1701 #[test]
1702 fn format_debug() {
1703 assert_eq!(
1704 r#"Tendril<UTF8>(inline: "foobar")"#,
1705 &*format!("{:?}", "foobar".to_tendril())
1706 );
1707 assert_eq!(
1708 r#"Tendril<Bytes>(inline: [102, 111, 111, 98, 97, 114])"#,
1709 &*format!("{:?}", b"foobar".to_tendril())
1710 );
1711
1712 let t = "anextralongstring".to_tendril();
1713 assert_eq!(
1714 r#"Tendril<UTF8>(owned: "anextralongstring")"#,
1715 &*format!("{:?}", t)
1716 );
1717 let _ = t.clone();
1718 assert_eq!(
1719 r#"Tendril<UTF8>(shared: "anextralongstring")"#,
1720 &*format!("{:?}", t)
1721 );
1722 }
1723
1724 #[test]
1725 fn subtendril() {
1726 assert_eq!("foo".to_tendril(), "foo-bar".to_tendril().subtendril(0, 3));
1727 assert_eq!("bar".to_tendril(), "foo-bar".to_tendril().subtendril(4, 3));
1728
1729 let mut t = "foo-bar".to_tendril();
1730 t.pop_front(2);
1731 assert_eq!("o-bar".to_tendril(), t);
1732 t.pop_back(1);
1733 assert_eq!("o-ba".to_tendril(), t);
1734
1735 assert_eq!(
1736 "foo".to_tendril(),
1737 "foo-a-longer-string-bar-baz".to_tendril().subtendril(0, 3)
1738 );
1739 assert_eq!(
1740 "oo-a-".to_tendril(),
1741 "foo-a-longer-string-bar-baz".to_tendril().subtendril(1, 5)
1742 );
1743 assert_eq!(
1744 "bar".to_tendril(),
1745 "foo-a-longer-string-bar-baz".to_tendril().subtendril(20, 3)
1746 );
1747
1748 let mut t = "another rather long string".to_tendril();
1749 t.pop_front(2);
1750 assert!(t.starts_with("other rather"));
1751 t.pop_back(1);
1752 assert_eq!("other rather long strin".to_tendril(), t);
1753 assert!(t.is_shared());
1754 }
1755
1756 #[test]
1757 fn subtendril_invalid() {
1758 assert!("\u{a66e}".to_tendril().try_subtendril(0, 2).is_err());
1759 assert!("\u{a66e}".to_tendril().try_subtendril(1, 2).is_err());
1760
1761 assert!("\u{1f4a9}".to_tendril().try_subtendril(0, 3).is_err());
1762 assert!("\u{1f4a9}".to_tendril().try_subtendril(0, 2).is_err());
1763 assert!("\u{1f4a9}".to_tendril().try_subtendril(0, 1).is_err());
1764 assert!("\u{1f4a9}".to_tendril().try_subtendril(1, 3).is_err());
1765 assert!("\u{1f4a9}".to_tendril().try_subtendril(1, 2).is_err());
1766 assert!("\u{1f4a9}".to_tendril().try_subtendril(1, 1).is_err());
1767 assert!("\u{1f4a9}".to_tendril().try_subtendril(2, 2).is_err());
1768 assert!("\u{1f4a9}".to_tendril().try_subtendril(2, 1).is_err());
1769 assert!("\u{1f4a9}".to_tendril().try_subtendril(3, 1).is_err());
1770
1771 let mut t = "\u{1f4a9}zzzzzz".to_tendril();
1772 assert!(t.try_pop_front(1).is_err());
1773 assert!(t.try_pop_front(2).is_err());
1774 assert!(t.try_pop_front(3).is_err());
1775 assert!(t.try_pop_front(4).is_ok());
1776 assert_eq!("zzzzzz", &*t);
1777
1778 let mut t = "zzzzzz\u{1f4a9}".to_tendril();
1779 assert!(t.try_pop_back(1).is_err());
1780 assert!(t.try_pop_back(2).is_err());
1781 assert!(t.try_pop_back(3).is_err());
1782 assert!(t.try_pop_back(4).is_ok());
1783 assert_eq!("zzzzzz", &*t);
1784 }
1785
1786 #[test]
1787 fn conversion() {
1788 assert_eq!(
1789 &[0x66, 0x6F, 0x6F].to_tendril(),
1790 "foo".to_tendril().as_bytes()
1791 );
1792 assert_eq!(
1793 [0x66, 0x6F, 0x6F].to_tendril(),
1794 "foo".to_tendril().into_bytes()
1795 );
1796
1797 let ascii: Tendril<fmt::ASCII> = b"hello".to_tendril().try_reinterpret().unwrap();
1798 assert_eq!(&"hello".to_tendril(), ascii.as_superset());
1799 assert_eq!("hello".to_tendril(), ascii.clone().into_superset());
1800
1801 assert!(b"\xFF"
1802 .to_tendril()
1803 .try_reinterpret::<fmt::ASCII>()
1804 .is_err());
1805
1806 let t = "hello".to_tendril();
1807 let ascii: &Tendril<fmt::ASCII> = t.try_as_subset().unwrap();
1808 assert_eq!(b"hello", &**ascii.as_bytes());
1809
1810 assert!("ő"
1811 .to_tendril()
1812 .try_reinterpret_view::<fmt::ASCII>()
1813 .is_err());
1814 assert!("ő".to_tendril().try_as_subset::<fmt::ASCII>().is_err());
1815
1816 let ascii: Tendril<fmt::ASCII> = "hello".to_tendril().try_into_subset().unwrap();
1817 assert_eq!(b"hello", &**ascii.as_bytes());
1818
1819 assert!("ő".to_tendril().try_reinterpret::<fmt::ASCII>().is_err());
1820 assert!("ő".to_tendril().try_into_subset::<fmt::ASCII>().is_err());
1821 }
1822
1823 #[test]
1824 fn clear() {
1825 let mut t = "foo-".to_tendril();
1826 t.clear();
1827 assert_eq!(t.len(), 0);
1828 assert_eq!(t.len32(), 0);
1829 assert_eq!(&*t, "");
1830
1831 let mut t = "much longer".to_tendril();
1832 let s = t.clone();
1833 t.clear();
1834 assert_eq!(t.len(), 0);
1835 assert_eq!(t.len32(), 0);
1836 assert_eq!(&*t, "");
1837 assert_eq!(&*s, "much longer");
1838 }
1839
1840 #[test]
1841 fn push_tendril() {
1842 let mut t = "abc".to_tendril();
1843 t.push_tendril(&"xyz".to_tendril());
1844 assert_eq!("abcxyz", &*t);
1845 }
1846
1847 #[test]
1848 fn wtf8() {
1849 assert!(Tendril::<fmt::WTF8>::try_from_byte_slice(b"\xED\xA0\xBD").is_ok());
1850 assert!(Tendril::<fmt::WTF8>::try_from_byte_slice(b"\xED\xB2\xA9").is_ok());
1851 assert!(Tendril::<fmt::WTF8>::try_from_byte_slice(b"\xED\xA0\xBD\xED\xB2\xA9").is_err());
1852
1853 let t: Tendril<fmt::WTF8> =
1854 Tendril::try_from_byte_slice(b"\xED\xA0\xBD\xEA\x99\xAE").unwrap();
1855 assert!(b"\xED\xA0\xBD".to_tendril().try_reinterpret().unwrap() == t.subtendril(0, 3));
1856 assert!(b"\xEA\x99\xAE".to_tendril().try_reinterpret().unwrap() == t.subtendril(3, 3));
1857 assert!(t.try_reinterpret_view::<fmt::UTF8>().is_err());
1858
1859 assert!(t.try_subtendril(0, 1).is_err());
1860 assert!(t.try_subtendril(0, 2).is_err());
1861 assert!(t.try_subtendril(1, 1).is_err());
1862
1863 assert!(t.try_subtendril(3, 1).is_err());
1864 assert!(t.try_subtendril(3, 2).is_err());
1865 assert!(t.try_subtendril(4, 1).is_err());
1866
1867 let mut t: Tendril<fmt::WTF8> = Tendril::try_from_byte_slice(b"\xED\xA0\xBD").unwrap();
1869 assert!(t.try_push_bytes(b"\xED\xB2\xA9").is_ok());
1870 assert_eq!(b"\xF0\x9F\x92\xA9", t.as_byte_slice());
1871 assert!(t.try_reinterpret_view::<fmt::UTF8>().is_ok());
1872
1873 let mut t: Tendril<fmt::WTF8> = Tendril::try_from_byte_slice(b"\xED\xA0\xBB").unwrap();
1875 assert!(t.try_push_bytes(b"\xED\xA0").is_err());
1876 assert!(t.try_push_bytes(b"\xED").is_err());
1877 assert!(t.try_push_bytes(b"\xA0").is_err());
1878 assert!(t.try_push_bytes(b"\xED\xA0\xBD").is_ok());
1879 assert_eq!(b"\xED\xA0\xBB\xED\xA0\xBD", t.as_byte_slice());
1880 assert!(t.try_push_bytes(b"\xED\xB2\xA9").is_ok());
1881 assert_eq!(b"\xED\xA0\xBB\xF0\x9F\x92\xA9", t.as_byte_slice());
1882 assert!(t.try_reinterpret_view::<fmt::UTF8>().is_err());
1883 }
1884
1885 #[test]
1886 fn front_char() {
1887 let mut t = "".to_tendril();
1888 assert_eq!(None, t.pop_front_char());
1889 assert_eq!(None, t.pop_front_char());
1890
1891 let mut t = "abc".to_tendril();
1892 assert_eq!(Some('a'), t.pop_front_char());
1893 assert_eq!(Some('b'), t.pop_front_char());
1894 assert_eq!(Some('c'), t.pop_front_char());
1895 assert_eq!(None, t.pop_front_char());
1896 assert_eq!(None, t.pop_front_char());
1897
1898 let mut t = "főo-a-longer-string-bar-baz".to_tendril();
1899 assert_eq!(28, t.len());
1900 assert_eq!(Some('f'), t.pop_front_char());
1901 assert_eq!(Some('ő'), t.pop_front_char());
1902 assert_eq!(Some('o'), t.pop_front_char());
1903 assert_eq!(Some('-'), t.pop_front_char());
1904 assert_eq!(23, t.len());
1905 }
1906
1907 #[test]
1908 fn char_run() {
1909 for &(s, exp) in &[
1910 ("", None),
1911 (" ", Some((" ", true))),
1912 ("x", Some(("x", false))),
1913 (" \t \n", Some((" \t \n", true))),
1914 ("xyzzy", Some(("xyzzy", false))),
1915 (" xyzzy", Some((" ", true))),
1916 ("xyzzy ", Some(("xyzzy", false))),
1917 (" xyzzy ", Some((" ", true))),
1918 ("xyzzy hi", Some(("xyzzy", false))),
1919 ("中 ", Some(("中", false))),
1920 (" 中 ", Some((" ", true))),
1921 (" 中 ", Some((" ", true))),
1922 (" 中 ", Some((" ", true))),
1923 ] {
1924 let mut t = s.to_tendril();
1925 let res = t.pop_front_char_run(char::is_whitespace);
1926 match exp {
1927 None => assert!(res.is_none()),
1928 Some((es, ec)) => {
1929 let (rt, rc) = res.unwrap();
1930 assert_eq!(es, &*rt);
1931 assert_eq!(ec, rc);
1932 },
1933 }
1934 }
1935 }
1936
1937 #[test]
1938 fn deref_mut_inline() {
1939 let mut t = "xyő".to_tendril().into_bytes();
1940 t[3] = 0xff;
1941 assert_eq!(b"xy\xC5\xFF", &*t);
1942 assert!(t.try_reinterpret_view::<fmt::UTF8>().is_err());
1943 t[3] = 0x8b;
1944 assert_eq!("xyŋ", &**t.try_reinterpret_view::<fmt::UTF8>().unwrap());
1945
1946 unsafe {
1947 t.push_uninitialized(3);
1948 t[4] = 0xEA;
1949 t[5] = 0x99;
1950 t[6] = 0xAE;
1951 assert_eq!(
1952 "xyŋ\u{a66e}",
1953 &**t.try_reinterpret_view::<fmt::UTF8>().unwrap()
1954 );
1955 t.push_uninitialized(20);
1956 t.pop_back(20);
1957 assert_eq!(
1958 "xyŋ\u{a66e}",
1959 &**t.try_reinterpret_view::<fmt::UTF8>().unwrap()
1960 );
1961 }
1962 }
1963
1964 #[test]
1965 fn deref_mut() {
1966 let mut t = b"0123456789".to_tendril();
1967 let u = t.clone();
1968 assert!(t.is_shared());
1969 t[9] = 0xff;
1970 assert!(!t.is_shared());
1971 assert_eq!(b"0123456789", &*u);
1972 assert_eq!(b"012345678\xff", &*t);
1973 }
1974
1975 #[test]
1976 fn push_char() {
1977 let mut t = "xyz".to_tendril();
1978 t.push_char('o');
1979 assert_eq!("xyzo", &*t);
1980 t.push_char('ő');
1981 assert_eq!("xyzoő", &*t);
1982 t.push_char('\u{a66e}');
1983 assert_eq!("xyzoő\u{a66e}", &*t);
1984 t.push_char('\u{1f4a9}');
1985 assert_eq!("xyzoő\u{a66e}\u{1f4a9}", &*t);
1986 assert_eq!(t.len(), 13);
1987 }
1988
1989 #[test]
1990 fn ascii() {
1991 fn mk(x: &[u8]) -> Tendril<fmt::ASCII> {
1992 x.to_tendril().try_reinterpret().unwrap()
1993 }
1994
1995 let mut t = mk(b"xyz");
1996 assert_eq!(Some('x'), t.pop_front_char());
1997 assert_eq!(Some('y'), t.pop_front_char());
1998 assert_eq!(Some('z'), t.pop_front_char());
1999 assert_eq!(None, t.pop_front_char());
2000
2001 let mut t = mk(b" \t xyz");
2002 assert!(Some((mk(b" \t "), true)) == t.pop_front_char_run(char::is_whitespace));
2003 assert!(Some((mk(b"xyz"), false)) == t.pop_front_char_run(char::is_whitespace));
2004 assert!(t.pop_front_char_run(char::is_whitespace).is_none());
2005
2006 let mut t = Tendril::<fmt::ASCII>::new();
2007 assert!(t.try_push_char('x').is_ok());
2008 assert!(t.try_push_char('\0').is_ok());
2009 assert!(t.try_push_char('\u{a0}').is_err());
2010 assert_eq!(b"x\0", t.as_byte_slice());
2011 }
2012
2013 #[test]
2014 fn latin1() {
2015 fn mk(x: &[u8]) -> Tendril<fmt::Latin1> {
2016 x.to_tendril().try_reinterpret().unwrap()
2017 }
2018
2019 let mut t = mk(b"\xd8_\xd8");
2020 assert_eq!(Some('Ø'), t.pop_front_char());
2021 assert_eq!(Some('_'), t.pop_front_char());
2022 assert_eq!(Some('Ø'), t.pop_front_char());
2023 assert_eq!(None, t.pop_front_char());
2024
2025 let mut t = mk(b" \t \xfe\xa7z");
2026 assert!(Some((mk(b" \t "), true)) == t.pop_front_char_run(char::is_whitespace));
2027 assert!(Some((mk(b"\xfe\xa7z"), false)) == t.pop_front_char_run(char::is_whitespace));
2028 assert!(t.pop_front_char_run(char::is_whitespace).is_none());
2029
2030 let mut t = Tendril::<fmt::Latin1>::new();
2031 assert!(t.try_push_char('x').is_ok());
2032 assert!(t.try_push_char('\0').is_ok());
2033 assert!(t.try_push_char('\u{a0}').is_ok());
2034 assert!(t.try_push_char('ő').is_err());
2035 assert!(t.try_push_char('я').is_err());
2036 assert!(t.try_push_char('\u{a66e}').is_err());
2037 assert!(t.try_push_char('\u{1f4a9}').is_err());
2038 assert_eq!(b"x\0\xa0", t.as_byte_slice());
2039 }
2040
2041 #[test]
2042 fn format() {
2043 assert_eq!("", &*format_tendril!(""));
2044 assert_eq!(
2045 "two and two make 4",
2046 &*format_tendril!("two and two make {}", 2 + 2)
2047 );
2048 }
2049
2050 #[test]
2051 fn merge_shared() {
2052 let t = "012345678901234567890123456789".to_tendril();
2053 let a = t.subtendril(10, 20);
2054 assert!(a.is_shared());
2055 assert_eq!("01234567890123456789", &*a);
2056 let mut b = t.subtendril(0, 10);
2057 assert!(b.is_shared());
2058 assert_eq!("0123456789", &*b);
2059
2060 b.push_tendril(&a);
2061 assert!(b.is_shared());
2062 assert!(a.is_shared());
2063 assert!(a.is_shared_with(&b));
2064 assert!(b.is_shared_with(&a));
2065 assert_eq!("012345678901234567890123456789", &*b);
2066
2067 assert!(t.is_shared());
2068 assert!(t.is_shared_with(&a));
2069 assert!(t.is_shared_with(&b));
2070 }
2071
2072 #[test]
2073 fn merge_cant_share() {
2074 let t = "012345678901234567890123456789".to_tendril();
2075 let mut b = t.subtendril(0, 10);
2076 assert!(b.is_shared());
2077 assert_eq!("0123456789", &*b);
2078
2079 b.push_tendril(&"abcd".to_tendril());
2080 assert!(!b.is_shared());
2081 assert_eq!("0123456789abcd", &*b);
2082 }
2083
2084 #[test]
2085 fn shared_doesnt_reserve() {
2086 let mut t = "012345678901234567890123456789".to_tendril();
2087 let a = t.subtendril(1, 10);
2088
2089 assert!(t.is_shared());
2090 t.reserve(10);
2091 assert!(t.is_shared());
2092
2093 let _ = a;
2094 }
2095
2096 #[test]
2097 fn out_of_bounds() {
2098 assert!("".to_tendril().try_subtendril(0, 1).is_err());
2099 assert!("abc".to_tendril().try_subtendril(0, 4).is_err());
2100 assert!("abc".to_tendril().try_subtendril(3, 1).is_err());
2101 assert!("abc".to_tendril().try_subtendril(7, 1).is_err());
2102
2103 let mut t = "".to_tendril();
2104 assert!(t.try_pop_front(1).is_err());
2105 assert!(t.try_pop_front(5).is_err());
2106 assert!(t.try_pop_front(500).is_err());
2107 assert!(t.try_pop_back(1).is_err());
2108 assert!(t.try_pop_back(5).is_err());
2109 assert!(t.try_pop_back(500).is_err());
2110
2111 let mut t = "abcd".to_tendril();
2112 assert!(t.try_pop_front(1).is_ok());
2113 assert!(t.try_pop_front(4).is_err());
2114 assert!(t.try_pop_front(500).is_err());
2115 assert!(t.try_pop_back(1).is_ok());
2116 assert!(t.try_pop_back(3).is_err());
2117 assert!(t.try_pop_back(500).is_err());
2118 }
2119
2120 #[test]
2121 fn compare() {
2122 for &a in &[
2123 "indiscretions",
2124 "validity",
2125 "hallucinogenics",
2126 "timelessness",
2127 "original",
2128 "microcosms",
2129 "boilers",
2130 "mammoth",
2131 ] {
2132 for &b in &[
2133 "intrepidly",
2134 "frigid",
2135 "spa",
2136 "cardigans",
2137 "guileful",
2138 "evaporated",
2139 "unenthusiastic",
2140 "legitimate",
2141 ] {
2142 let ta = a.to_tendril();
2143 let tb = b.to_tendril();
2144
2145 assert_eq!(a.eq(b), ta.eq(&tb));
2146 assert_eq!(a.ne(b), ta.ne(&tb));
2147 assert_eq!(a.lt(b), ta.lt(&tb));
2148 assert_eq!(a.le(b), ta.le(&tb));
2149 assert_eq!(a.gt(b), ta.gt(&tb));
2150 assert_eq!(a.ge(b), ta.ge(&tb));
2151 assert_eq!(a.partial_cmp(b), ta.partial_cmp(&tb));
2152 assert_eq!(a.cmp(b), ta.cmp(&tb));
2153 }
2154 }
2155 }
2156
2157 #[test]
2158 fn extend_and_from_iterator() {
2159 let mut t = "Hello".to_tendril();
2163 t.extend(None::<&Tendril<_>>);
2164 assert_eq!("Hello", &*t);
2165 t.extend(&[", ".to_tendril(), "world".to_tendril(), "!".to_tendril()]);
2166 assert_eq!("Hello, world!", &*t);
2167 assert_eq!(
2168 "Hello, world!",
2169 &*[
2170 "Hello".to_tendril(),
2171 ", ".to_tendril(),
2172 "world".to_tendril(),
2173 "!".to_tendril()
2174 ]
2175 .iter()
2176 .collect::<StrTendril>()
2177 );
2178
2179 let mut t = "Hello".to_tendril();
2181 t.extend(None::<&str>);
2182 assert_eq!("Hello", &*t);
2183 t.extend([", ", "world", "!"].iter().copied());
2184 assert_eq!("Hello, world!", &*t);
2185 assert_eq!(
2186 "Hello, world!",
2187 &*["Hello", ", ", "world", "!"]
2188 .iter()
2189 .copied()
2190 .collect::<StrTendril>()
2191 );
2192
2193 let mut t = b"Hello".to_tendril();
2195 t.extend(None::<&[u8]>);
2196 assert_eq!(b"Hello", &*t);
2197 t.extend(
2198 [b", ".as_ref(), b"world".as_ref(), b"!".as_ref()]
2199 .iter()
2200 .copied(),
2201 );
2202 assert_eq!(b"Hello, world!", &*t);
2203 assert_eq!(
2204 b"Hello, world!",
2205 &*[
2206 b"Hello".as_ref(),
2207 b", ".as_ref(),
2208 b"world".as_ref(),
2209 b"!".as_ref()
2210 ]
2211 .iter()
2212 .copied()
2213 .collect::<ByteTendril>()
2214 );
2215
2216 let string = "the quick brown fox jumps over the lazy dog";
2217 let string_expected = string.to_tendril();
2218 let bytes = string.as_bytes();
2219 let bytes_expected = bytes.to_tendril();
2220
2221 assert_eq!(string_expected, string.chars().collect::<Tendril<_>>());
2223 let mut tendril = StrTendril::new();
2224 tendril.extend(string.chars());
2225 assert_eq!(string_expected, tendril);
2226
2227 assert_eq!(bytes_expected, bytes.iter().collect::<Tendril<_>>());
2229 let mut tendril = ByteTendril::new();
2230 tendril.extend(bytes);
2231 assert_eq!(bytes_expected, tendril);
2232
2233 assert_eq!(
2235 bytes_expected,
2236 bytes.iter().copied().collect::<Tendril<_>>()
2237 );
2238 let mut tendril = ByteTendril::new();
2239 tendril.extend(bytes.iter().copied());
2240 assert_eq!(bytes_expected, tendril);
2241 }
2242
2243 #[test]
2244 fn from_str() {
2245 use std::str::FromStr;
2246 let t: Tendril<_> = FromStr::from_str("foo bar baz").unwrap();
2247 assert_eq!("foo bar baz", &*t);
2248 }
2249
2250 #[test]
2251 fn from_char() {
2252 assert_eq!("o", &*StrTendril::from_char('o'));
2253 assert_eq!("ő", &*StrTendril::from_char('ő'));
2254 assert_eq!("\u{a66e}", &*StrTendril::from_char('\u{a66e}'));
2255 assert_eq!("\u{1f4a9}", &*StrTendril::from_char('\u{1f4a9}'));
2256 }
2257
2258 #[test]
2259 #[cfg_attr(miri, ignore)] fn read() {
2261 fn check(x: &[u8]) {
2262 use std::io::Cursor;
2263 let mut t = ByteTendril::new();
2264 assert_eq!(x.len(), Cursor::new(x).read_to_tendril(&mut t).unwrap());
2265 assert_eq!(x, &*t);
2266 }
2267
2268 check(b"");
2269 check(b"abcd");
2270
2271 let long: Vec<u8> = iter::repeat(b'x').take(1_000_000).collect();
2272 check(&long);
2273 }
2274
2275 #[test]
2276 fn hash_map_key() {
2277 use std::collections::HashMap;
2278
2279 let mut map = HashMap::new();
2282 map.insert("foo".to_tendril(), 1);
2283 assert_eq!(map.get(b"foo".as_ref()), Some(&1));
2284 assert_eq!(map.get(b"bar".as_ref()), None);
2285
2286 let mut map = HashMap::new();
2287 map.insert(b"foo".to_tendril(), 1);
2288 assert_eq!(map.get(b"foo".as_ref()), Some(&1));
2289 assert_eq!(map.get(b"bar".as_ref()), None);
2290 }
2291
2292 #[test]
2293 fn atomic() {
2294 assert_send::<Tendril<fmt::UTF8, Atomic>>();
2295 let s: Tendril<fmt::UTF8, Atomic> = Tendril::from_slice("this is a string");
2296 assert!(!s.is_shared());
2297 let mut t = s.clone();
2298 assert!(s.is_shared());
2299 let sp = s.as_ptr() as usize;
2300 thread::spawn(move || {
2301 assert!(t.is_shared());
2302 t.push_slice(" extended");
2303 assert_eq!("this is a string extended", &*t);
2304 assert!(t.as_ptr() as usize != sp);
2305 assert!(!t.is_shared());
2306 })
2307 .join()
2308 .unwrap();
2309 assert!(s.is_shared());
2310 assert_eq!("this is a string", &*s);
2311 }
2312
2313 #[test]
2314 fn send() {
2315 assert_send::<SendTendril<fmt::UTF8>>();
2316 let s = "this is a string".to_tendril();
2317 let t = s.clone();
2318 let s2 = s.into_send();
2319 thread::spawn(move || {
2320 let s = StrTendril::from(s2);
2321 assert!(!s.is_shared());
2322 assert_eq!("this is a string", &*s);
2323 })
2324 .join()
2325 .unwrap();
2326 assert_eq!("this is a string", &*t);
2327 }
2328
2329 #[test]
2331 fn issue_58() {
2332 let data = "<p><i>Hello!</p>, World!</i>";
2333 let s: Tendril<fmt::UTF8, NonAtomic> = data.into();
2334 assert_eq!(&*s, data);
2335 let s: Tendril<fmt::UTF8, Atomic> = s.into_send().into();
2336 assert_eq!(&*s, data);
2337 }
2338
2339 #[test]
2340 fn inline_send() {
2341 let s = "x".to_tendril();
2342 let t = s.clone();
2343 let s2 = s.into_send();
2344 thread::spawn(move || {
2345 let s = StrTendril::from(s2);
2346 assert!(!s.is_shared());
2347 assert_eq!("x", &*s);
2348 })
2349 .join()
2350 .unwrap();
2351 assert_eq!("x", &*t);
2352 }
2353}