Skip to content

Commit

Permalink
feat: ipc server and cli
Browse files Browse the repository at this point in the history
  • Loading branch information
JakeStanger committed Jun 29, 2023
1 parent 93baf8f commit f5bdc5a
Show file tree
Hide file tree
Showing 10 changed files with 427 additions and 6 deletions.
122 changes: 122 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 16 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ version = "0.12.1"
edition = "2021"
license = "MIT"
description = "Customisable GTK Layer Shell wlroots/sway bar"
repository = "https://github.com/jakestanger/ironbar"

[features]
default = [
"cli",
"ipc",
"http",
"config+all",
"clipboard",
Expand All @@ -17,8 +20,11 @@ default = [
"upower",
"workspaces+all"
]

cli = ["dep:clap", "ipc"]
ipc = ["dep:serde_json"]

http = ["dep:reqwest"]
upower = ["upower_dbus", "zbus", "futures-lite"]

"config+all" = ["config+json", "config+yaml", "config+toml", "config+corn", "config+ron"]
"config+json" = ["universal-config/json"]
Expand All @@ -40,6 +46,8 @@ sys_info = ["sysinfo", "regex"]

tray = ["stray"]

upower = ["upower_dbus", "zbus", "futures-lite"]

workspaces = ["futures-util"]
"workspaces+all" = ["workspaces", "workspaces+sway", "workspaces+hyprland"]
"workspaces+sway" = ["workspaces", "swayipc-async"]
Expand Down Expand Up @@ -67,11 +75,18 @@ wayland-protocols = { version = "0.30.0", features = ["unstable", "client"] }
wayland-protocols-wlr = { version = "0.1.0", features = ["client"] }
smithay-client-toolkit = { version = "0.17.0", default-features = false, features = ["calloop"] }
universal-config = { version = "0.4.0", default_features = false }
ctrlc = "3.4.0"

lazy_static = "1.4.0"
async_once = "0.2.6"
cfg-if = "1.0.0"

# cli
clap = { version = "4.2.7", optional = true, features = ["derive"] }

# ipc
serde_json = { version = "1.0.96", optional = true }

# http
reqwest = { version = "0.11.18", optional = true }

Expand Down
2 changes: 1 addition & 1 deletion src/bridge_channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::send;
use tokio::spawn;
use tokio::sync::mpsc;

/// MPSC async -> sync channel.
/// MPSC async -> GTK sync channel.
/// The sender uses `tokio::sync::mpsc`
/// while the receiver uses `glib::MainContext::channel`.
///
Expand Down
19 changes: 19 additions & 0 deletions src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use crate::ipc::commands::Command;
use crate::ipc::responses::Response;
use clap::Parser;
use serde::{Deserialize, Serialize};

#[derive(Parser, Debug, Serialize, Deserialize)]
#[command(version)]
pub struct Args {
#[command(subcommand)]
pub command: Option<Command>,
}

pub fn handle_response(response: Response) {
match response {
Response::Ok => println!("ok"),
Response::OkValue { value } => println!("ok\n{value}"),
Response::Err { message } => eprintln!("error\n{}", message.unwrap_or_default()),
}
}
28 changes: 28 additions & 0 deletions src/ipc/client.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use super::Ipc;
use crate::ipc::{Command, Response};
use color_eyre::Result;
use color_eyre::{Help, Report};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::UnixStream;

impl Ipc {
/// Sends a command to the IPC server.
/// The server response is returned.
pub async fn send(&self, command: Command) -> Result<Response> {
let mut stream = match UnixStream::connect(&self.path).await {
Ok(stream) => Ok(stream),
Err(err) => Err(Report::new(err)
.wrap_err("Failed to connect to Ironbar IPC server")
.suggestion("Is Ironbar running?")),
}?;

let write_buffer = serde_json::to_vec(&command)?;
stream.write_all(&write_buffer).await?;

let mut read_buffer = vec![0; 1024];
let bytes = stream.read(&mut read_buffer).await?;

let response = serde_json::from_slice(&read_buffer[..bytes])?;
Ok(response)
}
}
14 changes: 14 additions & 0 deletions src/ipc/commands.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use clap::Subcommand;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;

#[derive(Subcommand, Debug, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum Command {
/// Return "ok"
Ping,

/// Open the GTK inspector
Inspect,
}

33 changes: 33 additions & 0 deletions src/ipc/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
mod client;
pub mod commands;
pub mod responses;
mod server;

use std::path::PathBuf;
use tracing::warn;

pub use commands::Command;
pub use responses::Response;

#[derive(Debug)]
pub struct Ipc {
path: PathBuf,
}

impl Ipc {
/// Creates a new IPC instance.
/// This can be used as both a server and client.
pub fn new() -> Self {
let ipc_socket_file = std::env::var("XDG_RUNTIME_DIR")
.map_or_else(|_| PathBuf::from("/tmp"), PathBuf::from)
.join("ironbar-ipc.sock");

if format!("{}", ipc_socket_file.display()).len() > 100 {
warn!("The IPC socket file's absolute path exceeds 100 bytes, the socket may fail to create.");
}

Self {
path: ipc_socket_file,
}
}
}
17 changes: 17 additions & 0 deletions src/ipc/responses.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum Response {
Ok,
Err { message: Option<String> },
}

impl Response {
/// Creates a new `Response::Error`.
pub fn error(message: &str) -> Self {
Self::Err {
message: Some(message.to_string()),
}
}
}
Loading

0 comments on commit f5bdc5a

Please sign in to comment.