use serde::{Deserialize, Serialize};
pub fn derive_display_title(path: &str, title: Option<&str>) -> String {
match title {
Some(t) if !t.is_empty() => t.to_string(),
_ => {
let stem = path.strip_suffix(".md").unwrap_or(path);
let filename = stem.split('/').next_back().unwrap_or(stem);
let cleaned: String = filename
.chars()
.map(|c| if c == '-' || c == '_' { ' ' } else { c })
.collect();
let mut chars = cleaned.chars();
match chars.next() {
None => path.to_string(),
Some(first) => first.to_uppercase().to_string() + chars.as_str(),
}
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SearchResult {
pub path: String,
pub title: Option<String>,
pub display_title: String,
#[serde(rename = "type")]
pub concept_type: Option<String>,
pub score: f64,
pub matching_section: Option<String>,
pub excerpt: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SearchResponse {
pub results: Vec<SearchResult>,
pub total_matches: usize,
pub truncated: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MetadataQueryResponse {
pub results: Vec<serde_json::Value>,
pub total_matches: usize,
pub truncated: bool,
}