1#[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 #[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}