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