use serde::Deserialize;
use std::collections::HashMap;
use time::OffsetDateTime;
use uuid::Uuid;
#[derive(Debug, Clone)]
#[modkit_macros::api_dto(request, response)]
pub struct FileParserInfoDto {
pub supported_extensions: HashMap<String, Vec<String>>,
}
#[derive(Debug, Clone)]
#[modkit_macros::api_dto(request)]
pub struct ParseLocalFileRequest {
pub file_path: String,
}
#[derive(Debug, Deserialize)]
pub struct UploadQuery {
#[serde(default)]
pub render_markdown: Option<bool>,
pub filename: Option<String>,
}
#[derive(Debug, Clone)]
#[modkit_macros::api_dto(request, response)]
pub struct ParsedDocMetadataDto {
pub source: ParsedDocSourceDto,
#[serde(skip_serializing_if = "Option::is_none")]
pub original_filename: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub content_type: Option<String>,
#[serde(with = "time::serde::rfc3339::option")]
#[serde(skip_serializing_if = "Option::is_none")]
pub created_at: Option<OffsetDateTime>,
#[serde(with = "time::serde::rfc3339::option")]
#[serde(skip_serializing_if = "Option::is_none")]
pub modified_at: Option<OffsetDateTime>,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub is_stub: bool,
}
#[derive(Debug, Clone)]
#[modkit_macros::api_dto(request, response)]
#[serde(tag = "type")]
pub enum ParsedDocSourceDto {
LocalPath { path: String },
Uploaded { original_name: String },
}
#[derive(Debug, Clone, Default)]
#[modkit_macros::api_dto(request, response)]
#[allow(clippy::struct_excessive_bools)]
pub struct InlineStyleDto {
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub bold: bool,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub italic: bool,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub underline: bool,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub strike: bool,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub code: bool,
}
#[derive(Debug, Clone)]
#[modkit_macros::api_dto(request, response)]
#[serde(tag = "type")]
pub enum InlineDto {
Text {
text: String,
style: InlineStyleDto,
},
Link {
text: String,
target: String,
style: InlineStyleDto,
},
Code {
text: String,
style: InlineStyleDto,
},
}
#[derive(Debug, Clone)]
#[modkit_macros::api_dto(request, response)]
pub struct TableCellDto {
#[schema(no_recursion)]
pub blocks: Vec<ParsedBlockDto>,
}
#[derive(Debug, Clone)]
#[modkit_macros::api_dto(request, response)]
pub struct TableRowDto {
pub is_header: bool,
pub cells: Vec<TableCellDto>,
}
#[derive(Debug, Clone)]
#[modkit_macros::api_dto(request, response)]
pub struct TableBlockDto {
pub rows: Vec<TableRowDto>,
}
#[derive(Debug, Clone)]
#[modkit_macros::api_dto(request, response)]
#[serde(tag = "type")]
pub enum ParsedBlockDto {
Heading {
level: u8,
inlines: Vec<InlineDto>,
},
Paragraph {
inlines: Vec<InlineDto>,
},
ListItem {
level: u8,
ordered: bool,
#[schema(no_recursion)]
blocks: Vec<ParsedBlockDto>,
},
CodeBlock {
language: Option<String>,
code: String,
},
Table {
#[schema(no_recursion)]
table: TableBlockDto,
},
Quote {
#[schema(no_recursion)]
blocks: Vec<ParsedBlockDto>,
},
HorizontalRule,
Image {
alt: Option<String>,
title: Option<String>,
src: Option<String>,
},
PageBreak,
}
#[derive(Debug, Clone)]
#[modkit_macros::api_dto(request, response)]
pub struct ParsedDocumentDto {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub language: Option<String>,
pub meta: ParsedDocMetadataDto,
pub blocks: Vec<ParsedBlockDto>,
}
#[derive(Debug, Clone)]
#[modkit_macros::api_dto(response)]
pub struct ParsedDocResponseDto {
pub document: ParsedDocumentDto,
#[serde(skip_serializing_if = "Option::is_none")]
pub markdown: Option<String>,
}