refactor: RequestData private, GET->Get etc. Docs.

This commit is contained in:
gak 2023-10-10 13:23:53 +11:00
parent a3f941544d
commit 041deeb3a6
No known key found for this signature in database
2 changed files with 29 additions and 22 deletions

View file

@ -35,20 +35,24 @@ pub struct VehicleId(u64);
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ExternalVehicleId(u64); pub struct ExternalVehicleId(u64);
pub enum RequestData<'a> { enum RequestData<'a> {
GET { url: &'a str }, Get { url: &'a str },
POST { url: &'a str, payload: &'a str }, Post { url: &'a str, payload: &'a str },
} }
impl Display for RequestData<'_> { impl Display for RequestData<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
RequestData::GET { url } => write!(f, "GET {}", url), RequestData::Get { url } => write!(f, "GET {}", url),
RequestData::POST { url, payload } => write!(f, "POST {} {}", url, payload), RequestData::Post { url, payload } => write!(f, "POST {} {}", url, payload),
} }
} }
} }
/// API client for the Tesla API.
///
/// Main entry point for the API. It contains the access token and refresh token, and can be used
/// to make requests to the API.
pub struct Api { pub struct Api {
pub access_token: AccessToken, pub access_token: AccessToken,
pub refresh_token: Option<RefreshToken>, pub refresh_token: Option<RefreshToken>,
@ -71,7 +75,7 @@ impl Api {
where where
D: for<'de> Deserialize<'de> + Debug, D: for<'de> Deserialize<'de> + Debug,
{ {
self.request(&RequestData::GET { url }).await self.request(&RequestData::Get { url }).await
} }
async fn post<S>(&self, url: &str, body: S) -> Result<ResponseData<PostResponse>, TeslatteError> async fn post<S>(&self, url: &str, body: S) -> Result<ResponseData<PostResponse>, TeslatteError>
@ -80,7 +84,7 @@ impl Api {
{ {
let payload = let payload =
&serde_json::to_string(&body).expect("Should not fail creating the request struct."); &serde_json::to_string(&body).expect("Should not fail creating the request struct.");
let request_data = RequestData::POST { url, payload }; let request_data = RequestData::Post { url, payload };
let data = self.request::<PostResponse>(&request_data).await?; let data = self.request::<PostResponse>(&request_data).await?;
if !data.data.result { if !data.data.result {
@ -105,8 +109,8 @@ impl Api {
debug!("{request_data}"); debug!("{request_data}");
let request_builder = match request_data { let request_builder = match request_data {
RequestData::GET { url } => self.client.get(*url), RequestData::Get { url } => self.client.get(*url),
RequestData::POST { url, payload } => self RequestData::Post { url, payload } => self
.client .client
.post(*url) .post(*url)
.header("Content-Type", "application/json") .header("Content-Type", "application/json")
@ -188,12 +192,14 @@ impl<T> From<ResponseDeserializer<T>> for Response<T> {
} }
} }
/// Standard response data from the API. Contains a reason string and a result bool.
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct PostResponse { pub struct PostResponse {
reason: String, reason: String,
result: bool, result: bool,
} }
/// Standard error response from the API.
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
struct ResponseError { struct ResponseError {
error: String, error: String,
@ -203,10 +209,11 @@ struct ResponseError {
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
struct Empty {} struct Empty {}
/// Data and body from a request. The body can be used for debugging. The CLI can optionally /// Data and body from a request. The body can be used for debugging.
/// print the raw JSON so the user can manipulate it.
/// ///
/// This struct will automatically deref to the data type for better ergonomics. /// The CLI can optionally print the raw JSON so the user can manipulate it.
///
/// This struct will automatically deref to the `data` type for better ergonomics.
#[derive(Debug)] #[derive(Debug)]
pub struct ResponseData<T> { pub struct ResponseData<T> {
data: T, data: T,
@ -335,7 +342,7 @@ mod tests {
"error":{"error": "timeout","error_description": "s"} "error":{"error": "timeout","error_description": "s"}
}"#; }"#;
let request_data = RequestData::POST { let request_data = RequestData::Post {
url: "https://example.com", url: "https://example.com",
payload: "doesn't matter", payload: "doesn't matter",
}; };

View file

@ -461,7 +461,7 @@ mod tests {
} }
"#; "#;
let request_data = RequestData::GET { let request_data = RequestData::Get {
url: "https://owner-api.teslamotors.com/api/1/vehicles/1234567890/data_request/charge_state", url: "https://owner-api.teslamotors.com/api/1/vehicles/1234567890/data_request/charge_state",
}; };
Api::parse_json::<ChargeState>(&request_data, s.to_string()).unwrap(); Api::parse_json::<ChargeState>(&request_data, s.to_string()).unwrap();
@ -508,7 +508,7 @@ mod tests {
} }
"#; "#;
let request_data = RequestData::GET { let request_data = RequestData::Get {
url: "https://owner-api.teslamotors.com/api/1/vehicles/1234567890/data_request/climate_state", url: "https://owner-api.teslamotors.com/api/1/vehicles/1234567890/data_request/climate_state",
}; };
Api::parse_json::<ClimateState>(&request_data, s.to_string()).unwrap(); Api::parse_json::<ClimateState>(&request_data, s.to_string()).unwrap();
@ -535,7 +535,7 @@ mod tests {
} }
"#; "#;
let request_data = RequestData::GET { let request_data = RequestData::Get {
url: "https://owner-api.teslamotors.com/api/1/vehicles/1234567890/data_request/drive_state", url: "https://owner-api.teslamotors.com/api/1/vehicles/1234567890/data_request/drive_state",
}; };
Api::parse_json::<DriveState>(&request_data, s.to_string()).unwrap(); Api::parse_json::<DriveState>(&request_data, s.to_string()).unwrap();
@ -557,7 +557,7 @@ mod tests {
} }
"#; "#;
let request_data = RequestData::GET { let request_data = RequestData::Get {
url: "https://owner-api.teslamotors.com/api/1/vehicles/1234567890/data_request/gui_settings", url: "https://owner-api.teslamotors.com/api/1/vehicles/1234567890/data_request/gui_settings",
}; };
Api::parse_json::<GuiSettings>(&request_data, s.to_string()).unwrap(); Api::parse_json::<GuiSettings>(&request_data, s.to_string()).unwrap();
@ -607,7 +607,7 @@ mod tests {
} }
"#; "#;
let request_data = RequestData::GET { let request_data = RequestData::Get {
url: "https://owner-api.teslamotors.com/api/1/vehicles/1234567890/data_request/vehicle_config", url: "https://owner-api.teslamotors.com/api/1/vehicles/1234567890/data_request/vehicle_config",
}; };
Api::parse_json::<VehicleConfig>(&request_data, s.to_string()).unwrap(); Api::parse_json::<VehicleConfig>(&request_data, s.to_string()).unwrap();
@ -682,7 +682,7 @@ mod tests {
} }
"#; "#;
let request_data = RequestData::GET { let request_data = RequestData::Get {
url: "https://owner-api.teslamotors.com/api/1/vehicles/1234567890/data_request/vehicle_state", url: "https://owner-api.teslamotors.com/api/1/vehicles/1234567890/data_request/vehicle_state",
}; };
Api::parse_json::<VehicleState>(&request_data, s.to_string()).unwrap(); Api::parse_json::<VehicleState>(&request_data, s.to_string()).unwrap();
@ -692,7 +692,7 @@ mod tests {
fn json_vehicle_data_htlc_2023_09_19() { fn json_vehicle_data_htlc_2023_09_19() {
let s = include_str!("../testdata/vehicle_data_HTLC_2023_09_19.json"); let s = include_str!("../testdata/vehicle_data_HTLC_2023_09_19.json");
let request_data = RequestData::GET { let request_data = RequestData::Get {
url: "https://owner-api.teslamotors.com/api/1/vehicles/1234567890/vehicle_data", url: "https://owner-api.teslamotors.com/api/1/vehicles/1234567890/vehicle_data",
}; };
Api::parse_json::<VehicleData>(&request_data, s.to_string()).unwrap(); Api::parse_json::<VehicleData>(&request_data, s.to_string()).unwrap();
@ -702,7 +702,7 @@ mod tests {
fn json_vehicle_data_htlc_2023_10_09() { fn json_vehicle_data_htlc_2023_10_09() {
let s = include_str!("../testdata/vehicle_data_HTLC_2023_10_09.json"); let s = include_str!("../testdata/vehicle_data_HTLC_2023_10_09.json");
let request_data = RequestData::GET { let request_data = RequestData::Get {
url: "https://owner-api.teslamotors.com/api/1/vehicles/1234567890/vehicle_data", url: "https://owner-api.teslamotors.com/api/1/vehicles/1234567890/vehicle_data",
}; };
Api::parse_json::<VehicleData>(&request_data, s.to_string()).unwrap(); Api::parse_json::<VehicleData>(&request_data, s.to_string()).unwrap();
@ -712,7 +712,7 @@ mod tests {
fn json_vehicle_data_bitcoin_lightning_2023_10_09() { fn json_vehicle_data_bitcoin_lightning_2023_10_09() {
let s = include_str!("../testdata/vehicle_data_BitcoinLightning_2023_10_09.json"); let s = include_str!("../testdata/vehicle_data_BitcoinLightning_2023_10_09.json");
let request_data = RequestData::GET { let request_data = RequestData::Get {
url: "https://owner-api.teslamotors.com/api/1/vehicles/1234567890/vehicle_data", url: "https://owner-api.teslamotors.com/api/1/vehicles/1234567890/vehicle_data",
}; };
Api::parse_json::<VehicleData>(&request_data, s.to_string()).unwrap(); Api::parse_json::<VehicleData>(&request_data, s.to_string()).unwrap();