use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use crate::summarizer::error::BackendError;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum CompactMode {
Extractive,
Abstractive,
Headlines,
}
impl CompactMode {
pub fn as_str(self) -> &'static str {
match self {
CompactMode::Extractive => "extractive",
CompactMode::Abstractive => "abstractive",
CompactMode::Headlines => "headlines",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Style {
Bullet,
Prose,
Executive,
}
impl Style {
pub fn as_str(self) -> &'static str {
match self {
Style::Bullet => "bullet",
Style::Prose => "prose",
Style::Executive => "executive",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum PreserveSection {
Code,
Tables,
Quotes,
Lists,
}
impl PreserveSection {
pub fn as_str(self) -> &'static str {
match self {
PreserveSection::Code => "code",
PreserveSection::Tables => "tables",
PreserveSection::Quotes => "quotes",
PreserveSection::Lists => "lists",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CompactOpts {
pub mode: CompactMode,
pub style: Style,
pub target_tokens: Option<usize>,
pub focus: Option<String>,
pub preserve: Vec<PreserveSection>,
pub backend_name: String,
}
#[async_trait]
pub trait SummarizerBackend: Send + Sync {
async fn compact(&self, content: &str, opts: &CompactOpts) -> Result<String, BackendError>;
fn name(&self) -> &str;
fn model_id(&self) -> &str {
""
}
fn uses_model_prompt(&self) -> bool {
false
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn enums_round_trip_through_as_str() {
assert_eq!(CompactMode::Extractive.as_str(), "extractive");
assert_eq!(CompactMode::Abstractive.as_str(), "abstractive");
assert_eq!(CompactMode::Headlines.as_str(), "headlines");
assert_eq!(Style::Bullet.as_str(), "bullet");
assert_eq!(Style::Prose.as_str(), "prose");
assert_eq!(Style::Executive.as_str(), "executive");
assert_eq!(PreserveSection::Code.as_str(), "code");
}
#[test]
fn compact_opts_is_clonable() {
let o = CompactOpts {
mode: CompactMode::Abstractive,
style: Style::Prose,
target_tokens: Some(500),
focus: Some("api shape".to_string()),
preserve: vec![PreserveSection::Code],
backend_name: "fast".to_string(),
};
let cloned = o.clone();
assert_eq!(o, cloned);
}
}