1#![no_std]
2extern crate alloc;
15
16use alloc::boxed::Box;
17use alloc::rc::Rc;
18use alloc::sync::Arc;
19use core::any::{Any, TypeId};
20
21use hashbrown::HashMap;
22use linkme::distributed_slice;
23use spin::Lazy;
24
25pub use intertrait_macros::*;
26
27use crate::hasher::BuildFastHasher;
28
29pub mod cast;
30mod hasher;
31
32#[doc(hidden)]
33pub type BoxedCaster = Box<dyn Any + Send + Sync>;
34
35#[doc(hidden)]
36pub mod __private {
37 pub use alloc::boxed::Box;
38 pub use linkme;
39}
40
41#[cfg(doctest)]
42doc_comment::doctest!("../README.md");
43
44#[doc(hidden)]
51#[distributed_slice]
52pub static CASTERS: [fn() -> (TypeId, BoxedCaster)] = [..];
53
54static CASTER_MAP: Lazy<HashMap<(TypeId, TypeId), BoxedCaster, BuildFastHasher>> =
58 Lazy::new(|| {
59 CASTERS
60 .iter()
61 .map(|f| {
62 let (type_id, caster) = f();
63 ((type_id, (*caster).type_id()), caster)
64 })
65 .collect()
66 });
67
68fn cast_arc_panic<T: ?Sized + 'static>(_: Arc<dyn Any + Sync + Send>) -> Arc<T> {
69 panic!("Prepend [sync] to the list of target traits for Sync + Send types")
70}
71
72#[doc(hidden)]
79pub struct Caster<T: ?Sized + 'static> {
80 pub cast_ref: fn(from: &dyn Any) -> &T,
83
84 pub cast_mut: fn(from: &mut dyn Any) -> &mut T,
87
88 pub cast_box: fn(from: Box<dyn Any>) -> Box<T>,
91
92 pub cast_rc: fn(from: Rc<dyn Any>) -> Rc<T>,
95
96 pub cast_arc: fn(from: Arc<dyn Any + Sync + Send + 'static>) -> Arc<T>,
99}
100
101impl<T: ?Sized + 'static> Caster<T> {
102 pub fn new(
103 cast_ref: fn(from: &dyn Any) -> &T,
104 cast_mut: fn(from: &mut dyn Any) -> &mut T,
105 cast_box: fn(from: Box<dyn Any>) -> Box<T>,
106 cast_rc: fn(from: Rc<dyn Any>) -> Rc<T>,
107 ) -> Caster<T> {
108 Caster::<T> {
109 cast_ref,
110 cast_mut,
111 cast_box,
112 cast_rc,
113 cast_arc: cast_arc_panic,
114 }
115 }
116
117 pub fn new_sync(
118 cast_ref: fn(from: &dyn Any) -> &T,
119 cast_mut: fn(from: &mut dyn Any) -> &mut T,
120 cast_box: fn(from: Box<dyn Any>) -> Box<T>,
121 cast_rc: fn(from: Rc<dyn Any>) -> Rc<T>,
122 cast_arc: fn(from: Arc<dyn Any + Sync + Send>) -> Arc<T>,
123 ) -> Caster<T> {
124 Caster::<T> {
125 cast_ref,
126 cast_mut,
127 cast_box,
128 cast_rc,
129 cast_arc,
130 }
131 }
132}
133
134fn caster<T: ?Sized + 'static>(type_id: TypeId) -> Option<&'static Caster<T>> {
136 CASTER_MAP
137 .get(&(type_id, TypeId::of::<Caster<T>>()))
138 .and_then(|caster| caster.downcast_ref::<Caster<T>>())
139}
140
141pub trait CastFrom: Any + 'static {
153 fn ref_any(&self) -> &dyn Any;
155
156 fn mut_any(&mut self) -> &mut dyn Any;
158
159 fn box_any(self: Box<Self>) -> Box<dyn Any>;
161
162 fn rc_any(self: Rc<Self>) -> Rc<dyn Any>;
164}
165
166pub trait CastFromSync: CastFrom + Sync + Send + 'static {
180 fn arc_any(self: Arc<Self>) -> Arc<dyn Any + Sync + Send + 'static>;
181}
182
183impl<T: Sized + Any + 'static> CastFrom for T {
184 fn ref_any(&self) -> &dyn Any {
185 self
186 }
187
188 fn mut_any(&mut self) -> &mut dyn Any {
189 self
190 }
191
192 fn box_any(self: Box<Self>) -> Box<dyn Any> {
193 self
194 }
195
196 fn rc_any(self: Rc<Self>) -> Rc<dyn Any> {
197 self
198 }
199}
200
201impl CastFrom for dyn Any + 'static {
202 fn ref_any(&self) -> &dyn Any {
203 self
204 }
205
206 fn mut_any(&mut self) -> &mut dyn Any {
207 self
208 }
209
210 fn box_any(self: Box<Self>) -> Box<dyn Any> {
211 self
212 }
213
214 fn rc_any(self: Rc<Self>) -> Rc<dyn Any> {
215 self
216 }
217}
218
219impl<T: Sized + Sync + Send + 'static> CastFromSync for T {
220 fn arc_any(self: Arc<Self>) -> Arc<dyn Any + Sync + Send + 'static> {
221 self
222 }
223}
224
225impl CastFrom for dyn Any + Sync + Send + 'static {
226 fn ref_any(&self) -> &dyn Any {
227 self
228 }
229
230 fn mut_any(&mut self) -> &mut dyn Any {
231 self
232 }
233
234 fn box_any(self: Box<Self>) -> Box<dyn Any> {
235 self
236 }
237
238 fn rc_any(self: Rc<Self>) -> Rc<dyn Any> {
239 self
240 }
241}
242
243impl CastFromSync for dyn Any + Sync + Send + 'static {
244 fn arc_any(self: Arc<Self>) -> Arc<dyn Any + Sync + Send + 'static> {
245 self
246 }
247}
248
249#[cfg(test)]
250extern crate std;
251
252#[cfg(test)]
253mod tests {
254 use std::any::{Any, TypeId};
255 use std::fmt::{Debug, Display};
256
257 use linkme::distributed_slice;
258
259 use crate::{BoxedCaster, CastFromSync};
260
261 use super::cast::*;
262 use super::*;
263
264 #[distributed_slice(super::CASTERS)]
265 static TEST_CASTER: fn() -> (TypeId, BoxedCaster) = create_test_caster;
266
267 #[derive(Debug)]
268 struct TestStruct;
269
270 trait SourceTrait: CastFromSync {}
271
272 impl SourceTrait for TestStruct {}
273
274 fn create_test_caster() -> (TypeId, BoxedCaster) {
275 let type_id = TypeId::of::<TestStruct>();
276 let caster = Box::new(Caster::<dyn Debug> {
277 cast_ref: |from| from.downcast_ref::<TestStruct>().unwrap(),
278 cast_mut: |from| from.downcast_mut::<TestStruct>().unwrap(),
279 cast_box: |from| from.downcast::<TestStruct>().unwrap(),
280 cast_rc: |from| from.downcast::<TestStruct>().unwrap(),
281 cast_arc: |from| from.downcast::<TestStruct>().unwrap(),
282 });
283 (type_id, caster)
284 }
285
286 #[test]
287 fn cast_ref() {
288 let ts = TestStruct;
289 let st: &dyn SourceTrait = &ts;
290 let debug = st.cast::<dyn Debug>();
291 assert!(debug.is_some());
292 }
293
294 #[test]
295 fn cast_mut() {
296 let mut ts = TestStruct;
297 let st: &mut dyn SourceTrait = &mut ts;
298 let debug = st.cast::<dyn Debug>();
299 assert!(debug.is_some());
300 }
301
302 #[test]
303 fn cast_box() {
304 let ts = Box::new(TestStruct);
305 let st: Box<dyn SourceTrait> = ts;
306 let debug = st.cast::<dyn Debug>();
307 assert!(debug.is_ok());
308 }
309
310 #[test]
311 fn cast_rc() {
312 let ts = Rc::new(TestStruct);
313 let st: Rc<dyn SourceTrait> = ts;
314 let debug = st.cast::<dyn Debug>();
315 assert!(debug.is_ok());
316 }
317
318 #[test]
319 fn cast_arc() {
320 let ts = Arc::new(TestStruct);
321 let st: Arc<dyn SourceTrait> = ts;
322 let debug = st.cast::<dyn Debug>();
323 assert!(debug.is_ok());
324 }
325
326 #[test]
327 fn cast_ref_wrong() {
328 let ts = TestStruct;
329 let st: &dyn SourceTrait = &ts;
330 let display = st.cast::<dyn Display>();
331 assert!(display.is_none());
332 }
333
334 #[test]
335 fn cast_mut_wrong() {
336 let mut ts = TestStruct;
337 let st: &mut dyn SourceTrait = &mut ts;
338 let display = st.cast::<dyn Display>();
339 assert!(display.is_none());
340 }
341
342 #[test]
343 fn cast_box_wrong() {
344 let ts = Box::new(TestStruct);
345 let st: Box<dyn SourceTrait> = ts;
346 let display = st.cast::<dyn Display>();
347 assert!(display.is_err());
348 }
349
350 #[test]
351 fn cast_rc_wrong() {
352 let ts = Rc::new(TestStruct);
353 let st: Rc<dyn SourceTrait> = ts;
354 let display = st.cast::<dyn Display>();
355 assert!(display.is_err());
356 }
357
358 #[test]
359 fn cast_arc_wrong() {
360 let ts = Arc::new(TestStruct);
361 let st: Arc<dyn SourceTrait> = ts;
362 let display = st.cast::<dyn Display>();
363 assert!(display.is_err());
364 }
365
366 #[test]
367 fn cast_ref_from_any() {
368 let ts = TestStruct;
369 let st: &dyn Any = &ts;
370 let debug = st.cast::<dyn Debug>();
371 assert!(debug.is_some());
372 }
373
374 #[test]
375 fn cast_mut_from_any() {
376 let mut ts = TestStruct;
377 let st: &mut dyn Any = &mut ts;
378 let debug = st.cast::<dyn Debug>();
379 assert!(debug.is_some());
380 }
381
382 #[test]
383 fn cast_box_from_any() {
384 let ts = Box::new(TestStruct);
385 let st: Box<dyn Any> = ts;
386 let debug = st.cast::<dyn Debug>();
387 assert!(debug.is_ok());
388 }
389
390 #[test]
391 fn cast_rc_from_any() {
392 let ts = Rc::new(TestStruct);
393 let st: Rc<dyn Any> = ts;
394 let debug = st.cast::<dyn Debug>();
395 assert!(debug.is_ok());
396 }
397
398 #[test]
399 fn cast_arc_from_any() {
400 let ts = Arc::new(TestStruct);
401 let st: Arc<dyn Any + Send + Sync> = ts;
402 let debug = st.cast::<dyn Debug>();
403 assert!(debug.is_ok());
404 }
405
406 #[test]
407 fn impls_ref() {
408 let ts = TestStruct;
409 let st: &dyn SourceTrait = &ts;
410 assert!(st.impls::<dyn Debug>());
411 }
412
413 #[test]
414 fn impls_mut() {
415 let mut ts = TestStruct;
416 let st: &mut dyn SourceTrait = &mut ts;
417 assert!((*st).impls::<dyn Debug>());
418 }
419
420 #[test]
421 fn impls_box() {
422 let ts = Box::new(TestStruct);
423 let st: Box<dyn SourceTrait> = ts;
424 assert!((*st).impls::<dyn Debug>());
425 }
426
427 #[test]
428 fn impls_rc() {
429 let ts = Rc::new(TestStruct);
430 let st: Rc<dyn SourceTrait> = ts;
431 assert!((*st).impls::<dyn Debug>());
432 }
433
434 #[test]
435 fn impls_arc() {
436 let ts = Arc::new(TestStruct);
437 let st: Arc<dyn SourceTrait> = ts;
438 assert!((*st).impls::<dyn Debug>());
439 }
440
441 #[test]
442 fn impls_not_ref() {
443 let ts = TestStruct;
444 let st: &dyn SourceTrait = &ts;
445 assert!(!st.impls::<dyn Display>());
446 }
447
448 #[test]
449 fn impls_not_mut() {
450 let mut ts = TestStruct;
451 let st: &mut dyn Any = &mut ts;
452 assert!(!(*st).impls::<dyn Display>());
453 }
454
455 #[test]
456 fn impls_not_box() {
457 let ts = Box::new(TestStruct);
458 let st: Box<dyn SourceTrait> = ts;
459 assert!(!st.impls::<dyn Display>());
460 }
461
462 #[test]
463 fn impls_not_rc() {
464 let ts = Rc::new(TestStruct);
465 let st: Rc<dyn SourceTrait> = ts;
466 assert!(!(*st).impls::<dyn Display>());
467 }
468
469 #[test]
470 fn impls_not_arc() {
471 let ts = Arc::new(TestStruct);
472 let st: Arc<dyn SourceTrait> = ts;
473 assert!(!(*st).impls::<dyn Display>());
474 }
475}