Core library for indexing and searching clipboard entries using SurrealDB (RocksDB backend) and object_store.
# Build
cargo build -p clipper-indexer
# Test
cargo test -p clipper-indexerClipperIndexeris the main entry point- Uses SurrealDB for metadata and full-text search (BM25)
- Uses object_store (LocalFileSystem) for file attachments
- All operations are async (Tokio runtime)
- Pagination support:
search_entries()andlist_entries()returnPagedResult<ClipboardEntry>
- Table:
clipboardwith fields: id, content, created_at, tags, additional_notes, file_attachment, original_filename, language, search_content - Indexes: created_at, tags, full-text search on search_content
- Schema auto-initialized in
ClipperIndexer::new()
The language field stores the user's preferred syntax highlighting language for a clip:
- Optional field (can be
None) - Set via
add_entry_from_text(..., language: Option<String>)orupdate_entry(..., language: Option<String>) - Pass
Some("")(empty string) to clear the language - Pass
Noneto leave the language unchanged during updates
- File Storage: Files stored separately via object_store, not in database. Entry contains file_key reference.
- Search Content: Concatenation of content + additional_notes for full-text indexing
- Pagination: Implemented with
PagingParamsandPagedResult<T>
// Always use ClipperIndexer through Arc in server context
let indexer = ClipperIndexer::new(db_path, storage_path).await?;
let state = AppState::new(indexer); // Wraps in Arc
// For file uploads, use add_entry_from_file_content (bytes + filename)
// For local files, use add_entry_from_file (path)
// Pagination
let paging = PagingParams::default(); // page: 1, page_size: 20
let result = indexer.search_entries(query, filters, paging).await?;let paging = PagingParams { page: 1, page_size: 20 };
let result: PagedResult<ClipboardEntry> = indexer.search_entries(query, filters, paging).await?;clipper_indexer::IndexerError- core library errors