1use std::env;
2use std::sync::Arc;
3
4use http::Uri;
5use tonic::transport::Channel;
6pub use tonic::Request;
7use tower::ServiceBuilder;
8
9use crate::api::airlines_service_client::AirlinesServiceClient;
10use crate::api::routes_service_client::RoutesServiceClient;
11use crate::api::virtual_airlines_service_client::VirtualAirlinesServiceClient;
12use crate::auth::AuthSvc;
13use crate::oauth2::TokenSource;
14
15pub mod api {
16 #[doc(inline)]
17 pub use vasystem_api_grpc::*;
18}
19mod auth;
20mod oauth2;
21
22pub struct Client {
23 channel: AuthSvc,
24}
25
26impl Client {
27 pub async fn connect(
28 domain: String,
29 client_id: String,
30 client_secret: String,
31 scopes: Vec<String>,
32 ) -> Result<Client, Box<dyn std::error::Error>> {
33 let token_source =
34 TokenSource::new(domain.clone(), client_id, client_secret, scopes).await?;
35
36 let mut uri: Uri = format!("https://api.{}", domain).parse()?;
37
38 if cfg!(debug_assertions) {
39 match env::var_os("VASYSTEM_API_URL") {
40 Some(val) => uri = val.into_string().unwrap().parse()?,
41 None => (),
42 }
43 }
44
45 let channel = Channel::builder(uri).connect().await?;
46
47 let token_source = Arc::new(token_source);
48
49 let channel = ServiceBuilder::new()
50 .layer_fn(|s| AuthSvc::new(s, token_source.clone()))
51 .service(channel);
52
53 Ok(Client { channel })
54 }
55
56 pub fn airlines(&self) -> AirlinesServiceClient<AuthSvc> {
57 AirlinesServiceClient::new(self.channel.clone())
58 }
59
60 pub fn routes(&self) -> RoutesServiceClient<AuthSvc> {
61 RoutesServiceClient::new(self.channel.clone())
62 }
63
64 pub fn virtual_airlines(&self) -> VirtualAirlinesServiceClient<AuthSvc> {
65 VirtualAirlinesServiceClient::new(self.channel.clone())
66 }
67}