Skip to content

Commit

Permalink
Merge pull request #2 from alloy-rs/prestwich/transports
Browse files Browse the repository at this point in the history
Add a transports crate  & initial Network abstraction
  • Loading branch information
prestwich authored Aug 24, 2023
2 parents 67161ac + 8a6a838 commit 611a057
Show file tree
Hide file tree
Showing 28 changed files with 2,099 additions and 33 deletions.
29 changes: 26 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,35 @@ edition = "2021"
rust-version = "1.65"
authors = ["Alloy Contributors"]
license = "MIT OR Apache-2.0"
homepage = "https://github.com/ethers-rs/next"
repository = "https://github.com/ethers-rs/next"
homepage = "https://github.com/alloy-rs/next"
repository = "https://github.com/alloy-rs/next"
exclude = ["benches/", "tests/"]

[workspace.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]

[workspace.dependencies]
[workspace.dependencies]

alloy-json-rpc = { path = "crates/json-rpc" }
alloy-transports = { path = "crates/transports" }
alloy-networks = { path = "crates/networks" }

alloy-primitives = { version = "0.2.0", features = ["serde"] }
alloy-rlp = "0.3.0"

# futures
futures-channel = "0.3"
futures-util = "0.3"

# serde
serde = { version = "1.0", default-features = false, features = ["alloc"] }
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }

# thiserror
thiserror = "1.0"

# transports
url = "2.4.0"
pin-project = "1.1.2"
tower = { version = "0.4.13", features = ["util"] }
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,12 @@
# alloy-next

### Layout

- alloy-json-rpc
- Core data types for JSON-RPC 2.0
- alloy-transports
- Transports and RPC call futures.
- alloy-networks
- Network abstraction for RPC types. Allows capturing different RPC param and response types on a per-network basis.
- alloy-provider
- Based on ethers::middleware::Middleware, but abstract over <N>, and object-safe.
16 changes: 16 additions & 0 deletions crates/json-rpc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "alloy-json-rpc"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
authors.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true
exclude.workspace = true

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
serde = { workspace = true, features = ["derive"] }
serde_json = { version = "1.0.103", features = ["raw_value"] }
43 changes: 43 additions & 0 deletions crates/json-rpc/src/common.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use serde::{Deserialize, Serialize};

/// A JSON-RPC 2.0 ID object. This may be a number, string, or null.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Hash)]
#[serde(untagged)]
pub enum Id {
Number(u64),
String(String),
None,
}

impl Id {
/// Returns `true` if the ID is a number.
pub fn is_number(&self) -> bool {
matches!(self, Id::Number(_))
}

/// Returns `true` if the ID is a string.
pub fn is_string(&self) -> bool {
matches!(self, Id::String(_))
}

/// Returns `true` if the ID is `None`.
pub fn is_none(&self) -> bool {
matches!(self, Id::None)
}

/// Returns the ID as a number, if it is one.
pub fn as_number(&self) -> Option<u64> {
match self {
Id::Number(n) => Some(*n),
_ => None,
}
}

/// Returns the ID as a string, if it is one.
pub fn as_string(&self) -> Option<&str> {
match self {
Id::String(s) => Some(s),
_ => None,
}
}
}
38 changes: 38 additions & 0 deletions crates/json-rpc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//! Alloy JSON-RPC data types.
//!
//! This crate provides data types for use with the JSON-RPC 2.0 protocol. It
//! does not provide any functionality for actually sending or receiving
//! JSON-RPC data.
//!
//! This crate is aimed at simplifying client implementations. It is not
//! well-suited to in-server applications. We do not support borrowing data from
//! deserializers, for example. This choice prevents complex lifetime
//! propagation in user code, at the expense of copying data
use serde::{de::DeserializeOwned, Serialize};

mod request;
pub use request::JsonRpcRequest;

mod response;
pub use response::{ErrorPayload, JsonRpcResponse, ResponsePayload};

mod common;
pub use common::Id;

mod result;
pub use result::RpcResult;

/// An object that can be used as a JSON-RPC parameter.
pub trait RpcParam: Serialize + Clone + Send + Sync + Unpin {}
impl<T> RpcParam for T where T: Serialize + Clone + Send + Sync + Unpin {}

/// An object that can be used as a JSON-RPC return value.
// Note: we add `'static` here to indicate that the Resp is wholly owned. It
// may not borrow.
pub trait RpcReturn: DeserializeOwned + Send + Sync + Unpin + 'static {}
impl<T> RpcReturn for T where T: DeserializeOwned + Send + Sync + Unpin + 'static {}

/// An object that can be used as a JSON-RPC parameter and return value.
pub trait RpcObject: RpcParam + RpcReturn {}
impl<T> RpcObject for T where T: RpcParam + RpcReturn {}
36 changes: 36 additions & 0 deletions crates/json-rpc/src/request.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use crate::{common::Id, RpcParam};

use serde::{ser::SerializeMap, Deserialize, Serialize};

/// A JSON-RPC 2.0 request object.
///
/// This is a generic type that can be used to represent any JSON-RPC request.
/// The `Params` type parameter is used to represent the parameters of the
/// request, and the `method` field is used to represent the method name.
///
/// ### Note
///
/// The value of `method` must be known at compile time.
#[derive(Debug, Deserialize, Clone)]
pub struct JsonRpcRequest<Params> {
pub method: &'static str,
pub params: Params,
pub id: Id,
}

impl<Params> Serialize for JsonRpcRequest<Params>
where
Params: RpcParam,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut map = serializer.serialize_map(Some(4))?;
map.serialize_entry("method", self.method)?;
map.serialize_entry("params", &self.params)?;
map.serialize_entry("id", &self.id)?;
map.serialize_entry("jsonrpc", "2.0")?;
map.end()
}
}
Loading

0 comments on commit 611a057

Please sign in to comment.