aboutsummaryrefslogtreecommitdiff
path: root/jsonrpc/jsonrpc_internal
diff options
context:
space:
mode:
authorhozan23 <hozan23@karyontech.net>2024-04-11 10:19:20 +0200
committerhozan23 <hozan23@karyontech.net>2024-05-19 13:51:30 +0200
commit0992071a7f1a36424bcfaf1fbc84541ea041df1a (patch)
tree961d73218af672797d49f899289bef295bc56493 /jsonrpc/jsonrpc_internal
parenta69917ecd8272a4946cfd12c75bf8f8c075b0e50 (diff)
add support for tokio & improve net crate api
Diffstat (limited to 'jsonrpc/jsonrpc_internal')
-rw-r--r--jsonrpc/jsonrpc_internal/Cargo.toml18
-rw-r--r--jsonrpc/jsonrpc_internal/src/error.rs40
-rw-r--r--jsonrpc/jsonrpc_internal/src/lib.rs65
3 files changed, 123 insertions, 0 deletions
diff --git a/jsonrpc/jsonrpc_internal/Cargo.toml b/jsonrpc/jsonrpc_internal/Cargo.toml
new file mode 100644
index 0000000..5a3acc4
--- /dev/null
+++ b/jsonrpc/jsonrpc_internal/Cargo.toml
@@ -0,0 +1,18 @@
+[package]
+name = "karyon_jsonrpc_internal"
+version.workspace = true
+edition.workspace = true
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[features]
+default = ["smol"]
+smol = ["karyon_core/smol", "karyon_net/smol"]
+tokio = ["karyon_core/tokio", "karyon_net/tokio"]
+
+[dependencies]
+karyon_core = { workspace = true, default-features = false }
+karyon_net = { workspace = true, default-features = false }
+
+serde_json = "1.0.114"
+thiserror = "1.0.58"
diff --git a/jsonrpc/jsonrpc_internal/src/error.rs b/jsonrpc/jsonrpc_internal/src/error.rs
new file mode 100644
index 0000000..7f89729
--- /dev/null
+++ b/jsonrpc/jsonrpc_internal/src/error.rs
@@ -0,0 +1,40 @@
+use thiserror::Error as ThisError;
+
+pub type Result<T> = std::result::Result<T, Error>;
+
+/// Represents karyon's jsonrpc Error.
+#[derive(ThisError, Debug)]
+pub enum Error {
+ #[error(transparent)]
+ IO(#[from] std::io::Error),
+
+ #[error("Call Error: code: {0} msg: {1}")]
+ CallError(i32, String),
+
+ #[error("RPC Method Error: code: {0} msg: {1}")]
+ RPCMethodError(i32, &'static str),
+
+ #[error("Invalid Params: {0}")]
+ InvalidParams(&'static str),
+
+ #[error("Invalid Request: {0}")]
+ InvalidRequest(&'static str),
+
+ #[error(transparent)]
+ ParseJSON(#[from] serde_json::Error),
+
+ #[error("Invalid Message Error: {0}")]
+ InvalidMsg(&'static str),
+
+ #[error("Unsupported protocol: {0}")]
+ UnsupportedProtocol(String),
+
+ #[error("Unexpected Error: {0}")]
+ General(&'static str),
+
+ #[error(transparent)]
+ KaryonCore(#[from] karyon_core::error::Error),
+
+ #[error(transparent)]
+ KaryonNet(#[from] karyon_net::Error),
+}
diff --git a/jsonrpc/jsonrpc_internal/src/lib.rs b/jsonrpc/jsonrpc_internal/src/lib.rs
new file mode 100644
index 0000000..95af82a
--- /dev/null
+++ b/jsonrpc/jsonrpc_internal/src/lib.rs
@@ -0,0 +1,65 @@
+mod error;
+use std::{future::Future, pin::Pin};
+
+pub use error::{Error, Result};
+
+/// Represents the RPC method
+pub type RPCMethod<'a> = Box<dyn Fn(serde_json::Value) -> RPCMethodOutput<'a> + Send + 'a>;
+type RPCMethodOutput<'a> =
+ Pin<Box<dyn Future<Output = Result<serde_json::Value>> + Send + Sync + 'a>>;
+
+/// Defines the interface for an RPC service.
+pub trait RPCService: Sync + Send {
+ fn get_method<'a>(&'a self, name: &'a str) -> Option<RPCMethod>;
+ fn name(&self) -> String;
+}
+
+/// Implements the [`RPCService`] trait for a provided type.
+///
+/// # Example
+///
+/// ```
+/// use serde_json::Value;
+///
+/// use karyon_jsonrpc_internal::{Error, impl_rpc_service};
+///
+/// struct Hello {}
+///
+/// impl Hello {
+/// async fn foo(&self, params: Value) -> Result<Value, Error> {
+/// Ok(serde_json::json!("foo!"))
+/// }
+///
+/// async fn bar(&self, params: Value) -> Result<Value, Error> {
+/// Ok(serde_json::json!("bar!"))
+/// }
+/// }
+///
+/// impl_rpc_service!(Hello, foo, bar);
+///
+/// ```
+#[macro_export]
+macro_rules! impl_rpc_service {
+ ($t:ty, $($m:ident),*) => {
+ impl karyon_jsonrpc_internal::RPCService for $t {
+ fn get_method<'a>(
+ &'a self,
+ name: &'a str
+ ) -> Option<karyon_jsonrpc_internal::RPCMethod> {
+ match name {
+ $(
+ stringify!($m) => {
+ Some(Box::new(move |params: serde_json::Value| Box::pin(self.$m(params))))
+ }
+ )*
+ _ => None,
+ }
+
+
+ }
+ fn name(&self) -> String{
+ stringify!($t).to_string()
+ }
+ }
+ };
+}