Crate pdf_derive
source ·Expand description
pdf_derive
provides a proc macro to derive the Object trait from the pdf
crate.
Usage
There are several ways to derive Object on a struct or enum:
1. Struct from PDF Dictionary
A lot of dictionary types defined in the PDF 1.7 reference have a finite amount of possible
fields. Each of these are usually either required or optional. The latter is achieved by using
a Option<T>
or Vec<T>
as type of a field.
Usually, dictionary types
require that the entry /Type
is some specific string. By default, pdf_derive
assumes that
this should equal the name of the input struct. This can be overridden by setting the Type
attribute equal to either the expected value of the /Type
entry, or to false
in order to
omit the type check completly.
Check similar to that of /Type
can also be specified in the same manner. (but the Type
attribute is special because it accepts a bool).
Examples:
#[derive(Object)]
#[pdf(Type="XObject", Subtype="Image")]
/// A variant of XObject
pub struct ImageDictionary {
#[pdf(key="Width")]
width: i32,
#[pdf(key="Height")]
height: i32,
// [...]
}
This enforces that the dictionary’s /Type
entry is present and equals /XObject
, and that the
/Subtype
entry is present and equals /Image
.
Each field in the struct needs to implement Object
. Implementation is provided already for
common types like i32, f32, usize, bool, String (from Primitive::Name), Option
Lastly, for each field, it’s possible to define a default value by setting the default
attribute to a string that can parse as Rust code.
Example:
#[derive(Object)]
#[pdf(Type = "XRef")]
pub struct XRefInfo {
#[pdf(key = "Filter")]
filter: Vec<StreamFilter>,
#[pdf(key = "Size")]
pub size: i32,
#[pdf(key = "Index", default = "vec![0, size]")]
pub index: Vec<i32>,
// [...]
}
2. Struct from PDF Stream
PDF Streams consist of a stream dictionary along with the stream itself. It is assumed that all
structs that want to derive Object where the primitive it converts from is a stream,
have a field info: T
, where T: Object
, and a field data: Vec<u8>
.
Deriving an Object that converts from Primitive::Stream, the flag is_stream
is required in
the proc macro attributes.
3. Enum from PDF Name
Example:
#[derive(Object, Debug)]
pub enum StreamFilter {
ASCIIHexDecode,
ASCII85Decode,
LZWDecode,
FlateDecode,
JPXDecode,
DCTDecode,
}
In this case, StreamFilter::from_primitive(primitive)
will return Ok(_) only if the primitive
is Primitive::Name
and matches one of the enum variants