Add naming support

This commit is contained in:
asonix 2021-05-06 00:26:15 -05:00
parent a6d11a9f1f
commit 381a54a62a
2 changed files with 177 additions and 0 deletions

View file

@ -331,6 +331,90 @@ impl Dbus {
}
},
);
b.method_with_cr_async(
"SetInputName",
("serial_number", "input", "name"),
(),
|mut ctx, cr, (serial_number, key, name): (String, u8, String)| {
log::debug!("SetInputName");
let state: &mut DbusState = cr.data_mut(ctx.path()).unwrap();
let store = state.store.clone();
async move {
if store
.set_input_name(&serial_number, key, &name)
.await
.is_ok()
{
return ctx.reply(Ok(()));
}
ctx.reply(Err(MethodErr::failed("Failed to set input name")))
}
},
);
b.method_with_cr_async(
"GetInputNames",
("serial_number",),
("names",),
|mut ctx, cr, (serial_number,): (String,)| {
log::debug!("InputNames");
let state: &mut DbusState = cr.data_mut(ctx.path()).unwrap();
let store = state.store.clone();
async move {
if let Ok(names) = store.input_names(&serial_number).await {
return ctx.reply(Ok((names.into_iter().collect::<Vec<_>>(),)));
}
ctx.reply(Err(MethodErr::failed("Failed to get input names")))
}
},
);
b.method_with_cr_async(
"SetDeckName",
("serial_number", "name"),
(),
|mut ctx, cr, (serial_number, name): (String, String)| {
log::debug!("SetDeckName");
let state: &mut DbusState = cr.data_mut(ctx.path()).unwrap();
let store = state.store.clone();
async move {
if store.set_deck_name(&serial_number, &name).await.is_ok() {
return ctx.reply(Ok(()));
}
ctx.reply(Err(MethodErr::failed("Failed to set deck name")))
}
},
);
b.method_with_cr_async(
"GetDeckName",
("serial_number",),
("name",),
|mut ctx, cr, (serial_number,): (String,)| {
log::debug!("GetDeckName");
let state: &mut DbusState = cr.data_mut(ctx.path()).unwrap();
let store = state.store.clone();
async move {
if let Ok(Some(name)) = store.deck_name(&serial_number).await {
return ctx.reply(Ok((name,)));
}
ctx.reply(Err(MethodErr::failed("Failed to fetch deck name")))
}
},
);
});
cr.insert("/dog/asonix/git/asonix/Streamdeck", &[iface_token], state);

View file

@ -1,10 +1,12 @@
use crate::message::Command;
use sled::{Db, IVec, Tree};
use std::collections::HashMap;
#[derive(Clone, Debug)]
pub(crate) struct Store {
commands: Tree,
settings: Tree,
names: Tree,
db: Db,
}
@ -14,12 +16,79 @@ impl Store {
Ok(Store {
commands: db.open_tree("dog.asonix.git.asonix.streamdeck/commands")?,
settings: db.open_tree("dog.asonix.git.asonix.streamdeck/settings")?,
names: db.open_tree("dog.asonix.git.asonix.streamdeck/names")?,
db,
}) as Result<Store, anyhow::Error>
})
.await?
}
pub(crate) async fn set_input_name(
&self,
deck: &str,
input: u8,
name: &str,
) -> Result<(), anyhow::Error> {
let key = self.input_name_key(deck, input);
let value = name.as_bytes().to_vec();
let names = self.names.clone();
tokio::task::spawn_blocking(move || names.insert(key, value)).await??;
Ok(())
}
pub(crate) async fn input_names(
&self,
deck: &str,
) -> Result<HashMap<u8, String>, anyhow::Error> {
let prefix = self.input_name_prefix(deck);
let prefix_len = prefix.len();
let names = self.names.clone();
let vec = tokio::task::spawn_blocking(move || {
names
.scan_prefix(prefix.clone())
.filter_map(|res| {
let (key, value) = res.ok()?;
if key.len() != prefix_len + 1 {
return None;
}
let input = key[prefix_len];
let value = String::from_utf8_lossy(&value).to_string();
Some((input, value))
})
.collect()
})
.await?;
Ok(vec)
}
pub(crate) async fn set_deck_name(&self, deck: &str, name: &str) -> Result<(), anyhow::Error> {
let key = self.deck_name_key(deck);
let value = name.as_bytes().to_vec();
let names = self.names.clone();
tokio::task::spawn_blocking(move || names.insert(key, value)).await??;
Ok(())
}
pub(crate) async fn deck_name(&self, deck: &str) -> Result<Option<String>, anyhow::Error> {
let key = self.deck_name_key(deck);
let names = self.names.clone();
let opt = tokio::task::spawn_blocking(move || names.get(key)).await??;
if let Some(ivec) = opt {
return Ok(Some(String::from_utf8_lossy(&ivec).to_string()));
}
Ok(None)
}
pub(crate) async fn setting<T>(&self, key: &str) -> Result<Option<T>, anyhow::Error>
where
T: serde::de::DeserializeOwned,
@ -119,6 +188,30 @@ impl Store {
Ok(vec)
}
fn deck_name_key(&self, deck: &str) -> IVec {
let mut key = b"names/".to_vec();
key.extend(deck.as_bytes());
IVec::from(key)
}
fn input_name_prefix(&self, deck: &str) -> IVec {
let mut key = b"names/".to_vec();
key.extend(deck.as_bytes());
key.push(b'/');
IVec::from(key)
}
fn input_name_key(&self, deck: &str, input: u8) -> IVec {
let mut key = b"names/".to_vec();
key.extend(deck.as_bytes());
key.push(b'/');
key.push(input);
IVec::from(key)
}
fn cmd_prefix(&self, deck: &str) -> IVec {
let mut prefix = deck.as_bytes().to_vec();
prefix.push(b'/');