wiwi/rc/
str.rs

1use crate::prelude::*;
2use super::{ Rc, RcWeak, Counter, ThreadCounter, AtomicCounter };
3
4#[repr(transparent)]
5pub struct RcStr<C, M = ()>
6where
7	C: Counter
8{
9	inner: Rc<C, M, u8>
10}
11
12#[repr(transparent)]
13pub struct RcStrWeak<C, M = ()>
14where
15	C: Counter
16{
17	inner: RcWeak<C, M, u8>
18}
19
20/// Single threaded reference counting thin pointer to a [`prim@str`],
21/// optionally carrying arbitrary additional metadata
22pub type RcStrThread<M = ()> = RcStr<ThreadCounter, M>;
23
24/// Weak pointer to a single threaded reference counted thin pointer [`RcStrThread`]
25pub type RcStrThreadWeak<M = ()> = RcStrWeak<ThreadCounter, M>;
26
27/// Atomically counted reference counting thin pointer to a [`prim@str`],
28/// optionally carrying arbitrary additional metadata
29pub type RcStrAtomic<M = ()> = RcStr<AtomicCounter, M>;
30
31/// Weak pointer to an atomically counted reference counted thin pointer [`RcStrAtomic`]
32pub type RcStrAtomicWeak<M = ()> = RcStrWeak<AtomicCounter, M>;
33
34impl<C> RcStr<C>
35where
36	C: Counter
37{
38	#[inline]
39	pub fn new(s: &str) -> Self {
40		Self { inner: Rc::from_slice_copy(s.as_bytes()) }
41	}
42}
43
44impl<C, M> RcStr<C, M>
45where
46	C: Counter
47{
48	#[inline]
49	pub fn with_metadata(s: &str, metadata: M) -> Self {
50		Self { inner: Rc::from_value_and_slice_copy(metadata, s.as_bytes()) }
51	}
52}
53
54impl<C, M> RcStr<C, M>
55where
56	C: Counter
57{
58	#[inline]
59	pub fn strong_count(&self) -> usize {
60		self.inner.strong_count()
61	}
62
63	#[inline]
64	pub fn weak_count(&self) -> usize {
65		self.inner.weak_count()
66	}
67
68	#[inline]
69	pub fn downgrade(&self) -> RcStrWeak<C, M> {
70		RcStrWeak { inner: self.inner.downgrade() }
71	}
72}
73
74impl<C, M> Clone for RcStr<C, M>
75where
76	C: Counter
77{
78	#[inline]
79	fn clone(&self) -> Self {
80		Self { inner: self.inner.clone() }
81	}
82}
83
84impl<C, M> Deref for RcStr<C, M>
85where
86	C: Counter
87{
88	type Target = str;
89
90	#[inline]
91	fn deref(&self) -> &str {
92		// SAFETY: `RcStr` has invariant of containing valid utf-8
93		unsafe { str::from_utf8_unchecked(self.inner.as_slice_ref()) }
94	}
95}
96
97impl<C, M> RcStrWeak<C, M>
98where
99	C: Counter
100{
101	#[inline]
102	pub fn strong_count(&self) -> usize {
103		self.inner.strong_count()
104	}
105
106	#[inline]
107	pub fn weak_count(&self) -> usize {
108		self.inner.weak_count()
109	}
110
111	#[inline]
112	pub fn upgrade(&self) -> Option<RcStr<C, M>> {
113		self.inner.upgrade().map(|inner| RcStr { inner })
114	}
115}
116
117impl<C, M> Clone for RcStrWeak<C, M>
118where
119	C: Counter
120{
121	#[inline]
122	fn clone(&self) -> Self {
123		Self { inner: self.inner.clone() }
124	}
125}