Skip to content

Commit 916803a

Browse files
committed
refactor: improve robustness of gmail draft-only check
1 parent 78c30d6 commit 916803a

1 file changed

Lines changed: 19 additions & 15 deletions

File tree

src/main.rs

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ async fn run() -> Result<(), GwsError> {
207207
}
208208

209209
// Walk the subcommand tree to find the target method
210-
let (method, matched_args) = resolve_method_from_matches(&doc, &matches)?;
210+
let (method, matched_args, method_path) = resolve_method_from_matches(&doc, &matches)?;
211211

212212
let params_json = matched_args.get_one::<String>("params").map(|s| s.as_str());
213213
let body_json = matched_args
@@ -229,11 +229,13 @@ async fn run() -> Result<(), GwsError> {
229229

230230
let dry_run = matched_args.get_flag("dry-run");
231231
let draft_only = matches.get_flag("draft-only");
232-
if draft_only && !dry_run {
233-
if let Some(ref id) = method.id {
234-
if id == "gmail.users.messages.send" || id == "gmail.users.drafts.send" {
235-
return Err(GwsError::Validation("Gmail draft-only mode is active. Sending mail is blocked (preparing a draft is still allowed).".to_string()));
236-
}
232+
if draft_only && !dry_run && api_name == "gmail" {
233+
let is_send_method = method_path.len() == 3
234+
&& method_path[0] == "users"
235+
&& (method_path[1] == "messages" || method_path[1] == "drafts")
236+
&& method_path[2] == "send";
237+
if is_send_method {
238+
return Err(GwsError::Validation("Gmail draft-only mode is active. Sending mail is blocked (preparing a draft is still allowed).".to_string()));
237239
}
238240
}
239241

@@ -369,13 +371,13 @@ fn parse_sanitize_config(
369371
fn resolve_method_from_matches<'a>(
370372
doc: &'a discovery::RestDescription,
371373
matches: &'a clap::ArgMatches,
372-
) -> Result<(&'a discovery::RestMethod, &'a clap::ArgMatches), GwsError> {
374+
) -> Result<(&'a discovery::RestMethod, &'a clap::ArgMatches, Vec<String>), GwsError> {
373375
// Walk the subcommand chain
374-
let mut path: Vec<&str> = Vec::new();
376+
let mut path: Vec<String> = Vec::new();
375377
let mut current_matches = matches;
376378

377379
while let Some((sub_name, sub_matches)) = current_matches.subcommand() {
378-
path.push(sub_name);
380+
path.push(sub_name.to_string());
379381
current_matches = sub_matches;
380382
}
381383

@@ -387,7 +389,7 @@ fn resolve_method_from_matches<'a>(
387389

388390
// path looks like ["files", "list"] or ["files", "permissions", "list"]
389391
// Walk the Discovery Document resources to find the method
390-
let resource_name = path[0];
392+
let resource_name = &path[0];
391393
let resource = doc
392394
.resources
393395
.get(resource_name)
@@ -396,7 +398,7 @@ fn resolve_method_from_matches<'a>(
396398
let mut current_resource = resource;
397399

398400
// Navigate sub-resources (everything except the last element, which is the method)
399-
for &name in &path[1..path.len() - 1] {
401+
for name in &path[1..path.len() - 1] {
400402
// Check if this is a sub-resource
401403
if let Some(sub) = current_resource.resources.get(name) {
402404
current_resource = sub;
@@ -408,11 +410,11 @@ fn resolve_method_from_matches<'a>(
408410
}
409411

410412
// The last element is the method name
411-
let method_name = path[path.len() - 1];
413+
let method_name = &path[path.len() - 1];
412414

413415
// Check if this is a method on the current resource
414416
if let Some(method) = current_resource.methods.get(method_name) {
415-
return Ok((method, current_matches));
417+
return Ok((method, current_matches, path));
416418
}
417419

418420
// Maybe it's a resource that has methods — need one more subcommand
@@ -630,8 +632,9 @@ mod tests {
630632
.subcommand(clap::Command::new("files").subcommand(clap::Command::new("list")));
631633

632634
let matches = cmd.get_matches_from(vec!["gws", "files", "list"]);
633-
let (method, _) = resolve_method_from_matches(&doc, &matches).unwrap();
635+
let (method, _, method_path) = resolve_method_from_matches(&doc, &matches).unwrap();
634636
assert_eq!(method.id.as_deref(), Some("drive.files.list"));
637+
assert_eq!(method_path, vec!["files", "list"]);
635638
}
636639

637640
#[test]
@@ -663,8 +666,9 @@ mod tests {
663666
));
664667

665668
let matches = cmd.get_matches_from(vec!["gws", "files", "permissions", "get"]);
666-
let (method, _) = resolve_method_from_matches(&doc, &matches).unwrap();
669+
let (method, _, method_path) = resolve_method_from_matches(&doc, &matches).unwrap();
667670
assert_eq!(method.id.as_deref(), Some("drive.files.permissions.get"));
671+
assert_eq!(method_path, vec!["files", "permissions", "get"]);
668672
}
669673

670674
#[test]

0 commit comments

Comments
 (0)