use serde::{Deserialize, Serialize};
use crate::genai_types::part::Part;
use crate::genai_types::role::Role;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Content {
pub role: Role,
#[serde(default)]
pub parts: Vec<Part>,
}
impl Content {
pub fn user_text(text: impl Into<String>) -> Self {
Self {
role: Role::User,
parts: vec![Part::text(text)],
}
}
pub fn model_text(text: impl Into<String>) -> Self {
Self {
role: Role::Model,
parts: vec![Part::text(text)],
}
}
pub fn system_text(text: impl Into<String>) -> Self {
Self {
role: Role::System,
parts: vec![Part::text(text)],
}
}
#[must_use]
pub fn text_concat(&self) -> String {
let mut out = String::new();
for p in &self.parts {
if let Some(t) = p.as_text() {
if !out.is_empty() {
out.push('\n');
}
out.push_str(t);
}
}
out
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn user_text_round_trip() {
let c = Content::user_text("hi");
let j = serde_json::to_value(&c).unwrap();
assert_eq!(j["role"], "user");
assert_eq!(j["parts"][0]["text"], "hi");
let back: Content = serde_json::from_value(j).unwrap();
assert_eq!(c, back);
}
#[test]
fn text_concat_joins() {
let c = Content {
role: Role::Model,
parts: vec![Part::text("a"), Part::text("b")],
};
assert_eq!(c.text_concat(), "a\nb");
}
}