use std::path::{Path, PathBuf};
use serde::{Deserialize, Serialize};
use crate::limits::Limits;
#[derive(Clone, Copy, Debug)]
pub enum Source<'a> {
Path(&'a Path),
Bytes(&'a [u8]),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Format {
Pdf,
Docx,
Xlsx,
}
impl Format {
pub fn as_str(self) -> &'static str {
match self {
Format::Pdf => "pdf",
Format::Docx => "docx",
Format::Xlsx => "xlsx",
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub struct ReadOptions {
pub limits: Limits,
pub pages: Option<Vec<u32>>,
pub sheets: Option<Vec<String>>,
pub range: Option<String>,
pub max_chars: usize,
pub max_cells: usize,
pub markdown: bool,
}
impl Default for ReadOptions {
fn default() -> Self {
Self {
limits: Limits::default(),
pages: None,
sheets: None,
range: None,
max_chars: 200_000,
max_cells: 50_000,
markdown: true,
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DocumentRead {
pub format: Format,
pub sha256: String,
pub size_bytes: u64,
pub text: String,
pub markdown: Option<String>,
pub truncated: bool,
pub content: Content,
pub omitted: Vec<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "camelCase")]
pub enum Content {
Docx(DocxContent),
Xlsx(XlsxContent),
Pdf(PdfContent),
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DocxContent {
pub blocks: Vec<DocxBlock>,
pub headers: Vec<String>,
pub footers: Vec<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "camelCase")]
pub enum DocxBlock {
Paragraph {
style: Option<String>,
list: bool,
text: String,
},
Table {
rows: Vec<Vec<String>>,
},
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct XlsxContent {
pub sheets: Vec<SheetRead>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SheetRead {
pub name: String,
pub state: String,
pub used_range: Option<String>,
pub cells: Vec<CellRead>,
pub truncated: bool,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CellRead {
pub cell: String,
pub row: u32,
pub col: u32,
pub value: CellValue,
pub formula: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", content = "value", rename_all = "camelCase")]
pub enum CellValue {
Empty,
Text(String),
Number(f64),
Bool(bool),
DateTime {
serial: f64,
iso: Option<String>,
},
Duration(f64),
Error(String),
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PdfContent {
pub page_count: u32,
pub pages: Vec<PdfPageText>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PdfPageText {
pub page: u32,
pub text: String,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "camelCase")]
pub enum Block {
Heading {
level: u8,
text: String,
},
Paragraph {
text: String,
},
Bullet {
text: String,
},
Numbered {
text: String,
},
Table {
rows: Vec<Vec<String>>,
header: bool,
},
PageBreak,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", content = "value", rename_all = "camelCase")]
pub enum CellInput {
Text(String),
Number(f64),
Bool(bool),
Formula(String),
Blank,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SheetSpec {
pub name: String,
pub rows: Vec<Vec<CellInput>>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CellSet {
pub cell: String,
pub value: CellInput,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "camelCase")]
pub enum Op {
CreateDocx { blocks: Vec<Block> },
CreateXlsx { sheets: Vec<SheetSpec> },
ReplaceText { find: String, replace: String },
AppendBlocks { blocks: Vec<Block> },
SetCells { sheet: String, cells: Vec<CellSet> },
AppendRows {
sheet: String,
rows: Vec<Vec<CellInput>>,
},
AddPdfText {
page: u32,
x: f64,
y: f64,
text: String,
size_pt: Option<f64>,
},
SelectPdfPages { pages: Vec<u32> },
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub struct WriteOptions {
pub limits: Limits,
pub expect_sha256: Option<String>,
pub overwrite: bool,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Loss {
pub part: String,
pub kind: String,
pub detail: String,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct WriteReceipt {
pub path: PathBuf,
pub format: Format,
pub created: bool,
pub source_sha256: Option<String>,
pub sha256: String,
pub bytes_written: u64,
pub ops_applied: usize,
pub replacements: usize,
pub cells_set: usize,
pub rows_appended: usize,
pub touched_parts: Vec<String>,
pub losses: Vec<Loss>,
pub warnings: Vec<String>,
}