Skip to main content

github_workflow_lib/
workflow.rs

1use crate::database::DbContext;
2use crate::errors::Error;
3use crate::github::{self, Account, GitHubAPI};
4use alfred::Item;
5
6pub struct Workflow {
7    accounts: Vec<Account>,
8    db: DbContext,
9}
10
11impl Workflow {
12    /// `api_keys` is a comma-separated list of `<token>` or `<token>@<ghes-host>` entries.
13    ///
14    /// # Errors
15    ///
16    /// Will return `Err` if `api_keys` is malformed or `database` could not be connected to.
17    ///
18    #[inline]
19    pub fn new(api_keys: &str, database_url: &str) -> Result<Self, Error> {
20        let accounts = github::parse_accounts(api_keys)?;
21        let db = DbContext::new(database_url)?;
22        Ok(Workflow { accounts, db })
23    }
24
25    /// Fetches repositories for every account before touching the cache, so a failing
26    /// account leaves the existing cache intact.
27    ///
28    /// # Errors
29    ///
30    /// Will return `Err` if Contacting GitHub returns an error.
31    ///
32    #[inline]
33    pub fn refresh_cache(&mut self) -> Result<(), Error> {
34        let mut repositories = Vec::new();
35        for account in &self.accounts {
36            let api = GitHubAPI::new(account);
37            for page in api.accessible_repositories() {
38                repositories.extend(page?);
39            }
40        }
41        self.db.replace_repositories(&repositories)?;
42        // and DB cleanup work
43        self.db.optimize()?;
44        Ok(())
45    }
46
47    /// # Errors
48    ///
49    /// Will return `Err` if querying the database fails.
50    ///
51    #[inline]
52    pub fn query<'items>(&self, repo_name: &str) -> Result<Vec<Item<'items>>, Error> {
53        self.db
54            .find_repositories(repo_name, 10)?
55            .into_iter()
56            .map(|repo| {
57                Ok(alfred::ItemBuilder::new(repo.name_with_owner)
58                    .subtitle(repo.name.clone())
59                    .autocomplete(repo.name)
60                    .arg(format!("open {}", repo.url))
61                    .into_item())
62            })
63            .collect::<Result<Vec<_>, _>>()
64    }
65}