Add naming support
This commit is contained in:
parent
a6d11a9f1f
commit
381a54a62a
84
src/dbus.rs
84
src/dbus.rs
|
@ -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);
|
||||
|
|
93
src/store.rs
93
src/store.rs
|
@ -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'/');
|
||||
|
|
Loading…
Reference in a new issue