Move more to common crate

This commit is contained in:
Aode 2021-05-23 11:52:21 -05:00
parent 92950569cb
commit 67a33c0e90
13 changed files with 162 additions and 50 deletions

16
Cargo.lock generated
View file

@ -194,13 +194,6 @@ dependencies = [
"num-traits",
]
[[package]]
name = "command"
version = "0.1.0"
dependencies = [
"serde",
]
[[package]]
name = "cpufeatures"
version = "0.1.1"
@ -1579,12 +1572,18 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "streamdeck-common"
version = "0.1.0"
dependencies = [
"serde",
]
[[package]]
name = "streamdeckd"
version = "0.1.0"
dependencies = [
"anyhow",
"command",
"dbus",
"dbus-crossroads",
"dbus-tokio",
@ -1596,6 +1595,7 @@ dependencies = [
"serde_json",
"serialport",
"sled",
"streamdeck-common",
"tokio",
]

View file

@ -1,6 +1,6 @@
[workspace]
members = [
"./command",
"./streamdeck-common",
"./daemon",
"./marble",
"./obws"

View file

@ -1,5 +0,0 @@
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
#[serde(tag = "type")]
pub enum Command {
SwitchScene { name: String },
}

View file

@ -12,7 +12,7 @@ ipc-dbus = ["dbus", "dbus-tokio", "dbus-crossroads"]
[dependencies]
anyhow = "1"
command = { path = "../command" }
streamdeck-common = { path = "../streamdeck-common" }
directories = "3.0"
env_logger = "0.8.0"
log = "0.4.0"

View file

@ -2,10 +2,10 @@ use crate::{
message::{InputMessage, ManagerMessage, ObsMessage, Query},
store::Store,
};
use command::Command;
use dbus::{channel::MatchingReceiver, message::MatchRule, nonblock::SyncConnection};
use dbus_crossroads::{Crossroads, MethodErr};
use std::sync::Arc;
use streamdeck_common::Command;
use tokio::sync::{mpsc::Sender, Notify};
pub(crate) struct Dbus {

View file

@ -1,6 +1,6 @@
use crate::port::Port;
use command::Command;
use std::collections::HashMap;
use streamdeck_common::{Command, ObsState};
use tokio::sync::oneshot::Sender;
#[derive(Debug)]
@ -8,20 +8,13 @@ pub(crate) enum Query {
GetScenes(Sender<Vec<String>>),
}
#[derive(Debug)]
pub(crate) enum State {
Disconnected,
Unauthenticated,
Connected,
}
#[derive(Debug)]
pub(crate) enum ObsMessage {
Query(Query),
Command(Command),
Connect(String, u16),
Authenticate(String),
State(Sender<State>),
State(Sender<ObsState>),
Disconnect,
}
@ -47,13 +40,3 @@ pub(crate) enum ManagerMessage {
Opened(DeckConfig, Port),
Closed(String),
}
impl std::fmt::Display for State {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
State::Disconnected => write!(f, "Disconnected"),
State::Unauthenticated => write!(f, "Unauthenticated"),
State::Connected => write!(f, "Connected"),
}
}
}

View file

@ -1,9 +1,9 @@
use crate::{
message::{ObsMessage, Query, State},
message::{ObsMessage, Query},
store::Store,
};
use command::Command;
use obws::Client;
use streamdeck_common::{Command, ObsState};
use tokio::sync::mpsc::{Receiver, Sender};
pub(crate) struct Obs {
@ -67,9 +67,9 @@ async fn connect_obs(store: Store, tx: Sender<ObsMessage>) -> Result<(), anyhow:
}
match rx.await? {
State::Disconnected => return Err(anyhow::anyhow!("Failed to connect to obs")),
State::Connected => return Ok(()),
State::Unauthenticated => {
ObsState::Disconnected => return Err(anyhow::anyhow!("Failed to connect to obs")),
ObsState::Connected => return Ok(()),
ObsState::Unauthenticated => {
let password = store
.setting("obs-password")
.await?
@ -87,7 +87,7 @@ async fn connect_obs(store: Store, tx: Sender<ObsMessage>) -> Result<(), anyhow:
return Err(anyhow::anyhow!("Failed to send state message"));
}
if !matches!(rx.await?, State::Connected) {
if !rx.await?.is_connected() {
return Err(anyhow::anyhow!("Failed to authenticate with OBS"));
}
@ -95,16 +95,18 @@ async fn connect_obs(store: Store, tx: Sender<ObsMessage>) -> Result<(), anyhow:
}
impl Obs {
fn to_obs_state(&self) -> ObsState {
match self.inner {
Inner::Disconnected(_) => ObsState::Disconnected,
Inner::Unauthenticated(_) => ObsState::Unauthenticated,
Inner::Connected(_) => ObsState::Connected,
}
}
async fn handle(&mut self, message: ObsMessage) {
match message {
ObsMessage::State(sender) => {
let state = match &self.inner {
Inner::Disconnected(_) => State::Disconnected,
Inner::Unauthenticated(_) => State::Unauthenticated,
Inner::Connected(_) => State::Connected,
};
let _ = sender.send(state);
let _ = sender.send(self.to_obs_state());
}
message => {
self.inner.handle(message, &self.store).await;

View file

@ -1,6 +1,6 @@
use command::Command;
use sled::{Db, IVec, Tree};
use std::collections::HashMap;
use streamdeck_common::Command;
#[derive(Clone, Debug)]
pub(crate) struct Store {

View file

@ -1,5 +1,5 @@
[package]
name = "command"
name = "streamdeck-common"
version = "0.1.0"
authors = ["asonix"]
edition = "2018"

View file

@ -0,0 +1,67 @@
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(tag = "type")]
pub enum Command {
SwitchScene { name: String },
}
#[derive(
Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, serde::Deserialize, serde::Serialize,
)]
pub enum CommandVariant {
SwitchScene,
}
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct ParseErr(String);
impl Command {
pub fn to_variant(&self) -> CommandVariant {
match self {
Self::SwitchScene { .. } => CommandVariant::SwitchScene,
}
}
}
impl CommandVariant {
pub fn all() -> &'static [Self] {
static ALL: &'static [CommandVariant] = &[CommandVariant::SwitchScene];
ALL
}
pub fn as_id(&self) -> &'static str {
match self {
Self::SwitchScene => "SwitchScene",
}
}
}
impl Default for CommandVariant {
fn default() -> Self {
CommandVariant::SwitchScene
}
}
impl std::str::FromStr for CommandVariant {
type Err = ParseErr;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"SwitchScene" => Ok(Self::SwitchScene),
_ => Err(ParseErr(s.to_owned())),
}
}
}
impl std::fmt::Display for CommandVariant {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.as_id())
}
}
impl std::fmt::Display for ParseErr {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "Invalid command variant '{}' supplied", self.0)
}
}
impl std::error::Error for ParseErr {}

