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 {
761 self.element("amd", Namespace::PdfUAId).value(amd);
762 self
763 }
764
765 pub fn pdfua_corr(&mut self, corr: &str) -> &mut Self {
772 self.element("corr", Namespace::PdfUAId).value(corr);
773 self
774 }
775
776 pub fn pdfua_rev(&mut self, rev: i32) -> &mut Self {
781 self.element("rev", Namespace::PdfUAId).value(rev);
782 self
783 }
784}
785
786pub struct ThumbnailWriter<'a, 'n: 'a> {
790 stc: Struct<'a, 'n>,
791}
792
793impl<'a, 'n: 'a> ThumbnailWriter<'a, 'n> {
794 fn start(stc: Struct<'a, 'n>) -> Self {
795 Self { stc }
796 }
797
798 pub fn format(&mut self, format: &str) -> &mut Self {
801 self.stc.element("format", Namespace::XmpImage).value(format);
802 self
803 }
804
805 pub fn format_jpeg(&mut self) -> &mut Self {
807 self.format("JPEG")
808 }
809
810 pub fn width(&mut self, width: u64) -> &mut Self {
812 self.stc.element("width", Namespace::XmpImage).value(width as i64);
813 self
814 }
815
816 pub fn height(&mut self, height: u64) -> &mut Self {
818 self.stc.element("height", Namespace::XmpImage).value(height as i64);
819 self
820 }
821
822 pub fn image(&mut self, image: &str) -> &mut Self {
826 self.stc.element("image", Namespace::XmpImage).value(image);
827 self
828 }
829}
830
831deref!('a, 'n, ThumbnailWriter<'a, 'n> => Struct<'a, 'n>, stc);
832
833pub struct ThumbnailsWriter<'a, 'n: 'a> {
837 array: Array<'a, 'n>,
838}
839
840impl<'a, 'n: 'a> ThumbnailsWriter<'a, 'n> {
841 fn start(array: Array<'a, 'n>) -> Self {
842 Self { array }
843 }
844
845 pub fn add_thumbnail(&mut self) -> ThumbnailWriter<'_, 'n> {
847 ThumbnailWriter::start(self.array.element().obj())
848 }
849}
850
851deref!('a, 'n, ThumbnailsWriter<'a, 'n> => Array<'a, 'n>, array);
852
853pub struct ResourceRefWriter<'a, 'n: 'a> {
857 stc: Struct<'a, 'n>,
858}
859
860impl<'a, 'n: 'a> ResourceRefWriter<'a, 'n> {
861 fn start(stc: Struct<'a, 'n>) -> Self {
862 Self { stc }
863 }
864
865 pub fn alternate_paths<'b>(
869 &mut self,
870 paths: impl IntoIterator<Item = &'b str>,
871 ) -> &mut Self {
872 self.stc
873 .element("alternatePaths", Namespace::XmpResourceRef)
874 .ordered_array(paths);
875 self
876 }
877
878 pub fn document_id(&mut self, id: &str) -> &mut Self {
882 self.stc.element("documentID", Namespace::XmpResourceRef).value(id);
883 self
884 }
885
886 pub fn file_path(&mut self, path: &str) -> &mut Self {
890 self.stc.element("filePath", Namespace::XmpResourceRef).value(path);
891 self
892 }
893
894 pub fn instance_id(&mut self, id: &str) -> &mut Self {
898 self.stc.element("instanceID", Namespace::XmpResourceRef).value(id);
899 self
900 }
901
902 pub fn last_modify_date(&mut self, date: DateTime) -> &mut Self {
906 self.stc
907 .element("lastModifyDate", Namespace::XmpResourceRef)
908 .value(date);
909 self
910 }
911
912 pub fn manager(&mut self, manager: &str) -> &mut Self {
916 self.stc.element("manager", Namespace::XmpResourceRef).value(manager);
917 self
918 }
919
920 pub fn manager_variant(&mut self, variant: &str) -> &mut Self {
924 self.stc
925 .element("managerVariant", Namespace::XmpResourceRef)
926 .value(variant);
927 self
928 }
929
930 pub fn manage_to(&mut self, uri: &str) -> &mut Self {
934 self.stc.element("manageTo", Namespace::XmpResourceRef).value(uri);
935 self
936 }
937
938 pub fn manage_ui(&mut self, uri: &str) -> &mut Self {
942 self.stc.element("manageTo", Namespace::XmpResourceRef).value(uri);
943 self
944 }
945
946 pub fn mask_markers(&mut self, markers: MaskMarkers) -> &mut Self {
950 self.stc
951 .element("maskMarkers", Namespace::XmpResourceRef)
952 .value(markers);
953 self
954 }
955
956 pub fn part_mapping(&mut self, mapping: &str) -> &mut Self {
960 self.stc
961 .element("partMapping", Namespace::XmpResourceRef)
962 .value(mapping);
963 self
964 }
965
966 pub fn rendition_class(&mut self, rendition: RenditionClass) -> &mut Self {
971 self.stc
972 .element("renditionClass", Namespace::XmpResourceRef)
973 .value(rendition);
974 self
975 }
976
977 pub fn rendition_params(&mut self, params: &str) -> &mut Self {
982 self.stc
983 .element("renditionParams", Namespace::XmpResourceRef)
984 .value(params);
985 self
986 }
987
988 pub fn to_part(&mut self, part: &str) -> &mut Self {
993 self.stc.element("toPart", Namespace::XmpResourceRef).value(part);
994 self
995 }
996
997 pub fn version_id(&mut self, id: &str) -> &mut Self {
1001 self.stc.element("versionID", Namespace::XmpResourceRef).value(id);
1002 self
1003 }
1004}
1005
1006deref!('a, 'n, ResourceRefWriter<'a, 'n> => Struct<'a, 'n>, stc);
1007
1008pub struct ResourceRefsWriter<'a, 'n: 'a> {
1012 array: Array<'a, 'n>,
1013}
1014
1015impl<'a, 'n: 'a> ResourceRefsWriter<'a, 'n> {
1016 fn start(array: Array<'a, 'n>) -> Self {
1017 Self { array }
1018 }
1019
1020 pub fn add_ref(&mut self) -> ResourceRefWriter<'_, 'n> {
1022 ResourceRefWriter::start(self.array.element().obj())
1023 }
1024}
1025
1026deref!('a, 'n, ResourceRefsWriter<'a, 'n> => Array<'a, 'n>, array);
1027
1028pub struct ResourceEventWriter<'a, 'n: 'a> {
1032 stc: Struct<'a, 'n>,
1033}
1034
1035impl<'a, 'n: 'a> ResourceEventWriter<'a, 'n> {
1036 fn start(stc: Struct<'a, 'n>) -> Self {
1037 Self { stc }
1038 }
1039
1040 pub fn action(&mut self, action: ResourceEventAction) -> &mut Self {
1044 self.stc.element("action", Namespace::XmpResourceEvent).value(action);
1045 self
1046 }
1047
1048 pub fn changed(&mut self, parts: &str) -> &mut Self {
1052 self.stc.element("changed", Namespace::XmpResourceEvent).value(parts);
1053 self
1054 }
1055 pub fn instance_id(&mut self, id: &str) -> &mut Self {
1059 self.stc.element("instanceID", Namespace::XmpResourceEvent).value(id);
1060 self
1061 }
1062
1063 pub fn parameters(&mut self, params: &str) -> &mut Self {
1067 self.stc
1068 .element("parameters", Namespace::XmpResourceEvent)
1069 .value(params);
1070 self
1071 }
1072
1073 pub fn software_agent(&mut self, agent: &str) -> &mut Self {
1077 self.stc
1078 .element("softwareAgent", Namespace::XmpResourceEvent)
1079 .value(agent);
1080 self
1081 }
1082
1083 pub fn when(&mut self, date: DateTime) -> &mut Self {
1087 self.stc.element("when", Namespace::XmpResourceEvent).value(date);
1088 self
1089 }
1090}
1091
1092deref!('a, 'n, ResourceEventWriter<'a, 'n> => Struct<'a, 'n>, stc);
1093
1094pub struct ResourceEventsWriter<'a, 'n: 'a> {
1098 array: Array<'a, 'n>,
1099}
1100
1101impl<'a, 'n: 'a> ResourceEventsWriter<'a, 'n> {
1102 fn start(array: Array<'a, 'n>) -> Self {
1103 Self { array }
1104 }
1105
1106 pub fn add_event(&mut self) -> ResourceEventWriter<'_, 'n> {
1108 ResourceEventWriter::start(self.array.element().obj())
1109 }
1110}
1111
1112deref!('a, 'n, ResourceEventsWriter<'a, 'n> => Array<'a, 'n>, array);
1113
1114pub struct PantryItemWriter<'a, 'n: 'a> {
1119 stc: Struct<'a, 'n>,
1120}
1121
1122impl<'a, 'n: 'a> PantryItemWriter<'a, 'n> {
1123 fn start(stc: Struct<'a, 'n>) -> Self {
1124 Self { stc }
1125 }
1126
1127 pub fn instance_id(&mut self, id: &str) -> &mut Self {
1129 self.stc.element("instanceID", Namespace::XmpMedia).value(id);
1130 self
1131 }
1132}
1133
1134deref!('a, 'n, PantryItemWriter<'a, 'n> => Struct<'a, 'n>, stc);
1135
1136pub struct PantryWriter<'a, 'n: 'a> {
1138 array: Array<'a, 'n>,
1139}
1140
1141impl<'a, 'n: 'a> PantryWriter<'a, 'n> {
1142 fn start(array: Array<'a, 'n>) -> Self {
1143 Self { array }
1144 }
1145
1146 pub fn add_item(&mut self) -> PantryItemWriter<'_, 'n> {
1148 PantryItemWriter::start(self.array.element().obj())
1149 }
1150}
1151
1152deref!('a, 'n, PantryWriter<'a, 'n> => Array<'a, 'n>, array);
1153
1154pub struct VersionWriter<'a, 'n: 'a> {
1158 stc: Struct<'a, 'n>,
1159}
1160
1161impl<'a, 'n: 'a> VersionWriter<'a, 'n> {
1162 fn start(stc: Struct<'a, 'n>) -> Self {
1163 Self { stc }
1164 }
1165
1166 pub fn comments(&mut self, comments: &str) -> &mut Self {
1170 self.stc.element("comments", Namespace::XmpVersion).value(comments);
1171 self
1172 }
1173
1174 pub fn event(&mut self) -> ResourceEventWriter<'_, 'n> {
1178 ResourceEventWriter::start(self.stc.element("event", Namespace::XmpVersion).obj())
1179 }
1180
1181 pub fn modifier(&mut self, modifier: &str) -> &mut Self {
1185 self.stc.element("modifier", Namespace::XmpVersion).value(modifier);
1186 self
1187 }
1188
1189 pub fn modify_date(&mut self, date: DateTime) -> &mut Self {
1193 self.stc.element("modifyDate", Namespace::XmpVersion).value(date);
1194 self
1195 }
1196
1197 pub fn version(&mut self, version: &str) -> &mut Self {
1201 self.stc.element("version", Namespace::XmpVersion).value(version);
1202 self
1203 }
1204}
1205
1206deref!('a, 'n, VersionWriter<'a, 'n> => Struct<'a, 'n>, stc);
1207
1208pub struct VersionsWriter<'a, 'n: 'a> {
1212 array: Array<'a, 'n>,
1213}
1214
1215impl<'a, 'n: 'a> VersionsWriter<'a, 'n> {
1216 fn start(array: Array<'a, 'n>) -> Self {
1217 Self { array }
1218 }
1219
1220 pub fn add_version(&mut self) -> VersionWriter<'_, 'n> {
1222 VersionWriter::start(self.array.element().obj())
1223 }
1224}
1225
1226deref!('a, 'n, VersionsWriter<'a, 'n> => Array<'a, 'n>, array);
1227
1228pub struct JobWriter<'a, 'n: 'a> {
1232 stc: Struct<'a, 'n>,
1233}
1234
1235impl<'a, 'n: 'a> JobWriter<'a, 'n> {
1236 fn start(stc: Struct<'a, 'n>) -> Self {
1237 Self { stc }
1238 }
1239
1240 pub fn id(&mut self, id: &str) -> &mut Self {
1244 self.stc.element("id", Namespace::XmpJob).value(id);
1245 self
1246 }
1247
1248 pub fn name(&mut self, name: &str) -> &mut Self {
1252 self.stc.element("name", Namespace::XmpJob).value(name);
1253 self
1254 }
1255
1256 pub fn url(&mut self, url: &str) -> &mut Self {
1260 self.stc.element("url", Namespace::XmpJob).value(url);
1261 self
1262 }
1263}
1264
1265deref!('a, 'n, JobWriter<'a, 'n> => Struct<'a, 'n>, stc);
1266
1267pub struct JobsWriter<'a, 'n: 'a> {
1271 array: Array<'a, 'n>,
1272}
1273
1274impl<'a, 'n: 'a> JobsWriter<'a, 'n> {
1275 fn start(array: Array<'a, 'n>) -> Self {
1276 Self { array }
1277 }
1278
1279 pub fn add_job(&mut self) -> JobWriter<'_, 'n> {
1281 JobWriter::start(self.array.element().obj())
1282 }
1283}
1284
1285deref!('a, 'n, JobsWriter<'a, 'n> => Array<'a, 'n>, array);
1286
1287pub struct ColorantWriter<'a, 'n: 'a> {
1291 stc: Struct<'a, 'n>,
1292}
1293
1294impl<'a, 'n: 'a> ColorantWriter<'a, 'n> {
1295 fn start(stc: Struct<'a, 'n>) -> Self {
1296 Self { stc }
1297 }
1298
1299 pub fn type_(&mut self, kind: ColorantType) -> &mut Self {
1303 self.stc.element("type", Namespace::XmpColorant).value(kind);
1304 self
1305 }
1306
1307 pub fn swatch_name(&mut self, name: &str) -> &mut Self {
1311 self.stc.element("swatchName", Namespace::XmpColorant).value(name);
1312 self
1313 }
1314
1315 pub fn colorant_mode(&mut self, mode: ColorantMode) -> &mut Self {
1319 self.stc.element("colorantMode", Namespace::XmpColorant).value(mode);
1320 self
1321 }
1322
1323 pub fn l(&mut self, l: f64) -> &mut Self {
1327 self.stc.element("L", Namespace::XmpColorant).value(l);
1328 self
1329 }
1330
1331 pub fn a(&mut self, a: i32) -> &mut Self {
1335 self.stc.element("A", Namespace::XmpColorant).value(a);
1336 self
1337 }
1338
1339 pub fn b(&mut self, b: i32) -> &mut Self {
1343 self.stc.element("B", Namespace::XmpColorant).value(b);
1344 self
1345 }
1346
1347 pub fn black(&mut self, black: f64) -> &mut Self {
1351 self.stc.element("black", Namespace::XmpColorant).value(black);
1352 self
1353 }
1354
1355 pub fn cyan(&mut self, cyan: f64) -> &mut Self {
1359 self.stc.element("cyan", Namespace::XmpColorant).value(cyan);
1360 self
1361 }
1362
1363 pub fn magenta(&mut self, magenta: f64) -> &mut Self {
1367 self.stc.element("magenta", Namespace::XmpColorant).value(magenta);
1368 self
1369 }
1370
1371 pub fn yellow(&mut self, yellow: f64) -> &mut Self {
1375 self.stc.element("yellow", Namespace::XmpColorant).value(yellow);
1376 self
1377 }
1378
1379 pub fn red(&mut self, red: i32) -> &mut Self {
1383 self.stc.element("red", Namespace::XmpColorant).value(red);
1384 self
1385 }
1386
1387 pub fn green(&mut self, green: i32) -> &mut Self {
1391 self.stc.element("green", Namespace::XmpColorant).value(green);
1392 self
1393 }
1394
1395 pub fn blue(&mut self, blue: i32) -> &mut Self {
1399 self.stc.element("blue", Namespace::XmpColorant).value(blue);
1400 self
1401 }
1402}
1403
1404deref!('a, 'n, ColorantWriter<'a, 'n> => Struct<'a, 'n>, stc);
1405
1406pub struct ColorantsWriter<'a, 'n: 'a> {
1410 array: Array<'a, 'n>,
1411}
1412
1413impl<'a, 'n> ColorantsWriter<'a, 'n> {
1414 fn start(array: Array<'a, 'n>) -> Self {
1415 Self { array }
1416 }
1417
1418 pub fn add_colorant(&mut self) -> ColorantWriter<'_, 'n> {
1420 ColorantWriter::start(self.array.element().obj())
1421 }
1422}
1423
1424deref!('a, 'n, ColorantsWriter<'a, 'n> => Array<'a, 'n>, array);
1425
1426pub struct DimensionsWriter<'a, 'n: 'a> {
1430 stc: Struct<'a, 'n>,
1431}
1432
1433impl<'a, 'n> DimensionsWriter<'a, 'n> {
1434 fn start(stc: Struct<'a, 'n>) -> Self {
1435 Self { stc }
1436 }
1437
1438 pub fn width(&mut self, width: f64) -> &mut Self {
1442 self.stc.element("w", Namespace::XmpDimensions).value(width);
1443 self
1444 }
1445
1446 pub fn height(&mut self, height: f64) -> &mut Self {
1450 self.stc.element("h", Namespace::XmpDimensions).value(height);
1451 self
1452 }
1453
1454 pub fn unit(&mut self, unit: DimensionUnit) -> &mut Self {
1458 self.stc.element("unit", Namespace::XmpDimensions).value(unit);
1459 self
1460 }
1461}
1462
1463deref!('a, 'n, DimensionsWriter<'a, 'n> => Struct<'a, 'n>, stc);
1464
1465pub struct FontWriter<'a, 'n: 'a> {
1469 stc: Struct<'a, 'n>,
1470}
1471
1472impl<'a, 'n: 'a> FontWriter<'a, 'n> {
1473 fn start(stc: Struct<'a, 'n>) -> Self {
1474 Self { stc }
1475 }
1476
1477 pub fn child_font_files<'b>(
1481 &mut self,
1482 files: impl IntoIterator<Item = &'b str>,
1483 ) -> &mut Self {
1484 self.stc
1485 .element("childFontFiles", Namespace::XmpFont)
1486 .ordered_array(files);
1487 self
1488 }
1489
1490 pub fn composite(&mut self, composite: bool) -> &mut Self {
1494 self.stc.element("composite", Namespace::XmpFont).value(composite);
1495 self
1496 }
1497
1498 pub fn font_face(&mut self, face: &str) -> &mut Self {
1502 self.stc.element("fontFace", Namespace::XmpFont).value(face);
1503 self
1504 }
1505
1506 pub fn font_family(&mut self, family: &str) -> &mut Self {
1510 self.stc.element("fontFamily", Namespace::XmpFont).value(family);
1511 self
1512 }
1513
1514 pub fn font_file(&mut self, file_name: &str) -> &mut Self {
1518 self.stc.element("fontFileName", Namespace::XmpFont).value(file_name);
1519 self
1520 }
1521
1522 pub fn font_name(&mut self, name: &str) -> &mut Self {
1526 self.stc.element("fontName", Namespace::XmpFont).value(name);
1527 self
1528 }
1529
1530 pub fn font_type(&mut self, font_type: FontType) -> &mut Self {
1534 self.stc.element("fontType", Namespace::XmpFont).value(font_type);
1535 self
1536 }
1537
1538 pub fn version_string(&mut self, version: &str) -> &mut Self {
1547 self.stc.element("versionString", Namespace::XmpFont).value(version);
1548 self
1549 }
1550}
1551
1552deref!('a, 'n, FontWriter<'a, 'n> => Struct<'a, 'n>, stc);
1553
1554pub struct FontsWriter<'a, 'n: 'a> {
1558 array: Array<'a, 'n>,
1559}
1560
1561impl<'a, 'n: 'a> FontsWriter<'a, 'n> {
1562 fn start(array: Array<'a, 'n>) -> Self {
1563 Self { array }
1564 }
1565
1566 pub fn add_font(&mut self) -> FontWriter<'_, 'n> {
1568 FontWriter::start(self.array.element().obj())
1569 }
1570}
1571
1572deref!('a, 'n, FontsWriter<'a, 'n> => Array<'a, 'n>, array);