From b4b1ac8d620f92befe5ad95e7cfb539ac8275e68 Mon Sep 17 00:00:00 2001 From: Nickiel12 Date: Sun, 18 Dec 2022 21:06:47 -0800 Subject: [PATCH] feat: Added basic communication protocol --- Cargo.toml | 2 ++ src/main.rs | 37 ++++++++++++++++-------- src/message_types.rs | 68 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 12 deletions(-) create mode 100644 src/message_types.rs diff --git a/Cargo.toml b/Cargo.toml index 5b2bfe3..b679ccb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,5 +8,7 @@ edition = "2021" [dependencies] clap = { version = "4.0.29", features = ["derive"] } confy = "0.5.1" +serde = { version = "1.0.151", features = ["derive"] } +serde_json = "1.0.91" tungstenite = "0.18.0" url = "2.3.1" diff --git a/src/main.rs b/src/main.rs index bed9847..2194f5a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,16 @@ use clap::{Parser, ValueEnum}; +use message_types::UIRequest; +use serde_json; use tungstenite::{connect, Message}; use url::Url; -const POSSIBLE_COMMANDS: &[&str] = &["play", "pause"]; +mod message_types; #[derive(ValueEnum, Debug, Clone)] enum SousaCommands { Play, Pause, + Search, } #[derive(Parser, Debug)] @@ -22,8 +25,21 @@ struct CliArgs { port: Option, /// The command to execute - #[arg(short, long, value_enum)] - action: SousaCommands, + #[arg(index = 1, value_enum)] + action: Option, + + /// The string to search for when paired with a "Search" action + #[arg(index = 2, required_if_eq("action", "search"))] + search_arg: Option, + + /// 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, } fn main() { @@ -35,16 +51,13 @@ fn main() { ) .expect("Couldn't connect to url"); - println!("Connected to the server"); - println!("Response HTTP code: {}", resp.status()); - println!("Response contains the following headers:"); - for (ref header, _value) in resp.headers() { - println!("* {}", header); - } + let message_string = match cli.action.unwrap() { + SousaCommands::Play => serde_json::to_string(&UIRequest::Play).unwrap(), + SousaCommands::Pause => serde_json::to_string(&UIRequest::Pause).unwrap(), + SousaCommands::Search => String::new(), + }; - socket - .write_message(Message::Text("Hello WebSocket".into())) - .unwrap(); + socket.write_message(Message::Text(message_string)).unwrap(); //let msg = socket.read_message().expect("Error reading message"); //println!("Received: {}", msg); socket.close(None).unwrap(); diff --git a/src/message_types.rs b/src/message_types.rs new file mode 100644 index 0000000..6f92edd --- /dev/null +++ b/src/message_types.rs @@ -0,0 +1,68 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Deserialize, Serialize)] +pub struct PartialTag { + pub path: Option, + pub title: Option, + pub artist: Option, + pub album: Option, + pub album_artist: Option, +} + +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, +}