greentic-designer 0.6.0

Greentic Designer — orchestrator that powers Adaptive Card design via the adaptive-card-mcp toolkit
Documentation
//! Image storage abstraction.

pub mod local;

use anyhow::Result;
use serde::{Deserialize, Serialize};
use std::time::SystemTime;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ImageMeta {
    pub id: String,
    pub original_filename: String,
    pub content_type: String,
    pub size_bytes: u64,
    #[serde(with = "system_time_serde")]
    pub stored_at: SystemTime,
}

pub trait ImageStore: Send + Sync {
    fn store(
        &self,
        filename: &str,
        data: &[u8],
    ) -> impl std::future::Future<Output = Result<ImageMeta>> + Send;

    fn load(
        &self,
        id: &str,
    ) -> impl std::future::Future<Output = Result<(ImageMeta, Vec<u8>)>> + Send;

    fn delete(&self, id: &str) -> impl std::future::Future<Output = Result<()>> + Send;
}

mod system_time_serde {
    use serde::{Deserialize, Deserializer, Serialize, Serializer};
    use std::time::{Duration, SystemTime, UNIX_EPOCH};

    pub fn serialize<S: Serializer>(time: &SystemTime, ser: S) -> Result<S::Ok, S::Error> {
        let d = time.duration_since(UNIX_EPOCH).unwrap_or(Duration::ZERO);
        d.as_secs().serialize(ser)
    }

    pub fn deserialize<'de, D: Deserializer<'de>>(de: D) -> Result<SystemTime, D::Error> {
        let secs = u64::deserialize(de)?;
        Ok(UNIX_EPOCH + Duration::from_secs(secs))
    }
}