use serde_json::{Value, json};
use super::config::{AzureAIConfig, AzureAIEndpointType};
use crate::core::providers::base::HttpErrorMapper;
use crate::core::providers::unified_provider::ProviderError;
use crate::core::types::{
context::RequestContext,
image::ImageGenerationRequest,
responses::{ImageData, ImageGenerationResponse},
};
#[derive(Debug, Clone)]
pub struct AzureAIImageHandler {
config: AzureAIConfig,
client: reqwest::Client,
}
impl AzureAIImageHandler {
pub fn new(config: AzureAIConfig) -> Result<Self, ProviderError> {
let client = reqwest::Client::new();
Ok(Self { config, client })
}
pub async fn generate_image(
&self,
request: ImageGenerationRequest,
_context: RequestContext,
) -> Result<ImageGenerationResponse, ProviderError> {
if request.prompt.is_empty() {
return Err(ProviderError::invalid_request(
"azure_ai",
"Prompt cannot be empty",
));
}
let azure_request = json!({
"model": request.model.clone().unwrap_or_else(|| "flux-1.1-pro".to_string()),
"prompt": request.prompt,
"n": request.n.unwrap_or(1),
"size": request.size.clone().unwrap_or_else(|| "1024x1024".to_string()),
"quality": request.quality.clone().unwrap_or_else(|| "standard".to_string())
});
let url = self
.config
.build_endpoint_url(AzureAIEndpointType::ImageGeneration.as_path())
.map_err(|e| ProviderError::configuration("azure_ai", &e))?;
let response = self
.client
.post(&url)
.header(
"Authorization",
format!(
"Bearer {}",
self.config.base.api_key.as_ref().ok_or_else(|| {
ProviderError::authentication("azure_ai", "API key not set")
})?
),
)
.header("Content-Type", "application/json")
.json(&azure_request)
.send()
.await
.map_err(|e| ProviderError::network("azure_ai", format!("Request failed: {}", e)))?;
if !response.status().is_success() {
let status = response.status().as_u16();
let error_body = response
.text()
.await
.unwrap_or_else(|_| "Unknown error".to_string());
return Err(HttpErrorMapper::map_status_code(
"azure_ai",
status,
&error_body,
));
}
let _response_json: Value = response.json().await.map_err(|e| {
ProviderError::serialization("azure_ai", format!("Failed to parse response: {}", e))
})?;
let data = vec![ImageData {
url: Some("https://example.com/generated_image.jpg".to_string()),
b64_json: None,
revised_prompt: None,
}];
Ok(ImageGenerationResponse {
created: chrono::Utc::now().timestamp() as u64,
data,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_handler_creation() {
let config = AzureAIConfig::new("azure_ai");
let _result = AzureAIImageHandler::new(config);
}
}