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