use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum Provider {
Claude,
OpenAi,
Gemini,
Grok,
OpenLlm,
Unknown,
}
impl Provider {
pub fn as_str(&self) -> &'static str {
match self {
Provider::Claude => "Claude (Anthropic)",
Provider::OpenAi => "OpenAI",
Provider::Gemini => "Gemini / SynthID (Google)",
Provider::Grok => "Grok (xAI)",
Provider::OpenLlm => "Open-LLM (KGW-class)",
Provider::Unknown => "Unknown",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum WatermarkKind {
UnicodeCarrier,
SpaceHomoglyph,
LatinConfusable,
TagChar,
VariationSelector,
Bidi,
ZwjFamily,
PrivateUse,
C2paMetadata,
ExifMetadata,
XmpMetadata,
PixelDomain,
DocumentProperty,
HtmlMeta,
MarkdownFrontmatter,
}
impl WatermarkKind {
pub fn as_str(&self) -> &'static str {
match self {
WatermarkKind::UnicodeCarrier => "unicode_carrier",
WatermarkKind::SpaceHomoglyph => "space_homoglyph",
WatermarkKind::LatinConfusable => "latin_confusable",
WatermarkKind::TagChar => "tag_chars",
WatermarkKind::VariationSelector => "variation_selector",
WatermarkKind::Bidi => "bidi",
WatermarkKind::ZwjFamily => "zwj_family",
WatermarkKind::PrivateUse => "private_use",
WatermarkKind::C2paMetadata => "c2pa_metadata",
WatermarkKind::ExifMetadata => "exif_metadata",
WatermarkKind::XmpMetadata => "xmp_metadata",
WatermarkKind::PixelDomain => "pixel_domain",
WatermarkKind::DocumentProperty => "document_property",
WatermarkKind::HtmlMeta => "html_meta",
WatermarkKind::MarkdownFrontmatter => "markdown_frontmatter",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum Confidence {
Confirmed,
Probable,
Informational,
LikelyFalsePositive,
}
impl Confidence {
pub fn as_str(&self) -> &'static str {
match self {
Confidence::Confirmed => "confirmed",
Confidence::Probable => "probable",
Confidence::Informational => "informational",
Confidence::LikelyFalsePositive => "likely_false_positive",
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CharHit {
pub codepoint: u32,
pub character: String,
pub label: String,
pub count: usize,
pub kind: WatermarkKind,
pub confidence: Confidence,
pub sample_offsets: Vec<usize>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MetaFinding {
pub description: String,
pub confidence: Confidence,
pub kind: Option<WatermarkKind>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TextInspectReport {
pub length: usize,
pub suspicious_total: usize,
pub hits: Vec<CharHit>,
pub notes: Vec<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum ImageFormat {
Png,
Jpeg,
Webp,
Svg,
}
impl ImageFormat {
pub fn mime_type(&self) -> &'static str {
match self {
ImageFormat::Png => "image/png",
ImageFormat::Jpeg => "image/jpeg",
ImageFormat::Webp => "image/webp",
ImageFormat::Svg => "image/svg+xml",
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ImageInspectReport {
pub format: ImageFormat,
pub findings: Vec<MetaFinding>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum MediaHint {
Text,
Png,
Jpeg,
Webp,
Svg,
Pdf,
Docx,
Odt,
Html,
Markdown,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct CleanStats {
pub removed_count: usize,
pub replaced_count: usize,
pub metadata_chunks_removed: usize,
pub summary: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct CleanOutput {
pub bytes: Vec<u8>,
pub stats: CleanStats,
pub format: MediaHint,
}
#[derive(Debug, Clone)]
pub struct InspectOutput {
pub text_report: Option<TextInspectReport>,
pub image_report: Option<ImageInspectReport>,
pub meta_findings: Vec<MetaFinding>,
pub format: MediaHint,
}