Skip to main content

gitee_cli_rs/api/
search.rs

1use super::client::Client;
2use crate::error::Result;
3use crate::models::{Issue, RepoDetails, UserBasic};
4
5// OMIT search code, search commits, search prs — swagger has NO /search/code or
6// /search/commits, and /search/issues has no PR type filter (verified 2026-07-18).
7
8pub struct Search<'a> {
9    client: &'a Client,
10}
11
12pub struct SearchReposFilter<'a> {
13    pub q: &'a str,
14    pub owner: Option<&'a str>,
15    pub language: Option<&'a str>,
16    pub fork: bool,
17    pub sort: Option<&'a str>,
18    pub order: Option<&'a str>,
19    pub limit: usize,
20}
21
22pub struct SearchIssuesFilter<'a> {
23    pub q: &'a str,
24    pub repo: Option<&'a str>,
25    pub language: Option<&'a str>,
26    pub label: Option<&'a str>,
27    pub state: Option<&'a str>,
28    pub author: Option<&'a str>,
29    pub assignee: Option<&'a str>,
30    pub sort: Option<&'a str>,
31    pub order: Option<&'a str>,
32    pub limit: usize,
33}
34
35pub struct SearchUsersFilter<'a> {
36    pub q: &'a str,
37    pub sort: Option<&'a str>,
38    pub order: Option<&'a str>,
39    pub limit: usize,
40}
41
42impl Search<'_> {
43    pub(crate) fn new(client: &Client) -> Search<'_> {
44        Search { client }
45    }
46
47    pub fn repos(&self, filter: &SearchReposFilter<'_>) -> Result<Vec<RepoDetails>> {
48        let mut q: Vec<(&str, String)> = vec![("q", filter.q.to_string())];
49        if let Some(v) = filter.owner {
50            q.push(("owner", v.to_string()));
51        }
52        if let Some(v) = filter.language {
53            q.push(("language", v.to_string()));
54        }
55        if filter.fork {
56            q.push(("fork", "true".to_string()));
57        }
58        if let Some(v) = filter.sort {
59            q.push(("sort", v.to_string()));
60        }
61        if let Some(v) = filter.order {
62            q.push(("order", v.to_string()));
63        }
64        let qref = Client::str_refs(&q);
65        self.client
66            .get_paged("/search/repositories", &qref, filter.limit)
67    }
68
69    pub fn issues(&self, filter: &SearchIssuesFilter<'_>) -> Result<Vec<Issue>> {
70        let mut q: Vec<(&str, String)> = vec![("q", filter.q.to_string())];
71        if let Some(v) = filter.repo {
72            q.push(("repo", v.to_string()));
73        }
74        if let Some(v) = filter.language {
75            q.push(("language", v.to_string()));
76        }
77        if let Some(v) = filter.label {
78            q.push(("label", v.to_string()));
79        }
80        if let Some(v) = filter.state {
81            q.push(("state", v.to_string()));
82        }
83        if let Some(v) = filter.author {
84            q.push(("author", v.to_string()));
85        }
86        if let Some(v) = filter.assignee {
87            q.push(("assignee", v.to_string()));
88        }
89        if let Some(v) = filter.sort {
90            q.push(("sort", v.to_string()));
91        }
92        if let Some(v) = filter.order {
93            q.push(("order", v.to_string()));
94        }
95        let qref = Client::str_refs(&q);
96        self.client.get_paged("/search/issues", &qref, filter.limit)
97    }
98
99    pub fn users(&self, filter: &SearchUsersFilter<'_>) -> Result<Vec<UserBasic>> {
100        let mut q: Vec<(&str, String)> = vec![("q", filter.q.to_string())];
101        if let Some(v) = filter.sort {
102            q.push(("sort", v.to_string()));
103        }
104        if let Some(v) = filter.order {
105            q.push(("order", v.to_string()));
106        }
107        let qref = Client::str_refs(&q);
108        self.client.get_paged("/search/users", &qref, filter.limit)
109    }
110}