jirust_cli/args/
commands.rs

1use crate::jira_doc_std_field;
2use clap::{ArgAction, Args, Parser, Subcommand, ValueEnum};
3use regex::Regex;
4use serde::{Deserialize, Serialize};
5use std::error::Error;
6
7/// Command line arguments base
8/// subcommands: Config, Version
9#[derive(Parser, Debug)]
10#[command(author, version, about, long_about = None)]
11pub struct JirustCliArgs {
12    /// Subcommands
13    #[clap(subcommand)]
14    pub subcmd: Commands,
15}
16
17/// Available CLI commands
18/// Config, Issue, Project, Transition, Version
19#[derive(Subcommand, Clone, Debug, Serialize, Deserialize)]
20pub enum Commands {
21    /// Configuration management
22    Config(ConfigArgs),
23    /// Issue management
24    Issue(IssueArgs),
25    /// Issue links management
26    Link(LinkIssueArgs),
27    /// Project management
28    Project(ProjectArgs),
29    /// Transition management
30    Transition(TransitionArgs),
31    /// Version management
32    Version(VersionArgs),
33}
34
35/// Available pagination command line arguments
36///
37/// * page_size: `Option<i32>`
38/// * page_offset: `Option<i64>`
39#[derive(Args, Clone, Debug, Serialize, Deserialize)]
40pub struct PaginationArgs {
41    /// page size for lists
42    #[clap(
43        long,
44        short = 'l',
45        value_name = "page_size",
46        help = "page size for lists"
47    )]
48    pub page_size: Option<i32>,
49    /// page offset for list
50    #[clap(
51        long,
52        short = 's',
53        value_name = "page_offset",
54        help = "page offset for list"
55    )]
56    pub page_offset: Option<i64>,
57}
58
59/// Available output values
60/// Table, Json
61///
62/// * Table: Print output in table format
63/// * Json: Print output in json format
64#[derive(ValueEnum, Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
65#[value(rename_all = "kebab-case")]
66pub enum OutputValues {
67    /// Print output in table format
68    #[value(name = "table", help = "Print output in table format")]
69    Table,
70    /// Print output in json format
71    #[value(name = "json", help = "Print output in json format")]
72    Json,
73}
74
75/// Available output types
76/// Table, Json
77///
78/// * Basic: Print basic output
79/// * Single: Print single row output
80/// * Full: Print full output
81#[derive(ValueEnum, Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
82#[value(rename_all = "kebab-case")]
83pub enum OutputTypes {
84    /// Print basic output
85    #[value(name = "basic", help = "Print basic output")]
86    Basic,
87    /// Print single row output
88    #[value(name = "single", help = "Print single row output")]
89    Single,
90    /// Print full output
91    #[value(name = "full", help = "Print full output")]
92    Full,
93}
94
95/// Available output values
96///
97/// * output: `Option<OutputValues>` - Output format
98#[derive(Args, Clone, Debug, Serialize, Deserialize)]
99pub struct OutputArgs {
100    /// Output format
101    #[clap(long, short = 'o', value_name = "table|json", help = "Output format")]
102    pub output_format: Option<OutputValues>,
103    /// Output type
104    #[clap(
105        long,
106        short = 'z',
107        value_name = "basic|single|full",
108        help = "Output type"
109    )]
110    pub output_type: Option<OutputTypes>,
111}
112
113/// Available configuration command line arguments
114/// cfg_act: ConfigActionValues
115///    Auth, Jira, Setup, Show
116#[derive(Args, Clone, Debug, Serialize, Deserialize)]
117pub struct ConfigArgs {
118    /// Configuration action
119    #[arg(
120        value_name = "auth|jira|setup|show",
121        help_heading = "Configuration management"
122    )]
123    pub cfg_act: ConfigActionValues,
124}
125
126/// Available configuration action values
127/// Auth, Jira, Setup, Show
128///
129/// * Auth: Set Jira API authentication (username, apikey)
130/// * Jira: Set Jira API base URL
131/// * Setup: Setup Jira API configuration (authentication data, jira base URL, etc.)
132/// * Show: Show current configuration
133#[derive(ValueEnum, Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
134#[value(rename_all = "kebab-case")]
135pub enum ConfigActionValues {
136    /// Set Jira API authentication (username, apikey)
137    #[value(name = "auth", help = "Set Jira API authentication (username, apikey)")]
138    Auth,
139    /// Set Jira API base URL
140    #[value(name = "jira", help = "Set Jira API base URL")]
141    Jira,
142    /// Setup Jira API configuration (authentication data, jira base URL, etc.)
143    #[value(
144        name = "setup",
145        help = "Setup Jira API configuration (authentication data, jira base URL, etc.)"
146    )]
147    Setup,
148    /// Show current configuration
149    #[value(name = "show", help = "Show current configuration")]
150    Show,
151}
152
153/// Available version command line arguments
154///
155/// * version_act: VersionActionValues - Version action
156/// * project_key: String - Jira Project key
157/// * project_id: `Option<i64>` - Jira Project ID
158/// * version_id: `Option<String>` - Jira Project version ID
159/// * version_name: `Option<String>` - Jira Project version name
160/// * version_description: `Option<String>` - Jira Project version description
161/// * version_start_date: `Option<String>` - Jira Project version start date
162/// * version_release_date: `Option<String>` - Jira Project version release date
163/// * version_archived: `Option<bool>` - Jira Project version archived
164/// * version_released: `Option<bool>` - Jira Project version released
165/// * changelog_file: `Option<String>` - Jira Project version changelog file
166/// * transition_issues: `Option<bool>` - Jira Project version automatically transition issues in changelog
167/// * transition_assignee: `Option<String>` - Jira Project version transition assignee
168/// * pagination: PaginationArgs - Jira Project version pagination
169/// * output: OutputArgs - Jira Project version actions result output format
170///
171#[derive(Args, Clone, Debug, Serialize, Deserialize)]
172pub struct VersionArgs {
173    /// Version action
174    #[arg(
175        value_name = "archive|create|delete|list|release|update",
176        help_heading = "Jira Project version management"
177    )]
178    pub version_act: VersionActionValues,
179    /// Jira Project key
180    #[clap(
181        long,
182        short = 'k',
183        value_name = "project_key",
184        required = true,
185        help = "Jira Project key"
186    )]
187    pub project_key: String,
188    /// Jira Project ID
189    #[clap(long, short = 'i', value_name = "project_id", help = "Jira Project ID")]
190    pub project_id: Option<i64>,
191    /// Jira Project version ID
192    #[clap(
193        long,
194        short = 'v',
195        value_name = "version_id",
196        help = "Jira Project version ID"
197    )]
198    pub version_id: Option<String>,
199    /// Jira Project version name
200    #[clap(
201        long,
202        short = 'n',
203        value_name = "version_name",
204        help = "Jira Project version name"
205    )]
206    pub version_name: Option<String>,
207    /// Jira Project version description
208    #[clap(
209        long,
210        short = 'd',
211        value_name = "version_description",
212        help = "Jira Project version description"
213    )]
214    pub version_description: Option<String>,
215    /// Jira Project version start date
216    #[clap(
217        long,
218        value_name = "version_start_date",
219        help = "Jira Project version start date"
220    )]
221    pub version_start_date: Option<String>,
222    /// Jira Project version release date
223    #[clap(
224        long,
225        value_name = "version_release_date",
226        help = "Jira Project version release date"
227    )]
228    pub version_release_date: Option<String>,
229    /// Jira Project version archived
230    #[clap(
231        long,
232        short = 'a',
233        value_name = "version_archived",
234        help = "Jira Project version archived"
235    )]
236    pub version_archived: Option<bool>,
237    /// Jira Project version released
238    #[clap(
239        long,
240        short = 'm',
241        action = ArgAction::SetTrue,
242        value_name = "version_released",
243        help = "Jira Project version released"
244    )]
245    pub version_released: Option<bool>,
246    /// Jira Project version changelog file
247    #[clap(
248        long,
249        short = 'c',
250        value_name = "changelog_file",
251        help = "changelog file path to be used for automatic description generation (if set the script detects automatically the first tagged block in the changelog and use it as description)"
252    )]
253    pub changelog_file: Option<String>,
254    /// Jira Project version automatically transition issues in changelog
255    #[clap(
256        long,
257        short = 'r',
258        action = ArgAction::SetTrue,
259        value_name = "resolve_issues",
260        help = "if changelog is set and this flag is set, the script will transition all issues in the changelog of the current version release to the \"resolved\" status setting the version as \"fixVersion\""
261    )]
262    pub transition_issues: Option<bool>,
263    /// Jira Project version transition assignee
264    #[clap(
265        long,
266        short = 'u',
267        value_name = "transition_assignee",
268        help = "if changelog is set and the resolve_issues flag is set, the script will assigned all the resolved issue to the user specified in this field (if not set the assignee will not be changed)"
269    )]
270    pub transition_assignee: Option<String>,
271    /// Jira Project version pagination
272    #[clap(flatten)]
273    pub pagination: PaginationArgs,
274    /// Jira Project version actions result output format
275    #[clap(flatten)]
276    pub output: OutputArgs,
277}
278
279/// Available version action values
280/// Archive, Create, Delete, List, Release, Update
281///
282/// * Archive: Archive a Jira Project version
283/// * Create: Create a Jira Project version
284/// * Delete: Delete a Jira Project version
285/// * List: List Jira Project versions
286/// * RelatedWorkItems: Get Project version related workitems
287/// * Release: Release a Jira Project version
288/// * Update: Update a Jira Project version
289#[derive(ValueEnum, Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
290#[value(rename_all = "kebab-case")]
291pub enum VersionActionValues {
292    /// Archive a Jira Project version
293    #[value(name = "archive", help = "Archive a Jira Project version")]
294    Archive,
295    /// Create a Jira Project version
296    #[value(name = "create", help = "Create a Jira Project version")]
297    Create,
298    /// Delete a Jira Project version
299    #[value(name = "delete", help = "Delete a Jira Project version")]
300    Delete,
301    /// List Jira Project versions
302    #[value(name = "list", help = "List Jira Project versions")]
303    List,
304    /// Get Project version related workitems
305    #[value(
306        name = "related-work-items",
307        help = "Get Project version related workitems"
308    )]
309    RelatedWorkItems,
310    /// Release a Jira Project version
311    #[value(name = "release", help = "Release a Jira Project version")]
312    Release,
313    /// Update a Jira Project version
314    #[value(name = "update", help = "Update a Jira Project version")]
315    Update,
316}
317
318/// Available project command line arguments
319///
320/// * project_act: ProjectActionValues - Project action
321/// * project_key: `Option<String>` - Jira Project key
322/// * project_issue_type: `Option<String>` - Jira Project issue type ID
323/// * project_name: `Option<String>` - Jira Project name
324/// * project_description: `Option<String>` - Jira Project description
325/// * project_field_configuration_id: `Option<i64>` - Jira Project field configuration ID
326/// * project_issue_security_scheme_id: `Option<i64>` - Jira Project issue security scheme ID
327/// * project_permission_scheme_id: `Option<i64>` - Jira Project permission scheme ID
328/// * project_issue_type_scheme_id: `Option<i64>` - Jira Project issue type scheme ID
329/// * project_issue_type_screen_scheme_id: `Option<i64>` - Jira Project issue type screen scheme ID
330/// * project_notification_scheme_id: `Option<i64>` - Jira Project notification scheme ID
331/// * project_workflow_scheme_id: `Option<i64>` - Jira Project workflow scheme ID
332/// * project_lead_account_id: `Option<String>` - Jira Project lead account ID
333/// * project_assignee_type: `Option<String>` - Jira Project assignee type
334/// * pagination: PaginationArgs - Jira Project pagination
335/// * output: OutputArgs - Jira Project actions result output format
336#[derive(Args, Clone, Debug, Serialize, Deserialize)]
337pub struct ProjectArgs {
338    /// Project action
339    #[arg(
340        value_name = "create|get-issue-types|get-issue-type-fields|list",
341        help_heading = "Jira Project management",
342        required = true
343    )]
344    pub project_act: ProjectActionValues,
345    /// Jira Project key
346    #[clap(
347        long,
348        short = 'k',
349        value_name = "project_key",
350        help = "Jira Project key"
351    )]
352    pub project_key: Option<String>,
353    /// Jira Project issue type ID
354    #[clap(
355        long,
356        short = 'i',
357        value_name = "project_issue_type",
358        help = "Jira Project issue type ID"
359    )]
360    pub project_issue_type: Option<String>,
361    /// Jira Project name
362    #[clap(long, value_name = "project_name", help = "Jira Project name")]
363    pub project_name: Option<String>,
364    /// Jira Project description
365    #[clap(
366        long,
367        value_name = "project_description",
368        help = "Jira Project description"
369    )]
370    pub project_description: Option<String>,
371    /// Jira Project field configuration ID
372    #[clap(
373        long,
374        value_name = "project_field_configuration_id",
375        help = "Jira Project field configuration ID"
376    )]
377    pub project_field_configuration_id: Option<i64>,
378    /// Jira Project issue security scheme ID
379    #[clap(
380        long,
381        value_name = "project_issue_security_scheme_id",
382        help = "Jira Project issue security scheme ID"
383    )]
384    pub project_issue_security_scheme_id: Option<i64>,
385    /// Jira Project issue type scheme ID
386    #[clap(
387        long,
388        value_name = "project_issue_type_scheme_id",
389        help = "Jira Project issue type scheme ID"
390    )]
391    pub project_issue_type_scheme_id: Option<i64>,
392    /// Jira Project issue type screen scheme ID
393    #[clap(
394        long,
395        value_name = "project_issue_type_screen_scheme_id",
396        help = "Jira Project issue type screen scheme ID"
397    )]
398    pub project_issue_type_screen_scheme_id: Option<i64>,
399    /// Jira Project notification scheme ID
400    #[clap(
401        long,
402        value_name = "project_notification_scheme_id",
403        help = "Jira Project notification scheme ID"
404    )]
405    pub project_notification_scheme_id: Option<i64>,
406    /// Jira Project permission scheme ID
407    #[clap(
408        long,
409        value_name = "project_permission_scheme_id",
410        help = "Jira Project permission scheme ID"
411    )]
412    pub project_permission_scheme_id: Option<i64>,
413    /// Jira project workflow scheme ID
414    #[clap(
415        long,
416        value_name = "project_workflow_scheme_id",
417        help = "Jira Project workflow scheme ID"
418    )]
419    pub project_workflow_scheme_id: Option<i64>,
420    /// Jira Project lead account ID
421    #[clap(
422        long,
423        value_name = "project_lead_account_id",
424        help = "Jira Project lead account ID"
425    )]
426    pub project_lead_account_id: Option<String>,
427    /// Jira Project Assignee Type
428    #[clap(
429        long,
430        value_name = "project_assignee_type",
431        help = "Jira Project Assignee Type"
432    )]
433    pub project_assignee_type: Option<String>,
434    /// Jira Project pagination
435    #[clap(flatten)]
436    pub pagination: PaginationArgs,
437    /// Jira Project actions result output format
438    #[clap(flatten)]
439    pub output: OutputArgs,
440}
441
442/// Available project action values
443///
444/// * Create: Create new Jira Project
445/// * GetIssueTypes: Get Jira Project issue types by Jira project key
446/// * GetIssueTypeFields: Get Jira Project issue type fields by Jira project key and issue type ID
447/// * List: List Jira Projects
448#[derive(ValueEnum, Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
449#[value(rename_all = "kebab-case")]
450pub enum ProjectActionValues {
451    /// Create new Jira Project
452    #[value(name = "create", help = "Create new Jira Project")]
453    Create,
454    /// Get Jira Project issue types by Jira project key
455    #[value(
456        name = "get-issue-types",
457        help = "Get Jira Project issue types by Jira project key"
458    )]
459    GetIssueTypes,
460    /// Get Jira Project issue type fields by Jira project key and issue type ID
461    #[value(
462        name = "get-issue-type-fields",
463        help = "Get Jira Project issue type fields by Jira project key and issue type ID"
464    )]
465    GetIssueTypeFields,
466    /// List Jira Projects
467    #[value(name = "list", help = "List Jira Projects")]
468    List,
469}
470
471/// Available issue command line arguments
472///
473/// * issue_act: IssueActionValues - Issue action
474/// * project_key: String - Jira Project key
475/// * issue_key: `Option<String>` - Jira Project issue key
476/// * issue_fields: `Option<Vec<(String, String)>>` - Jira Project issue fields
477/// * transition_to: `Option<String>` - Jira Project issue transition to
478/// * assignee: `Option<String>` - Jira Project issue assignee
479/// * query: `Option<String>` - Jira Project issue JQL query to search for issues
480/// * pagination: PaginationArgs - Jira Project issue pagination
481/// * output: OutputArgs - Jira Project issue actions result output format
482#[derive(Args, Clone, Debug, Serialize, Deserialize)]
483pub struct IssueArgs {
484    /// Issue action
485    #[arg(
486        value_name = "assign|create|delete|get|search|transition|update",
487        help_heading = "Jira Project issue management",
488        required = true
489    )]
490    pub issue_act: IssueActionValues,
491    /// Jira Project key
492    #[clap(
493        long,
494        short = 'k',
495        value_name = "project_key",
496        help = "Jira Project key"
497    )]
498    pub project_key: Option<String>,
499    /// Jira Project issue key
500    #[clap(
501        long,
502        short = 'i',
503        value_name = "issue_key",
504        help = "Jira Project issue key"
505    )]
506    pub issue_key: Option<String>,
507    /// Jira Project issue fields
508    #[clap(long,
509        short = 'f',
510        value_name = "issue_fields",
511        value_parser = parse_key_val::<String, String>,
512        help = "Jira Project issue fields (field_name=value)")]
513    pub issue_fields: Option<Vec<(String, String)>>,
514    /// Jira Project issue transition
515    #[clap(
516        long,
517        short = 't',
518        value_name = "transition_to",
519        help = "Jira Project issue transition to"
520    )]
521    pub transition_to: Option<String>,
522    /// Jira Project issue assignee
523    #[clap(
524        long,
525        short = 'a',
526        value_name = "assignee",
527        help = "Jira Project issue assignee"
528    )]
529    pub assignee: Option<String>,
530    /// Jira Project issue query
531    #[clap(
532        long,
533        short = 'q',
534        value_name = "query",
535        help = "Jira Project issue query"
536    )]
537    pub query: Option<String>,
538    /// Jira Project issue pagination
539    #[clap(flatten)]
540    pub pagination: PaginationArgs,
541    /// Jira Project issue actions result output format
542    #[clap(flatten)]
543    pub output: OutputArgs,
544}
545
546/// Available issue action values
547///
548/// * Assign: Assign a Jira Project issue
549/// * Create: Create a Jira Project issue
550/// * Delete: Delete a Jira Project issue
551/// * Get: Get a specific Jira Project issue
552/// * Search: Search for Jira Project issues using JQL
553/// * Transition: Transition a Jira Project issue
554/// * Update: Update a Jira Project issue
555#[derive(ValueEnum, Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
556#[value(rename_all = "kebab-case")]
557pub enum IssueActionValues {
558    /// Assign a Jira Project issue
559    #[value(name = "assign", help = "Assign a Jira Project issue")]
560    Assign,
561    /// Create a Jira Project issue
562    #[value(name = "create", help = "Create a Jira Project issue")]
563    Create,
564    /// Delete a Jira Project issue
565    #[value(name = "delete", help = "Delete a Jira Project issue")]
566    Delete,
567    /// Get a specific Jira Project issue
568    #[value(name = "get", help = "Get a specific Jira Project issue")]
569    Get,
570    /// Search for Jira Project issues using JQL query
571    #[value(name = "search", help = "Search for Jira Project issues")]
572    Search,
573    /// Transition a Jira Project issue
574    #[value(name = "transition", help = "Transition a Jira Project issue")]
575    Transition,
576    /// Update a Jira Project issue
577    #[value(name = "update", help = "Update a Jira Project issue")]
578    Update,
579}
580
581/// Available issues' links command line arguments
582///
583/// * link_act: LinkIssueActionValues - Jira link issue command available actions
584/// * project_key: `Option<String>` - Jira Project key
585/// * origin_issue_key: String - Jira origin issue link key
586/// * destination_issue_key: `Option<String>` - Jira destination issue link key
587/// * link_type: String - Jira issue link type
588/// * changelog_file: `Option<String>` - Jira Project version changelog file
589#[derive(Args, Clone, Debug, Serialize, Deserialize)]
590pub struct LinkIssueArgs {
591    /// Jira link issue command available actions
592    #[arg(
593        value_name = "create",
594        help_heading = "Jira issues links management",
595        required = true
596    )]
597    pub link_act: LinkIssueActionValues,
598    /// Jira Project key
599    #[clap(
600        long,
601        short = 'p',
602        value_name = "project_key",
603        help = "Jira Project key"
604    )]
605    pub project_key: Option<String>,
606    /// Jira origin issue link key
607    #[clap(
608        long,
609        short = 'i',
610        value_name = "issue_key",
611        help = "Jira issue link origin key",
612        required = true
613    )]
614    pub origin_issue_key: String,
615    /// Jira destination issue link key
616    #[clap(
617        long,
618        short = 'd',
619        value_name = "issue_key",
620        help = "Jira issue link destination key"
621    )]
622    pub destination_issue_key: Option<String>,
623    /// Jira issue link type
624    #[clap(
625        long,
626        short = 't',
627        value_name = "link_type",
628        help = "Jira issue link type",
629        required = true
630    )]
631    pub link_type: String,
632    /// Jira Project version changelog file
633    #[clap(
634        long,
635        short = 'c',
636        value_name = "changelog_file",
637        help = "changelog file path to be used for automatic issues' links generation (if set the script detects automatically the first tagged block in the changelog and use it as description)"
638    )]
639    pub changelog_file: Option<String>,
640}
641
642/// Available link issue action values
643///
644/// * Create: Create a Jira link between issues
645#[derive(ValueEnum, Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
646#[value(rename_all = "kebab-case")]
647pub enum LinkIssueActionValues {
648    /// Create a Jira link between issues
649    #[value(name = "create", help = "Create a Jira link between issues")]
650    Create,
651}
652
653/// Available transition command line arguments
654///
655/// * transition_act: TransitionActionValues - Transition action
656/// * issue_key: String - Jira issue key
657/// * output: OutputArgs - Jira issue output format
658#[derive(Args, Clone, Debug, Serialize, Deserialize)]
659pub struct TransitionArgs {
660    /// Transition action
661    #[arg(value_name = "list", help_heading = "Jira issue transition list")]
662    pub transition_act: TransitionActionValues,
663    /// Jira issue key
664    #[clap(
665        long,
666        short = 'i',
667        value_name = "issue_key",
668        help = "Jira Project issue key",
669        required = true
670    )]
671    pub issue_key: String,
672    /// Jira issue output format
673    #[clap(flatten)]
674    pub output: OutputArgs,
675}
676
677/// Available transition action values
678///
679/// * List: List Jira issue available transitions
680#[derive(ValueEnum, Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
681#[value(rename_all = "kebab-case")]
682pub enum TransitionActionValues {
683    /// List Jira issue available transitions
684    #[value(name = "list", help = "List Jira issue available transitions")]
685    List,
686}
687
688/// Parse a single key-value pair
689/// Thanks to the example from the clap documentation (https://github.com/clap-rs/clap/blob/master/examples/typed-derive.rs)
690fn parse_key_val<T, U>(s: &str) -> Result<(T, U), Box<dyn Error + Send + Sync + 'static>>
691where
692    T: std::str::FromStr,
693    T::Err: Error + Send + Sync + 'static,
694    U: std::str::FromStr,
695    U::Err: Error + Send + Sync + 'static,
696{
697    let pos = s
698        .find('=')
699        .ok_or_else(|| format!("invalid KEY=value: no `=` found in `{s}`"))?;
700    Ok((
701        s[..pos].parse()?,
702        manage_jira_document_field(s[pos + 1..].to_string()).parse()?,
703    ))
704}
705
706/// Manage Jira document field
707/// Relies on the manage_jira_document_field macro to wrap the field in the correct format
708fn manage_jira_document_field(value: String) -> String {
709    let re = Regex::new(r"^jira_doc_field\[(.+)\]$").unwrap();
710    let captures = re.captures(&value);
711    if let Some(captures) = &captures {
712        if let Some(first_match) = captures.get(1) {
713            jira_doc_std_field![first_match.as_str()].to_string()
714        } else {
715            value.to_string()
716        }
717    } else {
718        value.to_string()
719    }
720}