jirust_cli/runners/jira_cmd_runners/version_cmd_runner.rs
1use std::collections::HashMap;
2
3use crate::args::commands::VersionArgs;
4use crate::config::config_file::{AuthData, ConfigFile};
5use crate::jira_doc_std_field;
6use crate::utils::changelog_extractor::ChangelogExtractor;
7use chrono::Utc;
8use jira_v3_openapi::apis::Error;
9use jira_v3_openapi::apis::configuration::Configuration;
10use jira_v3_openapi::apis::issues_api::{assign_issue, do_transition, edit_issue, get_transitions};
11use jira_v3_openapi::apis::project_versions_api::*;
12use jira_v3_openapi::models::user::AccountType;
13use jira_v3_openapi::models::{
14 DeleteAndReplaceVersionBean, FieldUpdateOperation, IssueTransition, IssueUpdateDetails, User,
15 Version,
16};
17use serde_json::Value;
18
19/// Version command runner struct
20///
21/// This struct is responsible for holding the version command runner parameters
22/// and it is used to pass the parameters to the version commands runner
23pub struct VersionCmdRunner {
24 cfg: Configuration,
25 resolution_value: Value,
26 resolution_comment: Value,
27 resolution_transition_name: Option<Vec<String>>,
28}
29
30/// Version command runner implementation.
31///
32///
33/// # Methods
34///
35/// * `new` - This method creates a new instance of the VersionCmdRunner struct
36/// * `create_jira_version` - This method creates a new Jira version
37/// * `get_jira_version` - This method gets a Jira version
38/// * `list_jira_versions` - This method lists Jira versions
39/// * `update_jira_version` - This method updates a Jira version
40/// * `delete_jira_version` - This method deletes a Jira version
41/// * `release_jira_version` - This method releases a Jira version
42/// * `archive_jira_version` - This method archives a Jira version
43impl VersionCmdRunner {
44 /// This method creates a new instance of the VersionCmdRunner struct
45 ///
46 /// # Arguments
47 ///
48 /// * `cfg_file` - A ConfigFile struct
49 ///
50 /// # Returns
51 ///
52 /// * A new instance of the VersionCmdRunner struct
53 ///
54 /// # Examples
55 ///
56 /// ```
57 /// use jirust_cli::config::config_file::ConfigFile;
58 /// use jirust_cli::runners::jira_cmd_runners::version_cmd_runner::VersionCmdRunner;
59 /// use toml::Table;
60 ///
61 /// let cfg_file = ConfigFile::new("dXNlcm5hbWU6YXBpX2tleQ==".to_string(), "jira_url".to_string(), "standard_resolution".to_string(), "standard_resolution_comment".to_string(), Table::new());
62 ///
63 /// let version_cmd_runner = VersionCmdRunner::new(cfg_file);
64 /// ```
65 pub fn new(cfg_file: ConfigFile) -> VersionCmdRunner {
66 let mut config = Configuration::new();
67 let auth_data = AuthData::from_base64(cfg_file.get_auth_key());
68 config.base_path = cfg_file.get_jira_url().to_string();
69 config.basic_auth = Some((auth_data.0, Some(auth_data.1)));
70 VersionCmdRunner {
71 cfg: config,
72 resolution_value: serde_json::from_str(cfg_file.get_standard_resolution().as_str())
73 .unwrap_or(Value::Null),
74 resolution_comment: serde_json::from_str(
75 format!(
76 "{{\"body\": {}}}",
77 jira_doc_std_field!(cfg_file.get_standard_resolution_comment().as_str())
78 )
79 .as_str(),
80 )
81 .unwrap_or(Value::Null),
82 resolution_transition_name: cfg_file.get_transition_name("resolve"),
83 }
84 }
85
86 /// This method creates a new Jira version with the given parameters
87 /// and returns the created version
88 ///
89 /// # Arguments
90 ///
91 /// * `params` - A VersionCmdParams struct
92 ///
93 /// # Returns
94 ///
95 /// * A Result containing a Version struct or a Box<dyn std::error::Error>
96 ///
97 /// # Examples
98 ///
99 /// ```no_run
100 /// use jira_v3_openapi::models::Version;
101 /// use jirust_cli::runners::jira_cmd_runners::version_cmd_runner::VersionCmdParams;
102 /// use jirust_cli::config::config_file::ConfigFile;
103 /// use jirust_cli::runners::jira_cmd_runners::version_cmd_runner::VersionCmdRunner;
104 /// use toml::Table;
105 ///
106 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
107 /// # tokio_test::block_on(async {
108 /// let cfg_file = ConfigFile::new("dXNlcm5hbWU6YXBpX2tleQ==".to_string(), "jira_url".to_string(), "standard_resolution".to_string(), "standard_resolution_comment".to_string(), Table::new());
109 ///
110 /// let version_cmd_runner = VersionCmdRunner::new(cfg_file);
111 /// let params = VersionCmdParams::new();
112 ///
113 /// let version = version_cmd_runner.create_jira_version(params).await?;
114 /// # Ok(())
115 /// # })
116 /// # }
117 /// ```
118 pub async fn create_jira_version(
119 &self,
120 params: VersionCmdParams,
121 ) -> Result<(Version, Option<Vec<(String, String, String, String)>>), Box<dyn std::error::Error>>
122 {
123 let version_description;
124 let mut resolved_issues = vec![];
125 let mut transitioned_issue: Vec<(String, String, String, String)> = vec![];
126 if Option::is_some(¶ms.changelog_file) {
127 let changelog_extractor = ChangelogExtractor::new(params.changelog_file.unwrap());
128 version_description = Some(changelog_extractor.extract_version_changelog().unwrap_or(
129 if Option::is_some(¶ms.version_description) {
130 params.version_description.unwrap()
131 } else {
132 "No changelog found for this version".to_string()
133 },
134 ));
135 if Option::is_some(¶ms.transition_issues) && params.transition_issues.unwrap() {
136 resolved_issues = changelog_extractor
137 .extract_issues_from_changelog(
138 version_description.clone().unwrap(),
139 params.project.clone(),
140 )
141 .unwrap_or_default();
142 }
143 } else {
144 version_description = params.version_description;
145 }
146 let release_date =
147 if Option::is_some(¶ms.version_released) && params.version_released.unwrap() {
148 if Option::is_some(¶ms.version_release_date) {
149 params.version_release_date
150 } else {
151 Some(Utc::now().format("%Y-%m-%d").to_string())
152 }
153 } else {
154 None
155 };
156 let version = Version {
157 project: Some(params.project),
158 name: Some(
159 params
160 .version_name
161 .expect("VersionName is mandatory on cretion!"),
162 ),
163 description: version_description,
164 start_date: params.version_start_date,
165 release_date,
166 archived: params.version_archived,
167 released: params.version_released,
168 ..Default::default()
169 };
170 let version = create_version(&self.cfg, version).await?;
171 if !resolved_issues.is_empty() {
172 let user_data = if Option::is_some(¶ms.transition_assignee) {
173 Some(User {
174 account_id: Some(params.transition_assignee.expect("Assignee is required")),
175 account_type: Some(AccountType::Atlassian),
176 ..Default::default()
177 })
178 } else {
179 None
180 };
181 for issue in resolved_issues {
182 let all_transitions: Vec<IssueTransition> = get_transitions(
183 &self.cfg,
184 issue.clone().as_str(),
185 None,
186 None,
187 None,
188 Some(false),
189 None,
190 )
191 .await?
192 .transitions
193 .unwrap_or_default();
194 let transition_names: Vec<String> = self
195 .resolution_transition_name
196 .clone()
197 .expect("Transition name is required and must be set in the config file");
198 let resolve_transitions: Vec<IssueTransition> = all_transitions
199 .into_iter()
200 .filter(|t| {
201 transition_names.contains(&t.name.clone().unwrap_or("".to_string()))
202 })
203 .collect();
204 let transition_ids = resolve_transitions
205 .into_iter()
206 .map(|t| t.id.clone().unwrap_or("".to_string()))
207 .collect::<Vec<String>>();
208 let transitions = transition_ids
209 .into_iter()
210 .map(|id| {
211 Some(IssueTransition {
212 id: Some(id),
213 ..Default::default()
214 })
215 })
216 .collect::<Vec<Option<IssueTransition>>>();
217 let mut update_fields_hashmap: HashMap<String, Vec<FieldUpdateOperation>> =
218 HashMap::new();
219 let mut transition_fields_hashmap: HashMap<String, Vec<FieldUpdateOperation>> =
220 HashMap::new();
221 let mut version_update_op = FieldUpdateOperation::new();
222 let mut version_resolution_update_field = HashMap::new();
223 let mut version_resolution_comment_op = FieldUpdateOperation::new();
224 let version_json: Value =
225 serde_json::from_str(serde_json::to_string(&version).unwrap().as_str())
226 .unwrap_or(Value::Null);
227 let resolution_value = self.resolution_value.clone();
228 let comment_value = self.resolution_comment.clone();
229 version_update_op.add = Some(Some(version_json));
230 version_resolution_update_field.insert("resolution".to_string(), resolution_value);
231 version_resolution_comment_op.add = Some(Some(comment_value));
232 update_fields_hashmap.insert("fixVersions".to_string(), vec![version_update_op]);
233 transition_fields_hashmap
234 .insert("comment".to_string(), vec![version_resolution_comment_op]);
235 let issue_update_data = IssueUpdateDetails {
236 fields: None,
237 history_metadata: None,
238 properties: None,
239 transition: None,
240 update: Some(update_fields_hashmap),
241 };
242 let mut transition_result: String = "KO".to_string();
243 if !Vec::is_empty(&transitions) {
244 for transition in transitions {
245 let issue_transition_data = IssueUpdateDetails {
246 fields: Some(version_resolution_update_field.clone()),
247 history_metadata: None,
248 properties: None,
249 transition: Some(transition.clone().unwrap()),
250 update: Some(transition_fields_hashmap.clone()),
251 };
252 match do_transition(
253 &self.cfg,
254 issue.clone().as_str(),
255 issue_transition_data,
256 )
257 .await
258 {
259 Ok(_) => {
260 transition_result = "OK".to_string();
261 break;
262 }
263 Err(Error::Serde(e)) => {
264 if e.is_eof() {
265 transition_result = "OK".to_string();
266 break;
267 } else {
268 transition_result = "KO".to_string()
269 }
270 }
271 Err(_) => transition_result = "KO".to_string(),
272 }
273 }
274 }
275 let assign_result: String = match assign_issue(
276 &self.cfg,
277 issue.clone().as_str(),
278 user_data.clone().unwrap(),
279 )
280 .await
281 {
282 Ok(_) => "OK".to_string(),
283 Err(Error::Serde(e)) => {
284 if e.is_eof() {
285 "OK".to_string()
286 } else {
287 "KO".to_string()
288 }
289 }
290 Err(_) => "KO".to_string(),
291 };
292 let fixversion_result: String = match edit_issue(
293 &self.cfg,
294 issue.clone().as_str(),
295 issue_update_data,
296 Some(true),
297 None,
298 None,
299 Some(true),
300 None,
301 )
302 .await
303 {
304 Ok(_) => version.clone().name.unwrap_or("".to_string()),
305 Err(_) => "NO fixVersion set".to_string(),
306 };
307 transitioned_issue.push((
308 issue.clone(),
309 transition_result,
310 assign_result,
311 fixversion_result,
312 ));
313 }
314 }
315 Ok((
316 version,
317 if !transitioned_issue.is_empty() {
318 Some(transitioned_issue)
319 } else {
320 None
321 },
322 ))
323 }
324
325 /// This method gets a Jira version with the given parameters
326 /// and returns the version
327 /// If the version is not found, it returns an error
328 ///
329 /// # Arguments
330 ///
331 /// * `params` - A VersionCmdParams struct
332 ///
333 /// # Returns
334 ///
335 /// * A Result containing a Version struct or an Error<GetVersionError>
336 ///
337 /// # Examples
338 ///
339 /// ```no_run
340 /// use jira_v3_openapi::models::Version;
341 /// use jirust_cli::runners::jira_cmd_runners::version_cmd_runner::VersionCmdParams;
342 /// use jirust_cli::config::config_file::ConfigFile;
343 /// use jirust_cli::runners::jira_cmd_runners::version_cmd_runner::VersionCmdRunner;
344 /// use toml::Table;
345 ///
346 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
347 /// # tokio_test::block_on(async {
348 /// let cfg_file = ConfigFile::new("dXNlcm5hbWU6YXBpX2tleQ==".to_string(), "jira_url".to_string(), "standard_resolution".to_string(), "standard_resolution_comment".to_string(), Table::new());
349 /// let version_cmd_runner = VersionCmdRunner::new(cfg_file);
350 /// let params = VersionCmdParams::new();
351 ///
352 /// let version = version_cmd_runner.get_jira_version(params).await?;
353 /// # Ok(())
354 /// # })
355 /// # }
356 /// ```
357 pub async fn get_jira_version(
358 &self,
359 params: VersionCmdParams,
360 ) -> Result<Version, Error<GetVersionError>> {
361 get_version(
362 &self.cfg,
363 params.version_id.expect("VersionID is mandatory!").as_str(),
364 None,
365 )
366 .await
367 }
368
369 /// This method lists Jira versions with the given parameters
370 /// and returns the versions
371 /// If there are no versions, it returns an empty vector
372 /// If the version is not found, it returns an error
373 /// If the version page size is given, it returns the paginated versions
374 /// Otherwise, it returns all versions
375 ///
376 /// # Arguments
377 ///
378 /// * `params` - A VersionCmdParams struct
379 ///
380 /// # Returns
381 ///
382 /// * A Result containing a vector of Version structs or a Box<dyn std::error::Error>
383 ///
384 /// # Examples
385 ///
386 /// ```no_run
387 /// use jira_v3_openapi::models::Version;
388 /// use jirust_cli::runners::jira_cmd_runners::version_cmd_runner::VersionCmdParams;
389 /// use jirust_cli::config::config_file::ConfigFile;
390 /// use jirust_cli::runners::jira_cmd_runners::version_cmd_runner::VersionCmdRunner;
391 /// use toml::Table;
392 ///
393 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
394 /// # tokio_test::block_on(async {
395 /// let cfg_file = ConfigFile::new("dXNlcm5hbWU6YXBpX2tleQ==".to_string(), "jira_url".to_string(), "standard_resolution".to_string(), "standard_resolution_comment".to_string(), Table::new());
396 /// let version_cmd_runner = VersionCmdRunner::new(cfg_file);
397 /// let params = VersionCmdParams::new();
398 ///
399 /// let versions = version_cmd_runner.list_jira_versions(params).await?;
400 /// # Ok(())
401 /// # })
402 /// # }
403 /// ```
404 pub async fn list_jira_versions(
405 &self,
406 params: VersionCmdParams,
407 ) -> Result<Vec<Version>, Box<dyn std::error::Error>> {
408 if Option::is_some(¶ms.versions_page_size) {
409 match get_project_versions_paginated(
410 &self.cfg,
411 params.project.as_str(),
412 params.versions_page_offset,
413 params.versions_page_size,
414 None,
415 None,
416 None,
417 None,
418 )
419 .await?
420 .values
421 {
422 Some(values) => Ok(values),
423 None => Ok(vec![]),
424 }
425 } else {
426 Ok(get_project_versions(&self.cfg, params.project.as_str(), None).await?)
427 }
428 }
429
430 /// This method updates a Jira version with the given parameters
431 /// and returns the updated version
432 /// If the version is not found, it returns an error
433 /// If the version ID is not given, it returns an error
434 ///
435 /// # Arguments
436 ///
437 /// * `params` - A VersionCmdParams struct
438 ///
439 /// # Returns
440 ///
441 /// * A Result containing a Version struct or an Error<UpdateVersionError>
442 ///
443 /// # Examples
444 ///
445 /// ```no_run
446 /// use jira_v3_openapi::models::Version;
447 /// use jirust_cli::runners::jira_cmd_runners::version_cmd_runner::VersionCmdParams;
448 /// use jirust_cli::config::config_file::ConfigFile;
449 /// use jirust_cli::runners::jira_cmd_runners::version_cmd_runner::VersionCmdRunner;
450 /// use toml::Table;
451 ///
452 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
453 /// # tokio_test::block_on(async {
454 /// let cfg_file = ConfigFile::new("dXNlcm5hbWU6YXBpX2tleQ==".to_string(), "jira_url".to_string(), "standard_resolution".to_string(), "standard_resolution_comment".to_string(), Table::new());
455 /// let version_cmd_runner = VersionCmdRunner::new(cfg_file);
456 /// let params = VersionCmdParams::new();
457 ///
458 /// let version = version_cmd_runner.update_jira_version(params).await?;
459 /// # Ok(())
460 /// # })
461 /// # }
462 /// ```
463 pub async fn update_jira_version(
464 &self,
465 params: VersionCmdParams,
466 ) -> Result<Version, Error<UpdateVersionError>> {
467 let release_date =
468 if Option::is_some(¶ms.version_released) && params.version_released.unwrap() {
469 if Option::is_some(¶ms.version_release_date) {
470 params.version_release_date
471 } else {
472 Some(Utc::now().format("%Y-%m-%d").to_string())
473 }
474 } else {
475 None
476 };
477 let version = Version {
478 id: Some(params.version_id.clone().expect("VersionID is mandatory!")),
479 name: params.version_name,
480 description: params.version_description,
481 start_date: params.version_start_date,
482 release_date,
483 archived: params.version_archived,
484 released: params.version_released,
485 ..Default::default()
486 };
487 update_version(
488 &self.cfg,
489 params.version_id.expect("VersionID is mandatory!").as_str(),
490 version,
491 )
492 .await
493 }
494
495 /// This method deletes a Jira version with the given parameters
496 /// and returns the status of the deletion
497 ///
498 /// # Arguments
499 ///
500 /// * `params` - A VersionCmdParams struct
501 ///
502 /// # Returns
503 ///
504 /// * A Result containing a serde_json::Value or an Error<DeleteAndReplaceVersionError>
505 ///
506 /// # Examples
507 ///
508 /// ```no_run
509 /// use jirust_cli::runners::jira_cmd_runners::version_cmd_runner::VersionCmdParams;
510 /// use jirust_cli::config::config_file::ConfigFile;
511 /// use jirust_cli::runners::jira_cmd_runners::version_cmd_runner::VersionCmdRunner;
512 /// use toml::Table;
513 ///
514 /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
515 /// # tokio_test::block_on(async {
516 /// let cfg_file = ConfigFile::new("dXNlcm5hbWU6YXBpX2tleQ==".to_string(), "jira_url".to_string(), "standard_resolution".to_string(), "standard_resolution_comment".to_string(), Table::new());
517 /// let version_cmd_runner = VersionCmdRunner::new(cfg_file);
518 /// let params = VersionCmdParams::new();
519 ///
520 /// let status = version_cmd_runner.delete_jira_version(params).await?;
521 /// # Ok(())
522 /// # })
523 /// # }
524 /// ```
525 pub async fn delete_jira_version(
526 &self,
527 params: VersionCmdParams,
528 ) -> Result<serde_json::Value, Error<DeleteAndReplaceVersionError>> {
529 match delete_and_replace_version(
530 &self.cfg,
531 params.version_id.expect("VersionID is mandatory!").as_str(),
532 DeleteAndReplaceVersionBean::new(),
533 )
534 .await
535 {
536 Ok(_) => Ok(serde_json::json!({"status": "success"})),
537 Err(e) => match e {
538 Error::Serde(_) => Ok(
539 serde_json::json!({"status": "success", "warning": "Version was deleted, some issues in deserializing response!"}),
540 ),
541 _ => Err(e),
542 },
543 }
544 }
545}
546
547/// This struct defines the parameters for the Version commands
548///
549/// # Fields
550///
551/// * `project` - The project key, always **required**.
552/// * `project_id` - The project ID, optional.
553/// * `version_name` - The version name, optional.
554/// * `version_id` - The version ID, **required** for archive, delete, release and update.
555/// * `version_description` - The version description, optional.
556/// * `version_start_date` - The version start date, optional (default: today on create command).
557/// * `version_release_date` - The version release date, optional (default: today on release command).
558/// * `version_archived` - The version archived status, optional.
559/// * `version_released` - The version released status, optional.
560/// * `changelog_file` - The changelog file path, to be used for automatic description generation (changelog-based), optional: if set the script detects automatically the first tagged block in the changelog and use it as description
561/// * `resolve_issues` - The flag to resolve issues in the version, optional.
562/// * `versions_page_size` - The page size for the version, optional.
563/// * `versions_page_offset` - The page offset for the version, optional.
564pub struct VersionCmdParams {
565 pub project: String,
566 pub project_id: Option<i64>,
567 pub version_name: Option<String>,
568 pub version_id: Option<String>,
569 pub version_description: Option<String>,
570 pub version_start_date: Option<String>,
571 pub version_release_date: Option<String>,
572 pub version_archived: Option<bool>,
573 pub version_released: Option<bool>,
574 pub changelog_file: Option<String>,
575 pub transition_issues: Option<bool>,
576 pub transition_assignee: Option<String>,
577 pub versions_page_size: Option<i32>,
578 pub versions_page_offset: Option<i64>,
579}
580
581/// Implementation of the VersionCmdParams struct
582///
583/// # Methods
584///
585/// * `new` - returns a new VersionCmdParams struct
586/// * `merge_args` - merges the current version with the optional arguments
587/// * `mark_released` - marks the version as released
588/// * `mark_archived` - marks the version as archived
589impl VersionCmdParams {
590 /// This method returns a new VersionCmdParams struct
591 ///
592 /// # Returns
593 ///
594 /// * A VersionCmdParams struct
595 ///
596 /// # Examples
597 ///
598 /// ```
599 /// use jirust_cli::runners::jira_cmd_runners::version_cmd_runner::VersionCmdParams;
600 ///
601 /// let params = VersionCmdParams::new();
602 /// ```
603 pub fn new() -> VersionCmdParams {
604 VersionCmdParams {
605 project: "".to_string(),
606 project_id: None,
607 version_name: None,
608 version_id: None,
609 version_description: None,
610 version_start_date: None,
611 version_release_date: None,
612 version_archived: None,
613 version_released: None,
614 changelog_file: None,
615 transition_issues: None,
616 transition_assignee: None,
617 versions_page_size: None,
618 versions_page_offset: None,
619 }
620 }
621
622 /// This method merges the current version with the optional arguments
623 /// and returns a VersionCmdParams struct
624 /// If the optional arguments are not given, it uses the current version values
625 ///
626 /// # Arguments
627 ///
628 /// * `current_version` - A Version struct
629 /// * `opt_args` - An Option<&VersionArgs> struct
630 ///
631 /// # Returns
632 ///
633 /// * A VersionCmdParams struct
634 ///
635 /// # Examples
636 ///
637 /// ```
638 /// use jira_v3_openapi::models::Version;
639 /// use jirust_cli::args::commands::{VersionArgs, VersionActionValues, PaginationArgs, OutputArgs};
640 /// use jirust_cli::runners::jira_cmd_runners::version_cmd_runner::VersionCmdParams;
641 ///
642 /// let mut current_version: Version = Version::new();
643 /// current_version.id = Some("12345".to_string());
644 /// current_version.project_id = Some(9876);
645 /// current_version.project = Some("TEST_PROJECT".to_string());
646 /// current_version.name = Some("v1.0".to_string());
647 /// current_version.description = Some("This is the first version".to_string());
648 ///
649 /// let opt_args = VersionArgs {
650 /// version_act: VersionActionValues::List,
651 /// project_key: "project_key".to_string(),
652 /// project_id: None,
653 /// version_id: Some("97531".to_string()),
654 /// version_name: Some("version_name".to_string()),
655 /// version_description: Some("version_description".to_string()),
656 /// version_start_date: None,
657 /// version_release_date: None,
658 /// version_archived: None,
659 /// version_released: Some(true),
660 /// changelog_file: None,
661 /// pagination: PaginationArgs { page_size: None, page_offset: None },
662 /// output: OutputArgs { output_format: None, output_type: None },
663 /// transition_issues: None,
664 /// transition_assignee: None,
665 /// };
666 ///
667 /// let params = VersionCmdParams::merge_args(current_version, Some(&opt_args));
668 ///
669 /// assert_eq!(params.project, "TEST_PROJECT".to_string());
670 /// assert_eq!(params.project_id, Some(9876));
671 /// assert_eq!(params.version_id, Some("12345".to_string()));
672 /// assert_eq!(params.version_name, Some("version_name".to_string()));
673 /// assert_eq!(params.version_description, Some("version_description".to_string()));
674 /// assert_eq!(params.version_released, Some(true));
675 /// ```
676 pub fn merge_args(
677 current_version: Version,
678 opt_args: Option<&VersionArgs>,
679 ) -> VersionCmdParams {
680 match opt_args {
681 Some(args) => VersionCmdParams {
682 project: current_version.project.clone().unwrap_or("".to_string()),
683 project_id: current_version.project_id,
684 version_id: current_version.id,
685 version_name: if Option::is_some(&args.version_name) {
686 args.version_name.clone()
687 } else {
688 current_version.name
689 },
690 version_description: if Option::is_some(&args.version_description) {
691 args.version_description.clone()
692 } else {
693 current_version.description
694 },
695 version_start_date: if Option::is_some(&args.version_start_date) {
696 args.version_start_date.clone()
697 } else {
698 current_version.start_date
699 },
700 version_release_date: if Option::is_some(&args.version_release_date) {
701 args.version_release_date.clone()
702 } else {
703 current_version.release_date
704 },
705 version_archived: if Option::is_some(&args.version_archived) {
706 args.version_archived
707 } else {
708 current_version.archived
709 },
710 version_released: if Option::is_some(&args.version_released) {
711 args.version_released
712 } else {
713 current_version.released
714 },
715 changelog_file: None,
716 transition_issues: None,
717 transition_assignee: None,
718 versions_page_size: None,
719 versions_page_offset: None,
720 },
721 None => VersionCmdParams {
722 project: current_version.project.clone().unwrap_or("".to_string()),
723 project_id: current_version.project_id,
724 version_id: current_version.id,
725 version_name: current_version.name,
726 version_description: current_version.description,
727 version_start_date: current_version.start_date,
728 version_release_date: current_version.release_date,
729 version_archived: current_version.archived,
730 version_released: current_version.released,
731 changelog_file: None,
732 transition_issues: None,
733 transition_assignee: None,
734 versions_page_size: None,
735 versions_page_offset: None,
736 },
737 }
738 }
739
740 /// This method marks the version as released
741 /// and returns a VersionCmdParams struct
742 /// It sets the version_released and version_release_date fields
743 /// with the current date
744 ///
745 /// # Arguments
746 ///
747 /// * `version` - A Version struct
748 ///
749 /// # Returns
750 ///
751 /// * A VersionCmdParams struct
752 ///
753 /// # Examples
754 ///
755 /// ```
756 /// use jira_v3_openapi::models::Version;
757 /// use jirust_cli::runners::jira_cmd_runners::version_cmd_runner::VersionCmdParams;
758 ///
759 /// let mut version: Version = Version::new();
760 /// version.id = Some("12345".to_string());
761 /// version.project_id = Some(9876);
762 /// version.project = Some("TEST_PROJECT".to_string());
763 /// version.name = Some("v1.0".to_string());
764 /// version.description = Some("This is the first version".to_string());
765 ///
766 /// assert_eq!(version.released, None);
767 ///
768 /// let params = VersionCmdParams::mark_released(version);
769 ///
770 /// assert_eq!(params.version_released, Some(true));
771 /// ```
772 pub fn mark_released(version: Version) -> VersionCmdParams {
773 let mut version_to_release = Self::merge_args(version, None);
774 version_to_release.version_released = Some(true);
775 version_to_release.version_release_date = Some(Utc::now().format("%Y-%m-%d").to_string());
776 version_to_release
777 }
778
779 /// This method marks the version as archived
780 /// and returns a VersionCmdParams struct
781 ///
782 /// # Arguments
783 ///
784 /// * `version` - A Version struct
785 ///
786 /// # Returns
787 ///
788 /// * A VersionCmdParams struct
789 ///
790 /// # Examples
791 ///
792 /// ```
793 /// use jira_v3_openapi::models::Version;
794 /// use jirust_cli::runners::jira_cmd_runners::version_cmd_runner::VersionCmdParams;
795 ///
796 /// let mut version: Version = Version::new();
797 /// version.id = Some("12345".to_string());
798 /// version.project_id = Some(9876);
799 /// version.project = Some("TEST_PROJECT".to_string());
800 /// version.name = Some("v1.0".to_string());
801 /// version.description = Some("This is the first version".to_string());
802 ///
803 /// assert_eq!(version.archived, None);
804 ///
805 /// let params = VersionCmdParams::mark_archived(version);
806 ///
807 /// assert_eq!(params.version_archived, Some(true));
808 /// ```
809 ///
810 pub fn mark_archived(version: Version) -> VersionCmdParams {
811 let mut version_to_archive = Self::merge_args(version, None);
812 version_to_archive.version_archived = Some(true);
813 version_to_archive
814 }
815}
816
817/// Implementation of the From trait for the VersionArgs struct
818/// This implementation allows the conversion of a VersionArgs struct to a VersionCmdParams struct.
819impl From<&VersionArgs> for VersionCmdParams {
820 /// This method converts the VersionArgs struct to a VersionCmdParams struct
821 /// and returns a VersionCmdParams struct
822 ///
823 /// # Arguments
824 ///
825 /// * `args` - A VersionArgs struct
826 ///
827 /// # Returns
828 ///
829 /// * A VersionCmdParams struct
830 ///
831 /// # Examples
832 ///
833 /// ```
834 /// use jirust_cli::args::commands::{VersionActionValues, VersionArgs, PaginationArgs, OutputArgs};
835 /// use jirust_cli::runners::jira_cmd_runners::version_cmd_runner::VersionCmdParams;
836 ///
837 /// let version_args = VersionArgs {
838 /// version_act: VersionActionValues::List,
839 /// project_key: "project_key".to_string(),
840 /// project_id: None,
841 /// version_id: None,
842 /// version_name: Some("version_name".to_string()),
843 /// version_description: Some("version_description".to_string()),
844 /// version_start_date: None,
845 /// version_release_date: None,
846 /// version_archived: None,
847 /// version_released: None,
848 /// changelog_file: None,
849 /// pagination: PaginationArgs { page_size: Some(10), page_offset: Some(0) },
850 /// output: OutputArgs { output_format: None, output_type: None },
851 /// transition_issues: None,
852 /// transition_assignee: None,
853 /// };
854 ///
855 /// let params = VersionCmdParams::from(&version_args);
856 ///
857 /// assert_eq!(params.project, "project_key".to_string());
858 /// assert_eq!(params.version_name, Some("version_name".to_string()));
859 /// assert_eq!(params.version_description, Some("version_description".to_string()));
860 /// assert_eq!(params.versions_page_size, Some(10));
861 /// assert_eq!(params.versions_page_offset, Some(0));
862 /// ```
863 fn from(args: &VersionArgs) -> Self {
864 VersionCmdParams {
865 project: args.project_key.clone(),
866 project_id: args.project_id,
867 version_name: args.version_name.clone(),
868 version_id: args.version_id.clone(),
869 version_description: args.version_description.clone(),
870 version_start_date: Some(
871 args.version_start_date
872 .clone()
873 .unwrap_or(Utc::now().format("%Y-%m-%d").to_string()),
874 ),
875 version_release_date: args.version_release_date.clone(),
876 version_archived: args.version_archived,
877 version_released: args.version_released,
878 changelog_file: args.changelog_file.clone(),
879 transition_issues: args.transition_issues,
880 transition_assignee: args.transition_assignee.clone(),
881 versions_page_size: args.pagination.page_size,
882 versions_page_offset: args.pagination.page_offset,
883 }
884 }
885}
886
887/// Implementation of the Default trait for the VersionCmdParams struct
888impl Default for VersionCmdParams {
889 /// This method returns a VersionCmdParams struct with default values
890 /// and returns a VersionCmdParams struct
891 ///
892 /// # Returns
893 ///
894 /// * A VersionCmdParams struct initialized with default values
895 ///
896 /// # Examples
897 ///
898 /// ```
899 /// use jirust_cli::runners::jira_cmd_runners::version_cmd_runner::VersionCmdParams;
900 ///
901 /// let params = VersionCmdParams::default();
902 ///
903 /// assert_eq!(params.project, "".to_string());
904 /// assert_eq!(params.project_id, None);
905 /// assert_eq!(params.version_name, None);
906 /// assert_eq!(params.version_id, None);
907 /// assert_eq!(params.version_description, None);
908 /// assert_eq!(params.version_start_date, None);
909 /// assert_eq!(params.version_release_date, None);
910 /// assert_eq!(params.version_archived, None);
911 /// assert_eq!(params.version_released, None);
912 /// assert_eq!(params.changelog_file, None);
913 /// assert_eq!(params.transition_issues, None);
914 /// assert_eq!(params.transition_assignee, None);
915 /// assert_eq!(params.versions_page_size, None);
916 /// assert_eq!(params.versions_page_offset, None);
917 /// ```
918 fn default() -> Self {
919 VersionCmdParams::new()
920 }
921}