Skip to content

Commit 05e6099

Browse files
committed
wip: add anyhow results to store trait
1 parent 8e6fd80 commit 05e6099

6 files changed

Lines changed: 74 additions & 65 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ categories = ["command-line-utilities"]
1313
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1414

1515
[dependencies]
16+
anyhow = "1.0.102"
1617
json = "0.12.4"
1718
rusqlite = { version = "0.39.0", features = ["bundled"] }
1819
seahorse = "2.1.0"

src/actions.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use std::path::Path;
22

33
use seahorse::{ActionError, ActionResult, Context};
44

5-
use crate::config::{get_config_path, get_db_path};
6-
use crate::error::invalid;
5+
use crate::config::get_db_path;
6+
use crate::error::{invalid, to_action_error};
77
use crate::storage::sqlite::SQLiteStore;
88
use crate::storage::{self, Store, StoreValue};
99

@@ -20,10 +20,10 @@ pub fn init_action(_c: &Context) -> ActionResult {
2020
Ok(())
2121
}
2222

23-
pub fn list_action(c: &Context) -> ActionResult {
23+
pub fn list_action(_c: &Context) -> ActionResult {
2424
let store = storage::load_storage();
2525

26-
for (key, value) in store.all().iter() {
26+
for (key, value) in store.all().map_err(to_action_error)?.iter() {
2727
println!("{}\t{}", key, value);
2828
}
2929

@@ -33,9 +33,9 @@ pub fn list_action(c: &Context) -> ActionResult {
3333
pub fn clear_action(_c: &Context) -> ActionResult {
3434
let mut store = storage::load_storage();
3535

36-
store.clear();
36+
let count = store.clear().map_err(to_action_error)?;
3737

38-
println!("cleared config file at '{:?}'", get_config_path());
38+
println!("removed {} keys from store", count);
3939

4040
Ok(())
4141
}
@@ -53,7 +53,7 @@ pub fn get_action(c: &Context) -> ActionResult {
5353

5454
let store = storage::load_storage();
5555

56-
let value = store.get(key);
56+
let value = store.get(key).map_err(to_action_error)?;
5757

5858
match value {
5959
Some(v) => {
@@ -89,7 +89,7 @@ pub fn set_action(c: &Context) -> ActionResult {
8989
let mut store = storage::load_storage();
9090

9191
let value = StoreValue::Value(value_str.to_owned());
92-
store.set(key, value.clone());
92+
store.set(key, value.clone()).map_err(to_action_error)?;
9393

9494
println!("'{}' -> '{}'", key, value);
9595

@@ -103,7 +103,7 @@ pub fn remove_action(c: &Context) -> ActionResult {
103103

104104
let mut store = storage::load_storage();
105105

106-
match store.remove(key) {
106+
match store.remove(key).map_err(to_action_error)? {
107107
Some(value) => println!("{}\t{}", key, value),
108108
None => {
109109
println!("key '{}' was not found", key);

src/error.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,9 @@ pub fn invalid(cause: &str) -> ActionError {
99
),
1010
}
1111
}
12+
13+
pub fn to_action_error(err: anyhow::Error) -> ActionError {
14+
return ActionError {
15+
message: err.to_string(),
16+
};
17+
}

src/storage/json.rs

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use anyhow::Result;
2+
13
use std::fs::{read_to_string, File};
24
use std::io;
35
use std::io::Write;
@@ -59,45 +61,50 @@ impl JSONStore {
5961
}
6062

6163
impl Store for JSONStore {
62-
fn all(&self) -> Vec<(String, StoreValue)> {
63-
self
64-
.store
65-
.entries()
66-
.map(|(key, value)| (key.to_owned(), value.into()))
67-
.collect()
64+
fn all(&self) -> Result<Vec<(String, StoreValue)>> {
65+
Ok(
66+
self
67+
.store
68+
.entries()
69+
.map(|(key, value)| (key.to_owned(), value.into()))
70+
.collect(),
71+
)
6872
}
6973

70-
fn get(&self, key: &str) -> Option<StoreValue> {
74+
fn get(&self, key: &str) -> Result<Option<StoreValue>> {
7175
if !self.store.has_key(key) {
72-
return None;
76+
return Ok(None);
7377
}
7478

75-
Some(self.store[key].clone().into())
79+
Ok(Some(self.store[key].clone().into()))
7680
}
7781

78-
fn set(&mut self, key: &str, value: StoreValue) -> StoreValue {
82+
fn set(&mut self, key: &str, value: StoreValue) -> Result<StoreValue> {
7983
self.store.insert(key, value.clone()).unwrap();
8084

8185
self.save_store().unwrap();
8286

83-
value
87+
Ok(value)
8488
}
8589

86-
fn remove(&mut self, key: &str) -> Option<StoreValue> {
90+
fn remove(&mut self, key: &str) -> Result<Option<StoreValue>> {
8791
if !self.store.has_key(key) {
88-
return None;
92+
return Ok(None);
8993
}
9094

9195
let value = self.store.remove(key);
9296

9397
self.save_store().unwrap();
9498

95-
return Some(value.into());
99+
return Ok(Some(value.into()));
96100
}
97101

98-
fn clear(&mut self) {
102+
fn clear(&mut self) -> Result<usize> {
103+
let len = self.store.len();
99104
self.store.clear();
100105

101106
self.save_store().unwrap();
107+
108+
return Ok(len);
102109
}
103110
}

src/storage/mod.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use anyhow::Result;
2+
13
pub mod json;
24
pub mod sqlite;
35
mod value;
@@ -7,13 +9,13 @@ pub use value::StoreValue;
79
use crate::config::get_db_path;
810

911
pub trait Store {
10-
fn all(&self) -> Vec<(String, StoreValue)>;
12+
fn all(&self) -> Result<Vec<(String, StoreValue)>>;
1113

12-
fn get(&self, key: &str) -> Option<StoreValue>;
13-
fn set(&mut self, key: &str, value: StoreValue) -> StoreValue;
14-
fn remove(&mut self, key: &str) -> Option<StoreValue>;
14+
fn get(&self, key: &str) -> Result<Option<StoreValue>>;
15+
fn set(&mut self, key: &str, value: StoreValue) -> Result<StoreValue>;
16+
fn remove(&mut self, key: &str) -> Result<Option<StoreValue>>;
1517

16-
fn clear(&mut self);
18+
fn clear(&mut self) -> Result<usize>;
1719
}
1820

1921
//TODO: Change STORE Based on config.

src/storage/sqlite/mod.rs

Lines changed: 29 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use anyhow::{anyhow, Result};
12
use std::path::Path;
23

34
use rusqlite::OptionalExtension as _;
@@ -17,78 +18,70 @@ impl SQLiteStore {
1718
.execute_batch(include_str!("schema.sql"))
1819
.expect("To Create DB");
1920

20-
return Self { connection: conn };
21+
Self { connection: conn }
2122
}
2223
}
2324

2425
impl Store for SQLiteStore {
25-
fn all(&self) -> Vec<(String, super::StoreValue)> {
26-
let mut stmt = self.connection.prepare("SELECT key,value from KV").unwrap();
26+
fn all(&self) -> Result<Vec<(String, super::StoreValue)>> {
27+
let mut stmt = self.connection.prepare("SELECT key,value from KV")?;
2728

2829
let values = stmt
29-
.query_map([], |row| {
30-
let key: String = row.get(0)?;
31-
let value = StoreValue::Value(row.get::<_, String>(1)?);
30+
.query_map([], |row| Ok((row.get(0)?, StoreValue::Value(row.get(1)?))))?
31+
.collect::<Result<Vec<_>, _>>()?;
3232

33-
return Ok((key, value));
34-
})
35-
.unwrap()
36-
.collect::<Result<Vec<_>, _>>()
37-
.unwrap();
38-
39-
return values;
33+
Ok(values)
4034
}
4135

42-
fn get(&self, key: &str) -> Option<super::StoreValue> {
36+
fn get(&self, key: &str) -> Result<Option<super::StoreValue>> {
4337
let stmt = self
4438
.connection
4539
.query_row(
4640
"SELECT key,value from KV where key = ?1 LIMIT 1",
4741
[key],
48-
|row| Ok(StoreValue::Value(row.get(1).unwrap())),
42+
|row| Ok(StoreValue::Value(row.get(1)?)),
4943
)
50-
.optional()
51-
.unwrap();
44+
.optional()?;
5245

53-
return stmt;
46+
Ok(stmt)
5447
}
5548

56-
fn set(&mut self, key: &str, value: super::StoreValue) -> super::StoreValue {
49+
fn set(&mut self, key: &str, value: StoreValue) -> Result<StoreValue> {
5750
let StoreValue::Value(value) = value else {
58-
panic!("Invalid value passed into SQLiteStore GET [{}]", value)
51+
return Err(anyhow!(
52+
"Invalid value passed into SQLiteStore GET [{}]",
53+
value
54+
));
5955
};
6056

61-
self
62-
.connection
63-
.execute(
64-
"INSERT INTO KV VALUES(NULL,?1,?2) ON CONFLICT(key) DO UPDATE SET value = ?2 WHERE key = ?1",
65-
[key, &value],
66-
)
67-
.unwrap();
57+
self.connection.execute(
58+
"INSERT INTO KV VALUES(NULL,?1,?2) ON CONFLICT(key) DO UPDATE SET value = ?2 WHERE key = ?1",
59+
[key, &value],
60+
)?;
6861

69-
return StoreValue::Value(value);
62+
Ok(StoreValue::Value(value))
7063
}
7164

72-
fn remove(&mut self, key: &str) -> Option<super::StoreValue> {
73-
let value = self.get(key);
65+
fn remove(&mut self, key: &str) -> Result<Option<StoreValue>> {
66+
let value = self.get(key)?;
7467

7568
let Some(value) = value else {
76-
return None;
69+
return Ok(None);
7770
};
7871

7972
let stmt = self
8073
.connection
81-
.execute("DELETE FROM KV where key = ?1", [key])
82-
.unwrap();
74+
.execute("DELETE FROM KV where key = ?1", [key])?;
8375

8476
if stmt == 0 {
8577
panic!("Deleted 0 Rows when trying to delete Value from Store")
8678
}
8779

88-
Some(value)
80+
Ok(Some(value))
8981
}
9082

91-
fn clear(&mut self) {
92-
self.connection.execute("DELETE FROM KV", []).unwrap();
83+
fn clear(&mut self) -> Result<usize> {
84+
let deleted = self.connection.execute("DELETE FROM KV", [])?;
85+
Ok(deleted)
9386
}
9487
}

0 commit comments

Comments
 (0)