parent
2facd17653
commit
a39a278220
@ -0,0 +1,58 @@ |
|||||||
|
//! Key-value store in `*.stamps` file.
|
||||||
|
|
||||||
|
use failure::{self, ResultExt}; |
||||||
|
use std::{env, fs, path::PathBuf}; |
||||||
|
|
||||||
|
/// Get a value corresponding to the key from the JSON value.
|
||||||
|
///
|
||||||
|
/// You should use return value of function `read_stamps_file_to_json()` as `json` argument.
|
||||||
|
pub fn get_stamp_value( |
||||||
|
key: impl AsRef<str>, |
||||||
|
json: &serde_json::Value, |
||||||
|
) -> Result<String, failure::Error> { |
||||||
|
json.get(key.as_ref()) |
||||||
|
.and_then(|value| value.as_str().map(ToOwned::to_owned)) |
||||||
|
.ok_or_else(|| { |
||||||
|
failure::err_msg(format!("cannot get stamp value for key '{}'", key.as_ref())) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
/// Save the key-value pair to the store.
|
||||||
|
pub fn save_stamp_value( |
||||||
|
key: impl Into<String>, |
||||||
|
value: impl AsRef<str>, |
||||||
|
) -> Result<(), failure::Error> { |
||||||
|
let mut json = read_stamps_file_to_json().unwrap_or_else(|_| serde_json::Map::new().into()); |
||||||
|
|
||||||
|
let stamps = json |
||||||
|
.as_object_mut() |
||||||
|
.ok_or_else(|| failure::err_msg("stamps file doesn't contain JSON object"))?; |
||||||
|
stamps.insert(key.into(), value.as_ref().into()); |
||||||
|
|
||||||
|
write_to_stamps_file(json) |
||||||
|
} |
||||||
|
|
||||||
|
/// Get the path of the `*.stamps` file that is used as the store.
|
||||||
|
pub fn get_stamps_file_path() -> Result<PathBuf, failure::Error> { |
||||||
|
let path = env::current_exe() |
||||||
|
.map(|path| path.with_extension("stamps")) |
||||||
|
.context("cannot get stamps file path")?; |
||||||
|
Ok(path) |
||||||
|
} |
||||||
|
|
||||||
|
/// Read `*.stamps` file and convert its content to the JSON value.
|
||||||
|
pub fn read_stamps_file_to_json() -> Result<serde_json::Value, failure::Error> { |
||||||
|
let stamps_file_path = get_stamps_file_path()?; |
||||||
|
let stamps_file_content = |
||||||
|
fs::read_to_string(stamps_file_path).context("cannot find or read stamps file")?; |
||||||
|
let json: serde_json::Value = serde_json::from_str(&stamps_file_content) |
||||||
|
.context("stamps file doesn't contain valid JSON")?; |
||||||
|
Ok(json) |
||||||
|
} |
||||||
|
|
||||||
|
fn write_to_stamps_file(json: serde_json::Value) -> Result<(), failure::Error> { |
||||||
|
let stamps_file_path = get_stamps_file_path()?; |
||||||
|
let pretty_json = serde_json::to_string_pretty(&json).context("JSON serialization failed")?; |
||||||
|
fs::write(stamps_file_path, pretty_json).context("cannot write to stamps file")?; |
||||||
|
Ok(()) |
||||||
|
} |
@ -0,0 +1,71 @@ |
|||||||
|
use std::{fs, panic}; |
||||||
|
use wasm_pack::stamps; |
||||||
|
|
||||||
|
fn run_test<T>(test: T) -> () |
||||||
|
where |
||||||
|
T: FnOnce() -> () + panic::UnwindSafe, |
||||||
|
{ |
||||||
|
before(); |
||||||
|
let result = panic::catch_unwind(|| test()); |
||||||
|
after(); |
||||||
|
assert!(result.is_ok()) |
||||||
|
} |
||||||
|
|
||||||
|
fn before() { |
||||||
|
remove_stamps_file() |
||||||
|
} |
||||||
|
|
||||||
|
fn after() { |
||||||
|
remove_stamps_file() |
||||||
|
} |
||||||
|
|
||||||
|
fn remove_stamps_file() { |
||||||
|
let stamps_file_path = stamps::get_stamps_file_path().unwrap(); |
||||||
|
if stamps_file_path.exists() { |
||||||
|
fs::remove_file(stamps_file_path).unwrap(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#[test] |
||||||
|
#[should_panic] |
||||||
|
#[serial] |
||||||
|
fn load_stamp_from_non_existent_file() { |
||||||
|
run_test(|| { |
||||||
|
// ACT
|
||||||
|
let json = stamps::read_stamps_file_to_json().unwrap(); |
||||||
|
stamps::get_stamp_value("Foo", &json).unwrap(); |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
#[test] |
||||||
|
#[serial] |
||||||
|
fn load_stamp() { |
||||||
|
run_test(|| { |
||||||
|
// ARRANGE
|
||||||
|
stamps::save_stamp_value("Foo", "Bar").unwrap(); |
||||||
|
|
||||||
|
// ACT
|
||||||
|
let json = stamps::read_stamps_file_to_json().unwrap(); |
||||||
|
let stamp_value = stamps::get_stamp_value("Foo", &json).unwrap(); |
||||||
|
|
||||||
|
// ASSERT
|
||||||
|
assert_eq!(stamp_value, "Bar"); |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
#[test] |
||||||
|
#[serial] |
||||||
|
fn update_stamp() { |
||||||
|
run_test(|| { |
||||||
|
// ARRANGE
|
||||||
|
stamps::save_stamp_value("Foo", "Bar").unwrap(); |
||||||
|
|
||||||
|
// ACT
|
||||||
|
stamps::save_stamp_value("Foo", "John").unwrap(); |
||||||
|
|
||||||
|
// ASSERT
|
||||||
|
let json = stamps::read_stamps_file_to_json().unwrap(); |
||||||
|
let stamp_value = stamps::get_stamp_value("Foo", &json).unwrap(); |
||||||
|
assert_eq!(stamp_value, "John"); |
||||||
|
}) |
||||||
|
} |
Loading…
Reference in new issue