use crate::paths::Paths;
use axum::http::StatusCode;
use axum::Json;
use furigana::{AnalyzeResult, Furigana};
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
use std::sync::Arc;
use tokio::sync::RwLock;
pub(super) const MAX_TEXT_LEN: usize = 10_000;
#[derive(Clone)]
pub(super) struct AppState {
pub(super) furigana: Arc<RwLock<Arc<Furigana>>>,
pub(super) tokens: Arc<Vec<String>>,
pub(super) admin_tokens: Arc<Vec<String>>,
pub(super) paths: Arc<Paths>,
}
#[derive(Debug, Deserialize)]
pub(super) struct FuriganaParams {
#[serde(default)]
pub(super) text: Option<String>,
#[serde(default)]
pub(super) text_b64: Option<String>,
#[serde(default = "default_mode")]
pub(super) mode: String,
#[serde(default = "default_short_pause")]
pub(super) short_pause: String,
#[serde(default = "default_long_pause")]
pub(super) long_pause: String,
#[serde(default = "default_true")]
pub(super) keep_period: bool,
#[serde(default)]
pub(super) segmented: bool,
#[serde(default = "default_max_seg")]
pub(super) max_segment_len: usize,
#[serde(default)]
pub(super) debug: bool,
}
pub(super) fn default_mode() -> String {
"tts".to_string()
}
pub(super) fn default_short_pause() -> String {
" ".to_string()
}
pub(super) fn default_long_pause() -> String {
" ".to_string()
}
pub(super) fn default_true() -> bool {
true
}
pub(super) fn default_max_seg() -> usize {
60
}
#[derive(Debug, Serialize)]
pub(super) struct FuriganaResponse {
pub(super) result: String,
pub(super) mode: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub(super) segments: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub(super) timings_ms: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub(super) analyze: Option<AnalyzeResult>,
}
pub(super) type ApiError = (StatusCode, Json<Value>);
pub(super) fn error(code: StatusCode, msg: impl Into<String>) -> ApiError {
(code, Json(json!({ "error": msg.into() })))
}