start_command/
docker_recovery_options.rs1use crate::args_parser::WrapperOptions;
11
12fn parse_on_kill_resume_value(value: &str) -> Result<u32, String> {
13 let text = value.trim();
14 match text.parse::<u32>() {
15 Ok(count) if count >= 1 && text.chars().all(|c| c.is_ascii_digit()) => Ok(count),
16 _ => Err(format!(
17 "Invalid --on-kill-resume value: \"{}\". Expected a positive integer.",
18 value
19 )),
20 }
21}
22
23pub fn parse_docker_recovery_option(
28 args: &[String],
29 index: usize,
30 options: &mut WrapperOptions,
31) -> Result<usize, String> {
32 let arg = args[index].as_str();
33 if arg == "--on-kill-resume" || arg == "--recovery-command" {
34 let Some(value) = args.get(index + 1).filter(|value| !value.starts_with('-')) else {
35 let kind = if arg == "--on-kill-resume" {
36 "count"
37 } else {
38 "command"
39 };
40 return Err(format!("Option {} requires a {} argument", arg, kind));
41 };
42 if arg == "--on-kill-resume" {
43 options.on_kill_resume = Some(parse_on_kill_resume_value(value)?);
44 } else {
45 options.recovery_command = Some(value.clone());
46 }
47 return Ok(2);
48 }
49 if let Some(value) = arg.strip_prefix("--on-kill-resume=") {
50 options.on_kill_resume = Some(parse_on_kill_resume_value(value)?);
51 return Ok(1);
52 }
53 if let Some(value) = arg.strip_prefix("--recovery-command=") {
54 options.recovery_command = Some(value.to_string());
55 return Ok(1);
56 }
57 Ok(0)
58}
59
60pub fn validate_docker_recovery_options(options: &mut WrapperOptions) -> Result<(), String> {
63 if let Some(command) = options.recovery_command.as_deref() {
64 if command.trim().is_empty() {
65 return Err("--recovery-command requires a non-empty command".to_string());
66 }
67 options.on_kill_resume.get_or_insert(1);
68 }
69 if options.on_kill_resume.is_none() {
70 return Ok(());
71 }
72 let flag = if options.recovery_command.is_some() {
73 "--recovery-command"
74 } else {
75 "--on-kill-resume"
76 };
77 if options.isolated.as_deref() != Some("docker") {
78 return Err(format!(
79 "{} option is only valid with --isolated docker as the only isolation level",
80 flag
81 ));
82 }
83 if !options.detached {
84 return Err(format!("{} option requires --detached", flag));
85 }
86 Ok(())
87}