use llm_toolkit::ToPrompt;
use serde::Serialize;
#[derive(Debug, Clone, Serialize)]
struct Profile {
name: String,
role: String,
}
impl ToPrompt for Profile {
fn to_prompt(&self) -> String {
format!("Profile: {} ({})", self.name, self.role)
}
}
#[derive(ToPrompt, Serialize)]
#[prompt(template = "{{ profile }}")]
struct DefaultExample {
profile: Profile,
}
#[test]
fn test_default_uses_to_prompt() {
let example = DefaultExample {
profile: Profile {
name: "Alice".to_string(),
role: "Admin".to_string(),
},
};
let output = example.to_prompt();
assert_eq!(output, "Profile: Alice (Admin)");
}
#[derive(ToPrompt, Serialize)]
#[prompt(template = "User: {{ profile.name }}, Role: {{ profile.role }}")]
struct DotAccessExample {
#[prompt(as_serialize)]
profile: Profile,
}
#[test]
fn test_as_serialize_enables_dot_access() {
let example = DotAccessExample {
profile: Profile {
name: "Bob".to_string(),
role: "User".to_string(),
},
};
let output = example.to_prompt();
assert_eq!(output, "User: Bob, Role: User");
}
#[derive(ToPrompt, Serialize)]
#[prompt(template = "Name: {{ data.name }}, Description: {{ description }}")]
struct MixedExample {
#[prompt(as_serialize)]
data: Profile,
description: Profile,
}
#[test]
fn test_mixed_as_serialize_and_default() {
let example = MixedExample {
data: Profile {
name: "Charlie".to_string(),
role: "Developer".to_string(),
},
description: Profile {
name: "Charlie".to_string(),
role: "Developer".to_string(),
},
};
let output = example.to_prompt();
assert_eq!(
output,
"Name: Charlie, Description: Profile: Charlie (Developer)"
);
}
#[derive(Debug, Clone, Serialize, ToPrompt)]
struct Company {
name: String,
ceo: Profile,
}
#[derive(ToPrompt, Serialize)]
#[prompt(template = "Company: {{ company.name }}, CEO: {{ company.ceo.name }}")]
struct DeepDotAccessExample {
#[prompt(as_serialize)]
company: Company,
}
#[test]
fn test_deep_dot_access() {
let example = DeepDotAccessExample {
company: Company {
name: "Acme Corp".to_string(),
ceo: Profile {
name: "Dana".to_string(),
role: "CEO".to_string(),
},
},
};
let output = example.to_prompt();
assert_eq!(output, "Company: Acme Corp, CEO: Dana");
}
#[derive(ToPrompt, Serialize)]
#[prompt(template = "{% if profile %}Name: {{ profile.name }}{% else %}No profile{% endif %}")]
struct OptionDotAccessExample {
#[prompt(as_serialize)]
profile: Option<Profile>,
}
#[test]
fn test_option_dot_access_some() {
let example = OptionDotAccessExample {
profile: Some(Profile {
name: "Eve".to_string(),
role: "Manager".to_string(),
}),
};
let output = example.to_prompt();
assert_eq!(output, "Name: Eve");
}
#[test]
fn test_option_dot_access_none() {
let example = OptionDotAccessExample { profile: None };
let output = example.to_prompt();
assert_eq!(output, "No profile");
}
#[derive(ToPrompt, Serialize)]
#[prompt(template = "{% for p in profiles %}{{ p.name }}, {% endfor %}")]
struct VecDotAccessExample {
#[prompt(as_serialize)]
profiles: Vec<Profile>,
}
#[test]
fn test_vec_dot_access() {
let example = VecDotAccessExample {
profiles: vec![
Profile {
name: "Frank".to_string(),
role: "Dev".to_string(),
},
Profile {
name: "Grace".to_string(),
role: "QA".to_string(),
},
],
};
let output = example.to_prompt();
assert_eq!(output, "Frank, Grace, ");
}