1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
use std::any::TypeId; use std::rc::Rc; use crate::object::Object; use crate::error::{Result, PdfError}; pub trait AnyObject { fn serialize(&self, out: &mut Vec<u8>); fn type_name(&self) -> &'static str; fn type_id(&self) -> TypeId; } impl<T> AnyObject for T where T: Object + 'static { fn serialize(&self, out: &mut Vec<u8>) { Object::serialize(self, out).expect("write error on Vec<u8> ?!?") } fn type_name(&self) -> &'static str { std::any::type_name::<T>() } fn type_id(&self) -> TypeId { TypeId::of::<T>() } } #[derive(Clone)] pub struct Any(Rc<dyn AnyObject>); impl Any { pub fn downcast<T>(self) -> Result<Rc<T>> where T: AnyObject + 'static { if TypeId::of::<T>() == self.0.type_id() { unsafe { let raw: *const dyn AnyObject = Rc::into_raw(self.0); Ok(Rc::from_raw(raw as *const T)) } } else { Err(type_mismatch::<T>(&self)) } } pub fn new<T>(rc: Rc<T>) -> Any where T: AnyObject + 'static { Any(rc as _) } pub fn type_name(&self) -> &'static str { self.0.type_name() } } fn type_mismatch<T: AnyObject + 'static>(any: &Any) -> PdfError { PdfError::Other { msg: format!("expected {}, found {}", std::any::type_name::<T>(), any.type_name()) } }