1use std::fmt::Debug;
2use std::pin::Pin;
3
4use crate::{error::Error, http::HttpClient, request::Requestable, Client, Provider};
5
6use futures::Stream;
7
8#[derive(Debug, Clone)]
9pub struct Chat<'c, P: Provider, H: HttpClient> {
10 pub(crate) client: &'c Client<P, H>,
11}
12
13impl<'c, P, H> Chat<'c, P, H>
14where
15 P: Provider,
16 H: HttpClient,
17{
18 pub fn new(client: &'c Client<P, H>) -> Self {
19 Self { client }
20 }
21
22 pub async fn create<T>(&self, request: T) -> Result<P::ChatResponse, Error>
23 where
24 T: TryInto<P::ChatRequest>,
25 T::Error: Debug,
26 {
27 let request: P::ChatRequest = request.try_into().map_err(|e| {
28 Error::InvalidArgument(format!("Failed to convert to ChatRequest. Error = {e:?}"))
29 })?;
30 let stream = request.stream();
31 match stream {
32 true => Err(Error::InvalidArgument(
33 "When stream is true, use the client.create_stream function instead".into(),
34 )),
35 false => {
36 self.client
37 .provider
38 .chat(&self.client.http_client, request)
39 .await
40 }
41 }
42 }
43 pub async fn create_stream<T>(
44 &self,
45 request: T,
46 ) -> Result<Pin<Box<dyn Stream<Item = Result<P::ChatResponseStream, Error>> + Send>>, Error>
47 where
48 T: TryInto<P::ChatRequest>,
49 T::Error: Debug,
50 {
51 let request: P::ChatRequest = request.try_into().map_err(|e| {
52 Error::InvalidArgument(format!("Failed to convert to ChatRequest. Error = {e:?}"))
53 })?;
54 let stream = request.stream();
55 match stream {
56 false => Err(Error::InvalidArgument(
57 "When stream is false, use the client.create function instead".into(),
58 )),
59 true => {
60 self.client
61 .provider
62 .chat_stream(&self.client.http_client, request)
63 .await
64 }
65 }
66 }
67}