fjall_cli/command/keyspace_command/
get_command.rs1use crate::{ByteEncoding, ByteEncodingDecodeError, PrefixKind, Suffix};
2use errgonomic::{handle, handle_bool, handle_opt};
3use fjall::{Database, KeyspaceCreateOptions};
4use std::io;
5use std::io::Write;
6use std::process::ExitCode;
7use thiserror::Error;
8
9#[derive(clap::Parser, Clone, Debug)]
10pub struct GetCommand {
11 #[arg(value_name = "KEY")]
12 key: String,
13
14 #[arg(long, value_enum, default_value_t = ByteEncoding::String)]
15 key_encoding: ByteEncoding,
16
17 #[arg(long, value_enum)]
18 value_prefix: Option<PrefixKind>,
19
20 #[arg(long)]
21 value_suffix: Option<Suffix>,
22}
23
24impl GetCommand {
25 pub async fn run(self, db: &Database, keyspace: impl Into<String>) -> Result<ExitCode, GetCommandRunError> {
26 use GetCommandRunError::*;
27 let keyspace = keyspace.into();
28 let Self {
29 key,
30 key_encoding,
31 value_prefix,
32 value_suffix,
33 } = self;
34 let key_bytes = handle!(key_encoding.decode(&key), DecodeKeyBytesFailed, key, key_encoding);
35 handle_bool!(!db.keyspace_exists(&keyspace), KeyspaceNotFound, keyspace);
36 let keyspace_handle = handle!(db.keyspace(&keyspace, KeyspaceCreateOptions::default), KeyspaceFailed, keyspace);
37 let value_opt = handle!(keyspace_handle.get(&key_bytes), GetFailed, keyspace, key);
38 let value = handle_opt!(value_opt, KeyNotFound, keyspace, key);
39 let mut stdout = io::stdout().lock();
40 if let Some(prefix) = value_prefix {
41 let bytes = prefix.write(&value);
42 handle!(stdout.write_all(&bytes), WriteAllFailed);
43 }
44 handle!(stdout.write_all(value.as_ref()), WriteAllFailed);
45 if let Some(suffix) = value_suffix {
46 handle!(stdout.write_all(suffix.as_bytes()), WriteAllFailed);
47 }
48 Ok(ExitCode::SUCCESS)
49 }
50}
51
52#[derive(Error, Debug)]
53pub enum GetCommandRunError {
54 #[error("failed to decode key '{key}' with encoding '{key_encoding}'")]
55 DecodeKeyBytesFailed { source: ByteEncodingDecodeError, key: String, key_encoding: ByteEncoding },
56
57 #[error("keyspace '{keyspace}' not found")]
58 KeyspaceNotFound { keyspace: String },
59
60 #[error("failed to open keyspace '{keyspace}'")]
61 KeyspaceFailed { source: fjall::Error, keyspace: String },
62
63 #[error("failed to get key '{key}' from keyspace '{keyspace}'")]
64 GetFailed { source: fjall::Error, keyspace: String, key: String },
65
66 #[error("key '{key}' not found in keyspace '{keyspace}'")]
67 KeyNotFound { keyspace: String, key: String },
68
69 #[error("failed to write value to stdout")]
70 WriteAllFailed { source: io::Error },
71}