variadic_arguments/argument/
arg.rs1mod inner;
2
3#[cfg(no_std)]
4use core::{
5 any::Any,
6 fmt,
7 ops::Deref,
8 mem::ManuallyDrop
9};
10
11#[cfg(not(no_std))]
12use std::{
13 any::Any,
14 fmt,
15 ops::Deref,
16 mem::ManuallyDrop
17};
18
19use super::{OwnedArgument, discriminant::Discriminant};
20
21use inner::{RawArgument, InnerArgument};
22
23pub use inner::ArgumentKind;
24
25#[repr(transparent)]
33pub struct Argument<'a>
34{
35 inner: InnerArgument<'a>
36}
37
38
39impl fmt::Debug for Argument<'_>
40{
41 #[inline(always)]
42 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
43 {
44 match self.discriminant()
45 {
46 Discriminant::Borrowed =>
47 {
48 f.debug_tuple("Argument::Borrowed")
49 .field(&self.inner.to_ref())
50 .finish()
51 }
52 _ =>
53 {
54 f.debug_tuple("Argument::Owned")
55 .field(unsafe { self.inner.owned_debug_handle() })
56 .finish()
57 }
58 }
59 }
60}
61
62
63impl Drop for Argument<'_>
64{
65 #[inline(always)]
66 fn drop(&mut self)
67 {
68 let _ = unsafe { self.inner.take_raw_argument() };
69 }
70}
71
72
73impl<'a> Clone for Argument<'a>
74{
75 #[inline(always)]
76 fn clone(&self) -> Self
77 {
78 let inner =
79 match self.discriminant()
80 {
81 Discriminant::Borrowed =>
82 {
83 let ref_ =
84 unsafe {
85 self.inner
86 .ref_unchecked()
87 };
88
89 InnerArgument::new_ref(ref_)
90 }
91 _ =>
92 {
93 let owned =
94 {
95 let raw = &raw const self.inner;
96 unsafe
97 {
98 (*raw.cast::<OwnedArgument>()).clone()
99 }
100 };
101
102 InnerArgument::new_owned(owned)
103 }
104 };
105
106 Self
107 {
108 inner
109 }
110 }
111}
112
113impl Deref for Argument<'_>
114{
115 type Target = dyn Any;
116
117 #[inline(always)]
118 fn deref(&self) -> &dyn Any
119 {
120 self.inner
121 .to_ref()
122 }
123}
124
125impl Argument<'_>
126{
127 #[inline(always)]
129 pub fn new_owned<T>(item: T) -> Self
130 where
131 T: Any + Clone
132 {
133 let owned = OwnedArgument::new(item);
134
135 Self
136 {
137 inner: InnerArgument::new_owned(owned)
138 }
139 }
140
141 #[inline(always)]
143 pub fn is_owned(&self) -> bool
144 {
145 self.inner
146 .is_owned()
147 }
148
149 #[inline(always)]
151 pub fn is_borrowed(&self) -> bool
152 {
153 self.inner
154 .is_borrowed()
155 }
156
157 #[inline(always)]
162 pub fn to_mut(&mut self) -> &mut dyn Any
163 {
164 self.inner
165 .to_mut()
166 }
167
168 #[inline(always)]
169 fn discriminant(&self) -> Discriminant
170 {
171 self.inner
172 .discriminant()
173 }
174
175 #[inline(always)]
177 pub fn to_owned(&self) -> Self
178 {
179 match self.discriminant()
180 {
181 Discriminant::Borrowed =>
182 {
183 let ref_ =
184 unsafe
185 {
186 self.inner
187 .ref_unchecked()
188 };
189
190 let owned = ref_.clone_object();
191
192 Self
193 {
194 inner: InnerArgument::new_owned(owned)
195 }
196 }
197 _ => self.clone()
198 }
199 }
200
201 #[inline(always)]
207 pub fn downcast_owned<T>(self) -> Result<T, Self>
208 where
209 T: Clone + Any
210 {
211 match self.inner_contents()
212 {
213 RawArgument::Owned(owned)
214 if owned.is_type::<T>() =>
215 unsafe
216 {
217 Ok(owned.downcast_owned_unchecked())
218 }
219
220 RawArgument::Owned(o)
221 =>
222 Err(Self { inner: InnerArgument::new_owned(o) }),
223
224 RawArgument::Borrowed(b)
225 =>
226 Err(Self { inner: InnerArgument::new_ref(b) })
227 }
228 }
229
230 #[inline(always)]
238 pub unsafe fn downcast_owned_unchecked<T>(self) -> T
239 where
240 T: Clone + Any
241 {
242 debug_assert!(self.is_owned());
243
244 let RawArgument::Owned(contents) = self.inner_contents()
245 else
246 {
247 #[cfg(debug_assertions)]
248 {
249 unreachable!()
250 }
251 #[cfg(not(debug_assertions))]
252 {
253 panic!()
254 }
255 };
256
257 debug_assert!(contents.is_type::<T>());
258
259 unsafe
260 {
261 contents.downcast_owned_unchecked()
262 }
263 }
264
265 #[inline(always)]
269 pub fn downcast_cloned<T>(&self) -> Option<T>
270 where
271 T: Any + Clone
272 {
273 #[allow(clippy::manual_map)]
274 match self.downcast_ref::<T>()
275 {
276 Some(t) => Some(t.clone()),
277 None => None
278 }
279 }
280
281 #[inline(always)]
290 unsafe fn downcast_ref_unchecked<T>(&self) -> &T
291 where
292 T: Any + Clone
293 {
294 let binding = self.inner.to_ref();
295
296 debug_assert!(binding.is::<T>());
297
298 unsafe
299 {
300 &*(binding as *const dyn Any as *const T)
301 }
302 }
303
304 #[inline(always)]
309 pub unsafe fn downcast_cloned_unchecked<T>(&self) -> T
310 where
311 T: Any + Clone
312 {
313 unsafe
314 {
315 self.downcast_ref_unchecked::<T>().clone()
316 }
317 }
318}
319
320impl<'a> Argument<'a>
321{
322 #[inline(always)]
324 pub fn new_borrowed<T>(item: &'a T) -> Self
325 where
326 T: Any + Clone
327 {
328 Self
329 {
330 inner: InnerArgument::new_ref(item)
331 }
332 }
333
334 #[inline(always)]
336 pub fn as_ref(&'a self) -> Self
337 {
338 Self
339 {
340 inner: self.inner.as_ref()
341 }
342 }
343
344 #[inline(always)]
346 fn inner_contents(self) -> RawArgument<'a>
347 {
348 let mut store = ManuallyDrop::new(self);
349
350 unsafe
351 {
352 store.inner.take_raw_argument()
353 }
354 }
355
356 #[inline(always)]
358 pub fn into_inner(self) -> ArgumentKind<'a>
359 {
360 let store = ManuallyDrop::new(self);
361
362 let raw = &raw const store.inner;
363
364 unsafe
365 {
366 raw.read().into_inner()
367 }
368 }
369}
370
371impl From<OwnedArgument> for Argument<'_>
372{
373 fn from(item: OwnedArgument) -> Self
374 {
375 Self
376 {
377 inner: InnerArgument::new_owned(item)
378 }
379 }
380}