diff --git a/Cargo.lock b/Cargo.lock index 6b6fd61731..c9d3916d72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2015,7 +2015,7 @@ dependencies = [ "http", "hyper", "log", - "rustls 0.21.9", + "rustls 0.21.10", "rustls-native-certs 0.6.3", "tokio", "tokio-rustls 0.24.1", @@ -2264,7 +2264,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "776d009e2f591b78c038e0d053a796f94575d66ca4e77dd84bfc5e81419e436c" dependencies = [ "anyhow", - "async-lock 3.2.0", + "async-lock 3.3.0", "async-trait", "beef", "futures-timer", @@ -3289,7 +3289,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35e4980fa29e4c4b212ffb3db068a564cbf560e51d3944b7c88bd8bf5bec64f4" dependencies = [ - "base64 0.21.5", + "base64 0.21.6", "rustls-pki-types", ] @@ -4665,7 +4665,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.9", + "rustls 0.21.10", "tokio", ] diff --git a/codegen/Cargo.toml b/codegen/Cargo.toml index 666c52142d..1cf9638bae 100644 --- a/codegen/Cargo.toml +++ b/codegen/Cargo.toml @@ -5,14 +5,12 @@ authors.workspace = true edition.workspace = true rust-version.workspace = true publish = true - license.workspace = true repository.workspace = true documentation = "https://docs.rs/subxt-codegen" homepage.workspace = true description = "Generate an API for interacting with a substrate node from FRAME metadata" - [features] default = [] fetch-metadata = ["dep:jsonrpsee", "dep:tokio", "dep:frame-metadata"] @@ -38,3 +36,10 @@ getrandom = { workspace = true, optional = true } [dev-dependencies] scale-info = { workspace = true, features = ["bit-vec"] } + +[package.metadata.docs.rs] +features = ["fetch-metadata"] +rustdoc-args = ["--cfg", "docsrs"] + +[package.metadata.playground] +defalt-features = true diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs index 1baa7aa61d..47631888a9 100644 --- a/codegen/src/lib.rs +++ b/codegen/src/lib.rs @@ -7,6 +7,7 @@ //! be used directly if preferable. #![deny(unused_crate_dependencies, missing_docs)] +#![cfg_attr(docsrs, feature(doc_cfg))] mod api; pub mod error; @@ -16,6 +17,7 @@ mod ir; // macro and CLI tool, so they only live here because this is a common // crate that both depend on. #[cfg(feature = "fetch-metadata")] +#[cfg_attr(docsrs, doc(cfg(feature = "fetch-metadata")))] pub mod fetch_metadata; #[cfg(feature = "web")] diff --git a/lightclient/Cargo.toml b/lightclient/Cargo.toml index 1cc3b2310b..eb079b3e90 100644 --- a/lightclient/Cargo.toml +++ b/lightclient/Cargo.toml @@ -80,3 +80,10 @@ pin-project = { workspace = true, optional = true } # Included if "web" feature is enabled, to enable its js feature. getrandom = { workspace = true, optional = true } + +[package.metadata.docs.rs] +defalt-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[package.metadata.playground] +defalt-features = true diff --git a/lightclient/src/lib.rs b/lightclient/src/lib.rs index ee3f727e26..34800fe4f0 100644 --- a/lightclient/src/lib.rs +++ b/lightclient/src/lib.rs @@ -10,6 +10,8 @@ //! //! This leverages the smoldot crate to connect to the chain. +#![cfg_attr(docsrs, feature(doc_cfg))] + #[cfg(any( all(feature = "web", feature = "native"), not(any(feature = "web", feature = "native")) @@ -35,6 +37,7 @@ pub mod smoldot { }; #[cfg(feature = "native")] + #[cfg_attr(docsrs, doc(cfg(feature = "native")))] pub use smoldot_light::platform::default::DefaultPlatform; } diff --git a/signer/Cargo.toml b/signer/Cargo.toml index 11f6e5efdd..226237c315 100644 --- a/signer/Cargo.toml +++ b/signer/Cargo.toml @@ -58,3 +58,10 @@ sp-keyring = { workspace = true } [package.metadata.cargo-machete] ignored = ["getrandom"] + +[package.metadata.docs.rs] +defalt-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[package.metadata.playground] +defalt-features = true diff --git a/signer/src/lib.rs b/signer/src/lib.rs index 77cf5b3d41..2c79d6a1ec 100644 --- a/signer/src/lib.rs +++ b/signer/src/lib.rs @@ -13,16 +13,20 @@ //! Enable the `subxt` feature to enable use of this [`sr25519::Keypair`] in signing //! subxt transactions for chains supporting sr25519 signatures. +#![cfg_attr(docsrs, feature(doc_cfg))] + #[macro_use] mod utils; mod crypto; // An sr25519 key pair implementation. #[cfg(feature = "sr25519")] +#[cfg_attr(docsrs, doc(cfg(feature = "sr25519")))] pub mod sr25519; // An ecdsa key pair implementation. #[cfg(feature = "ecdsa")] +#[cfg_attr(docsrs, doc(cfg(feature = "ecdsa")))] pub mod ecdsa; // Re-export useful bits and pieces for generating a Pair from a phrase, diff --git a/signer/src/sr25519.rs b/signer/src/sr25519.rs index d3172e519b..01e6cc84b1 100644 --- a/signer/src/sr25519.rs +++ b/signer/src/sr25519.rs @@ -245,6 +245,7 @@ pub mod dev { // Make `Keypair` usable to sign transactions in Subxt. This is optional so that // `subxt-signer` can be used entirely independently of Subxt. #[cfg(feature = "subxt")] +#[cfg_attr(docsrs, doc(cfg(feature = "subxt")))] mod subxt_compat { use super::*; diff --git a/subxt/Cargo.toml b/subxt/Cargo.toml index 79c6837480..f0b0c04ce5 100644 --- a/subxt/Cargo.toml +++ b/subxt/Cargo.toml @@ -129,3 +129,10 @@ required-features = ["unstable-light-client", "jsonrpsee"] name = "light_client_parachains" path = "examples/light_client_parachains.rs" required-features = ["unstable-light-client", "jsonrpsee", "native"] + +[package.metadata.docs.rs] +features = ["default", "substrate-compat", "unstable-light-client"] +rustdoc-args = ["--cfg", "docsrs"] + +[package.metadata.playground] +features = ["default", "substrate-compat", "unstable-light-client"] diff --git a/subxt/src/backend/rpc/mod.rs b/subxt/src/backend/rpc/mod.rs index 0368a4a5c5..12910939e7 100644 --- a/subxt/src/backend/rpc/mod.rs +++ b/subxt/src/backend/rpc/mod.rs @@ -56,8 +56,9 @@ // with other file names for their types. #![allow(clippy::module_inception)] -#[cfg(feature = "jsonrpsee")] -mod jsonrpsee_impl; +crate::macros::cfg_jsonrpsee! { + mod jsonrpsee_impl; +} mod rpc_client; mod rpc_client_t; diff --git a/subxt/src/backend/rpc/rpc_client.rs b/subxt/src/backend/rpc/rpc_client.rs index 44afb39b8f..d960c010db 100644 --- a/subxt/src/backend/rpc/rpc_client.rs +++ b/subxt/src/backend/rpc/rpc_client.rs @@ -19,6 +19,7 @@ pub struct RpcClient { impl RpcClient { #[cfg(feature = "jsonrpsee")] + #[cfg_attr(docsrs, doc(cfg(feature = "jsonrpsee")))] /// Create a default RPC client pointed at some URL, currently based on [`jsonrpsee`]. /// /// Errors if an insecure URL is provided. In this case, use [`RpcClient::from_insecure_url`] instead. diff --git a/subxt/src/client/light_client/builder.rs b/subxt/src/client/light_client/builder.rs index 2957ea85c7..ce0f7c6aca 100644 --- a/subxt/src/client/light_client/builder.rs +++ b/subxt/src/client/light_client/builder.rs @@ -5,6 +5,7 @@ use super::{rpc::LightClientRpc, LightClient, LightClientError}; use crate::backend::rpc::RpcClient; use crate::client::RawLightClient; +use crate::macros::{cfg_jsonrpsee_native, cfg_jsonrpsee_web}; use crate::utils::validate_url_is_secure; use crate::{config::Config, error::Error, OnlineClient}; use std::num::NonZeroU32; @@ -101,6 +102,7 @@ impl LightClientBuilder { /// If smoldot panics, then the promise created will be leaked. For more details, see /// https://docs.rs/wasm-bindgen-futures/latest/wasm_bindgen_futures/fn.future_to_promise.html. #[cfg(feature = "jsonrpsee")] + #[cfg_attr(docsrs, doc(cfg(feature = "jsonrpsee")))] pub async fn build_from_url>(self, url: Url) -> Result, Error> { validate_url_is_secure(url.as_ref())?; self.build_from_insecure_url(url).await @@ -255,58 +257,60 @@ async fn fetch_url(url: impl AsRef) -> Result { .map_err(|err| Error::Rpc(crate::error::RpcError::ClientError(Box::new(err)))) } -#[cfg(all(feature = "jsonrpsee", feature = "native"))] -mod jsonrpsee_helpers { - use crate::error::{Error, LightClientError}; - use tokio_util::compat::Compat; +cfg_jsonrpsee_native! { + mod jsonrpsee_helpers { + use crate::error::{Error, LightClientError}; + use tokio_util::compat::Compat; - pub use jsonrpsee::{ - client_transport::ws::{self, EitherStream, Url, WsTransportClientBuilder}, - core::client::Client, - }; + pub use jsonrpsee::{ + client_transport::ws::{self, EitherStream, Url, WsTransportClientBuilder}, + core::client::Client, + }; - pub type Sender = ws::Sender>; - pub type Receiver = ws::Receiver>; + pub type Sender = ws::Sender>; + pub type Receiver = ws::Receiver>; - /// Build WS RPC client from URL - pub async fn client(url: &str) -> Result { - let url = Url::parse(url).map_err(|_| Error::LightClient(LightClientError::InvalidUrl))?; + /// Build WS RPC client from URL + pub async fn client(url: &str) -> Result { + let url = Url::parse(url).map_err(|_| Error::LightClient(LightClientError::InvalidUrl))?; - if url.scheme() != "ws" && url.scheme() != "wss" { - return Err(Error::LightClient(LightClientError::InvalidScheme)); - } + if url.scheme() != "ws" && url.scheme() != "wss" { + return Err(Error::LightClient(LightClientError::InvalidScheme)); + } - let (sender, receiver) = ws_transport(url).await?; + let (sender, receiver) = ws_transport(url).await?; - Ok(Client::builder() - .max_buffer_capacity_per_subscription(4096) - .build_with_tokio(sender, receiver)) - } + Ok(Client::builder() + .max_buffer_capacity_per_subscription(4096) + .build_with_tokio(sender, receiver)) + } - async fn ws_transport(url: Url) -> Result<(Sender, Receiver), Error> { - WsTransportClientBuilder::default() - .build(url) - .await - .map_err(|_| Error::LightClient(LightClientError::Handshake)) - } + async fn ws_transport(url: Url) -> Result<(Sender, Receiver), Error> { + WsTransportClientBuilder::default() + .build(url) + .await + .map_err(|_| Error::LightClient(LightClientError::Handshake)) + } + } } -#[cfg(all(feature = "jsonrpsee", feature = "web"))] -mod jsonrpsee_helpers { - use crate::error::{Error, LightClientError}; - pub use jsonrpsee::{ - client_transport::web, - core::client::{Client, ClientBuilder}, - }; - - /// Build web RPC client from URL - pub async fn client(url: &str) -> Result { - let (sender, receiver) = web::connect(url) - .await - .map_err(|_| Error::LightClient(LightClientError::Handshake))?; - - Ok(ClientBuilder::default() - .max_buffer_capacity_per_subscription(4096) - .build_with_wasm(sender, receiver)) +cfg_jsonrpsee_web! { + mod jsonrpsee_helpers { + use crate::error::{Error, LightClientError}; + pub use jsonrpsee::{ + client_transport::web, + core::client::{Client, ClientBuilder}, + }; + + /// Build web RPC client from URL + pub async fn client(url: &str) -> Result { + let (sender, receiver) = web::connect(url) + .await + .map_err(|_| Error::LightClient(LightClientError::Handshake))?; + + Ok(ClientBuilder::default() + .max_buffer_capacity_per_subscription(4096) + .build_with_wasm(sender, receiver)) + } } } diff --git a/subxt/src/client/mod.rs b/subxt/src/client/mod.rs index dbfbdd67d4..c764af4b59 100644 --- a/subxt/src/client/mod.rs +++ b/subxt/src/client/mod.rs @@ -11,15 +11,15 @@ mod offline_client; mod online_client; -#[cfg(feature = "unstable-light-client")] -mod light_client; +crate::macros::cfg_unstable_light_client! { + mod light_client; + + pub use light_client::{ + LightClient, LightClientBuilder, LightClientError, RawLightClient, RawLightClientBuilder, + }; +} pub use offline_client::{OfflineClient, OfflineClientT}; pub use online_client::{ ClientRuntimeUpdater, OnlineClient, OnlineClientT, RuntimeUpdaterStream, Update, UpgradeError, }; - -#[cfg(feature = "unstable-light-client")] -pub use light_client::{ - LightClient, LightClientBuilder, LightClientError, RawLightClient, RawLightClientBuilder, -}; diff --git a/subxt/src/client/online_client.rs b/subxt/src/client/online_client.rs index 1382e4f086..f4e2f8c723 100644 --- a/subxt/src/client/online_client.rs +++ b/subxt/src/client/online_client.rs @@ -56,6 +56,7 @@ impl std::fmt::Debug for OnlineClient { // The default constructors assume Jsonrpsee. #[cfg(feature = "jsonrpsee")] +#[cfg_attr(docsrs, doc(cfg(feature = "jsonrpsee")))] impl OnlineClient { /// Construct a new [`OnlineClient`] using default settings which /// point to a locally running node on `ws://127.0.0.1:9944`. diff --git a/subxt/src/config/mod.rs b/subxt/src/config/mod.rs index 32101d9b72..ddfa2466c7 100644 --- a/subxt/src/config/mod.rs +++ b/subxt/src/config/mod.rs @@ -15,6 +15,7 @@ pub mod polkadot; pub mod signed_extensions; pub mod substrate; +use crate::macros::cfg_substrate_compat; use codec::{Decode, Encode}; use core::fmt::Debug; use scale_decode::DecodeAsType; @@ -125,28 +126,29 @@ pub trait Header: Sized + Encode + Decode { } } -/// implement subxt's Hasher and Header traits for some substrate structs -#[cfg(feature = "substrate-compat")] -mod substrate_impls { - use super::*; - - impl Header for T - where - ::Number: Into, - { - type Number = T::Number; - type Hasher = T::Hashing; - - fn number(&self) -> Self::Number { - *self.number() +cfg_substrate_compat! { + /// implement subxt's Hasher and Header traits for some substrate structs + mod substrate_impls { + use super::*; + + impl Header for T + where + ::Number: Into, + { + type Number = T::Number; + type Hasher = T::Hashing; + + fn number(&self) -> Self::Number { + *self.number() + } } - } - impl Hasher for T { - type Output = T::Output; + impl Hasher for T { + type Output = T::Output; - fn hash(s: &[u8]) -> Self::Output { - ::hash(s) + fn hash(s: &[u8]) -> Self::Output { + ::hash(s) + } } } } diff --git a/subxt/src/error/mod.rs b/subxt/src/error/mod.rs index 02a2d5055d..78c5528012 100644 --- a/subxt/src/error/mod.rs +++ b/subxt/src/error/mod.rs @@ -8,8 +8,9 @@ mod dispatch_error; use core::fmt::Debug; -#[cfg(feature = "unstable-light-client")] -pub use crate::client::LightClientError; +crate::macros::cfg_unstable_light_client! { + pub use crate::client::LightClientError; +} // Re-export dispatch error types: pub use dispatch_error::{ @@ -73,6 +74,7 @@ pub enum Error { Unknown(Vec), /// Light client error. #[cfg(feature = "unstable-light-client")] + #[cfg_attr(docsrs, doc(cfg(feature = "unstable-light-client")))] #[error("An error occurred but it could not be decoded: {0}")] LightClient(#[from] LightClientError), /// Other error. diff --git a/subxt/src/lib.rs b/subxt/src/lib.rs index 34f5b8ffe5..b50880e1ea 100644 --- a/subxt/src/lib.rs +++ b/subxt/src/lib.rs @@ -10,6 +10,8 @@ //! //! Take a look at [the Subxt guide](book) to learn more about how to use Subxt. +#![cfg_attr(docsrs, feature(doc_cfg))] + #[cfg(any( all(feature = "web", feature = "native"), not(any(feature = "web", feature = "native")) @@ -55,6 +57,10 @@ pub mod storage; pub mod tx; pub mod utils; +// Internal helper macros +#[macro_use] +mod macros; + // Expose a few of the most common types at root, // but leave most types behind their respective modules. pub use crate::{ @@ -73,10 +79,11 @@ pub mod ext { pub use scale_decode; pub use scale_encode; pub use scale_value; - #[cfg(feature = "substrate-compat")] - pub use sp_core; - #[cfg(feature = "substrate-compat")] - pub use sp_runtime; + + cfg_substrate_compat! { + pub use sp_runtime; + pub use sp_core; + } } /// Generate a strongly typed API for interacting with a Substrate runtime from its metadata. diff --git a/subxt/src/macros.rs b/subxt/src/macros.rs new file mode 100644 index 0000000000..a8d86ada69 --- /dev/null +++ b/subxt/src/macros.rs @@ -0,0 +1,59 @@ +// Copyright 2019-2023 Parity Technologies (UK) Ltd. +// This file is dual-licensed as Apache-2.0 or GPL-3.0. +// see LICENSE for license details. + +macro_rules! cfg_feature { + ($feature:literal, $($item:item)*) => { + $( + #[cfg(feature = $feature)] + #[cfg_attr(docsrs, doc(cfg(feature = $feature)))] + $item + )* + } +} + +macro_rules! cfg_substrate_compat { + ($($item:item)*) => { + crate::macros::cfg_feature!("substrate-compat", $($item)*); + }; +} + +macro_rules! cfg_unstable_light_client { + ($($item:item)*) => { + crate::macros::cfg_feature!("unstable-light-client", $($item)*); + }; +} + +macro_rules! cfg_jsonrpsee { + ($($item:item)*) => { + crate::macros::cfg_feature!("jsonrpsee", $($item)*); + }; +} + +#[allow(unused)] +macro_rules! cfg_jsonrpsee_native { + ($($item:item)*) => { + $( + #[cfg(all(feature = "jsonrpsee", feature = "native"))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "jsonrpsee", feature = "native"))))] + $item + )* + } +} + +#[allow(unused)] +macro_rules! cfg_jsonrpsee_web { + ($($item:item)*) => { + $( + #[cfg(all(feature = "jsonrpsee", feature = "web"))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "jsonrpsee", feature = "web"))))] + $item + )* + } +} + +pub(crate) use {cfg_feature, cfg_jsonrpsee, cfg_substrate_compat, cfg_unstable_light_client}; + +// Only used by light-client. +#[allow(unused)] +pub(crate) use {cfg_jsonrpsee_native, cfg_jsonrpsee_web}; diff --git a/subxt/src/tx/mod.rs b/subxt/src/tx/mod.rs index 039db376bf..0bb2d9f3eb 100644 --- a/subxt/src/tx/mod.rs +++ b/subxt/src/tx/mod.rs @@ -9,6 +9,8 @@ //! additional and signed extra parameters are used when constructing an extrinsic, and is a part //! of the chain configuration (see [`crate::config::Config`]). +use crate::macros::cfg_substrate_compat; + mod signer; mod tx_client; mod tx_payload; @@ -16,8 +18,9 @@ mod tx_progress; // The PairSigner impl currently relies on Substrate bits and pieces, so make it an optional // feature if we want to avoid needing sp_core and sp_runtime. -#[cfg(feature = "substrate-compat")] -pub use self::signer::PairSigner; +cfg_substrate_compat! { + pub use self::signer::PairSigner; +} pub use self::{ signer::Signer, diff --git a/subxt/src/tx/signer.rs b/subxt/src/tx/signer.rs index b007cbb256..444aa46477 100644 --- a/subxt/src/tx/signer.rs +++ b/subxt/src/tx/signer.rs @@ -5,6 +5,7 @@ //! A library to **sub**mit e**xt**rinsics to a //! [substrate](https://github.com/paritytech/substrate) node via RPC. +use crate::macros::cfg_substrate_compat; use crate::Config; /// Signing transactions requires a [`Signer`]. This is responsible for @@ -24,8 +25,9 @@ pub trait Signer { fn sign(&self, signer_payload: &[u8]) -> T::Signature; } -#[cfg(feature = "substrate-compat")] -pub use pair_signer::PairSigner; +cfg_substrate_compat! { + pub use pair_signer::PairSigner; +} // A signer suitable for substrate based chains. This provides compatibility with Substrate // packages like sp_keyring and such, and so relies on sp_core and sp_runtime to be included.