use crate::{ client::ChurchApiClient, error::Result, models::{BibleVerse, VerseOfTheDay, VerseCategory, PaginationParams, ApiListResponse, ApiVersion}, }; pub async fn get_random_verse(client: &ChurchApiClient) -> Result { // The response format is {success: bool, data: Verse} #[derive(serde::Deserialize, serde::Serialize)] struct VerseResponse { success: bool, data: ApiVerse, } #[derive(serde::Deserialize, serde::Serialize)] struct ApiVerse { id: String, reference: String, text: String, #[serde(rename = "is_active")] is_active: bool, } let url = client.build_url("/bible_verses/random"); let raw_response = client.client.get(&url).send().await?; let response_text = raw_response.text().await?; let response: VerseResponse = serde_json::from_str(&response_text) .map_err(|e| crate::error::ChurchApiError::Json(e))?; if response.success { Ok(BibleVerse::new(response.data.text, response.data.reference)) } else { Err(crate::error::ChurchApiError::Api("Bible verse API returned success=false".to_string())) } } pub async fn get_verse_of_the_day(client: &ChurchApiClient) -> Result { client.get_api("/bible/verse-of-the-day").await } pub async fn get_verse_by_reference(client: &ChurchApiClient, reference: &str) -> Result> { let path = format!("/bible/verse?reference={}", urlencoding::encode(reference)); match client.get_api(&path).await { Ok(verse) => Ok(Some(verse)), Err(crate::error::ChurchApiError::NotFound) => Ok(None), Err(e) => Err(e), } } pub async fn get_verses_by_category(client: &ChurchApiClient, category: VerseCategory, limit: Option) -> Result> { let mut path = format!("/bible/category/{}", category.display_name().to_lowercase()); if let Some(limit) = limit { path.push_str(&format!("?limit={}", limit)); } let response: crate::models::ApiListResponse = client.get_api_list(&path).await?; Ok(response.data.items) } pub async fn search_verses(client: &ChurchApiClient, query: &str, limit: Option) -> Result> { let mut path = format!("/bible_verses/search?q={}", urlencoding::encode(query)); if let Some(limit) = limit { path.push_str(&format!("&limit={}", limit)); } // The bible_verses/search endpoint returns a custom format with additional fields #[derive(serde::Deserialize, serde::Serialize)] struct ApiBibleVerse { id: String, reference: String, text: String, is_active: bool, created_at: String, updated_at: String, } #[derive(serde::Deserialize, serde::Serialize)] struct BibleSearchResponse { success: bool, data: Vec, message: Option, } let url = client.build_url(&path); let raw_response = client.client.get(&url).send().await?; let response_text = raw_response.text().await?; let response: BibleSearchResponse = serde_json::from_str(&response_text) .map_err(|e| crate::error::ChurchApiError::Json(e))?; if response.success { // Convert ApiBibleVerse to BibleVerse let verses = response.data.into_iter() .map(|api_verse| BibleVerse::new(api_verse.text, api_verse.reference)) .collect(); Ok(verses) } else { Ok(Vec::new()) } } // V2 API methods pub async fn get_random_verse_v2(client: &ChurchApiClient) -> Result { #[derive(serde::Deserialize, serde::Serialize)] struct VerseResponse { success: bool, data: ApiVerse, } #[derive(serde::Deserialize, serde::Serialize)] struct ApiVerse { id: String, reference: String, text: String, #[serde(rename = "is_active")] is_active: bool, } let url = client.build_url_with_version("/bible_verses/random", ApiVersion::V2); let raw_response = client.client.get(&url).send().await?; let response_text = raw_response.text().await?; let response: VerseResponse = serde_json::from_str(&response_text) .map_err(|e| crate::error::ChurchApiError::Json(e))?; if response.success { Ok(BibleVerse::new(response.data.text, response.data.reference)) } else { Err(crate::error::ChurchApiError::Api("Bible verse API returned success=false".to_string())) } } pub async fn get_bible_verses_v2(client: &ChurchApiClient, params: Option) -> Result> { let mut path = "/bible_verses".to_string(); if let Some(params) = params { let mut query_params = Vec::new(); if let Some(page) = params.page { query_params.push(("page", page.to_string())); } if let Some(per_page) = params.per_page { query_params.push(("per_page", per_page.to_string())); } if !query_params.is_empty() { let query_string = query_params .iter() .map(|(k, v)| format!("{}={}", k, urlencoding::encode(v))) .collect::>() .join("&"); path.push_str(&format!("?{}", query_string)); } } client.get_api_list_with_version(&path, ApiVersion::V2).await } pub async fn search_verses_v2(client: &ChurchApiClient, query: &str, limit: Option) -> Result> { let mut path = format!("/bible_verses/search?q={}", urlencoding::encode(query)); if let Some(limit) = limit { path.push_str(&format!("&limit={}", limit)); } let response: crate::models::ApiListResponse = client.get_api_list_with_version(&path, ApiVersion::V2).await?; Ok(response.data.items) }