use dejadb_cal::store_types::GrainTypeDiversityConfig;
use dejadb_core::types::GrainType;
use std::collections::HashMap;
#[derive(Debug, Clone, PartialEq)]
pub enum OutputFormat {
Sml,
Toon,
Markdown,
PlainText,
Json,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum MetadataLevel {
None,
Minimal,
Full,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Ordering {
ByRelevance,
Chronological,
ReverseChronological,
ByEntity,
}
#[derive(Debug, Clone, Default)]
pub struct SectionConfig {
pub group_by_type: bool,
pub type_order: Vec<GrainType>,
}
#[derive(Debug, Clone)]
pub struct GrainTypeOverride {
pub include: bool,
pub max_count: Option<usize>,
}
impl Default for GrainTypeOverride {
fn default() -> Self {
Self {
include: true,
max_count: None,
}
}
}
#[derive(Debug, Clone)]
pub struct FormatPolicy {
pub format: OutputFormat,
pub metadata: MetadataLevel,
pub ordering: Ordering,
pub sections: SectionConfig,
pub token_budget: Option<usize>,
pub grain_overrides: HashMap<GrainType, GrainTypeOverride>,
pub query_text: Option<String>,
pub grain_type_diversity: Option<GrainTypeDiversityConfig>,
}
impl FormatPolicy {
pub fn new(format: OutputFormat) -> Self {
Self {
format,
metadata: MetadataLevel::Minimal,
ordering: Ordering::ByRelevance,
sections: SectionConfig::default(),
token_budget: None,
grain_overrides: HashMap::new(),
query_text: None,
grain_type_diversity: Some(GrainTypeDiversityConfig::default()),
}
}
pub fn metadata(mut self, level: MetadataLevel) -> Self {
self.metadata = level;
self
}
pub fn ordering(mut self, ordering: Ordering) -> Self {
self.ordering = ordering;
self
}
pub fn token_budget(mut self, budget: usize) -> Self {
self.token_budget = Some(budget);
self
}
pub fn group_by_type(mut self) -> Self {
self.sections.group_by_type = true;
self
}
pub fn grain_override(mut self, gt: GrainType, ovr: GrainTypeOverride) -> Self {
self.grain_overrides.insert(gt, ovr);
self
}
pub fn query_text(mut self, text: impl Into<String>) -> Self {
self.query_text = Some(text.into());
self
}
pub fn grain_type_diversity(mut self, config: GrainTypeDiversityConfig) -> Self {
self.grain_type_diversity = Some(config);
self
}
pub fn no_grain_type_diversity(mut self) -> Self {
self.grain_type_diversity = None;
self
}
}
impl Default for FormatPolicy {
fn default() -> Self {
Self::new(OutputFormat::PlainText)
.metadata(MetadataLevel::Minimal)
.ordering(Ordering::ByRelevance)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_policy() {
let p = FormatPolicy::default();
assert_eq!(p.format, OutputFormat::PlainText);
assert_eq!(p.metadata, MetadataLevel::Minimal);
assert_eq!(p.ordering, Ordering::ByRelevance);
assert!(p.token_budget.is_none());
assert!(!p.sections.group_by_type);
}
#[test]
fn test_builder_chain() {
let p = FormatPolicy::new(OutputFormat::Sml)
.metadata(MetadataLevel::Full)
.ordering(Ordering::Chronological)
.token_budget(4096)
.group_by_type()
.grain_override(
GrainType::Consent,
GrainTypeOverride {
include: true,
max_count: Some(5),
},
);
assert_eq!(p.format, OutputFormat::Sml);
assert_eq!(p.metadata, MetadataLevel::Full);
assert_eq!(p.ordering, Ordering::Chronological);
assert_eq!(p.token_budget, Some(4096));
assert!(p.sections.group_by_type);
assert_eq!(
p.grain_overrides
.get(&GrainType::Consent)
.unwrap()
.max_count,
Some(5)
);
}
}