seaplane_cli/context/
metadata.rs1use std::{
2 fs::File,
3 io::{self, Read},
4};
5
6use seaplane::api::{metadata::v1::Key, shared::v1::Directory};
7
8use crate::{
9 cli::cmds::metadata::{SeaplaneMetadataCommonArgMatches, SeaplaneMetadataSetArgMatches},
10 error::{CliError, Context, Result},
11 ops::metadata::{KeyValue, KeyValues},
12 printer::Color,
13};
14
15#[derive(Debug, Default, Clone)]
20pub struct MetadataCtx {
21 pub kvs: KeyValues,
22 pub directory: Option<Directory>,
23 pub base64: bool,
25 pub decode: bool,
27 pub decode_safe: bool,
29 pub no_decode: bool,
31 pub from: Option<Key>,
33 pub no_header: bool,
35 pub no_keys: bool,
37 pub no_values: bool,
39 pub keys_width_limit: usize,
41 pub values_width_limit: usize,
43}
44
45impl MetadataCtx {
46 pub fn from_md_common(matches: &SeaplaneMetadataCommonArgMatches) -> Result<MetadataCtx> {
48 let matches = matches.0;
49 let base64 = matches.get_flag("base64");
50 let raw_keys: Vec<_> = matches.get_many::<String>("key").unwrap().collect();
51
52 let mut kvs = KeyValues::default();
53 for key in raw_keys {
54 if base64 {
55 let engine = ::base64::engine::fast_portable::FastPortable::from(
57 &::base64::alphabet::URL_SAFE,
58 ::base64::engine::fast_portable::NO_PAD,
59 );
60 let _ = base64::decode_engine(key, &engine)?;
61 kvs.push(KeyValue::from_key(key));
62 } else {
63 kvs.push(KeyValue::from_key_unencoded(key));
64 }
65 }
66
67 Ok(MetadataCtx {
68 kvs,
69 base64: true, ..MetadataCtx::default()
71 })
72 }
73
74 pub fn from_md_set(matches: &SeaplaneMetadataSetArgMatches) -> Result<MetadataCtx> {
76 let matches = matches.0;
77 let base64 = matches.get_flag("base64");
78 let raw_key = matches.get_one::<String>("key").unwrap();
79 let raw_value = matches.get_one::<String>("value").unwrap();
80 let value = if let Some(val) = raw_value.strip_prefix('@') {
81 if val == "-" {
82 let mut buf: Vec<u8> = Vec::new();
83 let stdin = io::stdin();
84 let mut stdin_lock = stdin.lock();
85 stdin_lock.read_to_end(&mut buf)?;
86 buf
87 } else {
88 let mut f = File::open(val)
89 .map_err(CliError::from)
90 .context("\n\tpath: ")
91 .with_color_context(|| (Color::Yellow, val))?;
92
93 let mut buf = Vec::new();
95
96 f.read_to_end(&mut buf)?;
97 buf
98 }
99 } else {
100 raw_value.as_bytes().to_vec()
101 };
102
103 let engine = ::base64::engine::fast_portable::FastPortable::from(
104 &::base64::alphabet::URL_SAFE,
105 ::base64::engine::fast_portable::NO_PAD,
106 );
107 let kv = if base64 {
108 let _ = base64::decode_engine(raw_key, &engine)?;
110 let _ = base64::decode_engine(&value, &engine)?;
111 KeyValue::new(raw_key, &String::from_utf8(value)?)
114 } else {
115 KeyValue::new(
116 base64::encode_engine(raw_key, &engine),
117 base64::encode_engine(value, &engine),
118 )
119 };
120
121 let mut kvs = KeyValues::default();
122 kvs.push(kv);
123
124 Ok(MetadataCtx { kvs, base64: true, ..MetadataCtx::default() })
125 }
126}