feat: cli only prints json, cli-pretty-json feature
This commit is contained in:
parent
44fe9bc48e
commit
8881d0fa59
|
@ -6,10 +6,11 @@ edition = "2021"
|
|||
license = "MIT OR Apache-2.0"
|
||||
|
||||
[features]
|
||||
default = ["cli", "fancy"]
|
||||
default = ["cli", "cli-pretty-json", "fancy-errors"]
|
||||
|
||||
fancy = ["miette/fancy"]
|
||||
fancy-errors = ["miette/fancy"]
|
||||
cli = ["dep:clap", "dep:tracing-subscriber"]
|
||||
cli-pretty-json = ["dep:colored_json"]
|
||||
|
||||
[dependencies]
|
||||
miette = { version = "5.10.0", features = ["fancy"] }
|
||||
|
@ -30,6 +31,7 @@ pkce = "0.2.0"
|
|||
|
||||
clap = { version = "4.3.19", features = ["derive", "env"], optional = true }
|
||||
tracing-subscriber = { version = "0.3.17", optional = true }
|
||||
colored_json = { version = "3.2.0", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
test-log = { version = "0.2.12", default-features = false, features = ["trace"] }
|
||||
|
|
16
src/cli.rs
16
src/cli.rs
|
@ -1,4 +1,20 @@
|
|||
use crate::Data;
|
||||
|
||||
pub mod calendar_history;
|
||||
pub mod energy;
|
||||
pub mod powerwall;
|
||||
pub mod vehicle;
|
||||
|
||||
pub fn print_json<T>(data: Data<T>) {
|
||||
#[cfg(feature = "cli-pretty-json")]
|
||||
{
|
||||
use colored_json::prelude::*;
|
||||
println!("{}", data.body().to_colored_json_auto().unwrap());
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "cli-pretty-json"))]
|
||||
{
|
||||
println!("{:#?}", data.body());
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::calendar_history::CalendarHistoryValues;
|
||||
use crate::cli::calendar_history::CalendarHistoryArgs;
|
||||
use crate::cli::print_json;
|
||||
use crate::energy::EnergySiteId;
|
||||
use crate::Api;
|
||||
use chrono::DateTime;
|
||||
|
@ -42,8 +43,7 @@ impl EnergySiteArgs {
|
|||
start_date,
|
||||
end_date,
|
||||
};
|
||||
let history = api.energy_sites_calendar_history(&values).await?;
|
||||
println!("{:#?}", history);
|
||||
print_json(api.energy_sites_calendar_history(&values).await?);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::calendar_history::{HistoryKind, HistoryPeriod};
|
||||
use crate::cli::print_json;
|
||||
use crate::powerwall::{PowerwallEnergyHistoryValues, PowerwallId};
|
||||
use crate::Api;
|
||||
use clap::{Args, Subcommand};
|
||||
|
@ -23,18 +24,18 @@ impl PowerwallArgs {
|
|||
pub async fn run(&self, api: &Api) -> miette::Result<()> {
|
||||
match self.command {
|
||||
PowerwallCommand::Status => {
|
||||
dbg!(api.powerwall_status(&self.id).await?);
|
||||
print_json(api.powerwall_status(&self.id).await?);
|
||||
}
|
||||
PowerwallCommand::History => {
|
||||
dbg!(
|
||||
print_json(
|
||||
api.powerwall_energy_history(&PowerwallEnergyHistoryValues {
|
||||
powerwall_id: self.id.clone(),
|
||||
period: HistoryPeriod::Day,
|
||||
kind: HistoryKind::Power,
|
||||
start_date: None,
|
||||
end_date: None
|
||||
end_date: None,
|
||||
})
|
||||
.await?
|
||||
.await?,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::cli::print_json;
|
||||
use crate::vehicles::{SetChargeLimit, SetChargingAmps};
|
||||
use crate::{Api, VehicleId};
|
||||
use clap::{Args, Subcommand};
|
||||
|
@ -35,28 +36,24 @@ impl VehicleArgs {
|
|||
pub async fn run(self, api: &Api) -> miette::Result<()> {
|
||||
match self.command {
|
||||
VehicleCommand::Data => {
|
||||
dbg!(api.vehicle_data(&self.id).await?);
|
||||
print_json(api.vehicle_data(&self.id).await?);
|
||||
}
|
||||
VehicleCommand::ChargeState => {
|
||||
dbg!(api.charge_state(&self.id).await?);
|
||||
print_json(api.charge_state(&self.id).await?);
|
||||
}
|
||||
VehicleCommand::SetChargeLimit { percent } => {
|
||||
dbg!(
|
||||
api.set_charge_limit(&self.id, &SetChargeLimit { percent })
|
||||
.await?
|
||||
);
|
||||
.await?;
|
||||
}
|
||||
VehicleCommand::SetChargingAmps { charging_amps } => {
|
||||
dbg!(
|
||||
api.set_charging_amps(&self.id, &SetChargingAmps { charging_amps })
|
||||
.await?
|
||||
);
|
||||
.await?;
|
||||
}
|
||||
VehicleCommand::ChargeStart => {
|
||||
dbg!(api.charge_start(&self.id).await?);
|
||||
api.charge_start(&self.id).await?;
|
||||
}
|
||||
VehicleCommand::ChargeStop => {
|
||||
dbg!(api.charge_stop(&self.id).await?);
|
||||
api.charge_stop(&self.id).await?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
44
src/lib.rs
44
src/lib.rs
|
@ -55,7 +55,7 @@ impl Api {
|
|||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
async fn get<D>(&self, url: &str) -> Result<D, TeslatteError>
|
||||
async fn get<D>(&self, url: &str) -> Result<Data<D>, TeslatteError>
|
||||
where
|
||||
D: for<'de> Deserialize<'de> + Debug,
|
||||
{
|
||||
|
@ -82,10 +82,10 @@ impl Api {
|
|||
})?;
|
||||
trace!(?body);
|
||||
|
||||
let json = Self::parse_json::<D, _>(&body, request)?;
|
||||
trace!(?json);
|
||||
let data = Self::parse_json::<D, _>(&body, request)?;
|
||||
trace!(?data);
|
||||
|
||||
Ok(json)
|
||||
Ok(Data { data, body })
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
|
@ -201,10 +201,40 @@ struct ResponseError {
|
|||
#[derive(Debug, Serialize)]
|
||||
struct Empty {}
|
||||
|
||||
/// Data and body from a request. The body can be used for debugging. 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)]
|
||||
pub struct Data<T> {
|
||||
data: T,
|
||||
body: String,
|
||||
}
|
||||
|
||||
impl<T> Data<T> {
|
||||
pub fn data(&self) -> &T {
|
||||
&self.data
|
||||
}
|
||||
|
||||
pub fn body(&self) -> &str {
|
||||
&self.body
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> std::ops::Deref for Data<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.data
|
||||
}
|
||||
}
|
||||
|
||||
/// GET /api/1/[url]
|
||||
macro_rules! get {
|
||||
($name:ident, $return_type:ty, $url:expr) => {
|
||||
pub async fn $name(&self) -> Result<$return_type, crate::error::TeslatteError> {
|
||||
pub async fn $name(
|
||||
&self,
|
||||
) -> Result<crate::Data<$return_type>, crate::error::TeslatteError> {
|
||||
let url = format!("{}{}", crate::API_URL, $url);
|
||||
self.get(&url).await
|
||||
}
|
||||
|
@ -220,7 +250,7 @@ macro_rules! get_arg {
|
|||
pub async fn $name(
|
||||
&self,
|
||||
arg: &$arg_type,
|
||||
) -> miette::Result<$return_type, crate::error::TeslatteError> {
|
||||
) -> miette::Result<crate::Data<$return_type>, crate::error::TeslatteError> {
|
||||
let url = format!($url, arg);
|
||||
let url = format!("{}{}", crate::API_URL, url);
|
||||
self.get(&url).await
|
||||
|
@ -235,7 +265,7 @@ macro_rules! get_args {
|
|||
pub async fn $name(
|
||||
&self,
|
||||
values: &$args,
|
||||
) -> miette::Result<$return_type, crate::error::TeslatteError> {
|
||||
) -> miette::Result<crate::Data<$return_type>, crate::error::TeslatteError> {
|
||||
let url = values.format($url);
|
||||
let url = format!("{}{}", crate::API_URL, url);
|
||||
self.get(&url).await
|
||||
|
|
|
@ -3,6 +3,7 @@ use serde::{Deserialize, Serialize};
|
|||
use teslatte::auth::{AccessToken, RefreshToken};
|
||||
use teslatte::cli::energy::EnergySiteArgs;
|
||||
use teslatte::cli::powerwall::PowerwallArgs;
|
||||
use teslatte::cli::print_json;
|
||||
use teslatte::cli::vehicle::VehicleArgs;
|
||||
use teslatte::Api;
|
||||
|
||||
|
@ -10,7 +11,7 @@ use teslatte::Api;
|
|||
///
|
||||
/// A command line interface for the Tesla API.
|
||||
#[derive(Parser, Debug)]
|
||||
#[clap(author, version, about, long_about = None)]
|
||||
#[clap(author, version)]
|
||||
struct Cli {
|
||||
#[clap(subcommand)]
|
||||
command: Command,
|
||||
|
@ -105,13 +106,13 @@ async fn main() -> miette::Result<()> {
|
|||
let api = Api::new(access_token, refresh_token);
|
||||
match api_args.command {
|
||||
ApiCommand::Vehicles => {
|
||||
dbg!(api.vehicles().await?);
|
||||
print_json(api.vehicles().await?);
|
||||
}
|
||||
ApiCommand::Vehicle(v) => {
|
||||
v.run(&api).await?;
|
||||
}
|
||||
ApiCommand::EnergySites => {
|
||||
dbg!(api.energy_sites().await?);
|
||||
print_json(api.energy_sites().await?);
|
||||
}
|
||||
ApiCommand::EnergySite(e) => {
|
||||
e.run(&api).await?;
|
||||
|
|
Loading…
Reference in a new issue