|
1 |
| -mod groups_cmd; |
2 |
| -mod projects_cmd; |
3 |
| -mod users_cmd; |
| 1 | +pub(crate) mod commands; |
| 2 | +mod groups; |
| 3 | +mod projects; |
| 4 | +mod users; |
4 | 5 |
|
5 |
| -use std::io::{Error, ErrorKind}; |
6 |
| - |
7 |
| -use clap::{ArgMatches, Command}; |
| 6 | +use std::{ |
| 7 | + collections::HashMap, |
| 8 | + fmt::{self, Display, Formatter}, |
| 9 | + io::{Error, Result}, |
| 10 | + str::FromStr, |
| 11 | +}; |
8 | 12 |
|
9 | 13 | use gitlab::Gitlab;
|
10 | 14 |
|
11 |
| -use crate::{ |
12 |
| - args::{gitlab_token::ArgGitlabToken, gitlab_url::ArgGitlabUrl, Args}, |
13 |
| - cmd::Cmd, |
14 |
| -}; |
| 15 | +use self::{groups::Groups, projects::Projects, users::Users}; |
15 | 16 |
|
16 |
| -/// Register search cmd |
17 |
| -pub(crate) fn add_search_cmd() -> Command<'static> { |
18 |
| - return Command::new("search") |
19 |
| - .aliases(&["s", "find"]) |
20 |
| - .about("Search for GitLab entities") |
21 |
| - .arg(ArgGitlabToken::add()) |
22 |
| - .arg(ArgGitlabUrl::add()) |
23 |
| - .arg_required_else_help(true) |
24 |
| - .subcommand(projects_cmd::find_projects()) |
25 |
| - .subcommand(users_cmd::find_users()) |
26 |
| - .subcommand(groups_cmd::find_groups()); |
| 17 | +pub(crate) trait SearchEntity { |
| 18 | + fn search(&self, query: &str) -> Result<()>; |
27 | 19 | }
|
28 | 20 |
|
29 |
| -pub(crate) struct SearchCmd<'a> { |
30 |
| - // search_string: String, |
31 |
| - search_sub: Option<(&'a str, &'a ArgMatches)>, |
32 |
| - gitlab_client: Gitlab, |
| 21 | +pub(crate) struct SearchService<'a> { |
| 22 | + entities: HashMap<EntityName, Box<dyn SearchEntity + 'a>>, |
33 | 23 | }
|
34 | 24 |
|
35 |
| -pub(crate) fn prepare<'a>(sub_matches: &'a ArgMatches) -> Result<impl Cmd<'a>, Error> { |
36 |
| - let gitlab_token = match ArgGitlabToken::parse(sub_matches) { |
37 |
| - Ok(arg) => arg.value(), |
38 |
| - Err(err) => return Err(err), |
39 |
| - }; |
40 |
| - let gitlab_url = match ArgGitlabUrl::parse(sub_matches) { |
41 |
| - Ok(arg) => arg.value(), |
42 |
| - Err(err) => return Err(err), |
43 |
| - }; |
| 25 | +impl<'a> SearchService<'a> { |
| 26 | + pub fn new(gitlab_client: &'a Gitlab) -> Self { |
| 27 | + let mut entities: HashMap<EntityName, Box<dyn SearchEntity>> = HashMap::new(); |
| 28 | + entities.insert(EntityName::PROJECTS, Box::new(Projects::new(gitlab_client))); |
| 29 | + entities.insert(EntityName::GROUPS, Box::new(Groups::new(gitlab_client))); |
| 30 | + entities.insert(EntityName::USERS, Box::new(Users::new(gitlab_client))); |
| 31 | + SearchService { entities } |
| 32 | + } |
44 | 33 |
|
45 |
| - // Connect to gitlab |
46 |
| - let gitlab_client: Gitlab = match Gitlab::new( |
47 |
| - gitlab_url.to_string(), |
48 |
| - gitlab_token.to_string(), |
49 |
| - ) { |
50 |
| - Ok(g) => g, |
51 |
| - Err(_err) => return Err(Error::new(ErrorKind::Other, _err)), |
52 |
| - }; |
| 34 | + pub fn search(&self, entity_name: &str, query: &str) -> Result<()> { |
| 35 | + let entity_name = EntityName::from_str(entity_name)?; |
| 36 | + let entity = self.entities.get(&entity_name).ok_or_else(|| { |
| 37 | + Error::new( |
| 38 | + std::io::ErrorKind::NotFound, |
| 39 | + format!("Could not resolve entity with name {entity_name}"), |
| 40 | + ) |
| 41 | + })?; |
53 | 42 |
|
54 |
| - // Get search subcommand |
55 |
| - let search_sub = sub_matches.subcommand(); |
| 43 | + entity.search(query) |
| 44 | + } |
| 45 | +} |
56 | 46 |
|
57 |
| - Ok(SearchCmd { |
58 |
| - search_sub, |
59 |
| - gitlab_client, |
60 |
| - }) |
| 47 | +#[derive(Hash, PartialEq, Eq, Debug)] |
| 48 | +pub(crate) enum EntityName { |
| 49 | + GROUPS, |
| 50 | + PROJECTS, |
| 51 | + USERS, |
61 | 52 | }
|
62 | 53 |
|
63 |
| -impl<'a> Cmd<'a> for SearchCmd<'a> { |
64 |
| - fn exec(&self) -> Result<(), Error> { |
65 |
| - let result; |
66 |
| - match self.search_sub { |
67 |
| - Some(("users", sub_matches)) => { |
68 |
| - result = match users_cmd::prepare(sub_matches, &self.gitlab_client) { |
69 |
| - Ok(cmd) => cmd.exec(), |
70 |
| - Err(err) => Err(err), |
71 |
| - }; |
72 |
| - } |
73 |
| - Some(("projects", sub_matches)) => { |
74 |
| - result = match projects_cmd::prepare(sub_matches, &self.gitlab_client) { |
75 |
| - Ok(cmd) => cmd.exec(), |
76 |
| - Err(err) => Err(err), |
77 |
| - }; |
78 |
| - } |
79 |
| - Some(("groups", sub_matches)) => { |
80 |
| - result = match groups_cmd::prepare(sub_matches, &self.gitlab_client) { |
81 |
| - Ok(cmd) => cmd.exec(), |
82 |
| - Err(err) => Err(err), |
83 |
| - }; |
84 |
| - } |
85 |
| - _ => { |
86 |
| - return Err(Error::new( |
87 |
| - std::io::ErrorKind::InvalidInput, |
88 |
| - "You should specify what you are looking for, please use help", |
89 |
| - )); |
90 |
| - } |
| 54 | +impl FromStr for EntityName { |
| 55 | + type Err = Error; |
| 56 | + |
| 57 | + fn from_str(s: &str) -> Result<EntityName> { |
| 58 | + match s { |
| 59 | + "groups" => Ok(Self::GROUPS), |
| 60 | + "projects" => Ok(Self::PROJECTS), |
| 61 | + "users" => Ok(Self::USERS), |
| 62 | + name => Err(Error::new( |
| 63 | + std::io::ErrorKind::InvalidInput, |
| 64 | + format!("Entity with name {name} does not exist"), |
| 65 | + )), |
91 | 66 | }
|
92 |
| - return result; |
| 67 | + } |
| 68 | +} |
| 69 | + |
| 70 | +impl Display for EntityName { |
| 71 | + fn fmt(&self, f: &mut Formatter) -> fmt::Result { |
| 72 | + write!(f, "{:?}", self) |
93 | 73 | }
|
94 | 74 | }
|
0 commit comments