gr/cmds/
common.rs

1/// Common functions and macros that are used by multiple commands
2use crate::config::ConfigProperties;
3use crate::remote::CacheType;
4use crate::Result;
5use crate::{api_traits::MergeRequest, remote::ListRemoteCliArgs};
6use crate::{display, remote};
7use std::fmt::Display;
8use std::io::Write;
9use std::sync::Arc;
10
11use crate::api_traits::{
12    Cicd, CicdJob, CicdRunner, CodeGist, CommentMergeRequest, Deploy, DeployAsset, ProjectMember,
13    RemoteProject, RemoteTag, TrendingProjectURL,
14};
15
16use super::cicd::{JobListBodyArgs, JobListCliArgs, RunnerListBodyArgs, RunnerListCliArgs};
17use super::gist::{GistListBodyArgs, GistListCliArgs};
18use super::merge_request::{
19    CommentMergeRequestListBodyArgs, CommentMergeRequestListCliArgs, MergeRequestListBodyArgs,
20};
21use super::project::{Member, ProjectListBodyArgs, ProjectListCliArgs};
22use super::release::{ReleaseAssetListBodyArgs, ReleaseAssetListCliArgs, ReleaseBodyArgs};
23use super::trending::TrendingCliArgs;
24use super::{cicd::PipelineBodyArgs, merge_request::MergeRequestListCliArgs};
25
26macro_rules! query_pages {
27    ($func_name:ident, $trait_name:ident) => {
28        pub fn $func_name<W: Write>(remote: Arc<dyn $trait_name>, mut writer: W) -> Result<()> {
29            process_num_metadata(remote.num_pages(), MetadataName::Pages, &mut writer)
30        }
31    };
32    ($func_name:ident, $trait_name:ident, $body_args:ident) => {
33        pub fn $func_name<W: Write>(
34            remote: Arc<dyn $trait_name>,
35            body_args: $body_args,
36            mut writer: W,
37        ) -> Result<()> {
38            process_num_metadata(
39                remote.num_pages(body_args),
40                MetadataName::Pages,
41                &mut writer,
42            )
43        }
44    };
45}
46
47macro_rules! query_num_resources {
48    ($func_name:ident, $trait_name:ident) => {
49        pub fn $func_name<W: Write>(remote: Arc<dyn $trait_name>, mut writer: W) -> Result<()> {
50            process_num_metadata(remote.num_resources(), MetadataName::Resources, &mut writer)
51        }
52    };
53    ($func_name:ident, $trait_name:ident, $body_args:ident) => {
54        pub fn $func_name<W: Write>(
55            remote: Arc<dyn $trait_name>,
56            body_args: $body_args,
57            mut writer: W,
58        ) -> Result<()> {
59            process_num_metadata(
60                remote.num_resources(body_args),
61                MetadataName::Resources,
62                &mut writer,
63            )
64        }
65    };
66}
67
68#[derive(Debug)]
69pub enum MetadataName {
70    Pages,
71    Resources,
72}
73
74impl Display for MetadataName {
75    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76        match self {
77            MetadataName::Pages => write!(f, "pages"),
78            MetadataName::Resources => write!(f, "resources"),
79        }
80    }
81}
82
83pub fn process_num_metadata<W: Write, T: Display>(
84    num_metadata: Result<Option<T>>,
85    resource_name: MetadataName,
86    mut writer: W,
87) -> Result<()> {
88    let none_msg_info = format!("Number of {resource_name} not available.\n");
89    match num_metadata {
90        Ok(Some(count)) => writer.write_all(format!("{count}\n").as_bytes())?,
91        Ok(None) => {
92            writer.write_all(none_msg_info.as_bytes())?;
93        }
94        Err(e) => {
95            return Err(e);
96        }
97    };
98    Ok(())
99}
100
101query_pages!(num_release_pages, Deploy);
102query_pages!(
103    num_release_asset_pages,
104    DeployAsset,
105    ReleaseAssetListBodyArgs
106);
107query_pages!(num_cicd_pages, Cicd);
108query_pages!(num_runner_pages, CicdRunner, RunnerListBodyArgs);
109query_pages!(num_job_pages, CicdJob, JobListBodyArgs);
110
111query_pages!(
112    num_merge_request_pages,
113    MergeRequest,
114    MergeRequestListBodyArgs
115);
116query_pages!(num_project_pages, RemoteProject, ProjectListBodyArgs);
117query_num_resources!(num_project_resources, RemoteProject, ProjectListBodyArgs);
118
119query_pages!(num_tag_pages, RemoteTag, ProjectListBodyArgs);
120query_num_resources!(num_tag_resources, RemoteTag, ProjectListBodyArgs);
121
122query_pages!(num_project_member_pages, ProjectMember, ProjectListBodyArgs);
123query_num_resources!(
124    num_project_member_resources,
125    ProjectMember,
126    ProjectListBodyArgs
127);
128
129query_pages!(
130    num_comment_merge_request_pages,
131    CommentMergeRequest,
132    CommentMergeRequestListBodyArgs
133);
134
135query_num_resources!(num_release_resources, Deploy);
136query_num_resources!(
137    num_release_asset_resources,
138    DeployAsset,
139    ReleaseAssetListBodyArgs
140);
141query_num_resources!(num_cicd_resources, Cicd);
142query_num_resources!(num_runner_resources, CicdRunner, RunnerListBodyArgs);
143query_num_resources!(num_job_resources, CicdJob, JobListBodyArgs);
144query_num_resources!(
145    num_merge_request_resources,
146    MergeRequest,
147    MergeRequestListBodyArgs
148);
149query_pages!(
150    num_comment_merge_request_resources,
151    CommentMergeRequest,
152    CommentMergeRequestListBodyArgs
153);
154
155query_pages!(num_user_gists, CodeGist);
156query_num_resources!(num_user_gist_resources, CodeGist);
157
158macro_rules! list_resource {
159    ($func_name:ident, $trait_name:ident, $body_args:ident, $cli_args:ident, $embeds_list_args: literal) => {
160        pub fn $func_name<W: Write>(
161            remote: Arc<dyn $trait_name>,
162            body_args: $body_args,
163            cli_args: $cli_args,
164            mut writer: W,
165        ) -> Result<()> {
166            let objs =
167                list_remote_objs!(remote, body_args, cli_args.list_args, writer, $trait_name);
168            display::print(&mut writer, objs, cli_args.list_args.get_args)?;
169            Ok(())
170        }
171    };
172
173    ($func_name:ident, $trait_name:ident, $body_args:ident, $cli_args:ident) => {
174        pub fn $func_name<W: Write>(
175            remote: Arc<dyn $trait_name>,
176            body_args: $body_args,
177            cli_args: $cli_args,
178            mut writer: W,
179        ) -> Result<()> {
180            let objs = list_remote_objs!(remote, body_args, cli_args, writer, $trait_name);
181            display::print(&mut writer, objs, cli_args.get_args)?;
182            Ok(())
183        }
184    };
185}
186
187#[macro_export]
188macro_rules! list_remote_objs {
189    ($remote:expr, $body_args:expr, $cli_args:expr, $writer:expr, $trait_name:ident) => {{
190        let objs = $trait_name::list(&*$remote, $body_args)?;
191        if $cli_args.flush {
192            return Ok(());
193        }
194        if objs.is_empty() {
195            $writer.write_all(b"No resources found.\n")?;
196            return Ok(());
197        }
198        objs
199    }};
200}
201
202list_resource!(
203    list_merge_requests,
204    MergeRequest,
205    MergeRequestListBodyArgs,
206    MergeRequestListCliArgs,
207    true
208);
209
210list_resource!(list_pipelines, Cicd, PipelineBodyArgs, ListRemoteCliArgs);
211list_resource!(
212    list_runners,
213    CicdRunner,
214    RunnerListBodyArgs,
215    RunnerListCliArgs,
216    true
217);
218
219list_resource!(list_jobs, CicdJob, JobListBodyArgs, JobListCliArgs, true);
220
221list_resource!(list_releases, Deploy, ReleaseBodyArgs, ListRemoteCliArgs);
222list_resource!(
223    list_release_assets,
224    DeployAsset,
225    ReleaseAssetListBodyArgs,
226    ReleaseAssetListCliArgs,
227    true
228);
229
230list_resource!(
231    list_user_projects,
232    RemoteProject,
233    ProjectListBodyArgs,
234    ProjectListCliArgs,
235    true
236);
237
238list_resource!(
239    list_project_tags,
240    RemoteTag,
241    ProjectListBodyArgs,
242    ProjectListCliArgs,
243    true
244);
245
246list_resource!(
247    list_project_members,
248    ProjectMember,
249    ProjectListBodyArgs,
250    ProjectListCliArgs,
251    true
252);
253
254list_resource!(
255    list_user_gists,
256    CodeGist,
257    GistListBodyArgs,
258    GistListCliArgs,
259    true
260);
261
262list_resource!(
263    list_merge_request_comments,
264    CommentMergeRequest,
265    CommentMergeRequestListBodyArgs,
266    CommentMergeRequestListCliArgs,
267    true
268);
269
270list_resource!(list_trending, TrendingProjectURL, String, TrendingCliArgs);
271
272pub fn get_user(
273    domain: &str,
274    path: &str,
275    config: &Arc<dyn ConfigProperties>,
276    cli_args: &ListRemoteCliArgs,
277) -> Result<Member> {
278    let remote = remote::get_auth_user(
279        domain.to_string(),
280        path.to_string(),
281        config.clone(),
282        Some(&cli_args.get_args.cache_args),
283        CacheType::File,
284    )?;
285    let user = remote.get_auth_user()?;
286    Ok(user)
287}