#![allow(missing_docs)]
use crate::SensitiveString;
use serde::Serialize;
use thiserror::Error;
#[derive(Debug, Clone, Serialize)]
pub struct Chunk {
pub data: SensitiveString,
pub metadata: ChunkMetadata,
}
impl From<String> for Chunk {
fn from(data: String) -> Self {
Self {
data: data.into(),
metadata: ChunkMetadata::default(),
}
}
}
impl From<&str> for Chunk {
fn from(data: &str) -> Self {
Self::from(data.to_string())
}
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct ChunkMetadata {
pub source_type: String,
pub path: Option<String>,
pub commit: Option<String>,
pub author: Option<String>,
pub date: Option<String>,
pub base_offset: usize,
#[serde(default)]
pub base_line: usize,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub mtime_ns: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub size_bytes: Option<u64>,
}
pub trait Source: Send + Sync {
fn name(&self) -> &str;
fn chunks(&self) -> Box<dyn Iterator<Item = Result<Chunk, SourceError>> + '_>;
fn as_any(&self) -> &dyn std::any::Any;
}
#[derive(Debug, Error)]
pub enum SourceError {
#[error(
"failed to read source: {0}. Fix: check the path exists, is readable, and is not a broken symlink"
)]
Io(#[from] std::io::Error),
#[error(
"failed to access git source: {0}. Fix: run inside a valid git repository and verify the requested refs exist"
)]
Git(String),
#[error(
"failed to read source: {0}. Fix: adjust the source settings or input so KeyHog can read plain text safely"
)]
Other(String),
}