1use std::{hash::Hash, path::PathBuf};
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 ExportTeX(ExportTeXTask),
77 ExportText(ExportTextTask),
79 Query(QueryTask),
81 }
85
86impl ProjectTask {
87 pub fn when(&self) -> Option<&TaskWhen> {
89 Some(match self {
90 Self::Preview(task) => &task.when,
91 Self::ExportPdf(..)
92 | Self::ExportPng(..)
93 | Self::ExportSvg(..)
94 | Self::ExportHtml(..)
95 | Self::ExportSvgHtml(..)
96 | Self::ExportMd(..)
97 | Self::ExportTeX(..)
98 | Self::ExportText(..)
99 | Self::Query(..) => &self.as_export()?.when,
100 })
101 }
102
103 pub fn as_export(&self) -> Option<&ExportTask> {
105 Some(match self {
106 Self::Preview(..) => return None,
107 Self::ExportPdf(task) => &task.export,
108 Self::ExportPng(task) => &task.export,
109 Self::ExportSvg(task) => &task.export,
110 Self::ExportHtml(task) => &task.export,
111 Self::ExportSvgHtml(task) => &task.export,
112 Self::ExportTeX(task) => &task.export,
113 Self::ExportMd(task) => &task.export,
114 Self::ExportText(task) => &task.export,
115 Self::Query(task) => &task.export,
116 })
117 }
118
119 pub fn as_export_mut(&mut self) -> Option<&mut ExportTask> {
121 Some(match self {
122 Self::Preview(..) => return None,
123 Self::ExportPdf(task) => &mut task.export,
124 Self::ExportPng(task) => &mut task.export,
125 Self::ExportSvg(task) => &mut task.export,
126 Self::ExportHtml(task) => &mut task.export,
127 Self::ExportSvgHtml(task) => &mut task.export,
128 Self::ExportTeX(task) => &mut task.export,
129 Self::ExportMd(task) => &mut task.export,
130 Self::ExportText(task) => &mut task.export,
131 Self::Query(task) => &mut task.export,
132 })
133 }
134
135 pub fn extension(&self) -> &str {
137 match self {
138 Self::ExportPdf { .. } => "pdf",
139 Self::Preview(..) | Self::ExportSvgHtml { .. } | Self::ExportHtml { .. } => "html",
140 Self::ExportMd { .. } => "md",
141 Self::ExportTeX { .. } => "tex",
142 Self::ExportText { .. } => "txt",
143 Self::ExportSvg { .. } => "svg",
144 Self::ExportPng { .. } => "png",
145 Self::Query(QueryTask {
146 format,
147 output_extension,
148 ..
149 }) => output_extension.as_deref().unwrap_or(format),
150 }
151 }
152}
153
154#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
156#[serde(rename_all = "kebab-case")]
157pub struct PreviewTask {
158 pub when: TaskWhen,
161}
162
163#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
165#[serde(rename_all = "kebab-case")]
166pub struct ExportTask {
167 pub when: TaskWhen,
169 pub output: Option<PathPattern>,
171 #[serde(skip_serializing_if = "Vec::is_empty", default)]
173 pub transform: Vec<ExportTransform>,
174}
175
176impl ExportTask {
177 pub fn new(when: TaskWhen) -> Self {
179 Self {
180 when,
181 output: None,
182 transform: Vec::new(),
183 }
184 }
185
186 pub fn apply_pretty(&mut self) {
188 self.transform
189 .push(ExportTransform::Pretty { script: None });
190 }
191}
192
193#[derive(Default, Debug, Clone, Serialize, Deserialize)]
195#[serde(rename_all = "camelCase")]
196pub enum PageSelection {
197 #[default]
199 First,
200 Merged {
202 gap: Option<String>,
204 },
205}
206
207#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
209#[serde(rename_all = "kebab-case")]
210pub enum ExportTransform {
211 Pages {
213 ranges: Vec<Pages>,
215 },
216 Merge {
218 gap: Option<String>,
220 },
221 Script {
223 #[serde(skip_serializing_if = "Option::is_none", default)]
225 script: Option<String>,
226 },
227 Pretty {
229 #[serde(skip_serializing_if = "Option::is_none", default)]
234 script: Option<String>,
235 },
236}
237
238#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
240#[serde(rename_all = "kebab-case")]
241pub struct ExportPdfTask {
242 #[serde(flatten)]
244 pub export: ExportTask,
245 #[serde(skip_serializing_if = "Vec::is_empty", default)]
248 pub pdf_standards: Vec<PdfStandard>,
249 #[serde(skip_serializing_if = "Option::is_none", default)]
253 pub creation_timestamp: Option<i64>,
254}
255
256#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
258#[serde(rename_all = "kebab-case")]
259pub struct ExportPngTask {
260 #[serde(flatten)]
262 pub export: ExportTask,
263 pub ppi: Scalar,
265 #[serde(skip_serializing_if = "Option::is_none", default)]
271 pub fill: Option<String>,
272}
273
274#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
276#[serde(rename_all = "kebab-case")]
277pub struct ExportSvgTask {
278 #[serde(flatten)]
280 pub export: ExportTask,
281}
282
283#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
285#[serde(rename_all = "kebab-case")]
286pub struct ExportHtmlTask {
287 #[serde(flatten)]
289 pub export: ExportTask,
290}
291
292#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
294#[serde(rename_all = "kebab-case")]
295pub struct ExportMarkdownTask {
296 pub processor: Option<String>,
298 pub assets_path: Option<PathBuf>,
300 #[serde(flatten)]
302 pub export: ExportTask,
303}
304
305#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
307#[serde(rename_all = "kebab-case")]
308pub struct ExportTeXTask {
309 pub processor: Option<String>,
311 pub assets_path: Option<PathBuf>,
313 #[serde(flatten)]
315 pub export: ExportTask,
316}
317
318#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
320#[serde(rename_all = "kebab-case")]
321pub struct ExportTextTask {
322 #[serde(flatten)]
324 pub export: ExportTask,
325}
326
327#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
329#[serde(rename_all = "kebab-case")]
330pub struct QueryTask {
331 #[serde(flatten)]
333 pub export: ExportTask,
334 pub format: String,
336 pub output_extension: Option<String>,
339 pub selector: String,
341 pub field: Option<String>,
343 pub one: bool,
345}