Skip to content

Commit b30fa1d

Browse files
committed
lib: Add deny(missing_docs), also drop Client
Enforce documentation requirements for all public API items by adding the `#![deny(missing_docs)]` lint. Also while looking at this, the Client doesn't make sense because most use cases should be using async calls, so drop it. Assisted-by: OpenCode (Sonnet 4) Signed-off-by: Colin Walters <walters@verbum.org>
1 parent 4822881 commit b30fa1d

7 files changed

Lines changed: 105 additions & 78 deletions

File tree

examples/demo.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
use jsonrpc_fdpass::{Client, Result, Server};
1+
use jsonrpc_fdpass::{
2+
JsonRpcMessage, JsonRpcNotification, JsonRpcRequest, MessageWithFds, Result, Server,
3+
UnixSocketTransport,
4+
};
25
use serde_json::Value;
36
use std::fs::File;
47
use std::io::{Read, Write};
58
use std::os::unix::io::OwnedFd;
69
use std::path::PathBuf;
710
use tempfile::TempDir;
8-
use tokio::net::UnixListener;
11+
use tokio::net::{UnixListener, UnixStream};
912
use tracing::info;
1013

1114
#[tokio::main]
@@ -63,7 +66,7 @@ async fn run_server(listener: UnixListener) -> Result<()> {
6366

6467
// Accept one connection and handle it
6568
if let Ok((stream, _)) = listener.accept().await {
66-
let transport = jsonrpc_fdpass::UnixSocketTransport::new(stream);
69+
let transport = UnixSocketTransport::new(stream);
6770
let (mut sender, mut receiver) = transport.split();
6871

6972
// Handle messages from this connection
@@ -82,7 +85,9 @@ async fn run_server(listener: UnixListener) -> Result<()> {
8285
}
8386

8487
async fn run_client(socket_path: PathBuf) -> Result<()> {
85-
let mut client = Client::connect(&socket_path).await?;
88+
let stream = UnixStream::connect(&socket_path).await?;
89+
let transport = UnixSocketTransport::new(stream);
90+
let (mut sender, mut _receiver) = transport.split();
8691

8792
// Create a temporary file to send to the server
8893
let mut temp_file = tempfile::NamedTempFile::new().map_err(jsonrpc_fdpass::Error::Io)?;
@@ -97,19 +102,19 @@ async fn run_client(socket_path: PathBuf) -> Result<()> {
97102
});
98103

99104
info!("Client sending file descriptor to server");
100-
client
101-
.call_method("read_file", Some(params), vec![fd])
102-
.await?;
105+
let request = JsonRpcRequest::new("read_file".to_string(), Some(params), serde_json::json!(1));
106+
let message = MessageWithFds::new(JsonRpcMessage::Request(request), vec![fd]);
107+
sender.send(message).await?;
103108

104109
// Send notification
105110
let params = serde_json::json!({
106111
"message": "This is a test notification"
107112
});
108113

109114
info!("Client sending notification");
110-
client
111-
.send_notification("log_message", Some(params), vec![])
112-
.await?;
115+
let notification = JsonRpcNotification::new("log_message".to_string(), Some(params));
116+
let message = MessageWithFds::new(JsonRpcMessage::Notification(notification), vec![]);
117+
sender.send(message).await?;
113118

114119
info!("Client finished");
115120
Ok(())

src/client.rs

Lines changed: 0 additions & 54 deletions
This file was deleted.

src/error.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,43 @@
11
use thiserror::Error;
22

3+
/// Errors that can occur during JSON-RPC operations.
34
#[derive(Error, Debug)]
45
pub enum Error {
6+
/// JSON serialization or deserialization failed.
57
#[error("JSON parsing error: {0}")]
68
Json(#[from] serde_json::Error),
79

10+
/// An I/O error occurred.
811
#[error("IO error: {0}")]
912
Io(#[from] std::io::Error),
1013

14+
/// The message contained invalid JSON.
1115
#[error("Protocol framing error: invalid JSON in message")]
1216
FramingError,
1317

18+
/// The `fds` field in the message doesn't match the number of received file descriptors.
1419
#[error(
1520
"File descriptor count mismatch: fds field specifies {expected}, but {found} FDs available"
1621
)]
17-
MismatchedCount { expected: usize, found: usize },
18-
22+
MismatchedCount {
23+
/// Number of file descriptors specified in the `fds` field.
24+
expected: usize,
25+
/// Number of file descriptors actually available.
26+
found: usize,
27+
},
28+
29+
/// A system call failed.
1930
#[error("System call error: {0}")]
2031
SystemCall(String),
2132

33+
/// The connection was closed by the peer.
2234
#[error("Connection closed")]
2335
ConnectionClosed,
2436

37+
/// The message format was invalid.
2538
#[error("Invalid message format: {0}")]
2639
InvalidMessage(String),
2740
}
2841

42+
/// A specialized Result type for JSON-RPC operations.
2943
pub type Result<T> = std::result::Result<T, Error>;

src/lib.rs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,23 +44,33 @@
4444
//! ### Client Example
4545
//!
4646
//! ```rust,no_run
47-
//! use jsonrpc_fdpass::{Client, Result};
47+
//! use jsonrpc_fdpass::{
48+
//! JsonRpcRequest, JsonRpcMessage, MessageWithFds, UnixSocketTransport, Result
49+
//! };
4850
//! use std::fs::File;
4951
//! use std::os::unix::io::OwnedFd;
5052
//! use serde_json::json;
53+
//! use tokio::net::UnixStream;
5154
//!
5255
//! #[tokio::main]
5356
//! async fn main() -> Result<()> {
54-
//! let mut client = Client::connect("/tmp/test.sock").await?;
57+
//! let stream = UnixStream::connect("/tmp/test.sock").await?;
58+
//! let transport = UnixSocketTransport::new(stream);
59+
//! let (mut sender, mut receiver) = transport.split();
5560
//!
5661
//! let file = File::open("example.txt").unwrap();
5762
//! let fd: OwnedFd = file.into();
5863
//!
59-
//! let params = json!({
60-
//! "filename": "example.txt"
61-
//! });
64+
//! let request = JsonRpcRequest::new(
65+
//! "read_file".to_string(),
66+
//! Some(json!({"filename": "example.txt"})),
67+
//! json!(1),
68+
//! );
69+
//! let message = MessageWithFds::new(JsonRpcMessage::Request(request), vec![fd]);
70+
//! sender.send(message).await?;
6271
//!
63-
//! client.call_method("read_file", Some(params), vec![fd]).await?;
72+
//! let response = receiver.receive().await?;
73+
//! println!("Response: {:?}", response.message);
6474
//!
6575
//! Ok(())
6676
//! }
@@ -96,14 +106,17 @@
96106
//! mapping between FD positions and parameters.
97107
98108
#![forbid(unsafe_code)]
109+
#![deny(missing_docs)]
99110

100-
pub mod client;
111+
/// Error types for JSON-RPC operations.
101112
pub mod error;
113+
/// JSON-RPC message types and serialization.
102114
pub mod message;
115+
/// JSON-RPC 2.0 server implementation with file descriptor passing.
103116
pub mod server;
117+
/// Low-level Unix socket transport with ancillary data support.
104118
pub mod transport;
105119

106-
pub use client::Client;
107120
pub use error::{Error, Result};
108121
pub use jsonrpsee::types::error::{
109122
ErrorCode, ErrorObject as JsonRpcError, CALL_EXECUTION_FAILED_CODE, INTERNAL_ERROR_CODE,

src/message.rs

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,51 +23,69 @@ fn skip_if_zero_or_none(fds: &Option<usize>) -> bool {
2323
fds.map_or(true, |n| n == 0)
2424
}
2525

26-
// Define our own message types that don't have lifetime constraints
26+
/// A JSON-RPC 2.0 request message.
2727
#[derive(Debug, Clone, Serialize, Deserialize)]
2828
pub struct JsonRpcRequest {
29+
/// The JSON-RPC protocol version (always "2.0").
2930
pub jsonrpc: String,
31+
/// The name of the method to invoke.
3032
pub method: String,
33+
/// Optional parameters for the method.
3134
#[serde(skip_serializing_if = "Option::is_none")]
3235
pub params: Option<serde_json::Value>,
36+
/// The request identifier.
3337
pub id: serde_json::Value,
34-
/// Number of file descriptors attached to this message
38+
/// Number of file descriptors attached to this message.
3539
#[serde(skip_serializing_if = "skip_if_zero_or_none")]
3640
pub fds: Option<usize>,
3741
}
3842

43+
/// A JSON-RPC 2.0 response message.
3944
#[derive(Debug, Clone, Serialize, Deserialize)]
4045
pub struct JsonRpcResponse {
46+
/// The JSON-RPC protocol version (always "2.0").
4147
pub jsonrpc: String,
48+
/// The result of the method invocation (present on success).
4249
#[serde(skip_serializing_if = "Option::is_none")]
4350
pub result: Option<serde_json::Value>,
51+
/// The error object (present on failure).
4452
#[serde(skip_serializing_if = "Option::is_none")]
4553
pub error: Option<JsonRpcError<'static>>,
54+
/// The request identifier this response corresponds to.
4655
pub id: serde_json::Value,
47-
/// Number of file descriptors attached to this message
56+
/// Number of file descriptors attached to this message.
4857
#[serde(skip_serializing_if = "skip_if_zero_or_none")]
4958
pub fds: Option<usize>,
5059
}
5160

61+
/// A JSON-RPC 2.0 notification message (a request without an id).
5262
#[derive(Debug, Clone, Serialize, Deserialize)]
5363
pub struct JsonRpcNotification {
64+
/// The JSON-RPC protocol version (always "2.0").
5465
pub jsonrpc: String,
66+
/// The name of the method to invoke.
5567
pub method: String,
68+
/// Optional parameters for the method.
5669
#[serde(skip_serializing_if = "Option::is_none")]
5770
pub params: Option<serde_json::Value>,
58-
/// Number of file descriptors attached to this message
71+
/// Number of file descriptors attached to this message.
5972
#[serde(skip_serializing_if = "skip_if_zero_or_none")]
6073
pub fds: Option<usize>,
6174
}
6275

76+
/// A JSON-RPC 2.0 message (request, response, or notification).
6377
#[derive(Debug, Clone)]
6478
pub enum JsonRpcMessage {
79+
/// A request message expecting a response.
6580
Request(JsonRpcRequest),
81+
/// A response to a previous request.
6682
Response(JsonRpcResponse),
83+
/// A notification (no response expected).
6784
Notification(JsonRpcNotification),
6885
}
6986

7087
impl JsonRpcRequest {
88+
/// Create a new JSON-RPC request.
7189
pub fn new(method: String, params: Option<serde_json::Value>, id: serde_json::Value) -> Self {
7290
Self {
7391
jsonrpc: JSONRPC_VERSION.to_string(),
@@ -80,6 +98,7 @@ impl JsonRpcRequest {
8098
}
8199

82100
impl JsonRpcResponse {
101+
/// Create a successful JSON-RPC response.
83102
pub fn success(result: serde_json::Value, id: serde_json::Value) -> Self {
84103
Self {
85104
jsonrpc: JSONRPC_VERSION.to_string(),
@@ -90,6 +109,7 @@ impl JsonRpcResponse {
90109
}
91110
}
92111

112+
/// Create an error JSON-RPC response.
93113
pub fn error(error: JsonRpcError<'static>, id: serde_json::Value) -> Self {
94114
Self {
95115
jsonrpc: JSONRPC_VERSION.to_string(),
@@ -102,6 +122,7 @@ impl JsonRpcResponse {
102122
}
103123

104124
impl JsonRpcNotification {
125+
/// Create a new JSON-RPC notification.
105126
pub fn new(method: String, params: Option<serde_json::Value>) -> Self {
106127
Self {
107128
jsonrpc: JSONRPC_VERSION.to_string(),
@@ -113,6 +134,7 @@ impl JsonRpcNotification {
113134
}
114135

115136
impl JsonRpcMessage {
137+
/// Convert this message to a JSON value.
116138
pub fn to_json_value(&self) -> Result<serde_json::Value> {
117139
match self {
118140
JsonRpcMessage::Request(req) => Ok(serde_json::to_value(req)?),
@@ -121,6 +143,7 @@ impl JsonRpcMessage {
121143
}
122144
}
123145

146+
/// Parse a JSON-RPC message from a JSON value.
124147
pub fn from_json_value(value: serde_json::Value) -> Result<Self> {
125148
if let serde_json::Value::Object(obj) = &value {
126149
if obj.contains_key("method") && obj.contains_key("id") {
@@ -141,9 +164,12 @@ impl JsonRpcMessage {
141164
}
142165
}
143166

167+
/// A JSON-RPC message paired with file descriptors to send or that were received.
144168
#[derive(Debug)]
145169
pub struct MessageWithFds {
170+
/// The JSON-RPC message.
146171
pub message: JsonRpcMessage,
172+
/// File descriptors attached to this message.
147173
pub file_descriptors: Vec<OwnedFd>,
148174
}
149175

@@ -169,6 +195,7 @@ impl JsonRpcMessage {
169195
}
170196

171197
impl MessageWithFds {
198+
/// Create a new message with file descriptors.
172199
pub fn new(message: JsonRpcMessage, file_descriptors: Vec<OwnedFd>) -> Self {
173200
Self {
174201
message,
@@ -218,8 +245,10 @@ impl MessageWithFds {
218245
}
219246
}
220247

248+
/// JSON-RPC error code for file descriptor errors.
221249
pub const FILE_DESCRIPTOR_ERROR_CODE: i32 = -32050;
222250

251+
/// Create a JSON-RPC error object for file descriptor errors.
223252
pub fn file_descriptor_error() -> JsonRpcError<'static> {
224253
JsonRpcError::owned(
225254
FILE_DESCRIPTOR_ERROR_CODE,

0 commit comments

Comments
 (0)