1use base64::{engine::general_purpose, Engine};
2use serde::{Deserialize, Deserializer, Serialize, Serializer};
3
4#[derive(Debug, Serialize, Deserialize, Clone)]
5pub struct Content {
6 pub role: Role,
7 pub parts: Vec<Part>,
8}
9
10impl Content {
11 pub fn user(value: impl Into<Part>) -> Self {
12 Content {
13 role: Role::User,
14 parts: vec![value.into()],
15 }
16 }
17
18 pub fn model(value: impl Into<Part>) -> Self {
19 Content {
20 role: Role::Model,
21 parts: vec![value.into()],
22 }
23 }
24}
25
26impl<T> From<T> for Content
27where
28 T: Into<Part>,
29{
30 fn from(value: T) -> Self {
31 Content::user(value)
32 }
33}
34
35#[derive(Debug, Serialize, Deserialize, Clone)]
36pub struct Part {
37 #[serde(default)]
38 pub thought: bool,
39 pub thought_signature: Option<String>,
40 #[serde(flatten)]
41 pub inner: InnerPart
42}
43
44impl Part {
45 pub fn text(text: &str) -> Self {
46 Self { thought: false, thought_signature: None, inner: InnerPart::Text(text.to_string()) }
47 }
48
49 pub fn as_text(&self) -> Option<&str> {
50 match &self.inner {
51 InnerPart::Text(text) => Some(text),
52 _ => None
53 }
54
55 }
56}
57#[derive(Debug, Serialize, Deserialize, Clone)]
58#[serde(rename_all = "camelCase")]
59pub enum InnerPart {
60 Text(String),
61 #[serde(rename = "inlineData")]
62 Data {
63 #[serde(serialize_with = "ser_data")]
64 #[serde(deserialize_with = "des_data")]
65 data: Vec<u8>,
66 #[serde(rename = "mimeType")]
67 mime_type: String,
68 },
69 FunctionCall {
70 name: String,
71 args: Option<serde_json::Value>,
72 },
73 FunctionResponse {
74 name: String,
75 response: serde_json::Value,
76 },
77}
78
79fn ser_data<S>(bytes: &Vec<u8>, ser: S) -> Result<S::Ok, S::Error>
80where
81 S: Serializer,
82{
83 ser.serialize_str(&general_purpose::STANDARD.encode(bytes))
84}
85
86fn des_data<'de, D>(des: D) -> Result<Vec<u8>, D::Error>
87where
88 D: Deserializer<'de>,
89{
90 Ok(general_purpose::STANDARD
91 .decode(String::deserialize(des)?)
92 .unwrap())
93}
94impl From<&str> for Part {
95 fn from(value: &str) -> Self {
96 Part::text(value)
97 }
98}
99
100impl From<String> for Part {
101 fn from(value: String) -> Self {
102 Part::text(&value)
103 }
104}
105
106#[derive(Debug, Clone, Serialize, Deserialize)]
107#[serde(rename_all = "camelCase")]
108pub enum Role {
109 User,
110 Model,
111}