use crate::message::Message;
pub use crate::message::REMOVE_ALL_MESSAGES;
pub fn add_messages(existing: &mut Vec<Message>, updates: Vec<Message>) {
let has_remove = updates.iter().any(|m| m.id() == Some(REMOVE_ALL_MESSAGES));
if has_remove {
existing.clear();
for msg in updates {
if msg.id() != Some(REMOVE_ALL_MESSAGES) {
existing.push(msg);
}
}
return;
}
for msg in updates {
if let Some(msg_id) = msg.id() {
if let Some(pos) = existing.iter().position(|m| m.id() == Some(msg_id)) {
existing[pos] = msg;
continue;
}
}
existing.push(msg);
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::message::{HumanMessage, MessageContent, SystemMessage};
fn make_msg(id: &str, text: &str) -> Message {
Message::Human(HumanMessage {
content: MessageContent::Text(text.to_string()),
id: Some(id.to_string()),
name: None,
})
}
fn make_sentinel() -> Message {
Message::System(SystemMessage {
content: String::new(),
id: Some(REMOVE_ALL_MESSAGES.to_string()),
})
}
#[test]
fn test_append_new_messages() {
let mut existing = vec![make_msg("m1", "hello")];
let updates = vec![make_msg("m2", "world")];
add_messages(&mut existing, updates);
assert_eq!(existing.len(), 2);
assert_eq!(existing[1].id(), Some("m2"));
}
#[test]
fn test_update_existing_by_id() {
let mut existing = vec![make_msg("m1", "original")];
let updates = vec![make_msg("m1", "updated")];
add_messages(&mut existing, updates);
assert_eq!(existing.len(), 1);
if let Message::Human(ref h) = existing[0] {
match &h.content {
MessageContent::Text(t) => assert_eq!(t, "updated"),
_ => panic!("expected text content"),
}
} else {
panic!("expected Human message");
}
}
#[test]
fn test_remove_all_sentinel() {
let mut existing = vec![make_msg("m1", "a"), make_msg("m2", "b")];
let updates = vec![make_sentinel(), make_msg("m3", "fresh")];
add_messages(&mut existing, updates);
assert_eq!(existing.len(), 1);
assert_eq!(existing[0].id(), Some("m3"));
}
#[test]
fn test_append_messages_without_id() {
let mut existing = vec![make_msg("m1", "hello")];
let updates = vec![Message::human("anonymous")]; add_messages(&mut existing, updates);
assert_eq!(existing.len(), 2);
assert!(existing[1].id().is_none());
}
#[test]
fn test_mixed_update_and_append() {
let mut existing = vec![make_msg("m1", "first"), make_msg("m2", "second")];
let updates = vec![make_msg("m1", "updated first"), make_msg("m3", "third")];
add_messages(&mut existing, updates);
assert_eq!(existing.len(), 3);
if let Message::Human(ref h) = existing[0] {
match &h.content {
MessageContent::Text(t) => assert_eq!(t, "updated first"),
_ => panic!("expected text"),
}
}
assert_eq!(existing[2].id(), Some("m3"));
}
#[test]
fn test_empty_updates() {
let mut existing = vec![make_msg("m1", "hello")];
add_messages(&mut existing, vec![]);
assert_eq!(existing.len(), 1);
}
#[test]
fn test_remove_all_with_empty_list() {
let mut existing = vec![];
add_messages(&mut existing, vec![make_sentinel()]);
assert!(existing.is_empty());
}
}