alfred_workflow/lib.rs
1//! This contains common abstractions for reuse in multiple workflows
2//!
3use alfred::{json, Item};
4use failure::{format_err, Error};
5use rusqlite::Connection;
6use std::{fs, io::Write};
7
8/// Opens or creates if not exists an SQLite database.
9///
10/// # Arguments
11/// * `name` - The name of the workflow, which will create a dedicated sub-directory for.vec!
12/// * `f` - A lazily evaluated function that is called when the database is first created.
13///
14/// # Remarks
15/// `name` must be unique or it may conflict with other workflows.
16///
17/// # Examples
18///
19/// ```
20/// use failure::Error;
21/// use rusqlite::Connection;
22/// use rusqlite::NO_PARAMS;
23///
24/// fn main() -> Result<(), Error> {
25/// let conn = alfred_workflow::open_database_or_else("myworkflow", create_tables)?;
26/// Ok(())
27/// }
28///
29/// fn create_tables(conn: &Connection) -> Result<(), Error> {
30/// conn.execute(
31/// "CREATE TABLE IF NOT EXISTS config (
32/// key TEXT NOT NULL PRIMARY KEY,
33/// value TEXT NOT NULL
34/// );",
35/// NO_PARAMS,
36/// )?;
37/// Ok(())
38/// }
39/// ```
40pub fn open_database_or_else<F>(name: &str, f: F) -> Result<Connection, Error>
41where
42 F: Fn(&Connection) -> Result<(), Error>,
43{
44 let conn: Connection;
45 let path = dirs::home_dir()
46 .ok_or_else(|| format_err!("Impossible to get your home dir!"))?
47 .join(".alfred")
48 .join("workflows")
49 .join(name);
50
51 let db = path.join("db.sqlite3");
52 if !db.exists() {
53 fs::create_dir_all(path)?;
54 conn = Connection::open(&db)?;
55 f(&conn)?
56 } else {
57 conn = Connection::open(&db)?
58 }
59 Ok(conn)
60}
61
62/// Writes Alfred items to the provided writer.
63///
64/// # Arguments
65/// * `writer` - the writer to writer iterms to.vec!
66/// * `items` - the Alfred items to be written.vec!
67///
68/// # Examples
69/// ```
70/// use alfred::{json, Item};
71/// use std::{io, io::Write};
72/// use failure::Error;
73///
74/// fn main() -> Result<(), Error> {
75/// let item = alfred::ItemBuilder::new("settings")
76/// .subtitle("settings for the workflow")
77/// .into_item();
78/// alfred_workflow::write_items(io::stdout(), &[item])
79/// }
80/// ```
81pub fn write_items<W>(writer: W, items: &[Item]) -> Result<(), Error>
82where
83 W: Write,
84{
85 json::write_items(writer, &items[..])
86 .map_err(|e| format_err!("failed to write alfred items->json: {}", e))
87}