use crate::ai::stream::StreamMsg;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(super) enum InferenceAction {
Replace,
Insert,
Top,
Bottom,
CopyOnly,
ReplaceCorrected,
}
impl InferenceAction {
pub(super) fn label(&self) -> &'static str {
match self {
InferenceAction::Replace => "replaced",
InferenceAction::Insert => "inserted at cursor",
InferenceAction::Top => "prepended to top",
InferenceAction::Bottom => "appended to bottom",
InferenceAction::CopyOnly => "copied",
InferenceAction::ReplaceCorrected => "replaced with corrected text",
}
}
}
#[derive(Debug, Clone)]
pub(super) struct LiftTarget {
pub book_tag: &'static str,
pub book_label: &'static str,
pub title: String,
pub what: String,
pub stamp: std::time::Instant,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(super) enum AiMode {
None,
Selection,
Paragraph,
Subchapter,
Chapter,
Book,
Facts,
}
impl AiMode {
pub(super) fn label(self) -> &'static str {
match self {
AiMode::None => "None",
AiMode::Selection => "Selection",
AiMode::Paragraph => "Paragraph",
AiMode::Subchapter => "Subchapter",
AiMode::Chapter => "Chapter",
AiMode::Book => "Book",
AiMode::Facts => "Facts",
}
}
pub(super) fn next(self) -> Self {
match self {
AiMode::None => AiMode::Selection,
AiMode::Selection => AiMode::Paragraph,
AiMode::Paragraph => AiMode::Subchapter,
AiMode::Subchapter => AiMode::Chapter,
AiMode::Chapter => AiMode::Book,
AiMode::Book => AiMode::Facts,
AiMode::Facts => AiMode::None,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(super) enum InferenceMode {
Local,
Full,
}
impl InferenceMode {
pub(super) fn label(self) -> &'static str {
match self {
InferenceMode::Local => "Local",
InferenceMode::Full => "Full",
}
}
pub(super) fn toggle(self) -> Self {
match self {
InferenceMode::Local => InferenceMode::Full,
InferenceMode::Full => InferenceMode::Local,
}
}
}
#[derive(Debug)]
pub(super) struct Inference {
pub provider: String,
#[allow(dead_code)]
pub model: String,
pub response: String,
pub status: InferenceStatus,
pub rx: tokio::sync::mpsc::UnboundedReceiver<StreamMsg>,
pub started_at: std::time::Instant,
}
#[derive(Debug, Clone)]
pub(super) enum InferenceStatus {
Streaming,
Done,
Error(String),
}
#[cfg(test)]
mod ai_mode_tests {
use super::AiMode;
#[test]
fn cycle_includes_facts_after_book_and_wraps() {
let order: Vec<&str> = {
let mut m = AiMode::None;
let mut seen = vec![m.label()];
loop {
m = m.next();
if m == AiMode::None {
break;
}
seen.push(m.label());
}
seen
};
assert_eq!(
order,
vec![
"None", "Selection", "Paragraph", "Subchapter", "Chapter", "Book", "Facts",
],
);
assert_eq!(AiMode::Book.next(), AiMode::Facts);
assert_eq!(AiMode::Facts.next(), AiMode::None);
}
}