seaplane_cli/context/
locks.rs

1use seaplane::api::locks::v1::LockId;
2
3use crate::{cli::cmds::locks::SeaplaneLocksCommonArgMatches, error::Result, ops::locks::LockName};
4
5/// Represents the "Source of Truth" i.e. it combines all the CLI options, ENV vars, and config
6/// values into a single structure that can be used later to build models for the API or local
7/// structs for serializing
8#[derive(Debug, Default, Clone)]
9pub struct LocksCtx {
10    pub lock_name: Option<LockName>,
11    pub ttl: Option<u32>,
12    pub client_id: Option<String>,
13    pub lock_id: Option<LockId>,
14    /// Is the lock-name already URL safe base64 encoded
15    pub base64: bool,
16    /// Print with decoding
17    pub decode: bool,
18    /// Skip the KEY or VALUE header in --format=table
19    pub no_header: bool,
20}
21
22impl LocksCtx {
23    /// Builds a LocksCtx from ArgMatches
24    pub fn from_locks_common(matches: &SeaplaneLocksCommonArgMatches) -> Result<LocksCtx> {
25        let matches = matches.0;
26        let base64 = matches.get_flag("base64");
27        let raw_lock_name = matches.get_one::<String>("lock_name");
28
29        let lock_name: Option<LockName> = if base64 {
30            let res: Option<Result<LockName>> = raw_lock_name.map(|name| {
31                // Check that what the user passed really is valid base64
32                let engine = ::base64::engine::fast_portable::FastPortable::from(
33                    &::base64::alphabet::URL_SAFE,
34                    ::base64::engine::fast_portable::NO_PAD,
35                );
36                let _ = base64::decode_engine(name, &engine)?;
37                Ok::<LockName, _>(LockName::new(name))
38            });
39            res.transpose()?
40        } else {
41            raw_lock_name.map(LockName::from_name_unencoded)
42        };
43
44        Ok(LocksCtx {
45            lock_name,
46            base64: true, // At this point all keys and values should be encoded as base64
47            ..LocksCtx::default()
48        })
49    }
50}