diff --git a/tesla_api_coverage/src/main.rs b/tesla_api_coverage/src/main.rs index 5714add..fd2c769 100644 --- a/tesla_api_coverage/src/main.rs +++ b/tesla_api_coverage/src/main.rs @@ -37,26 +37,18 @@ async fn main() { cache_fetch(VEHICLE_COMMAND_URL, VEHICLE_COMMAND_FILE, args.cached) ); - // let timdorr_endpoints = timdorr::parse(&timdorr); - // let fleet_endpoints = fleet::parse(&fleet_html); - // let vehicle_command_endpoints = vehicle_command::parse(&command_golang); - let mut teslatte_project_path = PathBuf::from_str(env!("CARGO_MANIFEST_DIR")).unwrap(); teslatte_project_path.push(".."); + let teslatte_endpoints = teslatte::parse(&teslatte_project_path).unwrap(); - let teslatte_endpoints = teslatte::parse(&teslatte_project_path); + let fleet_endpoints = fleet::parse(&fleet_html); + let command_endpoints = vehicle_command::parse(&command_golang); + let timdorr_endpoints = timdorr::parse(&timdorr); - // // Make hashsets from all the keys and see what's different between timdorr and fleet - // let timdorr_keys: std::collections::HashSet<&String> = timdorr_endpoints.keys().collect(); - // let fleet_keys: std::collections::HashSet<&String> = fleet_endpoints.keys().collect(); - // - // let timdorr_only = timdorr_keys.difference(&fleet_keys); - // let fleet_only = fleet_keys.difference(&timdorr_keys); - // let both = timdorr_keys.intersection(&fleet_keys); - // - // info!("Timdorr only: {:?}", timdorr_only); - // info!("Fleet only: {:?}", fleet_only); - // info!("Both: {:?}", both); + info!("{} endpoints in teslatte", teslatte_endpoints.len()); + info!("{} endpoints in fleet", fleet_endpoints.len()); + info!("{} endpoints in command", command_endpoints.len()); + info!("{} endpoints in timdorr", timdorr_endpoints.len()); } async fn cache_fetch(url: &str, filename: &str, cache: bool) -> String { diff --git a/tesla_api_coverage/src/teslatte.rs b/tesla_api_coverage/src/teslatte.rs index 39379ba..b8cdfec 100644 --- a/tesla_api_coverage/src/teslatte.rs +++ b/tesla_api_coverage/src/teslatte.rs @@ -22,26 +22,22 @@ pub struct TeslatteEndpoint { } pub fn parse(path: &Path) -> anyhow::Result> { - // glob all .rs files from path - let mut path = PathBuf::from(path); path.push("src"); path.push("**/*.rs"); debug!("Globbing {path:?}"); + let mut endpoints = vec![]; let pattern = path.to_str().unwrap(); for file in glob::glob(pattern).unwrap() { let path = file?; - // if !path.ends_with("src/vehicles.rs") { - // continue; - // } - - parse_file(&path)?; + let append_endpoints = parse_file(&path)?; + endpoints.extend(append_endpoints); } - Ok(todo!()) + Ok(endpoints) } /// Examples @@ -58,8 +54,8 @@ pub fn parse(path: &Path) -> anyhow::Result> { /// pub_get_args!(powerwall_energy_history, PowerwallEnergyHistory, "/powerwalls/{}/energyhistory", PowerwallEnergyHistoryValues); /// } /// -fn parse_file(path: &PathBuf) -> anyhow::Result<()> { - info!("Parsing file: {path:?}"); +fn parse_file(path: &PathBuf) -> anyhow::Result> { + debug!("Parsing file: {path:?}"); let content = read_to_string(path)?; let mut endpoints = vec![]; @@ -91,32 +87,20 @@ fn parse_file(path: &PathBuf) -> anyhow::Result<()> { } trace!("Looking at line: {line:?}"); - let (_, maybe_endpoint) = opt(alt((get, get_arg, get_args)))(line).unwrap(); + let (_, maybe_endpoint) = + opt(alt((get, get_arg, get_args, post_arg, post_arg_empty)))(line).unwrap(); if let Some(endpoint) = maybe_endpoint { endpoints.push(endpoint); } } - dbg!(endpoints); - - Ok(()) + Ok(endpoints) } fn is_owner_api_start(line: &str) -> bool { line.ends_with("OwnerApi {") } -// fn common_macro_with_comma<'a>(expected_tag: &str, s: &'a str) -> IResult<&'a str, &'a str> { -// short_trace("common macro", s); -// let (s, _) = ignore_whitespace(s)?; -// let (s, _) = tag(expected_tag)(s)?; -// let (s, _) = tag("(")(s)?; -// let (s, fn_name) = function_name(s)?; -// let (s, ()) = comma(s)?; -// -// Ok((s, fn_name)) -// } - fn macro_fn_name_then_comma(expected_tag: &str) -> impl Fn(&str) -> IResult<&str, &str> + '_ { return move |s: &str| -> IResult<&str, &str> { short_trace("common macro", s); @@ -130,8 +114,8 @@ fn macro_fn_name_then_comma(expected_tag: &str) -> impl Fn(&str) -> IResult<&str }; } -/// get!(vehicles, Vec, "/vehicles"); -/// pub_get!(vehicles, Vec, "/vehicles"); +// get!(vehicles, Vec, "/vehicles"); +// pub_get!(vehicles, Vec, "/vehicles"); fn get(s: &str) -> IResult<&str, TeslatteEndpoint> { let (s, fn_name) = alt(( macro_fn_name_then_comma("get!"), @@ -152,7 +136,7 @@ fn get(s: &str) -> IResult<&str, TeslatteEndpoint> { Ok((s, endpoint)) } -/// get_arg!(vehicle_data, VehicleData, "/vehicles/{}/vehicle_data", VehicleId); +// get_arg!(vehicle_data, VehicleData, "/vehicles/{}/vehicle_data", VehicleId); fn get_arg(s: &str) -> IResult<&str, TeslatteEndpoint> { let (s, fn_name) = alt(( macro_fn_name_then_comma("get_arg!"), @@ -174,7 +158,7 @@ fn get_arg(s: &str) -> IResult<&str, TeslatteEndpoint> { Ok((s, endpoint)) } -/// pub_get_args!(powerwall_energy_history, PowerwallEnergyHistory, "/powerwalls/{}/energyhistory", PowerwallEnergyHistoryValues); +// pub_get_args!(powerwall_energy_history, PowerwallEnergyHistory, "/powerwalls/{}/energyhistory", PowerwallEnergyHistoryValues); fn get_args(s: &str) -> IResult<&str, TeslatteEndpoint> { let (s, fn_name) = alt(( macro_fn_name_then_comma("get_args!"), @@ -196,6 +180,49 @@ fn get_args(s: &str) -> IResult<&str, TeslatteEndpoint> { Ok((s, endpoint)) } +// post_arg!(set_charge_limit, SetChargeLimit, "/vehicles/{}/command/set_charge_limit", VehicleId); +fn post_arg(s: &str) -> IResult<&str, TeslatteEndpoint> { + let (s, fn_name) = alt(( + macro_fn_name_then_comma("post_arg!"), + macro_fn_name_then_comma("pub_post_arg!"), + ))(s)?; + let (s, response_type) = struct_name(s)?; + let (s, ()) = comma(s)?; + let (s, uri) = quoted_string(s)?; + let (s, ()) = comma(s)?; + let (s, arg_type) = struct_name(s)?; + let (s, _) = end_args(s)?; + + let endpoint = TeslatteEndpoint { + method: Method::POST, + endpoint: fn_name.to_string(), + uri: uri.to_string(), + }; + + Ok((s, endpoint)) +} + +// post_arg_empty!(charge_port_door_open, "/vehicles/{}/command/charge_port_door_open", VehicleId); +// post_arg_empty!(charge_port_door_close, "/vehicles/{}/command/charge_port_door_close", VehicleId); +fn post_arg_empty(s: &str) -> IResult<&str, TeslatteEndpoint> { + let (s, fn_name) = alt(( + macro_fn_name_then_comma("post_arg_empty!"), + macro_fn_name_then_comma("pub_post_arg_empty!"), + ))(s)?; + let (s, uri) = quoted_string(s)?; + let (s, ()) = comma(s)?; + let (s, arg_type) = struct_name(s)?; + let (s, _) = end_args(s)?; + + let endpoint = TeslatteEndpoint { + method: Method::POST, + endpoint: fn_name.to_string(), + uri: uri.to_string(), + }; + + Ok((s, endpoint)) +} + fn function_name(s: &str) -> IResult<&str, &str> { take_while1(is_function_chars)(s) } @@ -275,13 +302,16 @@ mod tests { let (_, endpoint) = get_args(s).unwrap(); } + // post_arg!(set_charge_limit, SetChargeLimit, "/vehicles/{}/command/set_charge_limit", VehicleId); #[test] fn test_post_arg() { - todo!() + let s = r#"post_arg!(set_charge_limit, SetChargeLimit, "/vehicles/{}/command/set_charge_limit", VehicleId);"#; + let (_, endpoint) = post_arg(s).unwrap(); } #[test] fn test_post_arg_empty() { - todo!() + let s = r#"post_arg_empty!(wake_up, "/vehicles/{}/command/wake_up", VehicleId);"#; + let (_, endpoint) = post_arg_empty(s).unwrap(); } }