Skip to main content

icann_rdap_cli/args/
target.rs

1use clap::{ArgGroup, Parser};
2use icann_rdap_client::rdap::QueryType;
3
4#[derive(Parser, Debug)]
5#[command(group(
6            ArgGroup::new("target")
7                .args(["link_target", "registry", "registrar", "up", "down", "bottom", "top"]),
8        ))]
9pub struct LinkTargetArgs {
10    /// Link Target
11    ///
12    /// Specifies a link target. If no link target is given, the
13    /// default is "related". More than one link target may be given.
14    /// A value of "_none" indicates no link target.
15    #[arg(long, required = false, value_enum)]
16    link_target: Vec<String>,
17
18    /// Only Show Link Target
19    ///
20    /// Unless specified, all responses are shown.
21    /// When specified, only the link target is shown.
22    #[arg(long, required = false)]
23    only_show_target: Option<bool>,
24
25    /// The minimum number of times to query for a link target.
26    #[arg(long, required = false)]
27    min_link_depth: Option<usize>,
28
29    /// The maximum number of times to query for a link target.
30    #[arg(long, required = false)]
31    max_link_depth: Option<usize>,
32
33    /// Set link target parameters for a domain registry.
34    #[arg(long, required = false, conflicts_with = "link_target")]
35    registry: bool,
36
37    /// Set link target parameters for a domain registrar.
38    #[arg(long, required = false, conflicts_with = "link_target")]
39    registrar: bool,
40
41    /// Set link target parameters for a parent network.
42    #[arg(long, required = false, conflicts_with = "link_target")]
43    up: bool,
44
45    /// Set link target parameters for the child networks.
46    #[arg(long, required = false, conflicts_with = "link_target")]
47    down: bool,
48
49    /// Set link target parameters for the least specific network.
50    #[arg(long, required = false, conflicts_with = "link_target")]
51    top: bool,
52
53    /// Set link target parameters for the most specific networks.
54    #[arg(long, required = false, conflicts_with = "link_target")]
55    bottom: bool,
56}
57
58#[derive(Clone)]
59pub struct LinkParams {
60    pub link_targets: Vec<String>,
61    pub only_show_target: bool,
62    pub min_link_depth: usize,
63    pub max_link_depth: usize,
64}
65
66pub fn default_link_params(query_type: &QueryType) -> LinkParams {
67    match query_type {
68        QueryType::IpV4Addr(_)
69        | QueryType::IpV6Addr(_)
70        | QueryType::IpV4Cidr(_)
71        | QueryType::IpV6Cidr(_)
72        | QueryType::AsNumber(_) => LinkParams {
73            link_targets: vec![],
74            only_show_target: false,
75            min_link_depth: 1,
76            max_link_depth: 1,
77        },
78        QueryType::Domain(_) => LinkParams {
79            link_targets: vec!["related".to_string()],
80            only_show_target: false,
81            min_link_depth: 1,
82            max_link_depth: 3,
83        },
84        _ => LinkParams {
85            link_targets: vec![],
86            only_show_target: false,
87            min_link_depth: 1,
88            max_link_depth: 1,
89        },
90    }
91}
92
93pub fn params_from_args(query_type: &QueryType, args: LinkTargetArgs) -> LinkParams {
94    if args.registry {
95        LinkParams {
96            link_targets: vec![],
97            only_show_target: false,
98            min_link_depth: 1,
99            max_link_depth: 1,
100        }
101    } else if args.registrar {
102        LinkParams {
103            link_targets: vec!["related".to_string()],
104            only_show_target: true,
105            min_link_depth: 2,
106            max_link_depth: 3,
107        }
108    } else if args.up {
109        LinkParams {
110            link_targets: vec!["rdap-up".to_string(), "rdap-active".to_string()],
111            only_show_target: true,
112            min_link_depth: 2,
113            max_link_depth: 2,
114        }
115    } else if args.down {
116        LinkParams {
117            link_targets: vec!["rdap-down".to_string(), "rdap-active".to_string()],
118            only_show_target: true,
119            min_link_depth: 2,
120            max_link_depth: 2,
121        }
122    } else if args.top {
123        LinkParams {
124            link_targets: vec!["rdap-top".to_string(), "rdap-active".to_string()],
125            only_show_target: true,
126            min_link_depth: 2,
127            max_link_depth: 2,
128        }
129    } else if args.bottom {
130        LinkParams {
131            link_targets: vec!["rdap-bottom".to_string(), "rdap-active".to_string()],
132            only_show_target: true,
133            min_link_depth: 2,
134            max_link_depth: 2,
135        }
136    } else if args.link_target.contains(&"_none".to_string()) {
137        let def_link_params = default_link_params(query_type);
138        LinkParams {
139            link_targets: vec![],
140            only_show_target: args
141                .only_show_target
142                .unwrap_or(def_link_params.only_show_target),
143            min_link_depth: args
144                .min_link_depth
145                .unwrap_or(def_link_params.min_link_depth),
146            max_link_depth: args
147                .max_link_depth
148                .unwrap_or(def_link_params.max_link_depth),
149        }
150    } else {
151        let def_link_params = default_link_params(query_type);
152        LinkParams {
153            link_targets: match args.link_target.is_empty() {
154                true => def_link_params.link_targets,
155                false => args.link_target,
156            },
157            only_show_target: args
158                .only_show_target
159                .unwrap_or(def_link_params.only_show_target),
160            min_link_depth: args
161                .min_link_depth
162                .unwrap_or(def_link_params.min_link_depth),
163            max_link_depth: args
164                .max_link_depth
165                .unwrap_or(def_link_params.max_link_depth),
166        }
167    }
168}