coder/
client.rs

1// TLS imports
2#[cfg(feature = "rustls")]
3type HttpsConnector = hyper_rustls::HttpsConnector<hyper::client::HttpConnector>;
4#[cfg(feature = "rust-native-tls")]
5use hyper_tls;
6#[cfg(feature = "rust-native-tls")]
7type HttpsConnector = hyper_tls::HttpsConnector<hyper::client::HttpConnector>;
8
9use std::error::Error;
10use std::sync::Arc;
11
12use hyper::StatusCode;
13use hyper::{self, Body};
14use hyper::{Client, Request};
15use url::Url;
16
17use crate::headers::Headers;
18use async_trait::async_trait;
19use serde::de::DeserializeOwned;
20use serde::Deserialize;
21
22const VERSION: &'static str = env!("CARGO_PKG_VERSION");
23
24pub struct Coder {
25    pub(crate) url: Url,
26    pub(crate) token: &'static str,
27    pub(crate) client: Arc<Client<HttpsConnector>>,
28}
29
30const API_PREFIX: &'static str = "/api";
31
32impl Coder {
33    pub fn new<T: ToString>(uri: String, token: T) -> Result<Self, Box<dyn Error>> {
34        Ok(Self {
35            url: uri.parse::<Url>()?.join(API_PREFIX)?,
36            token: Box::leak(token.to_string().into_boxed_str()),
37            client: Arc::new(Client::builder().build(HttpsConnector::new())),
38        })
39    }
40}
41
42#[derive(Debug)]
43pub struct ApiResponse<T: DeserializeOwned> {
44    pub headers: Headers,
45    pub status_code: StatusCode,
46    pub response: Result<T, ApiError>,
47}
48
49#[derive(Deserialize, Debug)]
50pub struct ApiError(pub serde_json::Value);
51
52#[async_trait]
53pub trait Executor {
54    type T: DeserializeOwned;
55
56    async fn execute(self) -> Result<ApiResponse<Self::T>, Box<dyn Error>>;
57}
58
59impl Coder {
60    /// Returns a populated request for creating custom queries.
61    #[inline]
62    pub fn new_request(&self) -> Result<Request<Body>, Box<dyn Error>> {
63        Ok(Request::builder()
64            .method(hyper::Method::GET)
65            .uri(self.url.to_string())
66            .header("User-Agent", format!("coder.rs {}", VERSION))
67            .header("Session-Token", self.token)
68            .body(Body::empty())?)
69    }
70}
71
72#[cfg(test)]
73pub(crate) mod test {
74    pub(crate) mod ids {
75        pub const ENV_ID: &'static str = "5ed15061-d7d3db1d91600a4fed28f6ed";
76        pub const IMAGE_ID: &'static str = "5ea8a569-596e6afd9301c23f8dabd87c";
77        pub const IMAGE_TAG_ID: &'static str = "latest";
78        pub const MEMBER_ID: &'static str = "5e876cf4-10abe9b2e54eb609c5ec1870";
79        pub const ORG_ID: &'static str = "default";
80        pub const REG_ID: &'static str = "5ea8a565-bdec42be59ffe9cf6b131e7c";
81        pub const SERVICE_ID: &'static str = "5f15b3a2-57f7a823e4d379409978edbf";
82        pub const USER_ID: &'static str = "5e876cf4-10abe9b2e54eb609c5ec1870";
83    }
84
85    use super::*;
86    use std::env;
87
88    pub(crate) fn client() -> Coder {
89        let url = env::var("MANAGER_URL").expect("no MANAGER_URL env provided");
90        let api_key = env::var("API_KEY").expect("no API_KEY env provided");
91        Coder::new(url, api_key).unwrap()
92    }
93}