use crate::types::ScrapedContent;
pub struct PromptBuilder {
query: String,
contents: Vec<ScrapedContent>,
}
impl PromptBuilder {
pub fn new(query: String) -> Self {
Self {
query,
contents: Vec::new(),
}
}
pub fn with_contents(mut self, contents: Vec<ScrapedContent>) -> Self {
self.contents = contents;
self
}
pub fn build(&self) -> String {
let formatted_contents = self.contents
.iter()
.map(|c| {
Self::clean_text(
&format!(
"Source: {}\nTimestamp: {}\nContent:\n{}\n---\n",
c.url, c.timestamp, c.content
)
)
})
.collect::<String>();
format!(
"{} {}", self.query,
formatted_contents
)
}
fn clean_text(text: &str) -> String {
text.lines()
.filter(|line| !line.trim().is_empty()) .map(|line| {
line.split_whitespace() .collect::<Vec<&str>>()
.join(" ") })
.collect::<Vec<String>>()
.join("\n") }
}
#[cfg(test)]
mod tests {
use super::*;
use chrono::Utc;
use std::collections::HashMap;
#[test]
fn test_prompt_builder() {
let content = ScrapedContent {
url: "https://example.com".to_string(),
content: "Test content".to_string(),
metadata: HashMap::new(),
timestamp: Utc::now(),
};
let prompt = PromptBuilder::new("What is Rust?".to_string())
.with_contents(vec![content])
.build();
assert!(prompt.contains("What is Rust?"));
assert!(prompt.contains("https://example.com"));
assert!(prompt.contains("Test content"));
}
}