feat: cli show json on POST and some errors
This commit is contained in:
parent
3fd59df8b8
commit
900be5aa1f
25
src/cli.rs
25
src/cli.rs
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(())
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 } => {
|
||||
print_json(
|
||||
api.set_charge_limit(&self.id, &SetChargeLimit { percent })
|
||||
.await?;
|
||||
.await,
|
||||
);
|
||||
}
|
||||
VehicleCommand::SetChargingAmps { charging_amps } => {
|
||||
print_json(
|
||||
api.set_charging_amps(&self.id, &SetChargingAmps { charging_amps })
|
||||
.await?;
|
||||
.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(())
|
||||
|
|
|
@ -6,6 +6,7 @@ pub enum TeslatteError {
|
|||
request: String,
|
||||
msg: String,
|
||||
description: Option<String>,
|
||||
body: Option<String>,
|
||||
},
|
||||
|
||||
#[error("{request} unhandled server response: {body}")]
|
||||
|
|
20
src/lib.rs
20
src/lib.rs
|
@ -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
|
||||
|
|
|
@ -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?;
|
||||
|
|
|
@ -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>,
|
||||
|
|
Loading…
Reference in a new issue