1#![deny(missing_docs)]
44
45#[cfg(feature = "pdfa")]
46pub mod pdfa;
47mod types;
48
49use std::collections::BTreeSet;
50use std::fmt::Write;
51
52#[cfg(feature = "pdfa")]
53use pdfa::PdfAExtSchemasWriter;
54
55pub use types::*;
56
57macro_rules! deref {
59 ($a:lifetime, $b:lifetime, $from:ty => $to:ty, $field:ident) => {
60 impl<$a, $b> std::ops::Deref for $from {
61 type Target = $to;
62
63 #[inline]
64 fn deref(&self) -> &Self::Target {
65 &self.$field
66 }
67 }
68
69 impl<$a, $b> std::ops::DerefMut for $from {
70 #[inline]
71 fn deref_mut(&mut self) -> &mut Self::Target {
72 &mut self.$field
73 }
74 }
75 };
76}
77pub(crate) use deref;
78
79#[derive(Default)]
84pub struct XmpWriter<'a> {
85 pub(crate) buf: String,
86 namespaces: BTreeSet<Namespace<'a>>,
87}
88
89impl<'n> XmpWriter<'n> {
90 pub fn new() -> XmpWriter<'n> {
92 Self::default()
93 }
94
95 #[inline]
97 pub fn element<'a>(
98 &'a mut self,
99 name: &'a str,
100 namespace: Namespace<'n>,
101 ) -> Element<'a, 'n> {
102 Element::start(self, name, namespace)
103 }
104
105 pub fn finish(self, about: Option<&str>) -> String {
107 let mut buf = String::with_capacity(280 + self.buf.len());
108 buf.push_str("<?xpacket begin=\"\u{feff}\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>");
109
110 write!(
111 &mut buf,
112 "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\"xmp-writer\"><rdf:RDF xmlns:rdf=\"{}\"><rdf:Description rdf:about=\"{}\"",
113 Namespace::Rdf.url(),
114 about.unwrap_or(""),
115 )
116 .unwrap();
117
118 for namespace in self.namespaces.into_iter().filter(|ns| &Namespace::Rdf != ns) {
119 write!(&mut buf, " xmlns:{}=\"{}\" ", namespace.prefix(), namespace.url())
120 .unwrap();
121 }
122
123 buf.push('>');
124 buf.push_str(&self.buf);
125 buf.push_str("</rdf:Description></rdf:RDF></x:xmpmeta><?xpacket end=\"r\"?>");
126 buf
127 }
128}
129
130impl XmpWriter<'_> {
132 pub fn contributor<'a>(
137 &mut self,
138 contributor: impl IntoIterator<Item = &'a str>,
139 ) -> &mut Self {
140 self.element("contributor", Namespace::DublinCore)
141 .unordered_array(contributor);
142 self
143 }
144
145 pub fn coverage(&mut self, coverage: &str) -> &mut Self {
149 self.element("coverage", Namespace::DublinCore).value(coverage);
150 self
151 }
152
153 pub fn creator<'a>(
157 &mut self,
158 creator: impl IntoIterator<Item = &'a str>,
159 ) -> &mut Self {
160 self.element("creator", Namespace::DublinCore).ordered_array(creator);
161 self
162 }
163
164 pub fn date(&mut self, date: impl IntoIterator<Item = DateTime>) -> &mut Self {
168 self.element("date", Namespace::DublinCore).ordered_array(date);
169 self
170 }
171
172 pub fn description<'a>(
176 &mut self,
177 description: impl IntoIterator<Item = (Option<LangId<'a>>, &'a str)>,
178 ) -> &mut Self {
179 self.element("description", Namespace::DublinCore)
180 .language_alternative(description);
181 self
182 }
183
184 pub fn format(&mut self, mime: &str) -> &mut Self {
188 self.element("format", Namespace::DublinCore).value(mime);
189 self
190 }
191
192 pub fn identifier(&mut self, id: &str) -> &mut Self {
196 self.element("identifier", Namespace::DublinCore).value(id);
197 self
198 }
199
200 pub fn language<'a>(
204 &mut self,
205 lang: impl IntoIterator<Item = LangId<'a>>,
206 ) -> &mut Self {
207 self.element("language", Namespace::DublinCore).unordered_array(lang);
208 self
209 }
210
211 pub fn publisher<'a>(
215 &mut self,
216 publisher: impl IntoIterator<Item = &'a str>,
217 ) -> &mut Self {
218 self.element("publisher", Namespace::DublinCore)
219 .unordered_array(publisher);
220 self
221 }
222
223 pub fn relation<'a>(
227 &mut self,
228 relation: impl IntoIterator<Item = &'a str>,
229 ) -> &mut Self {
230 self.element("relation", Namespace::DublinCore)
231 .unordered_array(relation);
232 self
233 }
234
235 pub fn rights<'a>(
239 &mut self,
240 rights: impl IntoIterator<Item = (Option<LangId<'a>>, &'a str)>,
241 ) -> &mut Self {
242 self.element("rights", Namespace::DublinCore)
243 .language_alternative(rights);
244 self
245 }
246
247 pub fn source(&mut self, source: &str) -> &mut Self {
251 self.element("source", Namespace::DublinCore).value(source);
252 self
253 }
254
255 pub fn subject<'a>(
259 &mut self,
260 subject: impl IntoIterator<Item = &'a str>,
261 ) -> &mut Self {
262 self.element("subject", Namespace::DublinCore)
263 .unordered_array(subject);
264 self
265 }
266
267 pub fn title<'a>(
271 &mut self,
272 title: impl IntoIterator<Item = (Option<LangId<'a>>, &'a str)>,
273 ) -> &mut Self {
274 self.element("title", Namespace::DublinCore)
275 .language_alternative(title);
276 self
277 }
278
279 pub fn type_<'a>(&mut self, kind: impl IntoIterator<Item = &'a str>) -> &mut Self {
284 self.element("type", Namespace::DublinCore).unordered_array(kind);
285 self
286 }
287}
288
289impl<'n> XmpWriter<'n> {
291 pub fn base_url(&mut self, url: &str) -> &mut Self {
295 self.element("BaseURL", Namespace::Xmp).value(url);
296 self
297 }
298
299 pub fn create_date(&mut self, date: DateTime) -> &mut Self {
303 self.element("CreateDate", Namespace::Xmp).value(date);
304 self
305 }
306
307 pub fn creator_tool(&mut self, tool: &str) -> &mut Self {
311 self.element("CreatorTool", Namespace::Xmp).value(tool);
312 self
313 }
314
315 pub fn xmp_identifier<'a>(
320 &mut self,
321 id: impl IntoIterator<Item = &'a str>,
322 ) -> &mut Self {
323 self.element("Identifier", Namespace::Xmp).unordered_array(id);
324 self
325 }
326
327 pub fn label(&mut self, label: &str) -> &mut Self {
331 self.element("Label", Namespace::Xmp).value(label);
332 self
333 }
334
335 pub fn metadata_date(&mut self, date: DateTime) -> &mut Self {
339 self.element("MetadataDate", Namespace::Xmp).value(date);
340 self
341 }
342
343 pub fn modify_date(&mut self, date: DateTime) -> &mut Self {
347 self.element("ModifyDate", Namespace::Xmp).value(date);
348 self
349 }
350
351 pub fn nickname(&mut self, nickname: &str) -> &mut Self {
355 self.element("Nickname", Namespace::Xmp).value(nickname);
356 self
357 }
358
359 pub fn rating(&mut self, rating: i64) -> &mut Self {
363 self.element("Rating", Namespace::Xmp).value(rating);
364 self
365 }
366
367 pub fn thumbnails(&mut self) -> ThumbnailsWriter<'_, 'n> {
371 ThumbnailsWriter::start(
372 self.element("Thumbnails", Namespace::Xmp)
373 .array(RdfCollectionType::Alt),
374 )
375 }
376}
377
378impl XmpWriter<'_> {
380 pub fn certificate(&mut self, cert: &str) -> &mut Self {
384 self.element("Certificate", Namespace::XmpRights).value(cert);
385 self
386 }
387
388 pub fn marked(&mut self, marked: bool) -> &mut Self {
393 self.element("Marked", Namespace::XmpRights).value(marked);
394 self
395 }
396
397 pub fn owner<'a>(&mut self, owner: impl IntoIterator<Item = &'a str>) -> &mut Self {
401 self.element("Owner", Namespace::XmpRights).unordered_array(owner);
402 self
403 }
404
405 pub fn usage_terms<'a>(
409 &mut self,
410 terms: impl IntoIterator<Item = (Option<LangId<'a>>, &'a str)>,
411 ) -> &mut Self {
412 self.element("UsageTerms", Namespace::XmpRights)
413 .language_alternative(terms);
414 self
415 }
416
417 pub fn web_statement(&mut self, statement: &str) -> &mut Self {
421 self.element("WebStatement", Namespace::XmpRights).value(statement);
422 self
423 }
424}
425
426impl<'n> XmpWriter<'n> {
428 pub fn derived_from(&mut self) -> ResourceRefWriter<'_, 'n> {
432 ResourceRefWriter::start(self.element("DerivedFrom", Namespace::XmpMedia).obj())
433 }
434
435 pub fn document_id(&mut self, id: &str) -> &mut Self {
440 self.element("DocumentID", Namespace::XmpMedia).value(id);
441 self
442 }
443
444 pub fn history(&mut self) -> ResourceEventsWriter<'_, 'n> {
448 ResourceEventsWriter::start(
449 self.element("History", Namespace::XmpMedia)
450 .array(RdfCollectionType::Seq),
451 )
452 }
453
454 pub fn ingredients(&mut self) -> ResourceRefsWriter<'_, 'n> {
458 ResourceRefsWriter::start(
459 self.element("Ingredients", Namespace::XmpMedia)
460 .array(RdfCollectionType::Bag),
461 )
462 }
463
464 pub fn instance_id(&mut self, id: &str) -> &mut Self {
469 self.element("InstanceID", Namespace::XmpMedia).value(id);
470 self
471 }
472
473 pub fn managed_from(&mut self) -> ResourceRefWriter<'_, 'n> {
477 ResourceRefWriter::start(self.element("ManagedFrom", Namespace::XmpMedia).obj())
478 }
479
480 pub fn manager(&mut self, manager: &str) -> &mut Self {
484 self.element("Manager", Namespace::XmpMedia).value(manager);
485 self
486 }
487
488 pub fn manage_to(&mut self, uri: &str) -> &mut Self {
492 self.element("ManageTo", Namespace::XmpMedia).value(uri);
493 self
494 }
495
496 pub fn manage_ui(&mut self, uri: &str) -> &mut Self {
500 self.element("ManageUI", Namespace::XmpMedia).value(uri);
501 self
502 }
503
504 pub fn manager_variant(&mut self, variant: &str) -> &mut Self {
508 self.element("ManagerVariant", Namespace::XmpMedia).value(variant);
509 self
510 }
511
512 pub fn original_doc_id(&mut self, id: &str) -> &mut Self {
516 self.element("OriginalDocumentID", Namespace::XmpMedia).value(id);
517 self
518 }
519
520 pub fn pantry(&mut self) -> PantryWriter<'_, 'n> {
525 PantryWriter::start(
526 self.element("Pantry", Namespace::XmpMedia)
527 .array(RdfCollectionType::Bag),
528 )
529 }
530
531 pub fn rendition_class(&mut self, class: RenditionClass) -> &mut Self {
536 self.element("RenditionClass", Namespace::XmpMedia).value(class);
537 self
538 }
539
540 pub fn rendition_params(&mut self, params: &str) -> &mut Self {
544 self.element("RenditionParams", Namespace::XmpMedia).value(params);
545 self
546 }
547
548 pub fn version_id(&mut self, id: &str) -> &mut Self {
552 self.element("VersionID", Namespace::XmpMedia).value(id);
553 self
554 }
555
556 pub fn version_ref(&mut self) -> VersionsWriter<'_, 'n> {
560 VersionsWriter::start(
561 self.element("Versions", Namespace::XmpMedia)
562 .array(RdfCollectionType::Seq),
563 )
564 }
565}
566
567impl<'n> XmpWriter<'n> {
569 pub fn jobs(&mut self) -> JobsWriter<'_, 'n> {
573 JobsWriter::start(
574 self.element("Job", Namespace::XmpJobManagement)
575 .array(RdfCollectionType::Bag),
576 )
577 }
578}
579
580impl<'n> XmpWriter<'n> {
582 pub fn colorants(&mut self) -> ColorantsWriter<'_, 'n> {
586 ColorantsWriter::start(
587 self.element("Colorants", Namespace::XmpPaged)
588 .array(RdfCollectionType::Seq),
589 )
590 }
591
592 pub fn fonts(&mut self) -> FontsWriter<'_, 'n> {
596 FontsWriter::start(
597 self.element("Fonts", Namespace::XmpPaged)
598 .array(RdfCollectionType::Bag),
599 )
600 }
601
602 pub fn max_page_size(&mut self) -> DimensionsWriter<'_, 'n> {
606 DimensionsWriter::start(self.element("MaxPageSize", Namespace::XmpPaged).obj())
607 }
608
609 pub fn num_pages(&mut self, num: u32) -> &mut Self {
613 self.element("NPages", Namespace::XmpPaged).value(num as i64);
614 self
615 }
616
617 pub fn plate_names<'a>(
621 &mut self,
622 names: impl IntoIterator<Item = &'a str>,
623 ) -> &mut Self {
624 self.element("PlateNames", Namespace::XmpPaged).ordered_array(names);
625 self
626 }
627}
628
629impl XmpWriter<'_> {
633 pub fn idq_scheme(&mut self, scheme: &str) -> &mut Self {
637 self.element("Scheme", Namespace::XmpIdq).value(scheme);
638 self
639 }
640}
641
642impl XmpWriter<'_> {
644 pub fn pdf_keywords(&mut self, keywords: &str) -> &mut Self {
648 self.element("Keywords", Namespace::AdobePdf).value(keywords);
649 self
650 }
651
652 pub fn pdf_version(&mut self, version: &str) -> &mut Self {
657 self.element("PDFVersion", Namespace::AdobePdf).value(version);
658 self
659 }
660
661 pub fn producer(&mut self, producer: &str) -> &mut Self {
665 self.element("Producer", Namespace::AdobePdf).value(producer);
666 self
667 }
668
669 pub fn trapped(&mut self, trapped: bool) -> &mut Self {
673 self.element("Trapped", Namespace::AdobePdf).value(trapped);
674 self
675 }
676}
677
678impl<'n> XmpWriter<'n> {
680 #[cfg(feature = "pdfa")]
685 pub fn pdfa_part(&mut self, part: i32) -> &mut Self {
686 self.element("part", Namespace::PdfAId).value(part);
687 self
688 }
689
690 #[cfg(feature = "pdfa")]
694 pub fn pdfa_amd(&mut self, amd: &str) -> &mut Self {
695 self.element("amd", Namespace::PdfAId).value(amd);
696 self
697 }
698
699 #[cfg(feature = "pdfa")]
703 pub fn pdfa_corr(&mut self, corr: &str) -> &mut Self {
704 self.element("corr", Namespace::PdfAId).value(corr);
705 self
706 }
707
708 #[cfg(feature = "pdfa")]
712 pub fn extension_schemas(&mut self) -> PdfAExtSchemasWriter<'_, 'n> {
713 PdfAExtSchemasWriter::start(
714 self.element("schemas", Namespace::PdfAExtension)
715 .array(RdfCollectionType::Bag),
716 )
717 }
718
719 #[cfg(feature = "pdfa")]
724 pub fn pdfa_conformance(&mut self, conformance: &str) -> &mut Self {
725 self.element("conformance", Namespace::PdfAId).value(conformance);
726 self
727 }
728
729 #[cfg(feature = "pdfa")]
733 pub fn pdfa_rev(&mut self, rev: i32) -> &mut Self {
734 self.element("rev", Namespace::PdfAId).value(rev);
735 self
736 }
737
738 pub fn pdfx_version(&mut self, version: &str) -> &mut Self {
743 self.element("GTS_PDFXVersion", Namespace::PdfXId).value(version);
744 self
745 }
746
747 pub fn pdfua_part(&mut self, part: i32) -> &mut Self {
752 self.element("part", Namespace::PdfUAId).value(part);
753 self
754 }
755
756 pub fn pdfua_amd(&mut self, amd: &str) -> &mut Self {
760 self.element("amd", Namespace::PdfUAId).value(amd);
761 self
762 }
763
764 pub fn pdfua_corr(&mut self, corr: &str) -> &mut Self {
768 self.element("corr", Namespace::PdfUAId).value(corr);
769 self
770 }
771}
772
773pub struct ThumbnailWriter<'a, 'n: 'a> {
777 stc: Struct<'a, 'n>,
778}
779
780impl<'a, 'n: 'a> ThumbnailWriter<'a, 'n> {
781 fn start(stc: Struct<'a, 'n>) -> Self {
782 Self { stc }
783 }
784
785 pub fn format(&mut self, format: &str) -> &mut Self {
788 self.stc.element("format", Namespace::XmpImage).value(format);
789 self
790 }
791
792 pub fn format_jpeg(&mut self) -> &mut Self {
794 self.format("JPEG")
795 }
796
797 pub fn width(&mut self, width: u64) -> &mut Self {
799 self.stc.element("width", Namespace::XmpImage).value(width as i64);
800 self
801 }
802
803 pub fn height(&mut self, height: u64) -> &mut Self {
805 self.stc.element("height", Namespace::XmpImage).value(height as i64);
806 self
807 }
808
809 pub fn image(&mut self, image: &str) -> &mut Self {
813 self.stc.element("image", Namespace::XmpImage).value(image);
814 self
815 }
816}
817
818deref!('a, 'n, ThumbnailWriter<'a, 'n> => Struct<'a, 'n>, stc);
819
820pub struct ThumbnailsWriter<'a, 'n: 'a> {
824 array: Array<'a, 'n>,
825}
826
827impl<'a, 'n: 'a> ThumbnailsWriter<'a, 'n> {
828 fn start(array: Array<'a, 'n>) -> Self {
829 Self { array }
830 }
831
832 pub fn add_thumbnail(&mut self) -> ThumbnailWriter<'_, 'n> {
834 ThumbnailWriter::start(self.array.element().obj())
835 }
836}
837
838deref!('a, 'n, ThumbnailsWriter<'a, 'n> => Array<'a, 'n>, array);
839
840pub struct ResourceRefWriter<'a, 'n: 'a> {
844 stc: Struct<'a, 'n>,
845}
846
847impl<'a, 'n: 'a> ResourceRefWriter<'a, 'n> {
848 fn start(stc: Struct<'a, 'n>) -> Self {
849 Self { stc }
850 }
851
852 pub fn alternate_paths<'b>(
856 &mut self,
857 paths: impl IntoIterator<Item = &'b str>,
858 ) -> &mut Self {
859 self.stc
860 .element("alternatePaths", Namespace::XmpResourceRef)
861 .ordered_array(paths);
862 self
863 }
864
865 pub fn document_id(&mut self, id: &str) -> &mut Self {
869 self.stc.element("documentID", Namespace::XmpResourceRef).value(id);
870 self
871 }
872
873 pub fn file_path(&mut self, path: &str) -> &mut Self {
877 self.stc.element("filePath", Namespace::XmpResourceRef).value(path);
878 self
879 }
880
881 pub fn instance_id(&mut self, id: &str) -> &mut Self {
885 self.stc.element("instanceID", Namespace::XmpResourceRef).value(id);
886 self
887 }
888
889 pub fn last_modify_date(&mut self, date: DateTime) -> &mut Self {
893 self.stc
894 .element("lastModifyDate", Namespace::XmpResourceRef)
895 .value(date);
896 self
897 }
898
899 pub fn manager(&mut self, manager: &str) -> &mut Self {
903 self.stc.element("manager", Namespace::XmpResourceRef).value(manager);
904 self
905 }
906
907 pub fn manager_variant(&mut self, variant: &str) -> &mut Self {
911 self.stc
912 .element("managerVariant", Namespace::XmpResourceRef)
913 .value(variant);
914 self
915 }
916
917 pub fn manage_to(&mut self, uri: &str) -> &mut Self {
921 self.stc.element("manageTo", Namespace::XmpResourceRef).value(uri);
922 self
923 }
924
925 pub fn manage_ui(&mut self, uri: &str) -> &mut Self {
929 self.stc.element("manageTo", Namespace::XmpResourceRef).value(uri);
930 self
931 }
932
933 pub fn mask_markers(&mut self, markers: MaskMarkers) -> &mut Self {
937 self.stc
938 .element("maskMarkers", Namespace::XmpResourceRef)
939 .value(markers);
940 self
941 }
942
943 pub fn part_mapping(&mut self, mapping: &str) -> &mut Self {
947 self.stc
948 .element("partMapping", Namespace::XmpResourceRef)
949 .value(mapping);
950 self
951 }
952
953 pub fn rendition_class(&mut self, rendition: RenditionClass) -> &mut Self {
958 self.stc
959 .element("renditionClass", Namespace::XmpResourceRef)
960 .value(rendition);
961 self
962 }
963
964 pub fn rendition_params(&mut self, params: &str) -> &mut Self {
969 self.stc
970 .element("renditionParams", Namespace::XmpResourceRef)
971 .value(params);
972 self
973 }
974
975 pub fn to_part(&mut self, part: &str) -> &mut Self {
980 self.stc.element("toPart", Namespace::XmpResourceRef).value(part);
981 self
982 }
983
984 pub fn version_id(&mut self, id: &str) -> &mut Self {
988 self.stc.element("versionID", Namespace::XmpResourceRef).value(id);
989 self
990 }
991}
992
993deref!('a, 'n, ResourceRefWriter<'a, 'n> => Struct<'a, 'n>, stc);
994
995pub struct ResourceRefsWriter<'a, 'n: 'a> {
999 array: Array<'a, 'n>,
1000}
1001
1002impl<'a, 'n: 'a> ResourceRefsWriter<'a, 'n> {
1003 fn start(array: Array<'a, 'n>) -> Self {
1004 Self { array }
1005 }
1006
1007 pub fn add_ref(&mut self) -> ResourceRefWriter<'_, 'n> {
1009 ResourceRefWriter::start(self.array.element().obj())
1010 }
1011}
1012
1013deref!('a, 'n, ResourceRefsWriter<'a, 'n> => Array<'a, 'n>, array);
1014
1015pub struct ResourceEventWriter<'a, 'n: 'a> {
1019 stc: Struct<'a, 'n>,
1020}
1021
1022impl<'a, 'n: 'a> ResourceEventWriter<'a, 'n> {
1023 fn start(stc: Struct<'a, 'n>) -> Self {
1024 Self { stc }
1025 }
1026
1027 pub fn action(&mut self, action: ResourceEventAction) -> &mut Self {
1031 self.stc.element("action", Namespace::XmpResourceEvent).value(action);
1032 self
1033 }
1034
1035 pub fn changed(&mut self, parts: &str) -> &mut Self {
1039 self.stc.element("changed", Namespace::XmpResourceEvent).value(parts);
1040 self
1041 }
1042 pub fn instance_id(&mut self, id: &str) -> &mut Self {
1046 self.stc.element("instanceID", Namespace::XmpResourceEvent).value(id);
1047 self
1048 }
1049
1050 pub fn parameters(&mut self, params: &str) -> &mut Self {
1054 self.stc
1055 .element("parameters", Namespace::XmpResourceEvent)
1056 .value(params);
1057 self
1058 }
1059
1060 pub fn software_agent(&mut self, agent: &str) -> &mut Self {
1064 self.stc
1065 .element("softwareAgent", Namespace::XmpResourceEvent)
1066 .value(agent);
1067 self
1068 }
1069
1070 pub fn when(&mut self, date: DateTime) -> &mut Self {
1074 self.stc.element("when", Namespace::XmpResourceEvent).value(date);
1075 self
1076 }
1077}
1078
1079deref!('a, 'n, ResourceEventWriter<'a, 'n> => Struct<'a, 'n>, stc);
1080
1081pub struct ResourceEventsWriter<'a, 'n: 'a> {
1085 array: Array<'a, 'n>,
1086}
1087
1088impl<'a, 'n: 'a> ResourceEventsWriter<'a, 'n> {
1089 fn start(array: Array<'a, 'n>) -> Self {
1090 Self { array }
1091 }
1092
1093 pub fn add_event(&mut self) -> ResourceEventWriter<'_, 'n> {
1095 ResourceEventWriter::start(self.array.element().obj())
1096 }
1097}
1098
1099deref!('a, 'n, ResourceEventsWriter<'a, 'n> => Array<'a, 'n>, array);
1100
1101pub struct PantryItemWriter<'a, 'n: 'a> {
1106 stc: Struct<'a, 'n>,
1107}
1108
1109impl<'a, 'n: 'a> PantryItemWriter<'a, 'n> {
1110 fn start(stc: Struct<'a, 'n>) -> Self {
1111 Self { stc }
1112 }
1113
1114 pub fn instance_id(&mut self, id: &str) -> &mut Self {
1116 self.stc.element("instanceID", Namespace::XmpMedia).value(id);
1117 self
1118 }
1119}
1120
1121deref!('a, 'n, PantryItemWriter<'a, 'n> => Struct<'a, 'n>, stc);
1122
1123pub struct PantryWriter<'a, 'n: 'a> {
1125 array: Array<'a, 'n>,
1126}
1127
1128impl<'a, 'n: 'a> PantryWriter<'a, 'n> {
1129 fn start(array: Array<'a, 'n>) -> Self {
1130 Self { array }
1131 }
1132
1133 pub fn add_item(&mut self) -> PantryItemWriter<'_, 'n> {
1135 PantryItemWriter::start(self.array.element().obj())
1136 }
1137}
1138
1139deref!('a, 'n, PantryWriter<'a, 'n> => Array<'a, 'n>, array);
1140
1141pub struct VersionWriter<'a, 'n: 'a> {
1145 stc: Struct<'a, 'n>,
1146}
1147
1148impl<'a, 'n: 'a> VersionWriter<'a, 'n> {
1149 fn start(stc: Struct<'a, 'n>) -> Self {
1150 Self { stc }
1151 }
1152
1153 pub fn comments(&mut self, comments: &str) -> &mut Self {
1157 self.stc.element("comments", Namespace::XmpVersion).value(comments);
1158 self
1159 }
1160
1161 pub fn event(&mut self) -> ResourceEventWriter<'_, 'n> {
1165 ResourceEventWriter::start(self.stc.element("event", Namespace::XmpVersion).obj())
1166 }
1167
1168 pub fn modifier(&mut self, modifier: &str) -> &mut Self {
1172 self.stc.element("modifier", Namespace::XmpVersion).value(modifier);
1173 self
1174 }
1175
1176 pub fn modify_date(&mut self, date: DateTime) -> &mut Self {
1180 self.stc.element("modifyDate", Namespace::XmpVersion).value(date);
1181 self
1182 }
1183
1184 pub fn version(&mut self, version: &str) -> &mut Self {
1188 self.stc.element("version", Namespace::XmpVersion).value(version);
1189 self
1190 }
1191}
1192
1193deref!('a, 'n, VersionWriter<'a, 'n> => Struct<'a, 'n>, stc);
1194
1195pub struct VersionsWriter<'a, 'n: 'a> {
1199 array: Array<'a, 'n>,
1200}
1201
1202impl<'a, 'n: 'a> VersionsWriter<'a, 'n> {
1203 fn start(array: Array<'a, 'n>) -> Self {
1204 Self { array }
1205 }
1206
1207 pub fn add_version(&mut self) -> VersionWriter<'_, 'n> {
1209 VersionWriter::start(self.array.element().obj())
1210 }
1211}
1212
1213deref!('a, 'n, VersionsWriter<'a, 'n> => Array<'a, 'n>, array);
1214
1215pub struct JobWriter<'a, 'n: 'a> {
1219 stc: Struct<'a, 'n>,
1220}
1221
1222impl<'a, 'n: 'a> JobWriter<'a, 'n> {
1223 fn start(stc: Struct<'a, 'n>) -> Self {
1224 Self { stc }
1225 }
1226
1227 pub fn id(&mut self, id: &str) -> &mut Self {
1231 self.stc.element("id", Namespace::XmpJob).value(id);
1232 self
1233 }
1234
1235 pub fn name(&mut self, name: &str) -> &mut Self {
1239 self.stc.element("name", Namespace::XmpJob).value(name);
1240 self
1241 }
1242
1243 pub fn url(&mut self, url: &str) -> &mut Self {
1247 self.stc.element("url", Namespace::XmpJob).value(url);
1248 self
1249 }
1250}
1251
1252deref!('a, 'n, JobWriter<'a, 'n> => Struct<'a, 'n>, stc);
1253
1254pub struct JobsWriter<'a, 'n: 'a> {
1258 array: Array<'a, 'n>,
1259}
1260
1261impl<'a, 'n: 'a> JobsWriter<'a, 'n> {
1262 fn start(array: Array<'a, 'n>) -> Self {
1263 Self { array }
1264 }
1265
1266 pub fn add_job(&mut self) -> JobWriter<'_, 'n> {
1268 JobWriter::start(self.array.element().obj())
1269 }
1270}
1271
1272deref!('a, 'n, JobsWriter<'a, 'n> => Array<'a, 'n>, array);
1273
1274pub struct ColorantWriter<'a, 'n: 'a> {
1278 stc: Struct<'a, 'n>,
1279}
1280
1281impl<'a, 'n: 'a> ColorantWriter<'a, 'n> {
1282 fn start(stc: Struct<'a, 'n>) -> Self {
1283 Self { stc }
1284 }
1285
1286 pub fn type_(&mut self, kind: ColorantType) -> &mut Self {
1290 self.stc.element("type", Namespace::XmpColorant).value(kind);
1291 self
1292 }
1293
1294 pub fn swatch_name(&mut self, name: &str) -> &mut Self {
1298 self.stc.element("swatchName", Namespace::XmpColorant).value(name);
1299 self
1300 }
1301
1302 pub fn colorant_mode(&mut self, mode: ColorantMode) -> &mut Self {
1306 self.stc.element("colorantMode", Namespace::XmpColorant).value(mode);
1307 self
1308 }
1309
1310 pub fn l(&mut self, l: f64) -> &mut Self {
1314 self.stc.element("L", Namespace::XmpColorant).value(l);
1315 self
1316 }
1317
1318 pub fn a(&mut self, a: i32) -> &mut Self {
1322 self.stc.element("A", Namespace::XmpColorant).value(a);
1323 self
1324 }
1325
1326 pub fn b(&mut self, b: i32) -> &mut Self {
1330 self.stc.element("B", Namespace::XmpColorant).value(b);
1331 self
1332 }
1333
1334 pub fn black(&mut self, black: f64) -> &mut Self {
1338 self.stc.element("black", Namespace::XmpColorant).value(black);
1339 self
1340 }
1341
1342 pub fn cyan(&mut self, cyan: f64) -> &mut Self {
1346 self.stc.element("cyan", Namespace::XmpColorant).value(cyan);
1347 self
1348 }
1349
1350 pub fn magenta(&mut self, magenta: f64) -> &mut Self {
1354 self.stc.element("magenta", Namespace::XmpColorant).value(magenta);
1355 self
1356 }
1357
1358 pub fn yellow(&mut self, yellow: f64) -> &mut Self {
1362 self.stc.element("yellow", Namespace::XmpColorant).value(yellow);
1363 self
1364 }
1365
1366 pub fn red(&mut self, red: i32) -> &mut Self {
1370 self.stc.element("red", Namespace::XmpColorant).value(red);
1371 self
1372 }
1373
1374 pub fn green(&mut self, green: i32) -> &mut Self {
1378 self.stc.element("green", Namespace::XmpColorant).value(green);
1379 self
1380 }
1381
1382 pub fn blue(&mut self, blue: i32) -> &mut Self {
1386 self.stc.element("blue", Namespace::XmpColorant).value(blue);
1387 self
1388 }
1389}
1390
1391deref!('a, 'n, ColorantWriter<'a, 'n> => Struct<'a, 'n>, stc);
1392
1393pub struct ColorantsWriter<'a, 'n: 'a> {
1397 array: Array<'a, 'n>,
1398}
1399
1400impl<'a, 'n> ColorantsWriter<'a, 'n> {
1401 fn start(array: Array<'a, 'n>) -> Self {
1402 Self { array }
1403 }
1404
1405 pub fn add_colorant(&mut self) -> ColorantWriter<'_, 'n> {
1407 ColorantWriter::start(self.array.element().obj())
1408 }
1409}
1410
1411deref!('a, 'n, ColorantsWriter<'a, 'n> => Array<'a, 'n>, array);
1412
1413pub struct DimensionsWriter<'a, 'n: 'a> {
1417 stc: Struct<'a, 'n>,
1418}
1419
1420impl<'a, 'n> DimensionsWriter<'a, 'n> {
1421 fn start(stc: Struct<'a, 'n>) -> Self {
1422 Self { stc }
1423 }
1424
1425 pub fn width(&mut self, width: f64) -> &mut Self {
1429 self.stc.element("w", Namespace::XmpDimensions).value(width);
1430 self
1431 }
1432
1433 pub fn height(&mut self, height: f64) -> &mut Self {
1437 self.stc.element("h", Namespace::XmpDimensions).value(height);
1438 self
1439 }
1440
1441 pub fn unit(&mut self, unit: DimensionUnit) -> &mut Self {
1445 self.stc.element("unit", Namespace::XmpDimensions).value(unit);
1446 self
1447 }
1448}
1449
1450deref!('a, 'n, DimensionsWriter<'a, 'n> => Struct<'a, 'n>, stc);
1451
1452pub struct FontWriter<'a, 'n: 'a> {
1456 stc: Struct<'a, 'n>,
1457}
1458
1459impl<'a, 'n: 'a> FontWriter<'a, 'n> {
1460 fn start(stc: Struct<'a, 'n>) -> Self {
1461 Self { stc }
1462 }
1463
1464 pub fn child_font_files<'b>(
1468 &mut self,
1469 files: impl IntoIterator<Item = &'b str>,
1470 ) -> &mut Self {
1471 self.stc
1472 .element("childFontFiles", Namespace::XmpFont)
1473 .ordered_array(files);
1474 self
1475 }
1476
1477 pub fn composite(&mut self, composite: bool) -> &mut Self {
1481 self.stc.element("composite", Namespace::XmpFont).value(composite);
1482 self
1483 }
1484
1485 pub fn font_face(&mut self, face: &str) -> &mut Self {
1489 self.stc.element("fontFace", Namespace::XmpFont).value(face);
1490 self
1491 }
1492
1493 pub fn font_family(&mut self, family: &str) -> &mut Self {
1497 self.stc.element("fontFamily", Namespace::XmpFont).value(family);
1498 self
1499 }
1500
1501 pub fn font_file(&mut self, file_name: &str) -> &mut Self {
1505 self.stc.element("fontFileName", Namespace::XmpFont).value(file_name);
1506 self
1507 }
1508
1509 pub fn font_name(&mut self, name: &str) -> &mut Self {
1513 self.stc.element("fontName", Namespace::XmpFont).value(name);
1514 self
1515 }
1516
1517 pub fn font_type(&mut self, font_type: FontType) -> &mut Self {
1521 self.stc.element("fontType", Namespace::XmpFont).value(font_type);
1522 self
1523 }
1524
1525 pub fn version_string(&mut self, version: &str) -> &mut Self {
1534 self.stc.element("versionString", Namespace::XmpFont).value(version);
1535 self
1536 }
1537}
1538
1539deref!('a, 'n, FontWriter<'a, 'n> => Struct<'a, 'n>, stc);
1540
1541pub struct FontsWriter<'a, 'n: 'a> {
1545 array: Array<'a, 'n>,
1546}
1547
1548impl<'a, 'n: 'a> FontsWriter<'a, 'n> {
1549 fn start(array: Array<'a, 'n>) -> Self {
1550 Self { array }
1551 }
1552
1553 pub fn add_font(&mut self) -> FontWriter<'_, 'n> {
1555 FontWriter::start(self.array.element().obj())
1556 }
1557}
1558
1559deref!('a, 'n, FontsWriter<'a, 'n> => Array<'a, 'n>, array);