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<MatchedFiles>,
7    markdown: &'a str,
8}
9impl<'a> MarkdownToParts<'a> {
10    ///# Panics
11    /// `regex` must have a Regex with atleast 1 capture group with file URL as first capture group, else it PANICS.
12    /// # Arguments
13    /// `guess_mime_type` is used to detect mimi_type of URL pointing to file system or web resource
14    /// with no "Content-Type" header.
15    /// # Example
16    /// ```ignore
17    /// from_regex("Your markdown string...", Regex::new(r"(?s)!\[.*?].?\((.*?)\)").unwrap(), |_| "image/png".to_string())
18    /// ```
19    pub async fn from_regex(
20        markdown: &'a str,
21        regex: Regex,
22        guess_mime_type: fn(url: &str) -> String,
23    ) -> Self {
24        Self {
25            base64s: utils::get_file_base64s(markdown, regex, guess_mime_type).await,
26            markdown,
27        }
28    }
29    ///Converts markdown to parts considering `![image](link)` means Gemini will be see the images too. `link` can be URL or file path.  
30    /// `guess_mime_type` is used to detect mimi_type of URL pointing to file system or web resource
31    /// with no "Content-Type" header.
32    /// # Example
33    /// ```ignore
34    /// new("Your markdown string...", |_| "image/png".to_string())
35    /// ```
36    pub async fn new(markdown: &'a str, guess_mime_type: fn(url: &str) -> String) -> Self {
37        let image_regex = Regex::new(r"(?s)!\[.*?].?\((.*?)\)").unwrap();
38        Self {
39            base64s: utils::get_file_base64s(markdown, image_regex, guess_mime_type).await,
40            markdown,
41        }
42    }
43    pub fn process(mut self) -> Vec<Part> {
44        let mut parts: Vec<Part> = Vec::new();
45        let mut removed_length = 0;
46        for file in self.base64s {
47            if let MatchedFiles {
48                index,
49                length,
50                mime_type: Some(mime_type),
51                base64: Some(base64),
52            } = file
53            {
54                let end = index + length - removed_length;
55                let text = &self.markdown[..end];
56                parts.push(Part::text(text.to_string()));
57                parts.push(Part::inline_data(InlineData::new(mime_type, base64)));
58
59                self.markdown = &self.markdown[end..];
60                removed_length += end;
61            }
62        }
63        if self.markdown.len() != 0 {
64            parts.push(Part::text(self.markdown.to_string()));
65        }
66        parts
67    }
68}