1use std::collections::HashMap;
6
7use crate::{
8 config::{Config, DeployStrategy},
9 error::ServerlessError,
10 serializer::{Serializer, get_default_serializer},
11 transport::{Transport, get_default_transport},
12};
13
14pub struct Client {
16 config: Config,
17 transport: Box<dyn Transport>,
18 serializer: Serializer,
19}
20
21impl Client {
22 pub fn new() -> Result<Self, ServerlessError> {
28 let config = Config::from_env();
29 let serializer = get_default_serializer();
30 let transport = get_default_transport(config.timeout, config.retries);
31
32 Ok(Self {
33 config,
34 transport,
35 serializer,
36 })
37 }
38
39 pub fn with_config(config: Config) -> Result<Self, ServerlessError> {
45 let serializer = get_default_serializer();
46 let transport = get_default_transport(config.timeout, config.retries);
47
48 Ok(Self {
49 config,
50 transport,
51 serializer,
52 })
53 }
54
55 pub async fn call_function(
67 &self,
68 function_name: &str,
69 payload: Vec<u8>,
70 headers: Option<HashMap<String, String>>,
71 ) -> Result<Vec<u8>, ServerlessError> {
72 match self.config.deploy_strategy() {
73 DeployStrategy::Remote => self.transport.call(function_name, payload, headers).await,
74 DeployStrategy::Local => Err(ServerlessError::Generic(
75 "Local call mode should not reach client runtime".into(),
76 )),
77 DeployStrategy::Mock => Ok(b"{}".to_vec()),
78 }
79 }
80
81 #[must_use]
83 pub fn transport(&self) -> &dyn Transport {
84 self.transport.as_ref()
85 }
86
87 #[must_use]
89 pub fn serializer(&self) -> &Serializer {
90 &self.serializer
91 }
92}
93
94impl Default for Client {
95 fn default() -> Self {
96 Self::new().expect("Failed to create default Client")
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn test_client_default() {
106 let client = Client::default();
107 assert_eq!(client.config.base_url, "http://localhost:3000");
108 }
109}