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