X-Git-Url: https://git.nmode.ca/signal-cli/blobdiff_plain/edbf803a987a4959d72a644e2fb3afc370a79cff..8037fb2d66e52fa65333e4b176c430118f59e89c:/client/src/main.rs diff --git a/client/src/main.rs b/client/src/main.rs index ea9cb9c8..f4ab67f9 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -1,40 +1,53 @@ -use clap::Parser; -use jsonrpc_client_transports::{RpcError, TypedSubscriptionStream}; -use jsonrpc_core::{futures_util::StreamExt, Value}; use std::{path::PathBuf, time::Duration}; + +use clap::Parser; +use cli::Cli; +use jsonrpsee::core::client::{Subscription, SubscriptionClientT}; +use jsonrpsee::core::Error as RpcError; +use serde_json::Value; use tokio::{select, time::sleep}; use crate::cli::{GroupPermission, LinkState}; +use crate::jsonrpc::RpcClient; mod cli; -#[allow(clippy::too_many_arguments)] +#[allow(non_snake_case, clippy::too_many_arguments)] mod jsonrpc; -mod tcp; +mod transports; const DEFAULT_TCP: &str = "127.0.0.1:7583"; const DEFAULT_SOCKET_SUFFIX: &str = "signal-cli/socket"; +const DEFAULT_HTTP: &str = "http://localhost:8080/api/v1/rpc"; #[tokio::main] async fn main() -> Result<(), anyhow::Error> { let cli = cli::Cli::parse(); - let client = connect(&cli) - .await - .map_err(|e| anyhow::anyhow!("Failed to connect to socket: {e}"))?; + let result = connect(cli).await; + + match result { + Ok(Value::Null) => {} + Ok(v) => println!("{v}"), + Err(e) => return Err(anyhow::anyhow!("JSON-RPC command failed: {e:?}")), + } + Ok(()) +} - let result = match cli.command { +async fn handle_command( + cli: Cli, + client: impl SubscriptionClientT + Sync, +) -> Result { + match cli.command { cli::CliCommands::Receive { timeout } => { - let mut stream = client - .subscribe_receive(cli.account) - .map_err(|e| anyhow::anyhow!("JSON-RPC command failed: {:?}", e))?; + let mut stream = client.subscribe_receive(cli.account).await?; { while let Some(v) = stream_next(timeout, &mut stream).await { - let v = v.map_err(|e| anyhow::anyhow!("JSON-RPC command failed: {:?}", e))?; + let v = v?; println!("{v}"); } } - return Ok(()); + Ok(Value::Null) } cli::CliCommands::AddDevice { uri } => client.add_device(cli.account, uri).await, cli::CliCommands::Block { @@ -54,7 +67,7 @@ async fn main() -> Result<(), anyhow::Error> { let url = client .start_link(cli.account) .await - .map_err(|e| anyhow::anyhow!("JSON-RPC command startLink failed: {e:?}",))? + .map_err(|e| RpcError::Custom(format!("JSON-RPC command startLink failed: {e:?}")))? .device_link_uri; println!("{}", url); client.finish_link(url, name).await @@ -349,18 +362,28 @@ async fn main() -> Result<(), anyhow::Error> { pin, } => client.verify(cli.account, verification_code, pin).await, cli::CliCommands::Version => client.version().await, - }; - - result - .map(|v| println!("{v}")) - .map_err(|e| anyhow::anyhow!("JSON-RPC command failed: {e:?}",))?; - Ok(()) + } } -async fn connect(cli: &cli::Cli) -> Result { - if let Some(tcp) = cli.json_rpc_tcp { +async fn connect(cli: Cli) -> Result { + if let Some(http) = &cli.json_rpc_http { + let uri = if let Some(uri) = http { + uri + } else { + DEFAULT_HTTP + }; + let client = jsonrpc::connect_http(uri) + .await + .map_err(|e| RpcError::Custom(format!("Failed to connect to socket: {e}")))?; + + handle_command(cli, client).await + } else if let Some(tcp) = cli.json_rpc_tcp { let socket_addr = tcp.unwrap_or_else(|| DEFAULT_TCP.parse().unwrap()); - jsonrpc::connect_tcp(socket_addr).await + let client = jsonrpc::connect_tcp(socket_addr) + .await + .map_err(|e| RpcError::Custom(format!("Failed to connect to socket: {e}")))?; + + handle_command(cli, client).await } else { let socket_path = cli .json_rpc_socket @@ -374,13 +397,17 @@ async fn connect(cli: &cli::Cli) -> Result { }) }) .unwrap_or_else(|| ("/run".to_owned() + DEFAULT_SOCKET_SUFFIX).into()); - jsonrpc::connect_unix(socket_path).await + let client = jsonrpc::connect_unix(socket_path) + .await + .map_err(|e| RpcError::Custom(format!("Failed to connect to socket: {e}")))?; + + handle_command(cli, client).await } } async fn stream_next( timeout: f64, - stream: &mut TypedSubscriptionStream, + stream: &mut Subscription, ) -> Option> { if timeout < 0.0 { stream.next().await