pub mod cli;
pub mod error;
pub mod gemini;
pub mod image_prompt;
pub mod markdown;
pub mod models;
pub mod openai;
pub mod output;
pub mod wechat;
pub use error::{Error, Result};
pub use models::{Config, Frontmatter};
use std::path::Path;
pub struct WxUploader {
wechat_client: wechat::WeChatClient,
config: Config,
}
impl WxUploader {
pub async fn new(config: Config) -> Result<Self> {
let wechat_client = wechat::WeChatClient::new(
config.wechat_app_id.clone(),
config.wechat_app_secret.clone(),
)
.await
.map_err(|e| Error::wechat(e.to_string()))?;
Ok(Self {
wechat_client,
config,
})
}
pub async fn refresh_token(&self) -> Result<String> {
self.wechat_client
.refresh_token()
.await
.map_err(|e| Error::wechat(e.to_string()))
}
pub async fn upload_file<P: AsRef<Path>>(&self, path: P, force: bool) -> Result<()> {
wechat::upload_file(
&self.wechat_client,
&self.config,
path.as_ref(),
force,
self.config.verbose,
)
.await
}
pub async fn process_directory<P: AsRef<Path>>(&self, dir: P) -> Result<()> {
wechat::process_directory(
&self.wechat_client,
&self.config,
dir.as_ref(),
self.config.verbose,
)
.await
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_uploader_creation_without_keys() {
let config = Config {
wechat_app_id: "test_app_id".to_string(),
wechat_app_secret: "test_secret".to_string(),
openai_api_key: None,
gemini_api_key: None,
verbose: false,
};
let result = WxUploader::new(config).await;
assert!(result.is_err());
}
#[test]
fn test_config_from_env_missing_required() {
unsafe {
std::env::remove_var("WECHAT_APP_ID");
std::env::remove_var("WECHAT_APP_SECRET");
}
let result = Config::from_env();
assert!(result.is_err());
}
}