pub mod default;
pub mod headings;
pub mod memory;
pub mod plan;
pub mod spec;
pub mod summary;
use crate::librarian::catalog::artifact::ArtifactRow;
use crate::librarian::tools::ToolContext;
use serde_json::Value;
pub fn extract(kind: &str, row: &ArtifactRow, body: &str, ctx: &ToolContext) -> Value {
match kind {
"plan" => plan::extract(row, body),
"spec" => spec::extract(row, body),
"memory" => memory::extract(row, body, ctx),
_ => default::extract(row, body),
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::librarian::catalog::artifact::ArtifactRow;
use crate::librarian::catalog::Catalog;
use crate::librarian::workspace::WorkspaceConfig;
use std::sync::Arc;
fn mk_row(kind: &str) -> ArtifactRow {
ArtifactRow {
id: "x".into(),
abs_path: std::path::PathBuf::from("/test/r/x.md"),
kind: kind.into(),
status: "draft".into(),
title: None,
owners: vec![],
tags: vec![],
topic: None,
time_scope: None,
source: None,
created_at: 0,
updated_at: 0,
file_mtime: 0,
file_sha256: String::new(),
confidence: 1.0,
}
}
fn mk_ctx() -> ToolContext {
let cat = Catalog::open_in_memory().unwrap();
ToolContext {
catalog: Arc::new(parking_lot::Mutex::new(cat)),
workspace: Arc::new(WorkspaceConfig {
roots: vec![],
ignore: vec![],
rules: vec![],
umbrellas: vec![],
}),
rules: Arc::new(vec![]),
embedding: None,
current_project: None,
}
}
#[test]
fn routes_plan_to_plan_extractor() {
let v = extract("plan", &mk_row("plan"), "- [ ] a\n", &mk_ctx());
assert_eq!(v["shape"], "plan");
}
#[test]
fn routes_spec_to_spec_extractor() {
let v = extract("spec", &mk_row("spec"), "# T\n\nx.\n", &mk_ctx());
assert_eq!(v["shape"], "spec");
}
#[test]
fn routes_memory_to_memory_extractor() {
let v = extract("memory", &mk_row("memory"), "", &mk_ctx());
assert_eq!(v["shape"], "memory");
}
#[test]
fn unknown_kind_falls_back_to_default() {
let v = extract("adr", &mk_row("adr"), "text\n", &mk_ctx());
assert_eq!(v["shape"], "default");
}
}