use futures_core::Stream;
use serde::{Deserialize, Serialize};
use crate::audio::AudioApiResult;
use crate::audio::SpeechInput;
use crate::audio::SpeechModel;
use crate::audio::SpeechResponseFormat;
use crate::audio::SpeechStreamResult;
use crate::audio::Speed;
use crate::audio::Voice;
use crate::macros::impl_display_for_serialize;
use crate::ApiError;
use crate::Client;
use crate::ClientError;
#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
pub struct SpeechRequestBody {
pub model: SpeechModel,
pub input: SpeechInput,
pub voice: Voice,
#[serde(skip_serializing_if = "Option::is_none")]
pub response_format: Option<SpeechResponseFormat>,
#[serde(skip_serializing_if = "Option::is_none")]
pub speed: Option<Speed>,
}
impl_display_for_serialize!(SpeechRequestBody);
pub(crate) async fn speech(
client: &Client,
request_body: SpeechRequestBody,
) -> AudioApiResult<impl Stream<Item = SpeechStreamResult>> {
let response = client
.post("https://api.openai.com/v1/audio/speech")
.json(&request_body)
.send()
.await
.map_err(ClientError::HttpRequestError)?;
let status_code = response.status();
if status_code.is_success() {
Ok(response.bytes_stream())
}
else {
let response_text = response
.text()
.await
.map_err(ClientError::ReadResponseTextFailed)?;
let error_response =
serde_json::from_str(&response_text).map_err(|error| {
ClientError::ErrorResponseDeserializationFailed {
error,
text: response_text,
}
})?;
Err(ApiError {
status_code,
error_response,
}.into())
}
}