View file

@ -0,0 +1,5 @@
mod command;
mod obs_state;
pub use command::{Command, CommandVariant, ParseErr as CommandVariantParseErr};
pub use obs_state::{ObsState, ParseErr as ObsStateParseErr};

View file

@ -0,0 +1,60 @@
#[derive(
Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, serde::Deserialize, serde::Serialize,
)]
pub enum ObsState {
Disconnected,
Unauthenticated,
Connected,
}
impl ObsState {
pub fn to_str(&self) -> &'static str {
match self {
Self::Disconnected => "Disconnected",
Self::Unauthenticated => "Unauthenticated",
Self::Connected => "Connected",
}
}
pub fn is_connected(&self) -> bool {
matches!(self, Self::Connected)
}
pub fn is_unauthenticated(&self) -> bool {
matches!(self, Self::Unauthenticated)
}
pub fn is_disconnected(&self) -> bool {
matches!(self, Self::Disconnected)
}
}
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct ParseErr(String);
impl std::str::FromStr for ObsState {
type Err = ParseErr;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"Disconnected" => Ok(Self::Disconnected),
"Unauthenticated" => Ok(Self::Unauthenticated),
"Connected" => Ok(Self::Connected),
_ => Err(ParseErr(s.to_string())),
}
}
}
impl std::fmt::Display for ObsState {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.to_str())
}
}
impl std::fmt::Display for ParseErr {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "Invalid OBS state '{}' supplied", self.0)
}
}
impl std::error::Error for ParseErr {}