feat: Added basic communication protocol

This commit is contained in:
Nickiel12 2022-12-18 21:06:47 -08:00
parent 141e4460ab
commit b4b1ac8d62
3 changed files with 95 additions and 12 deletions

View file

@ -8,5 +8,7 @@ edition = "2021"
[dependencies] [dependencies]
clap = { version = "4.0.29", features = ["derive"] } clap = { version = "4.0.29", features = ["derive"] }
confy = "0.5.1" confy = "0.5.1"
serde = { version = "1.0.151", features = ["derive"] }
serde_json = "1.0.91"
tungstenite = "0.18.0" tungstenite = "0.18.0"
url = "2.3.1" url = "2.3.1"

View file

@ -1,13 +1,16 @@
use clap::{Parser, ValueEnum}; use clap::{Parser, ValueEnum};
use message_types::UIRequest;
use serde_json;
use tungstenite::{connect, Message}; use tungstenite::{connect, Message};
use url::Url; use url::Url;
const POSSIBLE_COMMANDS: &[&str] = &["play", "pause"]; mod message_types;
#[derive(ValueEnum, Debug, Clone)] #[derive(ValueEnum, Debug, Clone)]
enum SousaCommands { enum SousaCommands {
Play, Play,
Pause, Pause,
Search,
} }
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
@ -22,8 +25,21 @@ struct CliArgs {
port: Option<String>, port: Option<String>,
/// The command to execute /// The command to execute
#[arg(short, long, value_enum)] #[arg(index = 1, value_enum)]
action: SousaCommands, action: Option<SousaCommands>,
/// The string to search for when paired with a "Search" action
#[arg(index = 2, required_if_eq("action", "search"))]
search_arg: Option<String>,
/// The field to search for when running `search`
#[arg(
short,
long,
required_if_eq("action", "search"),
value_parser(["title", "artist", "album", "album_artist"])
)]
search_field: Option<String>,
} }
fn main() { fn main() {
@ -35,16 +51,13 @@ fn main() {
) )
.expect("Couldn't connect to url"); .expect("Couldn't connect to url");
println!("Connected to the server"); let message_string = match cli.action.unwrap() {
println!("Response HTTP code: {}", resp.status()); SousaCommands::Play => serde_json::to_string(&UIRequest::Play).unwrap(),
println!("Response contains the following headers:"); SousaCommands::Pause => serde_json::to_string(&UIRequest::Pause).unwrap(),
for (ref header, _value) in resp.headers() { SousaCommands::Search => String::new(),
println!("* {}", header); };
}
socket socket.write_message(Message::Text(message_string)).unwrap();
.write_message(Message::Text("Hello WebSocket".into()))
.unwrap();
//let msg = socket.read_message().expect("Error reading message"); //let msg = socket.read_message().expect("Error reading message");
//println!("Received: {}", msg); //println!("Received: {}", msg);
socket.close(None).unwrap(); socket.close(None).unwrap();

68
src/message_types.rs Normal file
View file

@ -0,0 +1,68 @@
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]
pub struct PartialTag {
pub path: Option<String>,
pub title: Option<String>,
pub artist: Option<String>,
pub album: Option<String>,
pub album_artist: Option<String>,
}
impl Default for PartialTag {
fn default() -> Self {
PartialTag {
path: None,
title: None,
artist: None,
album: None,
album_artist: None,
}
}
}
impl PartialTag {
pub fn has_path(self: &Self) -> bool {
self.path.is_some()
}
pub fn has_title(self: &Self) -> bool {
self.title.is_some()
}
pub fn has_artist(self: &Self) -> bool {
self.artist.is_some()
}
pub fn has_album(self: &Self) -> bool {
self.album.is_some()
}
pub fn has_album_artist(self: &Self) -> bool {
self.album_artist.is_some()
}
pub fn is_empty(self: &Self) -> bool {
return self.path.is_none()
&& self.title.is_none()
&& self.artist.is_none()
&& self.album.is_none()
&& self.album_artist.is_none();
}
}
#[derive(Serialize, Deserialize)]
pub enum SkipDirection {
Forward,
Backward,
}
#[derive(Serialize, Deserialize)]
pub enum UIRequest {
Play,
Pause,
Skip(SkipDirection),
GetList(String),
SwitchTo(PartialTag),
GetStatus,
}