qemu_command_builder/args/
iscsi.rs1use bon::Builder;
2use proptest_derive::Arbitrary;
3use std::str::FromStr;
4
5use crate::parsers::{ARG_ISCSI, DELIM_COMMA};
6use crate::to_command::ToCommand;
7
8#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Default, Builder, Arbitrary)]
10pub struct Iscsi {
11 user: Option<String>,
13 password: Option<String>,
15 password_secret: Option<String>,
17 header_digest: Option<String>,
19 initiator_name: Option<String>,
21 id: Option<String>,
23 timeout: Option<usize>,
25}
26
27impl ToCommand for Iscsi {
28 fn command(&self) -> String {
29 ARG_ISCSI.to_string()
30 }
31 fn to_args(&self) -> Vec<String> {
32 let mut args = vec![];
33
34 if let Some(user) = &self.user {
35 args.push(format!("user={}", user));
36 }
37 if let Some(password) = &self.password {
38 args.push(format!("password={}", password));
39 }
40 if let Some(password_secret) = &self.password_secret {
41 args.push(format!("password-secret={}", password_secret));
42 }
43 if let Some(header_digest) = &self.header_digest {
44 args.push(format!("header-digest={}", header_digest));
45 }
46 if let Some(initiator_name) = &self.initiator_name {
47 args.push(format!("initiator-name={}", initiator_name));
48 }
49 if let Some(id) = &self.id {
50 args.push(format!("id={}", id));
51 }
52 if let Some(timeout) = self.timeout {
53 args.push(format!("timeout={}", timeout));
54 }
55
56 vec![args.join(DELIM_COMMA)]
57 }
58}
59
60impl FromStr for Iscsi {
61 type Err = String;
62
63 fn from_str(s: &str) -> Result<Self, Self::Err> {
64 let mut user = None;
65 let mut password = None;
66 let mut password_secret = None;
67 let mut header_digest = None;
68 let mut initiator_name = None;
69 let mut id = None;
70 let mut timeout = None;
71
72 for part in s.split(DELIM_COMMA).filter(|part| !part.is_empty()) {
73 let (key, value) = part.split_once('=').ok_or_else(|| format!("invalid -iscsi option: {part}"))?;
74 match key {
75 "user" => user = Some(value.to_string()),
76 "password" => password = Some(value.to_string()),
77 "password-secret" => password_secret = Some(value.to_string()),
78 "header-digest" => header_digest = Some(value.to_string()),
79 "initiator-name" => initiator_name = Some(value.to_string()),
80 "id" => id = Some(value.to_string()),
81 "timeout" => timeout = Some(value.parse::<usize>().map_err(|e| e.to_string())?),
82 other => return Err(format!("unsupported -iscsi option: {other}")),
83 }
84 }
85
86 Ok(Self {
87 user,
88 password,
89 password_secret,
90 header_digest,
91 initiator_name,
92 id,
93 timeout,
94 })
95 }
96}