Skip to main content

selection_capture/
rich_types.rs

1use crate::types::{ActiveApp, CaptureFailure, CaptureMethod, CaptureOptions, CaptureTrace};
2
3/// Explicit format tag for a rich-text payload.
4///
5/// Reserved for future use — currently not attached to payload fields,
6/// but preserved in the public API for upcoming typed format annotations.
7#[derive(Clone, Copy, Debug, PartialEq, Eq)]
8pub enum RichFormat {
9    Html,
10    Rtf,
11}
12
13#[derive(Clone, Copy, Debug, PartialEq, Eq)]
14pub enum RichSource {
15    ClipboardHtml,
16    ClipboardRtf,
17    AccessibilityAttributed,
18}
19
20#[derive(Clone, Copy, Debug, PartialEq, Eq)]
21pub enum RichConversion {
22    Markdown,
23}
24
25#[derive(Clone, Debug, PartialEq, Eq)]
26pub struct ContentMetadata {
27    pub active_app: Option<ActiveApp>,
28    pub method: CaptureMethod,
29    pub source: RichSource,
30    pub captured_at_unix_ms: u128,
31    /// FNV-1a 64-bit hash of `plain_text`. Stable across process restarts and Rust
32    /// versions — safe for persistent deduplication and cross-process comparison.
33    pub plain_text_hash: u64,
34}
35
36#[derive(Clone, Debug, PartialEq, Eq)]
37pub struct RichPayload {
38    pub plain_text: String,
39    pub html: Option<String>,
40    pub rtf: Option<String>,
41    pub markdown: Option<String>,
42    pub metadata: ContentMetadata,
43}
44
45#[derive(Clone, Debug, PartialEq, Eq)]
46pub enum CapturedContent {
47    Plain(String),
48    Rich(RichPayload),
49}
50
51#[derive(Clone, Debug, PartialEq, Eq)]
52pub struct CaptureRichSuccess {
53    pub content: CapturedContent,
54    pub method: CaptureMethod,
55    pub trace: Option<CaptureTrace>,
56}
57
58#[derive(Clone, Debug, PartialEq, Eq)]
59pub enum CaptureRichOutcome {
60    Success(CaptureRichSuccess),
61    Failure(CaptureFailure),
62}
63
64#[derive(Clone, Debug, PartialEq, Eq)]
65pub struct CaptureRichOptions {
66    pub base: CaptureOptions,
67    pub prefer_rich: bool,
68    pub allow_clipboard_rich: bool,
69    pub allow_direct_accessibility_rich: bool,
70    pub conversion: Option<RichConversion>,
71    pub max_rich_payload_bytes: usize,
72    pub require_plain_text_match: bool,
73}
74
75impl Default for CaptureRichOptions {
76    fn default() -> Self {
77        Self {
78            base: CaptureOptions::default(),
79            prefer_rich: true,
80            allow_clipboard_rich: true,
81            allow_direct_accessibility_rich: true,
82            conversion: None,
83            max_rich_payload_bytes: 256 * 1024,
84            require_plain_text_match: true,
85        }
86    }
87}