gemini_client_api/gemini/
utils.rs

1use super::types::request::*;
2use crate::utils::{self, MatchedFiles};
3use regex::Regex;
4
5pub struct MarkdownToParts<'a> {
6    base64s: Vec<Option<MatchedFiles>>,
7    markdown: &'a str,
8}
9impl<'a> MarkdownToParts<'a> {
10    pub async fn from_regex(
11        markdown: &'a str,
12        regex: Regex,
13        guess_mime_type: fn(url: &str) -> String,
14    ) -> Self {
15        Self {
16            base64s: utils::get_file_base64s(markdown, regex, guess_mime_type).await,
17            markdown,
18        }
19    }
20    ///Converts markdown to parts considering `![image](link)` means Gemini will be see the images too. `link` can be URL or file path.
21    pub async fn new(markdown: &'a str, guess_mime_type: fn(url: &str) -> String) -> Self {
22        let image_regex = Regex::new(r"(?s)!\[.*?].?\((.*?)\)").unwrap();
23        Self {
24            base64s: utils::get_file_base64s(markdown, image_regex, guess_mime_type).await,
25            markdown,
26        }
27    }
28    pub fn process(mut self) -> Vec<Part> {
29        let mut parts: Vec<Part> = Vec::new();
30        let mut removed_length = 0;
31        for file in self.base64s {
32            if let Some(file) = file {
33                let end = file.index + file.length - removed_length;
34                let text = &self.markdown[..end];
35                parts.push(Part::text(text.to_string()));
36                parts.push(Part::inline_data(InlineData::new(
37                    file.mime_type,
38                    file.base64,
39                )));
40
41                self.markdown = &self.markdown[end..];
42                removed_length += end;
43            }
44        }
45        if self.markdown.len() != 0 {
46            parts.push(Part::text(self.markdown.to_string()));
47        }
48        parts
49    }
50}