umshctl/command/
tables.rs

1//! `dev-channel` / `dev-peer`: the device identity's own key tables.
2//!
3//! The digest form differs by table (a 2-byte channel id versus the
4//! 32-byte peer key itself), so listings and mutation reports print
5//! whatever digest the device quotes.
6
7use anyhow::{Result, bail};
8
9use umsh::ulcp_wire::ids::prop;
10
11use super::persist;
12use super::values::KeyArg;
13use crate::App;
14use crate::output::hex;
15
16#[derive(Debug, clap::Subcommand)]
17pub enum TableOp {
18    /// List the entries the device holds, in digest form.
19    List,
20    /// Add an entry.
21    Add {
22        #[arg(value_name = "KEY")]
23        key: KeyArg,
24    },
25    /// Remove an entry.
26    Remove {
27        #[arg(value_name = "KEY")]
28        key: KeyArg,
29    },
30}
31
32pub async fn run(app: &mut App, key: u32, noun: &str, op: Option<TableOp>) -> Result<()> {
33    let no_save = app.no_save;
34    let device = app.device()?;
35    match op.unwrap_or(TableOp::List) {
36        TableOp::List => {
37            let value = device.get_prop(key).await?;
38            let digest_len = if key == prop::DEV_CHANNEL_KEYS { 2 } else { 32 };
39            if value.is_empty() {
40                println!("no device {noun}s provisioned");
41            } else if !value.len().is_multiple_of(digest_len) {
42                bail!("malformed device {noun} listing");
43            } else {
44                for digest in value.chunks(digest_len) {
45                    println!("{}", hex(digest));
46                }
47            }
48            Ok(())
49        }
50        TableOp::Add { key: item } => {
51            let digest = device.insert_prop_item(key, &item.0).await?;
52            println!("device {noun} added (digest {})", hex(&digest));
53            persist(device, no_save).await
54        }
55        TableOp::Remove { key: item } => {
56            let digest = device.remove_prop_item(key, &item.0).await?;
57            println!("device {noun} removed (digest {})", hex(&digest));
58            persist(device, no_save).await
59        }
60    }
61}