mod color;
mod function;
mod stream;
mod types;
pub use self::color::*;
pub use self::function::*;
pub use self::stream::*;
pub use self::types::*;
pub use crate::file::PromisedRef;
use crate::file::UpdateOptions;
use crate::parser::ParseFlags;
use crate::enc::*;
use crate::error::*;
use crate::primitive::*;
use datasize::DataSize;
use once_cell::sync::OnceCell;
use std::any::type_name;
use std::collections::HashMap;
use std::convert::TryInto;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::marker::PhantomData;
use std::ops::{Deref, Range};
use std::sync::Arc;
pub type ObjNr = u64;
pub type GenNr = u64;
#[derive(Clone)]
pub struct ParseOptions {
pub allow_error_in_option: bool,
pub allow_xref_error: bool,
pub allow_invalid_ops: bool,
pub allow_missing_endobj: bool,
}
impl ParseOptions {
pub const fn tolerant() -> Self {
ParseOptions {
allow_error_in_option: true,
allow_xref_error: true,
allow_invalid_ops: true,
allow_missing_endobj: true,
}
}
pub const fn strict() -> Self {
ParseOptions {
allow_error_in_option: false,
allow_xref_error: false,
allow_invalid_ops: true,
allow_missing_endobj: false,
}
}
}
pub trait Resolve {
fn resolve_flags(&self, r: PlainRef, flags: ParseFlags, depth: usize) -> Result<Primitive>;
fn resolve(&self, r: PlainRef) -> Result<Primitive> {
self.resolve_flags(r, ParseFlags::ANY, 16)
}
fn get<T: Object + DataSize>(&self, r: Ref<T>) -> Result<RcRef<T>>;
fn options(&self) -> &ParseOptions;
fn stream_data(&self, id: PlainRef, range: Range<usize>) -> Result<Arc<[u8]>>;
fn get_data_or_decode(
&self,
id: PlainRef,
range: Range<usize>,
filters: &[StreamFilter],
) -> Result<Arc<[u8]>>;
}
pub struct NoResolve;
impl Resolve for NoResolve {
fn resolve_flags(&self, _: PlainRef, _: ParseFlags, _: usize) -> Result<Primitive> {
Err(PdfError::Reference)
}
fn get<T: Object + DataSize>(&self, _r: Ref<T>) -> Result<RcRef<T>> {
Err(PdfError::Reference)
}
fn options(&self) -> &ParseOptions {
static STRICT: ParseOptions = ParseOptions::strict();
&STRICT
}
fn get_data_or_decode(
&self,
_: PlainRef,
_: Range<usize>,
_: &[StreamFilter],
) -> Result<Arc<[u8]>> {
Err(PdfError::Reference)
}
fn stream_data(&self, _id: PlainRef, _range: Range<usize>) -> Result<Arc<[u8]>> {
Err(PdfError::Reference)
}
}
pub trait Object: Sized + Sync + Send + 'static {
fn from_primitive(p: Primitive, resolve: &impl Resolve) -> Result<Self>;
}
pub trait Cloner: Updater + Resolve {
fn clone_plainref(&mut self, old: PlainRef) -> Result<PlainRef>;
fn clone_ref<T: DeepClone + Object + DataSize + ObjectWrite>(
&mut self,
old: Ref<T>,
) -> Result<Ref<T>>;
fn clone_rcref<T: DeepClone + ObjectWrite + DataSize>(
&mut self,
old: &RcRef<T>,
) -> Result<RcRef<T>>;
fn clone_shared<T: DeepClone>(&mut self, old: &Shared<T>) -> Result<Shared<T>>;
}
pub trait DeepClone: Sized + Sync + Send + 'static {
fn deep_clone(&self, cloner: &mut impl Cloner) -> Result<Self>;
}
pub trait Updater {
fn create<T: ObjectWrite>(&mut self, obj: T) -> Result<RcRef<T>>;
fn update<T: ObjectWrite>(&mut self, old: PlainRef, obj: T) -> Result<RcRef<T>> {
self.update_with(old, obj, UpdateOptions::default())
}
fn update_with<T: ObjectWrite>(&mut self, old: PlainRef, obj: T, options: UpdateOptions) -> Result<RcRef<T>>;
fn promise<T: Object>(&mut self) -> PromisedRef<T>;
fn fulfill<T: ObjectWrite>(&mut self, promise: PromisedRef<T>, obj: T) -> Result<RcRef<T>>;
fn update_ref<T: ObjectWrite>(&mut self, old: &RcRef<T>, obj: T) -> Result<RcRef<T>> {
self.update(old.get_ref().inner, obj)
}
}
pub struct NoUpdate;
impl Updater for NoUpdate {
fn create<T: ObjectWrite>(&mut self, _obj: T) -> Result<RcRef<T>> {
panic!()
}
fn update_with<T: ObjectWrite>(&mut self, _old: PlainRef, _obj: T, _options: UpdateOptions) -> Result<RcRef<T>> {
panic!()
}
fn promise<T: Object>(&mut self) -> PromisedRef<T> {
panic!()
}
fn fulfill<T: ObjectWrite>(&mut self, _promise: PromisedRef<T>, _obj: T) -> Result<RcRef<T>> {
panic!()
}
}
pub trait ObjectWrite {
fn to_primitive(&self, update: &mut impl Updater) -> Result<Primitive>;
}
pub trait FromDict: Sized {
fn from_dict(dict: Dictionary, resolve: &impl Resolve) -> Result<Self>;
}
pub trait ToDict: ObjectWrite {
fn to_dict(&self, update: &mut impl Updater) -> Result<Dictionary>;
}
pub trait SubType<T> {}
pub trait Trace {
fn trace(&self, _cb: &mut impl FnMut(PlainRef)) {}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, DataSize)]
pub struct PlainRef {
pub id: ObjNr,
pub gen: GenNr,
}
impl Object for PlainRef {
fn from_primitive(p: Primitive, _: &impl Resolve) -> Result<Self> {
p.into_reference()
}
}
impl ObjectWrite for PlainRef {
fn to_primitive(&self, _: &mut impl Updater) -> Result<Primitive> {
Ok(Primitive::Reference(*self))
}
}
impl DeepClone for PlainRef {
fn deep_clone(&self, cloner: &mut impl Cloner) -> Result<Self> {
cloner.clone_plainref(*self)
}
}
pub struct Ref<T> {
inner: PlainRef,
_marker: PhantomData<T>,
}
impl<T> Clone for Ref<T> {
fn clone(&self) -> Ref<T> {
*self
}
}
impl<T> Copy for Ref<T> {}
impl<T> DataSize for Ref<T> {
const IS_DYNAMIC: bool = false;
const STATIC_HEAP_SIZE: usize = size_of::<Self>();
fn estimate_heap_size(&self) -> usize {
size_of::<Self>()
}
}
impl<T> Ref<T> {
pub fn new(inner: PlainRef) -> Ref<T> {
Ref {
inner,
_marker: PhantomData,
}
}
pub fn from_id(id: ObjNr) -> Ref<T> {
Ref {
inner: PlainRef { id, gen: 0 },
_marker: PhantomData,
}
}
pub fn get_inner(&self) -> PlainRef {
self.inner
}
pub fn upcast<U>(self) -> Ref<U>
where
T: SubType<U>,
{
Ref::new(self.inner)
}
}
impl<T: Object> Object for Ref<T> {
fn from_primitive(p: Primitive, _: &impl Resolve) -> Result<Self> {
Ok(Ref::new(p.into_reference()?))
}
}
impl<T> ObjectWrite for Ref<T> {
fn to_primitive(&self, update: &mut impl Updater) -> Result<Primitive> {
self.inner.to_primitive(update)
}
}
impl<T: DeepClone + Object + DataSize + ObjectWrite> DeepClone for Ref<T> {
fn deep_clone(&self, cloner: &mut impl Cloner) -> Result<Self> {
cloner.clone_ref(*self)
}
}
impl<T> Trace for Ref<T> {
fn trace(&self, cb: &mut impl FnMut(PlainRef)) {
cb(self.inner);
}
}
impl<T> fmt::Debug for Ref<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Ref({})", self.inner.id)
}
}
impl<T> Hash for Ref<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.inner.hash(state)
}
}
impl<T> PartialEq for Ref<T> {
fn eq(&self, rhs: &Self) -> bool {
self.inner.eq(&rhs.inner)
}
}
impl<T> Eq for Ref<T> {}
pub type Shared<T> = Arc<T>;
#[derive(Debug, DataSize)]
pub struct RcRef<T> {
inner: PlainRef,
data: Shared<T>,
}
impl<T> From<RcRef<T>> for Primitive {
fn from(value: RcRef<T>) -> Self {
Primitive::Reference(value.inner)
}
}
impl<T> From<RcRef<T>> for Ref<T> {
fn from(value: RcRef<T>) -> Self {
value.get_ref()
}
}
impl<T> AsRef<Shared<T>> for RcRef<T> {
fn as_ref(&self) -> &Shared<T> {
&self.data
}
}
impl<T> RcRef<T> {
pub fn new(inner: PlainRef, data: Shared<T>) -> RcRef<T> {
RcRef { inner, data }
}
pub fn get_ref(&self) -> Ref<T> {
Ref::new(self.inner)
}
}
impl<T: Object + std::fmt::Debug + DataSize> Object for RcRef<T> {
fn from_primitive(p: Primitive, resolve: &impl Resolve) -> Result<Self> {
match p {
Primitive::Reference(r) => resolve.get(Ref::new(r)),
p => Err(PdfError::UnexpectedPrimitive {
expected: "Reference",
found: p.get_debug_name(),
}),
}
}
}
impl<T> ObjectWrite for RcRef<T> {
fn to_primitive(&self, update: &mut impl Updater) -> Result<Primitive> {
self.inner.to_primitive(update)
}
}
impl<T: DeepClone + std::fmt::Debug + DataSize + Object + ObjectWrite> DeepClone for RcRef<T> {
fn deep_clone(&self, cloner: &mut impl Cloner) -> Result<Self> {
cloner.clone_rcref(self)
}
}
impl<T> Deref for RcRef<T> {
type Target = T;
fn deref(&self) -> &T {
&self.data
}
}
impl<T> Clone for RcRef<T> {
fn clone(&self) -> RcRef<T> {
RcRef {
inner: self.inner,
data: self.data.clone(),
}
}
}
impl<T> Trace for RcRef<T> {
fn trace(&self, cb: &mut impl FnMut(PlainRef)) {
cb(self.inner);
}
}
impl<'a, T> From<&'a RcRef<T>> for Ref<T> {
fn from(r: &'a RcRef<T>) -> Ref<T> {
Ref::new(r.inner)
}
}
impl<T> Hash for RcRef<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
std::ptr::hash(&**self, state)
}
}
impl<T> PartialEq for RcRef<T> {
fn eq(&self, rhs: &Self) -> bool {
std::ptr::eq(&**self, &**rhs)
}
}
impl<T> Eq for RcRef<T> {}
#[derive(Debug, DataSize)]
pub enum MaybeRef<T> {
Direct(Shared<T>),
Indirect(RcRef<T>),
}
impl<T> MaybeRef<T> {
pub fn as_ref(&self) -> Option<Ref<T>> {
match *self {
MaybeRef::Indirect(ref r) => Some(r.get_ref()),
_ => None,
}
}
pub fn data(&self) -> &Shared<T> {
match *self {
MaybeRef::Direct(ref t) => t,
MaybeRef::Indirect(ref r) => &r.data,
}
}
}
impl<T: Clone> MaybeRef<T> {
pub fn owned(&self) -> T {
(**self.data()).clone()
}
}
impl<T: Object + DataSize> Object for MaybeRef<T> {
fn from_primitive(p: Primitive, resolve: &impl Resolve) -> Result<Self> {
Ok(match p {
Primitive::Reference(r) => MaybeRef::Indirect(resolve.get(Ref::new(r))?),
p => MaybeRef::Direct(Shared::new(T::from_primitive(p, resolve)?)),
})
}
}
impl<T: ObjectWrite> ObjectWrite for MaybeRef<T> {
fn to_primitive(&self, update: &mut impl Updater) -> Result<Primitive> {
match self {
MaybeRef::Direct(ref inner) => inner.to_primitive(update),
MaybeRef::Indirect(r) => r.to_primitive(update),
}
}
}
impl<T: DeepClone + std::fmt::Debug + DataSize + Object + ObjectWrite> DeepClone for MaybeRef<T> {
fn deep_clone(&self, cloner: &mut impl Cloner) -> Result<Self> {
match *self {
MaybeRef::Direct(ref old) => cloner.clone_shared(old).map(MaybeRef::Direct),
MaybeRef::Indirect(ref old) => cloner.clone_rcref(old).map(MaybeRef::Indirect),
}
}
}
impl<T> Deref for MaybeRef<T> {
type Target = T;
fn deref(&self) -> &T {
match *self {
MaybeRef::Direct(ref t) => t,
MaybeRef::Indirect(ref r) => r,
}
}
}
impl<T> Clone for MaybeRef<T> {
fn clone(&self) -> Self {
match *self {
MaybeRef::Direct(ref rc) => MaybeRef::Direct(rc.clone()),
MaybeRef::Indirect(ref r) => MaybeRef::Indirect(r.clone()),
}
}
}
impl<T> Trace for MaybeRef<T> {
fn trace(&self, cb: &mut impl FnMut(PlainRef)) {
match *self {
MaybeRef::Indirect(ref rc) => rc.trace(cb),
MaybeRef::Direct(_) => (),
}
}
}
impl<T> From<Shared<T>> for MaybeRef<T> {
fn from(r: Shared<T>) -> MaybeRef<T> {
MaybeRef::Direct(r)
}
}
impl<T> From<T> for MaybeRef<T> {
fn from(t: T) -> MaybeRef<T> {
MaybeRef::Direct(t.into())
}
}
impl<T> From<MaybeRef<T>> for Shared<T> {
fn from(r: MaybeRef<T>) -> Shared<T> {
match r {
MaybeRef::Direct(rc) => rc,
MaybeRef::Indirect(r) => r.data,
}
}
}
impl<'a, T> From<&'a MaybeRef<T>> for Shared<T> {
fn from(r: &'a MaybeRef<T>) -> Shared<T> {
match r {
MaybeRef::Direct(ref rc) => rc.clone(),
MaybeRef::Indirect(ref r) => r.data.clone(),
}
}
}
impl<T> From<RcRef<T>> for MaybeRef<T> {
fn from(r: RcRef<T>) -> MaybeRef<T> {
MaybeRef::Indirect(r)
}
}
impl<T> Hash for MaybeRef<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
std::ptr::hash(&**self, state)
}
}
impl<T> PartialEq for MaybeRef<T> {
fn eq(&self, rhs: &Self) -> bool {
std::ptr::eq(&**self, &**rhs)
}
}
impl<T> Eq for MaybeRef<T> {}
#[derive(Debug)]
pub struct Lazy<T> {
pub primitive: Primitive,
cache: OnceCell<MaybeRef<T>>,
_marker: PhantomData<T>,
}
impl<T: DataSize> DataSize for Lazy<T> {
const IS_DYNAMIC: bool = true;
const STATIC_HEAP_SIZE: usize = size_of::<Self>();
fn estimate_heap_size(&self) -> usize {
self.cache
.get()
.map(|value| value.estimate_heap_size())
.unwrap_or(0)
+ size_of::<Self>()
}
}
impl<T> Clone for Lazy<T> {
fn clone(&self) -> Self {
Lazy {
primitive: self.primitive.clone(),
cache: self.cache.clone(),
_marker: PhantomData,
}
}
}
impl<T: Object> DeepClone for Lazy<T> {
fn deep_clone(&self, cloner: &mut impl Cloner) -> Result<Self> {
Ok(Lazy {
primitive: self.primitive.deep_clone(cloner)?,
cache: OnceCell::new(),
_marker: PhantomData,
})
}
}
impl<T: Object + DataSize> Lazy<T> {
pub fn load(&self, resolve: &impl Resolve) -> Result<MaybeRef<T>> {
self.cache
.get_or_try_init(|| match self.primitive {
Primitive::Reference(r) => resolve.get(Ref::new(r)).map(MaybeRef::Indirect),
ref p => {
T::from_primitive(p.clone(), resolve).map(|o| MaybeRef::Direct(Arc::new(o)))
}
})
.cloned()
}
pub fn safe(value: MaybeRef<T>, update: &mut impl Updater) -> Result<Self>
where T: ObjectWrite
{
let primitive = value.to_primitive(update)?;
Ok(Lazy { primitive, _marker: PhantomData, cache: OnceCell::new() })
}
}
impl<T: ObjectWrite> Lazy<T> {
pub fn new(data: T, update: &mut impl Updater) -> Result<Self> {
let primitive = data.to_primitive(update)?;
Ok(Lazy { primitive, cache: OnceCell::new(), _marker: PhantomData })
}
}
impl<T: Object> Object for Lazy<T> {
fn from_primitive(p: Primitive, _: &impl Resolve) -> Result<Self> {
Ok(Self {
primitive: p,
cache: OnceCell::new(),
_marker: PhantomData,
})
}
}
impl<T: ObjectWrite> ObjectWrite for Lazy<T> {
fn to_primitive(&self, _update: &mut impl Updater) -> Result<Primitive> {
Ok(self.primitive.clone())
}
}
impl<T> Default for Lazy<T> {
fn default() -> Self {
Lazy {
primitive: Primitive::Null,
cache: OnceCell::new(),
_marker: PhantomData,
}
}
}
impl<T: Object> From<RcRef<T>> for Lazy<T> {
fn from(value: RcRef<T>) -> Self {
Lazy {
primitive: Primitive::Reference(value.inner),
cache: OnceCell::with_value(MaybeRef::Direct(value.data)),
_marker: PhantomData
}
}
}
impl Object for i32 {
fn from_primitive(p: Primitive, r: &impl Resolve) -> Result<Self> {
match p {
Primitive::Reference(id) => r.resolve(id)?.as_integer(),
p => p.as_integer(),
}
}
}
impl ObjectWrite for i32 {
fn to_primitive(&self, _: &mut impl Updater) -> Result<Primitive> {
Ok(Primitive::Integer(*self))
}
}
impl Object for u32 {
fn from_primitive(p: Primitive, r: &impl Resolve) -> Result<Self> {
match p {
Primitive::Reference(id) => r.resolve(id)?.as_u32(),
p => p.as_u32(),
}
}
}
impl ObjectWrite for u32 {
fn to_primitive(&self, _: &mut impl Updater) -> Result<Primitive> {
Ok(Primitive::Integer(*self as _))
}
}
impl Object for usize {
fn from_primitive(p: Primitive, r: &impl Resolve) -> Result<Self> {
match p {
Primitive::Reference(id) => Ok(r.resolve(id)?.as_usize()?),
p => Ok(p.as_usize()?),
}
}
}
impl ObjectWrite for usize {
fn to_primitive(&self, _: &mut impl Updater) -> Result<Primitive> {
Ok(Primitive::Integer(*self as _))
}
}
impl Object for f32 {
fn from_primitive(p: Primitive, r: &impl Resolve) -> Result<Self> {
match p {
Primitive::Reference(id) => r.resolve(id)?.as_number(),
p => p.as_number(),
}
}
}
impl ObjectWrite for f32 {
fn to_primitive(&self, _: &mut impl Updater) -> Result<Primitive> {
Ok(Primitive::Number(*self))
}
}
impl Object for bool {
fn from_primitive(p: Primitive, r: &impl Resolve) -> Result<Self> {
match p {
Primitive::Reference(id) => r.resolve(id)?.as_bool(),
p => p.as_bool(),
}
}
}
impl ObjectWrite for bool {
fn to_primitive(&self, _: &mut impl Updater) -> Result<Primitive> {
Ok(Primitive::Boolean(*self))
}
}
impl Object for Dictionary {
fn from_primitive(p: Primitive, r: &impl Resolve) -> Result<Self> {
match p {
Primitive::Dictionary(dict) => Ok(dict),
Primitive::Reference(id) => Dictionary::from_primitive(r.resolve(id)?, r),
_ => Err(PdfError::UnexpectedPrimitive {
expected: "Dictionary",
found: p.get_debug_name(),
}),
}
}
}
impl Object for Name {
fn from_primitive(p: Primitive, resolve: &impl Resolve) -> Result<Self> {
p.resolve(resolve)?.into_name()
}
}
impl ObjectWrite for Name {
fn to_primitive(&self, _: &mut impl Updater) -> Result<Primitive> {
Ok(Primitive::Name(self.0.clone()))
}
}
impl<T: Object> Object for Vec<T> {
fn from_primitive(p: Primitive, r: &impl Resolve) -> Result<Self> {
Ok(match p {
Primitive::Array(_) => p
.resolve(r)?
.into_array()?
.into_iter()
.map(|p| T::from_primitive(p, r))
.collect::<Result<Vec<T>>>()?,
Primitive::Null => Vec::new(),
Primitive::Reference(id) => Self::from_primitive(r.resolve(id)?, r)?,
_ => vec![T::from_primitive(p, r)?],
})
}
}
impl<T: ObjectWrite> ObjectWrite for Vec<T> {
fn to_primitive(&self, update: &mut impl Updater) -> Result<Primitive> {
Primitive::array::<T, _, _, _>(self.iter(), update)
}
}
impl<T: DeepClone> DeepClone for Vec<T> {
fn deep_clone(&self, cloner: &mut impl Cloner) -> Result<Self> {
self.iter().map(|t| t.deep_clone(cloner)).collect()
}
}
impl<T: Trace> Trace for Vec<T> {
fn trace(&self, cb: &mut impl FnMut(PlainRef)) {
for i in self.iter() {
i.trace(cb);
}
}
}
impl Object for Primitive {
fn from_primitive(p: Primitive, _: &impl Resolve) -> Result<Self> {
Ok(p)
}
}
impl ObjectWrite for Primitive {
fn to_primitive(&self, _: &mut impl Updater) -> Result<Primitive> {
Ok(self.clone())
}
}
impl DeepClone for Primitive {
fn deep_clone(&self, cloner: &mut impl Cloner) -> Result<Self> {
match *self {
Primitive::Array(ref parts) => Ok(Primitive::Array(
parts
.into_iter()
.map(|p| p.deep_clone(cloner))
.collect::<Result<Vec<_>, _>>()?,
)),
Primitive::Boolean(b) => Ok(Primitive::Boolean(b)),
Primitive::Dictionary(ref dict) => Ok(Primitive::Dictionary(dict.deep_clone(cloner)?)),
Primitive::Integer(i) => Ok(Primitive::Integer(i)),
Primitive::Name(ref name) => Ok(Primitive::Name(name.clone())),
Primitive::Null => Ok(Primitive::Null),
Primitive::Number(n) => Ok(Primitive::Number(n)),
Primitive::Reference(r) => Ok(Primitive::Reference(r.deep_clone(cloner)?)),
Primitive::Stream(ref s) => Ok(Primitive::Stream(s.deep_clone(cloner)?)),
Primitive::String(ref s) => Ok(Primitive::String(s.clone())),
}
}
}
impl Trace for Primitive {
fn trace(&self, cb: &mut impl FnMut(PlainRef)) {
match *self {
Primitive::Reference(r) => cb(r),
Primitive::Array(ref parts) => parts.iter().for_each(|p| p.trace(cb)),
Primitive::Dictionary(ref dict) => dict.values().for_each(|p| p.trace(cb)),
_ => (),
}
}
}
impl<V: Object> Object for HashMap<Name, V> {
fn from_primitive(p: Primitive, resolve: &impl Resolve) -> Result<Self> {
match p {
Primitive::Null => Ok(HashMap::new()),
Primitive::Dictionary(dict) => {
let mut new = Self::new();
for (key, val) in dict.iter() {
new.insert(key.clone(), V::from_primitive(val.clone(), resolve)?);
}
Ok(new)
}
Primitive::Reference(id) => HashMap::from_primitive(resolve.resolve(id)?, resolve),
p => Err(PdfError::UnexpectedPrimitive {
expected: "Dictionary",
found: p.get_debug_name(),
}),
}
}
}
impl<V: ObjectWrite> ObjectWrite for HashMap<Name, V> {
fn to_primitive(&self, update: &mut impl Updater) -> Result<Primitive> {
if self.is_empty() {
Ok(Primitive::Null)
} else {
let mut dict = Dictionary::new();
for (k, v) in self.iter() {
dict.insert(k.clone(), v.to_primitive(update)?);
}
Ok(Primitive::Dictionary(dict))
}
}
}
impl<V: DeepClone> DeepClone for HashMap<Name, V> {
fn deep_clone(&self, cloner: &mut impl Cloner) -> Result<Self> {
self.iter()
.map(|(k, v)| Ok((k.clone(), v.deep_clone(cloner)?)))
.collect()
}
}
impl<T: Object> Object for Option<T> {
fn from_primitive(p: Primitive, resolve: &impl Resolve) -> Result<Self> {
match p {
Primitive::Null => Ok(None),
p => match T::from_primitive(p, resolve) {
Ok(p) => Ok(Some(p)),
Err(PdfError::NullRef { .. }) => Ok(None),
Err(PdfError::FreeObject { .. }) => Ok(None),
Err(e) if resolve.options().allow_error_in_option => {
warn!("ignoring {:?}", e);
Ok(None)
}
Err(e) => Err(e),
},
}
}
}
impl<T: ObjectWrite> ObjectWrite for Option<T> {
fn to_primitive(&self, update: &mut impl Updater) -> Result<Primitive> {
match self {
None => Ok(Primitive::Null),
Some(t) => t.to_primitive(update),
}
}
}
impl<T: DeepClone> DeepClone for Option<T> {
fn deep_clone(&self, cloner: &mut impl Cloner) -> Result<Self> {
match self {
None => Ok(None),
Some(t) => t.deep_clone(cloner).map(Some),
}
}
}
impl<T: Trace> Trace for Option<T> {
fn trace(&self, cb: &mut impl FnMut(PlainRef)) {
if let Some(ref t) = *self {
t.trace(cb)
}
}
}
impl<T: Object> Object for Box<T> {
fn from_primitive(p: Primitive, resolve: &impl Resolve) -> Result<Self> {
T::from_primitive(p, resolve).map(Box::new)
}
}
impl<T: ObjectWrite> ObjectWrite for Box<T> {
fn to_primitive(&self, update: &mut impl Updater) -> Result<Primitive> {
(**self).to_primitive(update)
}
}
impl<T: Trace> Trace for Box<T> {
fn trace(&self, cb: &mut impl FnMut(PlainRef)) {
(**self).trace(cb)
}
}
#[derive(Debug, Clone, DataSize)]
pub enum Either<T, U> {
Left(T),
Right(U)
}
impl<T, U> Object for Either<T, U>
where
T: Object,
U: Object
{
fn from_primitive(p: Primitive, resolve: &impl Resolve) -> Result<Self> {
match T::from_primitive(p.clone(), resolve) {
Ok(left) => Ok(Either::Left(left)),
Err(left_e) => match U::from_primitive(p, resolve) {
Ok(right) => Ok(Either::Right(right)),
Err(right_e) => Err(PdfError::Either { left_t: type_name::<T>(), left_e: left_e.into(), right_t: type_name::<U>(), right_e: right_e.into() })
}
}
}
}
impl<T, U> ObjectWrite for Either<T, U> where T: ObjectWrite, U: ObjectWrite {
fn to_primitive(&self, update: &mut impl Updater) -> Result<Primitive> {
match self {
Either::Left(left) => left.to_primitive(update),
Either::Right(right) => right.to_primitive(update)
}
}
}
impl Object for () {
fn from_primitive(_p: Primitive, _resolve: &impl Resolve) -> Result<Self> {
Ok(())
}
}
impl ObjectWrite for () {
fn to_primitive(&self, _: &mut impl Updater) -> Result<Primitive> {
Ok(Primitive::Null)
}
}
impl Trace for () {}
impl<T, U> Object for (T, U)
where
T: Object,
U: Object,
{
fn from_primitive(p: Primitive, resolve: &impl Resolve) -> Result<Self> {
let arr = p.resolve(resolve)?.into_array()?;
if arr.len() != 2 {
bail!("expected array of length 2 (found {})", arr.len());
}
let [a, b]: [Primitive; 2] = arr.try_into().unwrap();
Ok((
T::from_primitive(a, resolve)?,
U::from_primitive(b, resolve)?,
))
}
}
impl<T, U> ObjectWrite for (T, U)
where
T: ObjectWrite,
U: ObjectWrite,
{
fn to_primitive(&self, update: &mut impl Updater) -> Result<Primitive> {
Ok(Primitive::Array(vec![
self.0.to_primitive(update)?,
self.1.to_primitive(update)?,
]))
}
}
impl<T: Trace, U: Trace> Trace for (T, U) {
fn trace(&self, cb: &mut impl FnMut(PlainRef)) {
self.0.trace(cb);
self.1.trace(cb);
}
}
impl<T: DeepClone> DeepClone for Box<T> {
fn deep_clone(&self, cloner: &mut impl Cloner) -> Result<Self> {
Ok(Box::new((&**self).deep_clone(cloner)?))
}
}
macro_rules! deep_clone_simple {
($($t:ty),*) => (
$(
impl DeepClone for $t {
fn deep_clone(&self, _cloner: &mut impl Cloner) -> Result<Self> {
Ok(self.clone())
}
}
)*
)
}
deep_clone_simple!(
f32,
i32,
u32,
bool,
Name,
(),
Date,
PdfString,
Rectangle,
u8,
Arc<[u8]>,
Vec<u16>
);
impl<A: DeepClone, B: DeepClone> DeepClone for (A, B) {
fn deep_clone(&self, cloner: &mut impl Cloner) -> Result<Self> {
Ok((self.0.deep_clone(cloner)?, self.1.deep_clone(cloner)?))
}
}
#[derive(DataSize)]
pub struct Merged<A, B> {
pub a: Option<A>,
pub b: Option<B>,
}
impl<A, B> Merged<A, B> {
pub fn a(a: A) -> Self {
Merged { a: Some(a), b: None }
}
pub fn b(b: B) -> Self {
Merged { a: None, b: Some(b) }
}
pub fn a_and_b(a: A, b: B) -> Self {
Merged { a: Some(a), b: Some(b) }
}
pub fn none() -> Self {
Merged { a: None, b: None }
}
pub fn merged_ref_a(a: &RcRef<A>) -> Ref<Self> {
Ref { inner: a.inner, _marker: PhantomData }
}
pub fn merged_ref_b(b: &RcRef<B>) -> Ref<Self> {
Ref { inner: b.inner, _marker: PhantomData }
}
}
impl<A, B> RcRef<Merged<A, B>> {
pub fn ref_a(&self) -> Option<Ref<A>> {
if self.a.is_some() {
Some(Ref { inner: self.inner, _marker: PhantomData })
} else {
None
}
}
pub fn ref_b(&self) -> Option<Ref<B>> {
if self.b.is_some() {
Some(Ref { inner: self.inner, _marker: PhantomData })
} else {
None
}
}
}
impl<A: FromDict, B: FromDict> FromDict for Merged<A, B> {
fn from_dict(dict: Dictionary, resolve: &impl Resolve) -> Result<Self> {
let a = A::from_dict(dict.clone(), resolve).ok();
let b = B::from_dict(dict, resolve).ok();
Ok(Merged { a, b })
}
}
impl<A: FromDict + Send + Sync + 'static, B: FromDict + Send + Sync + 'static> Object
for Merged<A, B>
{
fn from_primitive(p: Primitive, resolve: &impl Resolve) -> Result<Self> {
let dict = p.resolve(resolve)?.into_dictionary()?;
Self::from_dict(dict, resolve)
}
}
impl<A: ToDict, B: ToDict> ToDict for Merged<A, B> {
fn to_dict(&self, update: &mut impl Updater) -> Result<Dictionary> {
let a = self
.a
.as_ref()
.map(|a| a.to_dict(update))
.transpose()?
.unwrap_or_default();
let b = self
.b
.as_ref()
.map(|b| b.to_dict(update))
.transpose()?
.unwrap_or_default();
let mut out = a;
out.append(b);
Ok(out)
}
}
impl<A: ToDict, B: ToDict> ObjectWrite for Merged<A, B> {
fn to_primitive(&self, update: &mut impl Updater) -> Result<Primitive> {
self.to_dict(update).map(Primitive::Dictionary)
}
}