So I have a design choice to make and am not sure what is the "better" way of doing this. Roughly speaking I want to have objects for interacting with several different public api's. I want the interaction to be the same from the code, atlhough all the details of the different api's are different. Also each of the api's have several common attributes, like name, api endpoints, connection client, timeout restrictions etc...
I want in the end to be able to shove all those api's as Boxed traits so I can treat them as the same type. The other requirement is that I need methods to be async. So far I have smth like this:
struct Executor<T> where T implements MyAPI {
pub id: String,
pub name: String,
pub general_endpoint: Url,
pub client: reqwest::Client,
....
}
impl Executor {
pub async fn call_method_1_api(args...) -> Result<Whatever> {
let response = self.client.call(T::get_url_for_method_1(args)).await?;
return T::process_method_1_response(response)
}
}
trait MyAPI {
pub fn get_url_for_method_1(args...) -> Url;
pub fn processes_method_1(response: Response) -> Url;
}
The main issue of this approach is that I can't stick all of my Executors (since they have different concrete types T) in a vector of Boxed values. I also can't make the trait to be responsible for the async calls since still that is not allowed in Rust. What is a good way of doing this at the moment? what to wrap/put in what in order to achieve this?