1use std::hash::Hash;
4
5use serde::{Deserialize, Serialize};
6
7use super::{Id, Pages, PathPattern, PdfStandard, Scalar, TaskWhen};
8
9#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
34#[serde(rename_all = "kebab-case", tag = "type")]
35pub struct ApplyProjectTask {
36 pub id: Id,
38 pub document: Id,
40 #[serde(flatten)]
42 pub task: ProjectTask,
43}
44
45impl ApplyProjectTask {
46 pub fn doc_id(&self) -> &Id {
48 &self.document
49 }
50
51 pub fn id(&self) -> &Id {
53 &self.id
54 }
55}
56
57#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
59#[serde(rename_all = "kebab-case", tag = "type")]
60pub enum ProjectTask {
61 Preview(PreviewTask),
63 ExportPdf(ExportPdfTask),
65 ExportPng(ExportPngTask),
67 ExportSvg(ExportSvgTask),
69 ExportHtml(ExportHtmlTask),
71 ExportSvgHtml(ExportHtmlTask),
73 ExportMd(ExportMarkdownTask),
75 ExportText(ExportTextTask),
77 Query(QueryTask),
79 }
83
84impl ProjectTask {
85 pub fn when(&self) -> Option<TaskWhen> {
87 Some(match self {
88 Self::Preview(task) => task.when,
89 Self::ExportPdf(..)
90 | Self::ExportPng(..)
91 | Self::ExportSvg(..)
92 | Self::ExportHtml(..)
93 | Self::ExportSvgHtml(..)
94 | Self::ExportMd(..)
95 | Self::ExportText(..)
96 | Self::Query(..) => self.as_export()?.when,
97 })
98 }
99
100 pub fn as_export(&self) -> Option<&ExportTask> {
102 Some(match self {
103 Self::Preview(..) => return None,
104 Self::ExportPdf(task) => &task.export,
105 Self::ExportPng(task) => &task.export,
106 Self::ExportSvg(task) => &task.export,
107 Self::ExportHtml(task) => &task.export,
108 Self::ExportSvgHtml(task) => &task.export,
109 Self::ExportMd(task) => &task.export,
110 Self::ExportText(task) => &task.export,
111 Self::Query(task) => &task.export,
112 })
113 }
114
115 pub fn extension(&self) -> &str {
117 match self {
118 Self::ExportPdf { .. } => "pdf",
119 Self::Preview(..) | Self::ExportSvgHtml { .. } | Self::ExportHtml { .. } => "html",
120 Self::ExportMd { .. } => "md",
121 Self::ExportText { .. } => "txt",
122 Self::ExportSvg { .. } => "svg",
123 Self::ExportPng { .. } => "png",
124 Self::Query(QueryTask {
125 format,
126 output_extension,
127 ..
128 }) => output_extension.as_deref().unwrap_or(format),
129 }
130 }
131}
132
133#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
135#[serde(rename_all = "kebab-case")]
136pub struct PreviewTask {
137 pub when: TaskWhen,
140}
141
142#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
144#[serde(rename_all = "kebab-case")]
145pub struct ExportTask {
146 pub when: TaskWhen,
148 pub output: Option<PathPattern>,
150 #[serde(skip_serializing_if = "Vec::is_empty", default)]
152 pub transform: Vec<ExportTransform>,
153}
154
155impl ExportTask {
156 pub fn new(when: TaskWhen) -> Self {
158 Self {
159 when,
160 output: None,
161 transform: Vec::new(),
162 }
163 }
164
165 pub fn apply_pretty(&mut self) {
167 self.transform
168 .push(ExportTransform::Pretty { script: None });
169 }
170}
171
172#[derive(Default, Debug, Clone, Serialize, Deserialize)]
174#[serde(rename_all = "camelCase")]
175pub enum PageSelection {
176 #[default]
178 First,
179 Merged {
181 gap: Option<String>,
183 },
184}
185
186#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
188#[serde(rename_all = "kebab-case")]
189pub enum ExportTransform {
190 Pages {
192 ranges: Vec<Pages>,
194 },
195 Merge {
197 gap: Option<String>,
199 },
200 Script {
202 #[serde(skip_serializing_if = "Option::is_none", default)]
204 script: Option<String>,
205 },
206 Pretty {
208 #[serde(skip_serializing_if = "Option::is_none", default)]
213 script: Option<String>,
214 },
215}
216
217#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
219#[serde(rename_all = "kebab-case")]
220pub struct ExportPdfTask {
221 #[serde(flatten)]
223 pub export: ExportTask,
224 #[serde(skip_serializing_if = "Vec::is_empty", default)]
227 pub pdf_standards: Vec<PdfStandard>,
228 #[serde(skip_serializing_if = "Option::is_none", default)]
232 pub creation_timestamp: Option<i64>,
233}
234
235#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
237#[serde(rename_all = "kebab-case")]
238pub struct ExportPngTask {
239 #[serde(flatten)]
241 pub export: ExportTask,
242 pub ppi: Scalar,
244 #[serde(skip_serializing_if = "Option::is_none", default)]
250 pub fill: Option<String>,
251}
252
253#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
255#[serde(rename_all = "kebab-case")]
256pub struct ExportSvgTask {
257 #[serde(flatten)]
259 pub export: ExportTask,
260}
261
262#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
264#[serde(rename_all = "kebab-case")]
265pub struct ExportHtmlTask {
266 #[serde(flatten)]
268 pub export: ExportTask,
269}
270
271#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
273#[serde(rename_all = "kebab-case")]
274pub struct ExportMarkdownTask {
275 #[serde(flatten)]
277 pub export: ExportTask,
278}
279
280#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
282#[serde(rename_all = "kebab-case")]
283pub struct ExportTextTask {
284 #[serde(flatten)]
286 pub export: ExportTask,
287}
288
289#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
291#[serde(rename_all = "kebab-case")]
292pub struct QueryTask {
293 #[serde(flatten)]
295 pub export: ExportTask,
296 pub format: String,
298 pub output_extension: Option<String>,
301 pub selector: String,
303 pub field: Option<String>,
305 pub one: bool,
307}