feat: cli show json on POST and some errors

This commit is contained in:
gak 2023-08-29 16:13:43 +10:00
parent 3fd59df8b8
commit 900be5aa1f
No known key found for this signature in database
8 changed files with 53 additions and 27 deletions

View file

@ -2,17 +2,36 @@ pub mod energy;
pub mod powerwall;
pub mod vehicle;
use crate::error::TeslatteError;
use crate::Data;
use std::process::exit;
pub fn print_json<T>(data: Data<T>) {
pub fn print_json<T>(result: Result<Data<T>, TeslatteError>) {
match result {
Ok(data) => print_json_data(data),
Err(TeslatteError::ServerError { ref body, .. }) if body.is_some() => {
print_json_str(&body.clone().unwrap())
}
Err(e) => {
eprintln!("{}", e);
exit(1);
}
}
}
pub fn print_json_data<T>(data: Data<T>) {
// TODO: pretty print cli option
print_json_str(data.body());
}
pub fn print_json_str(body: &str) {
#[cfg(feature = "cli-pretty-json")]
{
use colored_json::prelude::*;
println!("{}", data.body().to_colored_json_auto().unwrap());
println!("{}", body.to_colored_json_auto().unwrap());
}
#[cfg(not(feature = "cli-pretty-json"))]
{
println!("{}", data.body());
println!("{}", body);
}
}

View file

@ -42,7 +42,7 @@ impl EnergySiteArgs {
start_date,
end_date,
};
print_json(api.energy_sites_calendar_history(&values).await?);
print_json(api.energy_sites_calendar_history(&values).await);
}
}
Ok(())

View file

@ -1,5 +1,5 @@
use crate::calendar_history::{HistoryKind, HistoryPeriod};
use crate::cli::print_json;
use crate::cli::print_json_data;
use crate::powerwall::{PowerwallEnergyHistoryValues, PowerwallId};
use crate::Api;
use clap::{Args, Subcommand};
@ -24,10 +24,10 @@ impl PowerwallArgs {
pub async fn run(&self, api: &Api) -> miette::Result<()> {
match self.command {
PowerwallCommand::Status => {
print_json(api.powerwall_status(&self.id).await?);
print_json_data(api.powerwall_status(&self.id).await?);
}
PowerwallCommand::History => {
print_json(
print_json_data(
api.powerwall_energy_history(&PowerwallEnergyHistoryValues {
powerwall_id: self.id.clone(),
period: HistoryPeriod::Day,

View file

@ -36,24 +36,28 @@ impl VehicleArgs {
pub async fn run(self, api: &Api) -> miette::Result<()> {
match self.command {
VehicleCommand::Data => {
print_json(api.vehicle_data(&self.id).await?);
print_json(api.vehicle_data(&self.id).await);
}
VehicleCommand::ChargeState => {
print_json(api.charge_state(&self.id).await?);
print_json(api.charge_state(&self.id).await);
}
VehicleCommand::SetChargeLimit { percent } => {
api.set_charge_limit(&self.id, &SetChargeLimit { percent })
.await?;
print_json(
api.set_charge_limit(&self.id, &SetChargeLimit { percent })
.await,
);
}
VehicleCommand::SetChargingAmps { charging_amps } => {
api.set_charging_amps(&self.id, &SetChargingAmps { charging_amps })
.await?;
print_json(
api.set_charging_amps(&self.id, &SetChargingAmps { charging_amps })
.await,
);
}
VehicleCommand::ChargeStart => {
api.charge_start(&self.id).await?;
print_json(api.charge_start(&self.id).await);
}
VehicleCommand::ChargeStop => {
api.charge_stop(&self.id).await?;
print_json(api.charge_stop(&self.id).await);
}
}
Ok(())

View file

@ -6,6 +6,7 @@ pub enum TeslatteError {
request: String,
msg: String,
description: Option<String>,
body: Option<String>,
},
#[error("{request} unhandled server response: {body}")]

View file

@ -89,7 +89,7 @@ impl Api {
}
#[instrument(skip(self))]
async fn post<S>(&self, url: &str, body: S) -> Result<(), TeslatteError>
async fn post<S>(&self, url: &str, body: S) -> Result<Data<PostResponse>, TeslatteError>
where
S: Serialize + Debug,
{
@ -122,16 +122,17 @@ impl Api {
source,
request: req_ctx(),
})?;
let json = Self::parse_json::<PostResponse, _>(&body, req_ctx)?;
trace!(?json);
let data = Self::parse_json::<PostResponse, _>(&body, req_ctx)?;
trace!(?data);
if json.result {
Ok(())
if data.result {
Ok(Data { data, body })
} else {
Err(TeslatteError::ServerError {
request: req_ctx(),
msg: json.reason,
msg: data.reason,
description: None,
body: Some(body),
})
}
}
@ -157,6 +158,7 @@ impl Api {
request: request(),
msg: e.error,
description: e.error_description,
body: Some(body.to_owned()),
}),
}
}
@ -187,7 +189,7 @@ impl<T> From<ResponseDeserializer<T>> for Response<T> {
}
#[derive(Debug, Deserialize)]
struct PostResponse {
pub struct PostResponse {
reason: String,
result: bool,
}
@ -281,7 +283,7 @@ macro_rules! post_arg {
&self,
arg: &$arg_type,
data: &$request_type,
) -> miette::Result<(), crate::error::TeslatteError> {
) -> miette::Result<crate::Data<crate::PostResponse>, crate::error::TeslatteError> {
let url = format!($url, arg);
let url = format!("{}{}", crate::API_URL, url);
self.post(&url, data).await
@ -296,7 +298,7 @@ macro_rules! post_arg_empty {
pub async fn $name(
&self,
arg: &$arg_type,
) -> miette::Result<(), crate::error::TeslatteError> {
) -> miette::Result<crate::Data<crate::PostResponse>, crate::error::TeslatteError> {
let url = format!($url, arg);
let url = format!("{}{}", crate::API_URL, url);
self.post(&url, &Empty {}).await

View file

@ -106,13 +106,13 @@ async fn main() -> miette::Result<()> {
let api = Api::new(access_token, refresh_token);
match api_args.command {
ApiCommand::Vehicles => {
print_json(api.vehicles().await?);
print_json(api.vehicles().await);
}
ApiCommand::Vehicle(v) => {
v.run(&api).await?;
}
ApiCommand::EnergySites => {
print_json(api.energy_sites().await?);
print_json(api.energy_sites().await);
}
ApiCommand::EnergySite(e) => {
e.run(&api).await?;

View file

@ -38,7 +38,7 @@ pub struct VehicleData {
/// gak: This was null for me, assuming String.
pub backseat_token_updated_at: Option<String>,
/// Some of these have been null for me, so making them all Option.
/// gak: Some of these have been null for me, so making them all Option.
pub charge_state: Option<ChargeState>,
pub climate_state: Option<ClimateState>,
pub drive_state: Option<DriveState>,