terraphim_middleware 1.16.34

Terraphim middleware for searching haystacks
Documentation
use crate::indexer::IndexMiddleware;
use crate::Result;
use terraphim_config::Haystack;
use terraphim_types::Index;

#[derive(Debug, Clone, Default)]
pub struct JmapHaystackIndexer;

impl IndexMiddleware for JmapHaystackIndexer {
    fn index(
        &self,
        needle: &str,
        haystack: &Haystack,
    ) -> impl std::future::Future<Output = Result<Index>> + Send {
        let query = needle.to_string();
        let extras = haystack.get_extra_parameters().clone();
        let location = haystack.location.clone();
        async move {
            let session_url = std::env::var("JMAP_SESSION_URL")
                .ok()
                .or(if !location.is_empty() {
                    Some(location)
                } else {
                    None
                })
                .unwrap_or("https://api.fastmail.com/jmap/session".to_string());

            let access_token = std::env::var("JMAP_ACCESS_TOKEN")
                .ok()
                .or_else(|| extras.get("access_token").cloned())
                .unwrap_or_default();

            if access_token.is_empty() {
                log::warn!("JMAP_ACCESS_TOKEN not set; returning empty index");
                return Ok(Index::default());
            }

            let limit: u32 = extras
                .get("limit")
                .and_then(|s| s.parse().ok())
                .unwrap_or(50);

            let jmap_client = match haystack_jmap::JMAPClient::new(access_token, &session_url).await
            {
                Ok(c) => c,
                Err(e) => {
                    log::error!("Failed to create JMAP client: {}", e);
                    return Ok(Index::default());
                }
            };

            let emails = match jmap_client.search_emails(&query, limit).await {
                Ok(e) => e,
                Err(e) => {
                    log::warn!("JMAP search failed: {}", e);
                    return Ok(Index::default());
                }
            };

            let mut index = Index::new();
            for email in &emails {
                let doc = haystack_jmap::email_to_document(email);
                index.insert(doc.id.clone(), doc);
            }
            Ok(index)
        }
    }
}