1use std::any::TypeId;
2use std::rc::Rc;
3use std::sync::Arc;
4use datasize::DataSize;
5use crate::object::{Object};
6use crate::error::{Result, PdfError};
7
8pub trait AnyObject {
9 fn type_name(&self) -> &'static str;
10 fn type_id(&self) -> TypeId;
11 fn size(&self) -> usize;
12}
13
14#[repr(transparent)]
15pub struct NoSize<T>(T);
16impl<T: 'static> AnyObject for NoSize<T> {
17 fn size(&self) -> usize {
18 0
19 }
20 fn type_id(&self) -> TypeId {
21 TypeId::of::<T>()
22 }
23 fn type_name(&self) -> &'static str {
24 std::any::type_name::<T>()
25 }
26}
27
28#[repr(transparent)]
29pub struct WithSize<T>(T);
30impl<T: DataSize + 'static> AnyObject for WithSize<T> {
31 fn size(&self) -> usize {
32 datasize::data_size(&self.0)
33 }
34 fn type_id(&self) -> TypeId {
35 TypeId::of::<T>()
36 }
37 fn type_name(&self) -> &'static str {
38 std::any::type_name::<T>()
39 }
40}
41
42#[derive(DataSize)]
43pub struct Any(Rc<dyn AnyObject>);
44
45impl Any {
46 pub fn downcast<T>(self) -> Result<Rc<T>>
47 where T: AnyObject + 'static
48 {
49 if TypeId::of::<T>() == self.0.type_id() {
50 unsafe {
51 let raw: *const dyn AnyObject = Rc::into_raw(self.0);
52 Ok(Rc::from_raw(raw as *const T))
53 }
54 } else {
55 Err(type_mismatch::<T>(self.0.type_name()))
56 }
57 }
58 pub fn new<T>(rc: Rc<T>) -> Any
59 where WithSize<T>: AnyObject, T: 'static
60 {
61 Any(unsafe {
62 std::mem::transmute::<Rc<T>, Rc<WithSize<T>>>(rc)
63 } as _)
64 }
65 pub fn new_without_size<T>(rc: Rc<T>) -> Any
66 where NoSize<T>: AnyObject, T: 'static
67 {
68 Any(unsafe {
69 std::mem::transmute::<Rc<T>, Rc<NoSize<T>>>(rc)
70 } as _)
71 }
72 pub fn type_name(&self) -> &'static str {
73 self.0.type_name()
74 }
75}
76
77#[derive(Clone, DataSize)]
78pub struct AnySync(Arc<dyn AnyObject+Sync+Send>);
79
80#[cfg(feature="cache")]
81impl globalcache::ValueSize for AnySync {
82 #[inline]
83 fn size(&self) -> usize {
84 self.0.size()
85 }
86}
87
88impl AnySync {
89 pub fn downcast<T>(self) -> Result<Arc<T>>
90 where T: 'static
91 {
92 if TypeId::of::<T>() == self.0.type_id() {
93 unsafe {
94 let raw: *const (dyn AnyObject+Sync+Send) = Arc::into_raw(self.0);
95 Ok(Arc::from_raw(raw as *const T))
96 }
97 } else {
98 Err(type_mismatch::<T>(self.0.type_name()))
99 }
100 }
101 pub fn new<T>(arc: Arc<T>) -> AnySync
102 where WithSize<T>: AnyObject, T: Sync + Send + 'static
103 {
104 AnySync(unsafe {
105 std::mem::transmute::<Arc<T>, Arc<WithSize<T>>>(arc)
106 } as _)
107 }
108 pub fn new_without_size<T>(arc: Arc<T>) -> AnySync
109 where NoSize<T>: AnyObject, T: Sync + Send + 'static
110 {
111 AnySync(unsafe {
112 std::mem::transmute::<Arc<T>, Arc<NoSize<T>>>(arc)
113 } as _)
114 }
115 pub fn type_name(&self) -> &'static str {
116 self.0.type_name()
117 }
118}
119fn type_mismatch<T>(name: &str) -> PdfError {
120 PdfError::Other { msg: format!("expected {}, found {}", std::any::type_name::<T>(), name) }
121}