Skip to content

Commit 7447800

Browse files
authored
feat: add utility functions for simplified type conversions (#33)
* add new utility functions * fix fmt
1 parent 28afc0d commit 7447800

File tree

4 files changed

+488
-10
lines changed

4 files changed

+488
-10
lines changed

src/generated_schema/2024_11_05/mcp_schema.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
///
77
/// Generated from : <https://github.com/modelcontextprotocol/specification.git>
88
/// Hash : bb1446ff1810a0df57989d78366d626d2c01b9d7
9-
/// Generated at : 2025-02-20 19:37:53
9+
/// Generated at : 2025-02-22 11:26:40
1010
/// ----------------------------------------------------------------------------
1111
///
1212
/// MCP Protocol Version

src/generated_schema/2024_11_05/schema_utils.rs

Lines changed: 243 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::generated_schema::*;
22
use serde::ser::SerializeStruct;
33
use serde_json::{json, Value};
44
use std::hash::{Hash, Hasher};
5+
use std::result;
56
use std::{fmt::Display, str::FromStr};
67

78
#[derive(Debug, PartialEq)]
@@ -139,6 +140,92 @@ pub enum ClientMessage {
139140
Error(JsonrpcError),
140141
}
141142

143+
impl ClientMessage {
144+
/// Converts the current message into a `ClientJsonrpcResponse` if it's of the correct type.
145+
///
146+
/// This function checks if the current message is of type `Response`. If so, it returns the
147+
/// `ClientJsonrpcResponse` wrapped in a `Result::Ok`. If the message is not a `Response`,
148+
/// it returns an error with a descriptive message indicating the mismatch in expected message types.
149+
///
150+
/// # Returns
151+
/// - `Ok(ClientJsonrpcResponse)` if the message is a valid `Response`.
152+
/// - `Err(JsonrpcErrorError)` if the message type is invalid
153+
pub fn as_response(self) -> std::result::Result<ClientJsonrpcResponse, JsonrpcErrorError> {
154+
if let Self::Response(response) = self {
155+
Ok(response)
156+
} else {
157+
Err(JsonrpcErrorError::internal_error().with_message(format!(
158+
"Invalid message type, expected: \"{}\" received\"{}\"",
159+
MessageTypes::Response,
160+
self.message_type()
161+
)))
162+
}
163+
}
164+
165+
/// Converts the current message into a `ClientJsonrpcRequest` if it's of the correct type.
166+
///
167+
/// This function checks if the current message is of type `Request`. If so, it returns the
168+
/// `ClientJsonrpcRequest` wrapped in a `Result::Ok`. If the message is not a `Request`,
169+
/// it returns an error with a descriptive message indicating the mismatch in expected message types.
170+
///
171+
/// # Returns
172+
/// - `Ok(ClientJsonrpcRequest)` if the message is a valid `Request`.
173+
/// - `Err(JsonrpcErrorError)` if the message type is invalid
174+
pub fn as_request(self) -> std::result::Result<ClientJsonrpcRequest, JsonrpcErrorError> {
175+
if let Self::Request(request) = self {
176+
Ok(request)
177+
} else {
178+
Err(JsonrpcErrorError::internal_error().with_message(format!(
179+
"Invalid message type, expected: \"{}\" received\"{}\"",
180+
MessageTypes::Request,
181+
self.message_type()
182+
)))
183+
}
184+
}
185+
186+
/// Converts the current message into a `ClientJsonrpcNotification` if it's of the correct type.
187+
///
188+
/// This function checks if the current message is of type `Notification`. If so, it returns the
189+
/// `ClientJsonrpcNotification` wrapped in a `Result::Ok`. If the message is not a `Notification`,
190+
/// it returns an error with a descriptive message indicating the mismatch in expected message types.
191+
///
192+
/// # Returns
193+
/// - `Ok(ClientJsonrpcNotification)` if the message is a valid `Notification`.
194+
/// - `Err(JsonrpcErrorError)` if the message type is invalid
195+
pub fn as_notification(self) -> std::result::Result<ClientJsonrpcNotification, JsonrpcErrorError> {
196+
if let Self::Notification(notification) = self {
197+
Ok(notification)
198+
} else {
199+
Err(JsonrpcErrorError::internal_error().with_message(format!(
200+
"Invalid message type, expected: \"{}\" received\"{}\"",
201+
MessageTypes::Notification,
202+
self.message_type()
203+
)))
204+
}
205+
}
206+
207+
/// Converts the current message into a `JsonrpcError` if it's of the correct type.
208+
///
209+
/// This function checks if the current message is of type `Error`. If so, it returns the
210+
/// `JsonrpcError` wrapped in a `Result::Ok`. If the message is not a `Error`,
211+
/// it returns an error with a descriptive message indicating the mismatch in expected message types.
212+
///
213+
/// # Returns
214+
/// - `Ok(JsonrpcError)` if the message is a valid `Error`.
215+
/// - `Err(JsonrpcErrorError)` if the message type is invalid
216+
pub fn as_error(self) -> std::result::Result<JsonrpcError, JsonrpcErrorError> {
217+
if let Self::Error(error) = self {
218+
Ok(error)
219+
} else {
220+
Err(JsonrpcErrorError::internal_error().with_message(format!(
221+
"Invalid message type, expected: \"{}\" received\"{}\"",
222+
MessageTypes::Error,
223+
self.message_type()
224+
)))
225+
}
226+
}
227+
}
228+
142229
impl RPCMessage for ClientMessage {
143230
// Retrieves the request ID associated with the message, if applicable
144231
fn request_id(&self) -> Option<&RequestId> {
@@ -279,6 +366,17 @@ pub enum RequestFromClient {
279366
CustomRequest(serde_json::Value),
280367
}
281368

369+
impl TryFrom<RequestFromClient> for ClientRequest {
370+
type Error = JsonrpcErrorError;
371+
fn try_from(value: RequestFromClient) -> result::Result<Self, Self::Error> {
372+
if let RequestFromClient::ClientRequest(client_request) = value {
373+
Ok(client_request)
374+
} else {
375+
Err(JsonrpcErrorError::internal_error().with_message("Not a ClientRequest".to_string()))
376+
}
377+
}
378+
}
379+
282380
impl RequestFromClient {
283381
#[deprecated(since = "0.1.4", note = "Use `method()` instead.")]
284382
pub fn get_method(&self) -> &str {
@@ -383,6 +481,17 @@ pub enum NotificationFromClient {
383481
CustomNotification(serde_json::Value),
384482
}
385483

484+
impl TryFrom<NotificationFromClient> for ClientNotification {
485+
type Error = JsonrpcErrorError;
486+
fn try_from(value: NotificationFromClient) -> result::Result<Self, Self::Error> {
487+
if let NotificationFromClient::ClientNotification(client_notification) = value {
488+
Ok(client_notification)
489+
} else {
490+
Err(JsonrpcErrorError::internal_error().with_message("Not a ClientNotification".to_string()))
491+
}
492+
}
493+
}
494+
386495
impl NotificationFromClient {
387496
#[deprecated(since = "0.1.4", note = "Use `method()` instead.")]
388497
pub fn get_method(&self) -> &str {
@@ -473,6 +582,17 @@ pub enum ResultFromClient {
473582
CustomResult(serde_json::Value),
474583
}
475584

585+
impl TryFrom<ResultFromClient> for ClientResult {
586+
type Error = JsonrpcErrorError;
587+
fn try_from(value: ResultFromClient) -> result::Result<Self, Self::Error> {
588+
if let ResultFromClient::ClientResult(client_result) = value {
589+
Ok(client_result)
590+
} else {
591+
Err(JsonrpcErrorError::internal_error().with_message("Not a ClientResult".to_string()))
592+
}
593+
}
594+
}
595+
476596
impl From<ClientResult> for ResultFromClient {
477597
fn from(value: ClientResult) -> Self {
478598
Self::ClientResult(value)
@@ -539,16 +659,102 @@ pub enum ServerMessage {
539659
Error(JsonrpcError),
540660
}
541661

662+
impl ServerMessage {
663+
/// Converts the current message into a `ServerJsonrpcResponse` if it's of the correct type.
664+
///
665+
/// This function checks if the current message is of type `Response`. If so, it returns the
666+
/// `ServerJsonrpcResponse` wrapped in a `Result::Ok`. If the message is not a `Response`,
667+
/// it returns an error with a descriptive message indicating the mismatch in expected message types.
668+
///
669+
/// # Returns
670+
/// - `Ok(ServerJsonrpcResponse)` if the message is a valid `Response`.
671+
/// - `Err(JsonrpcErrorError)` if the message type is invalid
672+
pub fn as_response(self) -> std::result::Result<ServerJsonrpcResponse, JsonrpcErrorError> {
673+
if let Self::Response(response) = self {
674+
Ok(response)
675+
} else {
676+
Err(JsonrpcErrorError::internal_error().with_message(format!(
677+
"Invalid message type, expected: \"{}\" received\"{}\"",
678+
MessageTypes::Response,
679+
self.message_type()
680+
)))
681+
}
682+
}
683+
684+
/// Converts the current message into a `ServerJsonrpcRequest` if it's of the correct type.
685+
///
686+
/// This function checks if the current message is of type `Request`. If so, it returns the
687+
/// `ServerJsonrpcRequest` wrapped in a `Result::Ok`. If the message is not a `Request`,
688+
/// it returns an error with a descriptive message indicating the mismatch in expected message types.
689+
///
690+
/// # Returns
691+
/// - `Ok(ServerJsonrpcRequest)` if the message is a valid `Request`.
692+
/// - `Err(JsonrpcErrorError)` if the message type is invalid
693+
pub fn as_request(self) -> std::result::Result<ServerJsonrpcRequest, JsonrpcErrorError> {
694+
if let Self::Request(request) = self {
695+
Ok(request)
696+
} else {
697+
Err(JsonrpcErrorError::internal_error().with_message(format!(
698+
"Invalid message type, expected: \"{}\" received\"{}\"",
699+
MessageTypes::Request,
700+
self.message_type()
701+
)))
702+
}
703+
}
704+
705+
/// Converts the current message into a `ServerJsonrpcNotification` if it's of the correct type.
706+
///
707+
/// This function checks if the current message is of type `Notification`. If so, it returns the
708+
/// `ServerJsonrpcNotification` wrapped in a `Result::Ok`. If the message is not a `Notification`,
709+
/// it returns an error with a descriptive message indicating the mismatch in expected message types.
710+
///
711+
/// # Returns
712+
/// - `Ok(ServerJsonrpcNotification)` if the message is a valid `Notification`.
713+
/// - `Err(JsonrpcErrorError)` if the message type is invalid
714+
pub fn as_notification(self) -> std::result::Result<ServerJsonrpcNotification, JsonrpcErrorError> {
715+
if let Self::Notification(notification) = self {
716+
Ok(notification)
717+
} else {
718+
Err(JsonrpcErrorError::internal_error().with_message(format!(
719+
"Invalid message type, expected: \"{}\" received\"{}\"",
720+
MessageTypes::Notification,
721+
self.message_type()
722+
)))
723+
}
724+
}
725+
726+
/// Converts the current message into a `JsonrpcError` if it's of the correct type.
727+
///
728+
/// This function checks if the current message is of type `Error`. If so, it returns the
729+
/// `JsonrpcError` wrapped in a `Result::Ok`. If the message is not a `Error`,
730+
/// it returns an error with a descriptive message indicating the mismatch in expected message types.
731+
///
732+
/// # Returns
733+
/// - `Ok(JsonrpcError)` if the message is a valid `Error`.
734+
/// - `Err(JsonrpcErrorError)` if the message type is invalid
735+
pub fn as_error(self) -> std::result::Result<JsonrpcError, JsonrpcErrorError> {
736+
if let Self::Error(error) = self {
737+
Ok(error)
738+
} else {
739+
Err(JsonrpcErrorError::internal_error().with_message(format!(
740+
"Invalid message type, expected: \"{}\" received\"{}\"",
741+
MessageTypes::Error,
742+
self.message_type()
743+
)))
744+
}
745+
}
746+
}
747+
542748
impl RPCMessage for ServerMessage {
543749
// Retrieves the request ID associated with the message, if applicable
544750
fn request_id(&self) -> Option<&RequestId> {
545751
match self {
546752
// If the message is a request, return the associated request ID
547-
ServerMessage::Request(client_jsonrpc_request) => Some(&client_jsonrpc_request.id),
753+
ServerMessage::Request(server_jsonrpc_request) => Some(&server_jsonrpc_request.id),
548754
// Notifications do not have request IDs
549755
ServerMessage::Notification(_) => None,
550756
// If the message is a response, return the associated request ID
551-
ServerMessage::Response(client_jsonrpc_response) => Some(&client_jsonrpc_response.id),
757+
ServerMessage::Response(server_jsonrpc_response) => Some(&server_jsonrpc_response.id),
552758
// If the message is an error, return the associated request ID
553759
ServerMessage::Error(jsonrpc_error) => Some(&jsonrpc_error.id),
554760
}
@@ -557,11 +763,11 @@ impl RPCMessage for ServerMessage {
557763
fn jsonrpc(&self) -> &str {
558764
match self {
559765
// If the message is a request, return the associated request ID
560-
ServerMessage::Request(client_jsonrpc_request) => client_jsonrpc_request.jsonrpc(),
766+
ServerMessage::Request(server_jsonrpc_request) => server_jsonrpc_request.jsonrpc(),
561767
// Notifications do not have request IDs
562768
ServerMessage::Notification(notification) => notification.jsonrpc(),
563769
// If the message is a response, return the associated request ID
564-
ServerMessage::Response(client_jsonrpc_response) => client_jsonrpc_response.jsonrpc(),
770+
ServerMessage::Response(server_jsonrpc_response) => server_jsonrpc_response.jsonrpc(),
565771
// If the message is an error, return the associated request ID
566772
ServerMessage::Error(jsonrpc_error) => jsonrpc_error.jsonrpc(),
567773
}
@@ -680,6 +886,17 @@ pub enum RequestFromServer {
680886
CustomRequest(serde_json::Value),
681887
}
682888

889+
impl TryFrom<RequestFromServer> for ServerRequest {
890+
type Error = JsonrpcErrorError;
891+
fn try_from(value: RequestFromServer) -> result::Result<Self, Self::Error> {
892+
if let RequestFromServer::ServerRequest(server_request) = value {
893+
Ok(server_request)
894+
} else {
895+
Err(JsonrpcErrorError::internal_error().with_message("Not a ServerRequest".to_string()))
896+
}
897+
}
898+
}
899+
683900
impl RequestFromServer {
684901
#[deprecated(since = "0.1.4", note = "Use `method()` instead.")]
685902
pub fn get_method(&self) -> &str {
@@ -783,6 +1000,17 @@ pub enum NotificationFromServer {
7831000
CustomNotification(serde_json::Value),
7841001
}
7851002

1003+
impl TryFrom<NotificationFromServer> for ServerNotification {
1004+
type Error = JsonrpcErrorError;
1005+
fn try_from(value: NotificationFromServer) -> result::Result<Self, Self::Error> {
1006+
if let NotificationFromServer::ServerNotification(server_notification) = value {
1007+
Ok(server_notification)
1008+
} else {
1009+
Err(JsonrpcErrorError::internal_error().with_message("Not a ServerNotification".to_string()))
1010+
}
1011+
}
1012+
}
1013+
7861014
impl NotificationFromServer {
7871015
#[deprecated(since = "0.1.4", note = "Use `method()` instead.")]
7881016
pub fn get_method(&self) -> &str {
@@ -873,6 +1101,17 @@ pub enum ResultFromServer {
8731101
CustomResult(serde_json::Value),
8741102
}
8751103

1104+
impl TryFrom<ResultFromServer> for ServerResult {
1105+
type Error = JsonrpcErrorError;
1106+
fn try_from(value: ResultFromServer) -> result::Result<Self, Self::Error> {
1107+
if let ResultFromServer::ServerResult(server_result) = value {
1108+
Ok(server_result)
1109+
} else {
1110+
Err(JsonrpcErrorError::internal_error().with_message("Not a ServerResult".to_string()))
1111+
}
1112+
}
1113+
}
1114+
8761115
impl From<ServerResult> for ResultFromServer {
8771116
fn from(value: ServerResult) -> Self {
8781117
Self::ServerResult(value)

src/generated_schema/draft/mcp_schema.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
///
77
/// Generated from : <https://github.com/modelcontextprotocol/specification.git>
88
/// Hash : bb1446ff1810a0df57989d78366d626d2c01b9d7
9-
/// Generated at : 2025-02-20 19:37:53
9+
/// Generated at : 2025-02-22 11:26:41
1010
/// ----------------------------------------------------------------------------
1111
///
1212
/// MCP Protocol Version

0 commit comments

Comments
 (0)