use mentra::ContentBlock;
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum PromptPart {
Text(String),
Image {
media_type: String,
data: Vec<u8>,
},
}
impl PromptPart {
pub fn text(text: impl Into<String>) -> Self {
Self::Text(text.into())
}
pub fn image(media_type: impl Into<String>, data: Vec<u8>) -> Self {
Self::Image {
media_type: media_type.into(),
data,
}
}
fn is_empty(&self) -> bool {
match self {
Self::Text(text) => text.trim().is_empty(),
Self::Image { data, .. } => data.is_empty(),
}
}
fn into_block(self) -> ContentBlock {
match self {
Self::Text(text) => ContentBlock::text(text),
Self::Image { media_type, data } => ContentBlock::image_bytes(media_type, data),
}
}
}
impl From<String> for PromptPart {
fn from(text: String) -> Self {
Self::Text(text)
}
}
impl From<&str> for PromptPart {
fn from(text: &str) -> Self {
Self::Text(text.to_string())
}
}
pub(super) fn says_nothing(parts: &[PromptPart]) -> bool {
parts.iter().all(PromptPart::is_empty)
}
pub(super) fn into_blocks(parts: Vec<PromptPart>) -> Vec<ContentBlock> {
parts.into_iter().map(PromptPart::into_block).collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_prompt_of_whitespace_says_nothing() {
assert!(says_nothing(&[PromptPart::text(" \n ")]));
assert!(says_nothing(&[]));
}
#[test]
fn an_image_with_a_blank_caption_still_says_something() {
assert!(!says_nothing(&[
PromptPart::text(""),
PromptPart::image("image/png", vec![1, 2, 3]),
]));
}
#[test]
fn an_image_with_no_bytes_is_not_an_image() {
assert!(says_nothing(&[PromptPart::image("image/png", Vec::new())]));
}
#[test]
fn parts_reach_mentra_in_the_order_they_were_given() {
let blocks = into_blocks(vec![
PromptPart::text("before"),
PromptPart::image("image/png", vec![7]),
PromptPart::text("after"),
]);
assert!(matches!(blocks[0], ContentBlock::Text { .. }));
assert!(matches!(blocks[1], ContentBlock::Image { .. }));
assert!(matches!(blocks[2], ContentBlock::Text { .. }));
}
#[test]
fn a_bare_string_is_a_text_part() {
assert_eq!(
PromptPart::from("hello"),
PromptPart::Text("hello".to_string())
);
}
}