cooklang_import/converters/
mod.rs1mod anthropic;
2mod azure_openai;
3mod google;
4mod ollama;
5mod open_ai;
6mod prompt;
7
8pub use anthropic::AnthropicConverter;
9pub use azure_openai::AzureOpenAiConverter;
10pub use google::GoogleConverter;
11pub use ollama::OllamaConverter;
12pub use open_ai::OpenAiConverter;
13pub use prompt::{inject_recipe, COOKLANG_CONVERTER_PROMPT};
14
15use async_trait::async_trait;
16use serde::Serialize;
17use std::error::Error;
18
19#[derive(Debug, Clone, Default, Serialize)]
21pub struct TokenUsage {
22 pub input_tokens: Option<u32>,
24 pub output_tokens: Option<u32>,
26}
27
28#[derive(Debug, Clone, Default, Serialize)]
30pub struct ConversionMetadata {
31 pub model_version: Option<String>,
33 pub tokens_used: TokenUsage,
35 pub latency_ms: u64,
37}
38
39#[derive(Debug, Clone)]
41pub struct ConversionResult {
42 pub content: String,
44 pub metadata: ConversionMetadata,
46}
47
48#[async_trait]
50pub trait Converter: Send + Sync {
51 fn name(&self) -> &str;
53
54 async fn convert(
56 &self,
57 ingredients_and_instructions: &str,
58 ) -> Result<ConversionResult, Box<dyn Error + Send + Sync>>;
59}
60
61pub fn create_converter(
71 name: &str,
72 config: &crate::config::ProviderConfig,
73) -> Option<Box<dyn Converter>> {
74 match name {
75 "open_ai" => OpenAiConverter::new(config)
76 .ok()
77 .map(|c| Box::new(c) as Box<dyn Converter>),
78 "anthropic" => AnthropicConverter::new(config)
79 .ok()
80 .map(|c| Box::new(c) as Box<dyn Converter>),
81 "azure_openai" => AzureOpenAiConverter::new(config)
82 .ok()
83 .map(|c| Box::new(c) as Box<dyn Converter>),
84 "google" => GoogleConverter::new(config)
85 .ok()
86 .map(|c| Box::new(c) as Box<dyn Converter>),
87 "ollama" => OllamaConverter::new(config)
88 .ok()
89 .map(|c| Box::new(c) as Box<dyn Converter>),
90 _ => None,
91 }
92}