mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-25 12:57:58 +00:00
Tidy subxt-codegen crate interface (#1225)
* first pass tidying codegen crate interface * fix a codegen test * macro: keep error spans * clippy * fix doc example * removecommented-out code
This commit is contained in:
@@ -3,10 +3,7 @@
|
||||
// see LICENSE for license details.
|
||||
|
||||
use super::CodegenError;
|
||||
use crate::{
|
||||
types::{CompositeDefFields, TypeGenerator},
|
||||
CratePath,
|
||||
};
|
||||
use crate::types::{CompositeDefFields, TypeGenerator};
|
||||
use heck::{ToSnakeCase as _, ToUpperCamelCase as _};
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::{format_ident, quote};
|
||||
@@ -25,7 +22,7 @@ pub fn generate_calls(
|
||||
type_gen: &TypeGenerator,
|
||||
pallet: &PalletMetadata,
|
||||
types_mod_ident: &syn::Ident,
|
||||
crate_path: &CratePath,
|
||||
crate_path: &syn::Path,
|
||||
should_gen_docs: bool,
|
||||
) -> Result<TokenStream2, CodegenError> {
|
||||
// Early return if the pallet has no calls.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
use crate::{types::TypeGenerator, CratePath};
|
||||
use crate::types::TypeGenerator;
|
||||
use heck::ToSnakeCase as _;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::{format_ident, quote};
|
||||
@@ -37,7 +37,7 @@ pub fn generate_constants(
|
||||
type_gen: &TypeGenerator,
|
||||
pallet: &PalletMetadata,
|
||||
types_mod_ident: &syn::Ident,
|
||||
crate_path: &CratePath,
|
||||
crate_path: &syn::Path,
|
||||
should_gen_docs: bool,
|
||||
) -> Result<TokenStream2, CodegenError> {
|
||||
// Early return if the pallet has no constants.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
use crate::{types::TypeGenerator, CratePath};
|
||||
use crate::types::TypeGenerator;
|
||||
use heck::ToSnakeCase as _;
|
||||
use subxt_metadata::{CustomValueMetadata, Metadata};
|
||||
|
||||
@@ -12,10 +12,10 @@ use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::{quote, ToTokens};
|
||||
|
||||
/// Generate the custom values mod, if there are any custom values in the metadata. Else returns None.
|
||||
pub fn generate_custom_values<'a>(
|
||||
metadata: &'a Metadata,
|
||||
type_gen: &'a TypeGenerator,
|
||||
crate_path: &'a CratePath,
|
||||
pub fn generate_custom_values(
|
||||
metadata: &Metadata,
|
||||
type_gen: &TypeGenerator,
|
||||
crate_path: &syn::Path,
|
||||
) -> TokenStream2 {
|
||||
let mut fn_names_taken = HashSet::new();
|
||||
let custom = metadata.custom();
|
||||
@@ -37,7 +37,7 @@ pub fn generate_custom_values<'a>(
|
||||
fn generate_custom_value_fn(
|
||||
custom_value: CustomValueMetadata,
|
||||
type_gen: &TypeGenerator,
|
||||
crate_path: &CratePath,
|
||||
crate_path: &syn::Path,
|
||||
fn_names_taken: &mut HashSet<String>,
|
||||
) -> Option<TokenStream2> {
|
||||
// names are transformed to snake case to make for good function identifiers.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
use crate::{types::TypeGenerator, CratePath};
|
||||
use crate::types::TypeGenerator;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::quote;
|
||||
use subxt_metadata::PalletMetadata;
|
||||
@@ -42,7 +42,7 @@ pub fn generate_events(
|
||||
type_gen: &TypeGenerator,
|
||||
pallet: &PalletMetadata,
|
||||
types_mod_ident: &syn::Ident,
|
||||
crate_path: &CratePath,
|
||||
crate_path: &syn::Path,
|
||||
should_gen_docs: bool,
|
||||
) -> Result<TokenStream2, CodegenError> {
|
||||
// Early return if the pallet has no events.
|
||||
|
||||
+4
-188
@@ -14,203 +14,19 @@ mod storage;
|
||||
|
||||
use subxt_metadata::Metadata;
|
||||
|
||||
use super::DerivesRegistry;
|
||||
use crate::api::custom_values::generate_custom_values;
|
||||
use crate::error::CodegenError;
|
||||
use crate::types::DerivesRegistry;
|
||||
use crate::{
|
||||
ir,
|
||||
types::{CompositeDef, CompositeDefFields, TypeGenerator, TypeSubstitutes},
|
||||
CratePath,
|
||||
};
|
||||
|
||||
use codec::Decode;
|
||||
use heck::ToSnakeCase as _;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::{format_ident, quote};
|
||||
use std::{fs, io::Read, path, string::ToString};
|
||||
use syn::parse_quote;
|
||||
|
||||
/// Generate the runtime API for interacting with a substrate runtime.
|
||||
pub struct GenerateRuntimeApi {
|
||||
item_mod: syn::ItemMod,
|
||||
derives: DerivesRegistry,
|
||||
type_substitutes: TypeSubstitutes,
|
||||
crate_path: CratePath,
|
||||
should_gen_docs: bool,
|
||||
runtime_types_only: bool,
|
||||
unstable_metadata: bool,
|
||||
}
|
||||
|
||||
impl GenerateRuntimeApi {
|
||||
/// Construct a new [`GenerateRuntimeApi`].
|
||||
pub fn new(item_mod: syn::ItemMod, crate_path: CratePath) -> Self {
|
||||
GenerateRuntimeApi {
|
||||
item_mod,
|
||||
derives: DerivesRegistry::new(),
|
||||
type_substitutes: TypeSubstitutes::new(),
|
||||
crate_path,
|
||||
should_gen_docs: false,
|
||||
runtime_types_only: false,
|
||||
unstable_metadata: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Provide custom derives for the generated types.
|
||||
///
|
||||
/// Default is no derives.
|
||||
pub fn derives_registry(mut self, derives: DerivesRegistry) -> Self {
|
||||
self.derives = derives;
|
||||
self
|
||||
}
|
||||
|
||||
/// Provide custom type substitutes.
|
||||
///
|
||||
/// Default is no substitutes.
|
||||
pub fn type_substitutes(mut self, type_substitutes: TypeSubstitutes) -> Self {
|
||||
self.type_substitutes = type_substitutes;
|
||||
self
|
||||
}
|
||||
|
||||
/// True if the generated API contains the documentation from the metadata.
|
||||
///
|
||||
/// Default: false.
|
||||
pub fn generate_docs(mut self, should_gen_docs: bool) -> Self {
|
||||
self.should_gen_docs = should_gen_docs;
|
||||
self
|
||||
}
|
||||
|
||||
/// Whether to limit code generation to only runtime types.
|
||||
///
|
||||
/// Default: false.
|
||||
pub fn runtime_types_only(mut self, runtime_types_only: bool) -> Self {
|
||||
self.runtime_types_only = runtime_types_only;
|
||||
self
|
||||
}
|
||||
|
||||
/// Whether to fetch the unstable metadata first.
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// This takes effect only if the API is generated from URL.
|
||||
///
|
||||
/// Default: false.
|
||||
pub fn unstable_metadata(mut self, unstable_metadata: bool) -> Self {
|
||||
self.unstable_metadata = unstable_metadata;
|
||||
self
|
||||
}
|
||||
|
||||
/// Generate the runtime API from path.
|
||||
pub fn generate_from_path<P>(self, path: P) -> Result<TokenStream2, CodegenError>
|
||||
where
|
||||
P: AsRef<path::Path>,
|
||||
{
|
||||
let to_err = |err| CodegenError::Io(path.as_ref().to_string_lossy().into(), err);
|
||||
|
||||
let mut file = fs::File::open(&path).map_err(to_err)?;
|
||||
let mut bytes = Vec::new();
|
||||
file.read_to_end(&mut bytes).map_err(to_err)?;
|
||||
|
||||
let metadata = Metadata::decode(&mut &bytes[..])?;
|
||||
|
||||
generate_runtime_api_with_metadata(
|
||||
self.item_mod,
|
||||
metadata,
|
||||
self.derives,
|
||||
self.type_substitutes,
|
||||
self.crate_path,
|
||||
self.should_gen_docs,
|
||||
self.runtime_types_only,
|
||||
)
|
||||
}
|
||||
|
||||
/// Generate the runtime API from the provided metadata bytes.
|
||||
pub fn generate_from_bytes(self, bytes: &[u8]) -> Result<TokenStream2, CodegenError> {
|
||||
let metadata = Metadata::decode(&mut &bytes[..])?;
|
||||
|
||||
generate_runtime_api_with_metadata(
|
||||
self.item_mod,
|
||||
metadata,
|
||||
self.derives,
|
||||
self.type_substitutes,
|
||||
self.crate_path,
|
||||
self.should_gen_docs,
|
||||
self.runtime_types_only,
|
||||
)
|
||||
}
|
||||
|
||||
/// Generate the runtime API from URL.
|
||||
///
|
||||
/// The metadata will be downloaded from a node at the provided URL.
|
||||
/// This function blocks while retrieving the metadata.
|
||||
///
|
||||
/// # Warning
|
||||
///
|
||||
/// Not recommended to be used in production environments.
|
||||
#[cfg(feature = "fetch-metadata")]
|
||||
pub fn generate_from_url(self, url: crate::utils::Url) -> Result<TokenStream2, CodegenError> {
|
||||
use crate::utils::{fetch_metadata_bytes_blocking, MetadataVersion, Url};
|
||||
|
||||
fn fetch_metadata(url: Url, version: MetadataVersion) -> Result<Metadata, CodegenError> {
|
||||
let bytes = fetch_metadata_bytes_blocking(url, version)?;
|
||||
Ok(Metadata::decode(&mut &bytes[..])?)
|
||||
}
|
||||
|
||||
let metadata = self
|
||||
.unstable_metadata
|
||||
.then(|| fetch_metadata(url.clone(), MetadataVersion::Unstable).ok())
|
||||
.flatten();
|
||||
|
||||
let metadata = if let Some(unstable) = metadata {
|
||||
unstable
|
||||
} else {
|
||||
match fetch_metadata(url.clone(), MetadataVersion::Version(15)) {
|
||||
Ok(metadata) => metadata,
|
||||
Err(_) => fetch_metadata(url, MetadataVersion::Version(14))?,
|
||||
}
|
||||
};
|
||||
|
||||
generate_runtime_api_with_metadata(
|
||||
self.item_mod,
|
||||
metadata,
|
||||
self.derives,
|
||||
self.type_substitutes,
|
||||
self.crate_path,
|
||||
self.should_gen_docs,
|
||||
self.runtime_types_only,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates the API for interacting with a substrate runtime, using the `subxt::Metadata`.
|
||||
fn generate_runtime_api_with_metadata(
|
||||
item_mod: syn::ItemMod,
|
||||
metadata: Metadata,
|
||||
derives: DerivesRegistry,
|
||||
type_substitutes: TypeSubstitutes,
|
||||
crate_path: CratePath,
|
||||
should_gen_docs: bool,
|
||||
runtime_types_only: bool,
|
||||
) -> Result<TokenStream2, CodegenError> {
|
||||
let generator = RuntimeGenerator::new(metadata);
|
||||
if runtime_types_only {
|
||||
generator.generate_runtime_types(
|
||||
item_mod,
|
||||
derives,
|
||||
type_substitutes,
|
||||
crate_path,
|
||||
should_gen_docs,
|
||||
)
|
||||
} else {
|
||||
generator.generate_runtime(
|
||||
item_mod,
|
||||
derives,
|
||||
type_substitutes,
|
||||
crate_path,
|
||||
should_gen_docs,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Create the API for interacting with a Substrate runtime.
|
||||
pub struct RuntimeGenerator {
|
||||
metadata: Metadata,
|
||||
@@ -246,7 +62,7 @@ impl RuntimeGenerator {
|
||||
item_mod: syn::ItemMod,
|
||||
derives: DerivesRegistry,
|
||||
type_substitutes: TypeSubstitutes,
|
||||
crate_path: CratePath,
|
||||
crate_path: syn::Path,
|
||||
should_gen_docs: bool,
|
||||
) -> Result<TokenStream2, CodegenError> {
|
||||
let item_mod_attrs = item_mod.attrs.clone();
|
||||
@@ -300,7 +116,7 @@ impl RuntimeGenerator {
|
||||
item_mod: syn::ItemMod,
|
||||
derives: DerivesRegistry,
|
||||
type_substitutes: TypeSubstitutes,
|
||||
crate_path: CratePath,
|
||||
crate_path: syn::Path,
|
||||
should_gen_docs: bool,
|
||||
) -> Result<TokenStream2, CodegenError> {
|
||||
let item_mod_attrs = item_mod.attrs.clone();
|
||||
@@ -545,7 +361,7 @@ pub fn generate_structs_from_variants<F>(
|
||||
type_id: u32,
|
||||
variant_to_struct_name: F,
|
||||
error_message_type_name: &str,
|
||||
crate_path: &CratePath,
|
||||
crate_path: &syn::Path,
|
||||
should_gen_docs: bool,
|
||||
) -> Result<Vec<(String, CompositeDef)>, CodegenError>
|
||||
where
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
use crate::{types::TypeGenerator, CodegenError, CratePath};
|
||||
use crate::{types::TypeGenerator, CodegenError};
|
||||
use heck::ToSnakeCase as _;
|
||||
use heck::ToUpperCamelCase as _;
|
||||
use subxt_metadata::{Metadata, RuntimeApiMetadata};
|
||||
@@ -15,7 +15,7 @@ fn generate_runtime_api(
|
||||
api: RuntimeApiMetadata,
|
||||
type_gen: &TypeGenerator,
|
||||
types_mod_ident: &syn::Ident,
|
||||
crate_path: &CratePath,
|
||||
crate_path: &syn::Path,
|
||||
should_gen_docs: bool,
|
||||
) -> Result<(TokenStream2, TokenStream2), CodegenError> {
|
||||
// Trait name must remain as is (upper case) to identity the runtime call.
|
||||
@@ -130,7 +130,7 @@ pub fn generate_runtime_apis(
|
||||
metadata: &Metadata,
|
||||
type_gen: &TypeGenerator,
|
||||
types_mod_ident: &syn::Ident,
|
||||
crate_path: &CratePath,
|
||||
crate_path: &syn::Path,
|
||||
should_gen_docs: bool,
|
||||
) -> Result<TokenStream2, CodegenError> {
|
||||
let runtime_fns: Vec<_> = metadata
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
use crate::types::TypeGenerator;
|
||||
use crate::types::TypePath;
|
||||
use crate::{types::TypeGenerator, CratePath};
|
||||
use heck::ToSnakeCase as _;
|
||||
use proc_macro2::{Ident, TokenStream as TokenStream2, TokenStream};
|
||||
use quote::{format_ident, quote};
|
||||
@@ -27,7 +27,7 @@ pub fn generate_storage(
|
||||
type_gen: &TypeGenerator,
|
||||
pallet: &PalletMetadata,
|
||||
types_mod_ident: &syn::Ident,
|
||||
crate_path: &CratePath,
|
||||
crate_path: &syn::Path,
|
||||
should_gen_docs: bool,
|
||||
) -> Result<TokenStream2, CodegenError> {
|
||||
let Some(storage) = pallet.storage() else {
|
||||
@@ -59,7 +59,7 @@ fn generate_storage_entry_fns(
|
||||
type_gen: &TypeGenerator,
|
||||
pallet: &PalletMetadata,
|
||||
storage_entry: &StorageEntryMetadata,
|
||||
crate_path: &CratePath,
|
||||
crate_path: &syn::Path,
|
||||
should_gen_docs: bool,
|
||||
) -> Result<TokenStream2, CodegenError> {
|
||||
let keys: Vec<(Ident, TypePath)> = match storage_entry.entry_type() {
|
||||
@@ -269,7 +269,7 @@ mod tests {
|
||||
item_mod,
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
"::subxt_path".into(),
|
||||
syn::parse_str("::subxt_path").unwrap(),
|
||||
false,
|
||||
)
|
||||
.expect("should be able to generate runtime");
|
||||
|
||||
@@ -16,9 +16,6 @@ pub enum CodegenError {
|
||||
/// Cannot fetch the metadata bytes.
|
||||
#[error("Failed to fetch metadata, make sure that you're pointing at a node which is providing substrate-based metadata: {0}")]
|
||||
Fetch(#[from] FetchMetadataError),
|
||||
/// Failed IO for the metadata file.
|
||||
#[error("Failed IO for {0}, make sure that you are providing the correct file path for metadata: {1}")]
|
||||
Io(String, std::io::Error),
|
||||
/// Cannot decode the metadata bytes.
|
||||
#[error("Could not decode metadata, only V14 and V15 metadata are supported: {0}")]
|
||||
Decode(#[from] codec::Error),
|
||||
@@ -85,15 +82,23 @@ impl CodegenError {
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[non_exhaustive]
|
||||
pub enum FetchMetadataError {
|
||||
/// Error decoding from a hex value.
|
||||
#[error("Cannot decode hex value: {0}")]
|
||||
DecodeError(#[from] hex::FromHexError),
|
||||
/// Some SCALE codec error.
|
||||
#[error("Cannot scale encode/decode value: {0}")]
|
||||
CodecError(#[from] codec::Error),
|
||||
/// JSON-RPC error fetching metadata.
|
||||
#[cfg(feature = "fetch-metadata")]
|
||||
#[error("Request error: {0}")]
|
||||
RequestError(#[from] jsonrpsee::core::Error),
|
||||
/// Failed IO when fetching from a file.
|
||||
#[error("Failed IO for {0}, make sure that you are providing the correct file path for metadata: {1}")]
|
||||
Io(String, std::io::Error),
|
||||
/// URL scheme is not http, https, ws or wss.
|
||||
#[error("'{0}' not supported, supported URI schemes are http, https, ws or wss.")]
|
||||
InvalidScheme(String),
|
||||
/// Some other error.
|
||||
#[error("Other error: {0}")]
|
||||
Other(String),
|
||||
}
|
||||
|
||||
@@ -2,17 +2,22 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! Helper methods for fetching metadata from a file or URL.
|
||||
|
||||
use crate::error::FetchMetadataError;
|
||||
use codec::{Decode, Encode};
|
||||
use jsonrpsee::{
|
||||
async_client::ClientBuilder,
|
||||
client_transport::ws::{Url, WsTransportClientBuilder},
|
||||
client_transport::ws::WsTransportClientBuilder,
|
||||
core::{client::ClientT, Error},
|
||||
http_client::HttpClientBuilder,
|
||||
rpc_params,
|
||||
};
|
||||
use std::time::Duration;
|
||||
|
||||
// Part of the public interface:
|
||||
pub use jsonrpsee::client_transport::ws::Url;
|
||||
|
||||
/// The metadata version that is fetched from the node.
|
||||
#[derive(Default, Debug, Clone, Copy)]
|
||||
pub enum MetadataVersion {
|
||||
@@ -44,20 +49,24 @@ impl std::str::FromStr for MetadataVersion {
|
||||
}
|
||||
}
|
||||
|
||||
/// Fetch metadata from a file.
|
||||
pub fn fetch_metadata_from_file_blocking(
|
||||
path: &std::path::Path,
|
||||
) -> Result<Vec<u8>, FetchMetadataError> {
|
||||
use std::io::Read;
|
||||
let to_err = |err| FetchMetadataError::Io(path.to_string_lossy().into(), err);
|
||||
let mut file = std::fs::File::open(path).map_err(to_err)?;
|
||||
let mut bytes = Vec::new();
|
||||
file.read_to_end(&mut bytes).map_err(to_err)?;
|
||||
Ok(bytes)
|
||||
}
|
||||
|
||||
/// Returns the metadata bytes from the provided URL, blocking the current thread.
|
||||
pub fn fetch_metadata_bytes_blocking(
|
||||
pub fn fetch_metadata_from_url_blocking(
|
||||
url: Url,
|
||||
version: MetadataVersion,
|
||||
) -> Result<Vec<u8>, FetchMetadataError> {
|
||||
tokio_block_on(fetch_metadata_bytes(url, version))
|
||||
}
|
||||
|
||||
/// Returns the raw, 0x prefixed metadata hex from the provided URL, blocking the current thread.
|
||||
pub fn fetch_metadata_hex_blocking(
|
||||
url: Url,
|
||||
version: MetadataVersion,
|
||||
) -> Result<String, FetchMetadataError> {
|
||||
tokio_block_on(fetch_metadata_hex(url, version))
|
||||
tokio_block_on(fetch_metadata_from_url(url, version))
|
||||
}
|
||||
|
||||
// Block on some tokio runtime for sync contexts
|
||||
@@ -70,7 +79,7 @@ fn tokio_block_on<T, Fut: std::future::Future<Output = T>>(fut: Fut) -> T {
|
||||
}
|
||||
|
||||
/// Returns the metadata bytes from the provided URL.
|
||||
pub async fn fetch_metadata_bytes(
|
||||
pub async fn fetch_metadata_from_url(
|
||||
url: Url,
|
||||
version: MetadataVersion,
|
||||
) -> Result<Vec<u8>, FetchMetadataError> {
|
||||
@@ -83,16 +92,6 @@ pub async fn fetch_metadata_bytes(
|
||||
Ok(bytes)
|
||||
}
|
||||
|
||||
/// Returns the raw, 0x prefixed metadata hex from the provided URL.
|
||||
pub async fn fetch_metadata_hex(
|
||||
url: Url,
|
||||
version: MetadataVersion,
|
||||
) -> Result<String, FetchMetadataError> {
|
||||
let bytes = fetch_metadata_bytes(url, version).await?;
|
||||
let hex_data = format!("0x{}", hex::encode(bytes));
|
||||
Ok(hex_data)
|
||||
}
|
||||
|
||||
async fn fetch_metadata_ws(
|
||||
url: Url,
|
||||
version: MetadataVersion,
|
||||
+252
-50
@@ -2,65 +2,267 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! Library to generate an API for a Substrate runtime from its metadata.
|
||||
//!
|
||||
//! ## Generated Structure
|
||||
//!
|
||||
//! The API generator logic:
|
||||
//! - At the root there is the `item_mod` provided (ie `pub mod api {}`)
|
||||
//! - Pallets are represented by a child module (ie `pub mod PalletName {}`) of the root
|
||||
//! - Each pallet exposes as child modules (if applicable):
|
||||
//! - Calls (`pub mod calls {}`)
|
||||
//! - Events (`pub mod events {}`)
|
||||
//! - Storage (`pub mod storage {}`)
|
||||
//! - Constants (`pub mod constants {}`)
|
||||
//!
|
||||
//! ## Example
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use std::fs;
|
||||
//! use codec::Decode;
|
||||
//! use subxt_metadata::Metadata;
|
||||
//! use subxt_codegen::{CratePath, DerivesRegistry, TypeSubstitutes};
|
||||
//!
|
||||
//! let encoded = fs::read("../artifacts/polkadot_metadata_full.scale").unwrap();
|
||||
//!
|
||||
//! // Runtime metadata obtained from a node.
|
||||
//! let metadata = Metadata::decode(&mut &*encoded).unwrap();
|
||||
//! // Module under which the API is generated.
|
||||
//! let item_mod = syn::parse_quote!(
|
||||
//! pub mod api {}
|
||||
//! );
|
||||
//! // Default module derivatives.
|
||||
//! let mut derives = DerivesRegistry::with_default_derives(&CratePath::default());
|
||||
//! // Default type substitutes.
|
||||
//! let substs = TypeSubstitutes::with_default_substitutes(&CratePath::default());
|
||||
//! // Generate the Runtime API.
|
||||
//! let generator = subxt_codegen::RuntimeGenerator::new(metadata);
|
||||
//! // Include metadata documentation in the Runtime API.
|
||||
//! let generate_docs = true;
|
||||
//! let runtime_api = generator.generate_runtime(item_mod, derives, substs, CratePath::default(), generate_docs).unwrap();
|
||||
//! println!("{}", runtime_api);
|
||||
//! ```
|
||||
//! Generate a type safe Subxt interface for a Substrate runtime from its metadata.
|
||||
//! This is used by the `#[subxt]` macro and `subxt codegen` CLI command, but can also
|
||||
//! be used directly if preferable.
|
||||
|
||||
#![deny(unused_crate_dependencies, missing_docs)]
|
||||
|
||||
mod api;
|
||||
mod error;
|
||||
mod ir;
|
||||
mod types;
|
||||
|
||||
pub mod error;
|
||||
|
||||
// These should probably be in a separate crate; they are used by the
|
||||
// macro and CLI tool, so they only live here because this is a common
|
||||
// crate that both depend on.
|
||||
#[cfg(feature = "fetch-metadata")]
|
||||
pub mod utils;
|
||||
pub mod fetch_metadata;
|
||||
|
||||
#[cfg(feature = "web")]
|
||||
use getrandom as _;
|
||||
|
||||
pub use self::{
|
||||
api::{GenerateRuntimeApi, RuntimeGenerator},
|
||||
error::{CodegenError, TypeSubstitutionError},
|
||||
types::{
|
||||
CratePath, Derives, DerivesRegistry, Module, TypeDefGen, TypeDefParameters, TypeGenerator,
|
||||
TypeSubstitutes,
|
||||
},
|
||||
};
|
||||
use api::RuntimeGenerator;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use std::collections::HashMap;
|
||||
|
||||
// We expose these only because they are currently needed in subxt-explorer.
|
||||
// Eventually we'll move the type generation stuff out into a separate crate.
|
||||
#[doc(hidden)]
|
||||
pub mod __private {
|
||||
pub use crate::types::{DerivesRegistry, TypeDefGen, TypeGenerator, TypeSubstitutes};
|
||||
}
|
||||
|
||||
// Part of the public interface, so expose:
|
||||
pub use error::CodegenError;
|
||||
pub use subxt_metadata::Metadata;
|
||||
pub use syn;
|
||||
|
||||
/// Generate a type safe interface to use with `subxt`.
|
||||
/// The options exposed here are similar to those exposed via
|
||||
/// the `#[subxt]` macro or via the `subxt codegen` CLI command.
|
||||
/// Both use this under the hood.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// Generating an interface using all of the defaults:
|
||||
///
|
||||
/// ```rust
|
||||
/// use codec::Decode;
|
||||
/// use subxt_codegen::{ Metadata, CodegenBuilder };
|
||||
///
|
||||
/// // Get hold of and decode some metadata:
|
||||
/// let encoded = std::fs::read("../artifacts/polkadot_metadata_full.scale").unwrap();
|
||||
/// let metadata = Metadata::decode(&mut &*encoded).unwrap();
|
||||
///
|
||||
/// // Generate a TokenStream representing the code for the interface.
|
||||
/// // This can be converted to a string, displayed as-is or output from a macro.
|
||||
/// let token_stream = CodegenBuilder::new().generate(metadata);
|
||||
/// ````
|
||||
pub struct CodegenBuilder {
|
||||
crate_path: syn::Path,
|
||||
use_default_derives: bool,
|
||||
use_default_substitutions: bool,
|
||||
generate_docs: bool,
|
||||
runtime_types_only: bool,
|
||||
item_mod: syn::ItemMod,
|
||||
extra_global_derives: Vec<syn::Path>,
|
||||
extra_global_attributes: Vec<syn::Attribute>,
|
||||
type_substitutes: HashMap<syn::Path, syn::Path>,
|
||||
derives_for_type: HashMap<syn::TypePath, Vec<syn::Path>>,
|
||||
attributes_for_type: HashMap<syn::TypePath, Vec<syn::Attribute>>,
|
||||
}
|
||||
|
||||
impl Default for CodegenBuilder {
|
||||
fn default() -> Self {
|
||||
CodegenBuilder {
|
||||
crate_path: syn::parse_quote!(::subxt),
|
||||
use_default_derives: true,
|
||||
use_default_substitutions: true,
|
||||
generate_docs: true,
|
||||
runtime_types_only: false,
|
||||
item_mod: syn::parse_quote!(
|
||||
pub mod api {}
|
||||
),
|
||||
extra_global_derives: Vec::new(),
|
||||
extra_global_attributes: Vec::new(),
|
||||
type_substitutes: HashMap::new(),
|
||||
derives_for_type: HashMap::new(),
|
||||
attributes_for_type: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CodegenBuilder {
|
||||
/// Construct a builder to configure and generate a type-safe interface for Subxt.
|
||||
pub fn new() -> Self {
|
||||
CodegenBuilder::default()
|
||||
}
|
||||
|
||||
/// Disable the default derives that are applied to all types.
|
||||
///
|
||||
/// # Warning
|
||||
///
|
||||
/// This is not recommended, and is highly likely to break some part of the
|
||||
/// generated interface. Expect compile errors.
|
||||
pub fn disable_default_derives(&mut self) {
|
||||
self.use_default_derives = false;
|
||||
}
|
||||
|
||||
/// Disable the default type substitutions that are applied to the generated
|
||||
/// code.
|
||||
///
|
||||
/// # Warning
|
||||
///
|
||||
/// This is not recommended, and is highly likely to break some part of the
|
||||
/// generated interface. Expect compile errors.
|
||||
pub fn disable_default_substitutes(&mut self) {
|
||||
self.use_default_substitutions = false;
|
||||
}
|
||||
|
||||
/// Disable the output of doc comments associated with the generated types and
|
||||
/// methods. This can reduce the generated code size at the expense of losing
|
||||
/// documentation.
|
||||
pub fn no_docs(&mut self) {
|
||||
self.generate_docs = false;
|
||||
}
|
||||
|
||||
/// Only generate the types, and don't generate the rest of the Subxt specific
|
||||
/// interface.
|
||||
pub fn runtime_types_only(&mut self) {
|
||||
self.runtime_types_only = true;
|
||||
}
|
||||
|
||||
/// Set the additional derives that will be applied to all types. By default,
|
||||
/// a set of derives required for Subxt are automatically added for all types.
|
||||
///
|
||||
/// # Warning
|
||||
///
|
||||
/// Invalid derives, or derives that cannot be applied to _all_ of the generated
|
||||
/// types (taking into account that some types are substituted for hand written ones
|
||||
/// that we cannot add extra derives for) will lead to compile errors in the
|
||||
/// generated code.
|
||||
pub fn set_additional_global_derives(&mut self, derives: Vec<syn::Path>) {
|
||||
self.extra_global_derives = derives;
|
||||
}
|
||||
|
||||
/// Set the additional attributes that will be applied to all types. By default,
|
||||
/// a set of attributes required for Subxt are automatically added for all types.
|
||||
///
|
||||
/// # Warning
|
||||
///
|
||||
/// Invalid attributes can very easily lead to compile errors in the generated code.
|
||||
pub fn set_additional_global_attributes(&mut self, attributes: Vec<syn::Attribute>) {
|
||||
self.extra_global_attributes = attributes;
|
||||
}
|
||||
|
||||
/// Set additional derives for a specific type at the path given.
|
||||
///
|
||||
/// # Warning
|
||||
///
|
||||
/// For composite types, you may also need to set the same additional derives on all of
|
||||
/// the contained types as well to avoid compile errors in the generated code.
|
||||
pub fn add_derives_for_type(
|
||||
&mut self,
|
||||
ty: syn::TypePath,
|
||||
derives: impl IntoIterator<Item = syn::Path>,
|
||||
) {
|
||||
self.derives_for_type.entry(ty).or_default().extend(derives);
|
||||
}
|
||||
|
||||
/// Set additional attributes for a specific type at the path given.
|
||||
///
|
||||
/// # Warning
|
||||
///
|
||||
/// For composite types, you may also need to consider contained types and whether they need
|
||||
/// similar attributes setting.
|
||||
pub fn add_attributes_for_type(
|
||||
&mut self,
|
||||
ty: syn::TypePath,
|
||||
attributes: impl IntoIterator<Item = syn::Attribute>,
|
||||
) {
|
||||
self.attributes_for_type
|
||||
.entry(ty)
|
||||
.or_default()
|
||||
.extend(attributes);
|
||||
}
|
||||
|
||||
/// Substitute a type at the given path with some type at the second path. During codegen,
|
||||
/// we will avoid generating the type at the first path given, and instead point any references
|
||||
/// to that type to the second path given.
|
||||
///
|
||||
/// The substituted type will need to implement the relevant traits to be compatible with the
|
||||
/// original, and it will need to SCALE encode and SCALE decode in a compatible way.
|
||||
pub fn set_type_substitute(&mut self, ty: syn::Path, with: syn::Path) {
|
||||
self.type_substitutes.insert(ty, with);
|
||||
}
|
||||
|
||||
/// By default, all of the code is generated inside a module `pub mod api {}`. We decorate
|
||||
/// this module with a few attributes to reduce compile warnings and things. You can provide a
|
||||
/// target module here, allowing you to add additional attributes or inner code items (with the
|
||||
/// warning that duplicate identifiers will lead to compile errors).
|
||||
pub fn set_target_module(&mut self, item_mod: syn::ItemMod) {
|
||||
self.item_mod = item_mod;
|
||||
}
|
||||
|
||||
/// Set the path to the `subxt` crate. By default, we expect it to be at `::subxt`.
|
||||
pub fn set_subxt_crate_path(&mut self, crate_path: syn::Path) {
|
||||
self.crate_path = crate_path;
|
||||
}
|
||||
|
||||
/// Generate an interface, assuming that the default path to the `subxt` crate is `::subxt`.
|
||||
/// If the `subxt` crate is not available as a top level dependency, use `generate` and provide
|
||||
/// a valid path to the `subxt¦ crate.
|
||||
pub fn generate(self, metadata: Metadata) -> Result<TokenStream2, CodegenError> {
|
||||
let crate_path = self.crate_path;
|
||||
|
||||
let mut derives_registry = if self.use_default_derives {
|
||||
types::DerivesRegistry::with_default_derives(&crate_path)
|
||||
} else {
|
||||
types::DerivesRegistry::new()
|
||||
};
|
||||
|
||||
derives_registry.extend_for_all(self.extra_global_derives, self.extra_global_attributes);
|
||||
|
||||
for (ty, derives) in self.derives_for_type {
|
||||
derives_registry.extend_for_type(ty, derives, vec![]);
|
||||
}
|
||||
for (ty, attributes) in self.attributes_for_type {
|
||||
derives_registry.extend_for_type(ty, vec![], attributes);
|
||||
}
|
||||
|
||||
let mut type_substitutes = if self.use_default_substitutions {
|
||||
types::TypeSubstitutes::with_default_substitutes(&crate_path)
|
||||
} else {
|
||||
types::TypeSubstitutes::new()
|
||||
};
|
||||
|
||||
for (from, with) in self.type_substitutes {
|
||||
let abs_path = with.try_into()?;
|
||||
type_substitutes.insert(from, abs_path)?;
|
||||
}
|
||||
|
||||
let item_mod = self.item_mod;
|
||||
let generator = RuntimeGenerator::new(metadata);
|
||||
let should_gen_docs = self.generate_docs;
|
||||
|
||||
if self.runtime_types_only {
|
||||
generator.generate_runtime_types(
|
||||
item_mod,
|
||||
derives_registry,
|
||||
type_substitutes,
|
||||
crate_path,
|
||||
should_gen_docs,
|
||||
)
|
||||
} else {
|
||||
generator.generate_runtime(
|
||||
item_mod,
|
||||
derives_registry,
|
||||
type_substitutes,
|
||||
crate_path,
|
||||
should_gen_docs,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
use crate::error::CodegenError;
|
||||
|
||||
use super::{CratePath, Derives, Field, TypeDefParameters, TypeGenerator, TypeParameter, TypePath};
|
||||
use super::{Derives, Field, TypeDefParameters, TypeGenerator, TypeParameter, TypePath};
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{format_ident, quote};
|
||||
use scale_info::{form::PortableForm, Type, TypeDef, TypeDefPrimitive};
|
||||
@@ -36,7 +36,7 @@ impl CompositeDef {
|
||||
field_visibility: Option<syn::Visibility>,
|
||||
type_gen: &TypeGenerator,
|
||||
docs: &[String],
|
||||
crate_path: &CratePath,
|
||||
crate_path: &syn::Path,
|
||||
) -> Result<Self, CodegenError> {
|
||||
let mut derives = type_gen.type_derives(ty)?;
|
||||
let fields: Vec<_> = fields_def.field_types().collect();
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
use crate::CratePath;
|
||||
use syn::{parse_quote, Path};
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
@@ -35,7 +34,7 @@ impl DerivesRegistry {
|
||||
///
|
||||
/// The `crate_path` denotes the `subxt` crate access path in the
|
||||
/// generated code.
|
||||
pub fn with_default_derives(crate_path: &CratePath) -> Self {
|
||||
pub fn with_default_derives(crate_path: &syn::Path) -> Self {
|
||||
Self {
|
||||
default_derives: Derives::with_defaults(crate_path),
|
||||
specific_type_derives: Default::default(),
|
||||
@@ -117,7 +116,7 @@ impl Derives {
|
||||
|
||||
/// Creates a new instance of `Derives` with the `crate_path` prepended
|
||||
/// to the set of default derives that reside in `subxt`.
|
||||
pub fn with_defaults(crate_path: &CratePath) -> Self {
|
||||
pub fn with_defaults(crate_path: &syn::Path) -> Self {
|
||||
let mut derives = HashSet::new();
|
||||
let mut attributes = HashSet::new();
|
||||
|
||||
@@ -148,7 +147,7 @@ impl Derives {
|
||||
}
|
||||
|
||||
/// Add `#crate_path::ext::codec::CompactAs` to the derives.
|
||||
pub fn insert_codec_compact_as(&mut self, crate_path: &CratePath) {
|
||||
pub fn insert_codec_compact_as(&mut self, crate_path: &syn::Path) {
|
||||
self.insert_derive(parse_quote!(#crate_path::ext::codec::CompactAs));
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ pub struct TypeGenerator<'a> {
|
||||
/// Set of derives with which to annotate generated types.
|
||||
derives: DerivesRegistry,
|
||||
/// The `subxt` crate access path in the generated code.
|
||||
crate_path: CratePath,
|
||||
crate_path: syn::Path,
|
||||
/// True if codegen should generate the documentation for the API.
|
||||
should_gen_docs: bool,
|
||||
}
|
||||
@@ -53,7 +53,7 @@ impl<'a> TypeGenerator<'a> {
|
||||
root_mod: &'static str,
|
||||
type_substitutes: TypeSubstitutes,
|
||||
derives: DerivesRegistry,
|
||||
crate_path: CratePath,
|
||||
crate_path: syn::Path,
|
||||
should_gen_docs: bool,
|
||||
) -> Self {
|
||||
let root_mod_ident = Ident::new(root_mod, Span::call_site());
|
||||
@@ -334,55 +334,3 @@ impl Module {
|
||||
&self.root_mod
|
||||
}
|
||||
}
|
||||
|
||||
/// A newtype wrapper which stores the path to the Subxt crate.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CratePath(syn::Path);
|
||||
|
||||
impl CratePath {
|
||||
/// Create a new `CratePath` from a `syn::Path`.
|
||||
pub fn new(path: syn::Path) -> Self {
|
||||
Self(path)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for CratePath {
|
||||
fn default() -> Self {
|
||||
Self(syn::parse_quote!(::subxt))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<syn::Path> for CratePath {
|
||||
fn from(path: syn::Path) -> Self {
|
||||
CratePath::new(path)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for CratePath {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
self.0.to_tokens(tokens)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for CratePath {
|
||||
fn from(crate_path: &str) -> Self {
|
||||
Self(syn::parse_str(crate_path).unwrap_or_else(|err| {
|
||||
panic!("failed converting {crate_path:?} to `syn::Path`: {err:?}");
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for CratePath {
|
||||
fn from(crate_path: String) -> Self {
|
||||
CratePath::from(crate_path.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Option<String>> for CratePath {
|
||||
fn from(maybe_crate_path: Option<String>) -> Self {
|
||||
match maybe_crate_path {
|
||||
None => CratePath::default(),
|
||||
Some(crate_path) => crate_path.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
use crate::{error::TypeSubstitutionError, CratePath};
|
||||
use crate::error::TypeSubstitutionError;
|
||||
use std::{borrow::Borrow, collections::HashMap};
|
||||
use syn::{parse_quote, spanned::Spanned as _};
|
||||
|
||||
@@ -55,7 +55,7 @@ impl TypeSubstitutes {
|
||||
///
|
||||
/// The `crate_path` denotes the `subxt` crate access path in the
|
||||
/// generated code.
|
||||
pub fn with_default_substitutes(crate_path: &CratePath) -> Self {
|
||||
pub fn with_default_substitutes(crate_path: &syn::Path) -> Self {
|
||||
// Some hardcoded default type substitutes, can be overridden by user
|
||||
let defaults = [
|
||||
(
|
||||
|
||||
+22
-22
@@ -34,7 +34,7 @@ fn generate_struct_with_primitives() {
|
||||
registry.register_type(&meta_type::<S>());
|
||||
let portable_types: PortableRegistry = registry.into();
|
||||
|
||||
let crate_path = "::subxt_path".into();
|
||||
let crate_path = syn::parse_str("::subxt_path").unwrap();
|
||||
let type_gen = TypeGenerator::new(
|
||||
&portable_types,
|
||||
"root",
|
||||
@@ -86,7 +86,7 @@ fn generate_struct_with_a_struct_field() {
|
||||
registry.register_type(&meta_type::<Parent>());
|
||||
let portable_types: PortableRegistry = registry.into();
|
||||
|
||||
let crate_path = "::subxt_path".into();
|
||||
let crate_path = syn::parse_str("::subxt_path").unwrap();
|
||||
let type_gen = TypeGenerator::new(
|
||||
&portable_types,
|
||||
"root",
|
||||
@@ -140,7 +140,7 @@ fn generate_tuple_struct() {
|
||||
registry.register_type(&meta_type::<Parent>());
|
||||
let portable_types: PortableRegistry = registry.into();
|
||||
|
||||
let crate_path = "::subxt_path".into();
|
||||
let crate_path = syn::parse_str("::subxt_path").unwrap();
|
||||
let type_gen = TypeGenerator::new(
|
||||
&portable_types,
|
||||
"root",
|
||||
@@ -231,7 +231,7 @@ fn derive_compact_as_for_uint_wrapper_structs() {
|
||||
registry.register_type(&meta_type::<TSu128>());
|
||||
let portable_types: PortableRegistry = registry.into();
|
||||
|
||||
let crate_path = "::subxt_path".into();
|
||||
let crate_path = syn::parse_str("::subxt_path").unwrap();
|
||||
let type_gen = TypeGenerator::new(
|
||||
&portable_types,
|
||||
"root",
|
||||
@@ -328,7 +328,7 @@ fn generate_enum() {
|
||||
registry.register_type(&meta_type::<E>());
|
||||
let portable_types: PortableRegistry = registry.into();
|
||||
|
||||
let crate_path = "::subxt_path".into();
|
||||
let crate_path = syn::parse_str("::subxt_path").unwrap();
|
||||
let type_gen = TypeGenerator::new(
|
||||
&portable_types,
|
||||
"root",
|
||||
@@ -392,7 +392,7 @@ fn compact_fields() {
|
||||
registry.register_type(&meta_type::<E>());
|
||||
let portable_types: PortableRegistry = registry.into();
|
||||
|
||||
let crate_path = "::subxt_path".into();
|
||||
let crate_path = syn::parse_str("::subxt_path").unwrap();
|
||||
let type_gen = TypeGenerator::new(
|
||||
&portable_types,
|
||||
"root",
|
||||
@@ -460,7 +460,7 @@ fn compact_generic_parameter() {
|
||||
registry.register_type(&meta_type::<S>());
|
||||
let portable_types: PortableRegistry = registry.into();
|
||||
|
||||
let crate_path = "::subxt_path".into();
|
||||
let crate_path = syn::parse_str("::subxt_path").unwrap();
|
||||
let type_gen = TypeGenerator::new(
|
||||
&portable_types,
|
||||
"root",
|
||||
@@ -507,7 +507,7 @@ fn generate_array_field() {
|
||||
registry.register_type(&meta_type::<S>());
|
||||
let portable_types: PortableRegistry = registry.into();
|
||||
|
||||
let crate_path = "::subxt_path".into();
|
||||
let crate_path = syn::parse_str("::subxt_path").unwrap();
|
||||
let type_gen = TypeGenerator::new(
|
||||
&portable_types,
|
||||
"root",
|
||||
@@ -550,7 +550,7 @@ fn option_fields() {
|
||||
registry.register_type(&meta_type::<S>());
|
||||
let portable_types: PortableRegistry = registry.into();
|
||||
|
||||
let crate_path = "::subxt_path".into();
|
||||
let crate_path = syn::parse_str("::subxt_path").unwrap();
|
||||
let type_gen = TypeGenerator::new(
|
||||
&portable_types,
|
||||
"root",
|
||||
@@ -596,7 +596,7 @@ fn box_fields_struct() {
|
||||
registry.register_type(&meta_type::<S>());
|
||||
let portable_types: PortableRegistry = registry.into();
|
||||
|
||||
let crate_path = "::subxt_path".into();
|
||||
let crate_path = syn::parse_str("::subxt_path").unwrap();
|
||||
let type_gen = TypeGenerator::new(
|
||||
&portable_types,
|
||||
"root",
|
||||
@@ -642,7 +642,7 @@ fn box_fields_enum() {
|
||||
registry.register_type(&meta_type::<E>());
|
||||
let portable_types: PortableRegistry = registry.into();
|
||||
|
||||
let crate_path = "::subxt_path".into();
|
||||
let crate_path = syn::parse_str("::subxt_path").unwrap();
|
||||
let type_gen = TypeGenerator::new(
|
||||
&portable_types,
|
||||
"root",
|
||||
@@ -688,7 +688,7 @@ fn range_fields() {
|
||||
registry.register_type(&meta_type::<S>());
|
||||
let portable_types: PortableRegistry = registry.into();
|
||||
|
||||
let crate_path = "::subxt_path".into();
|
||||
let crate_path = syn::parse_str("::subxt_path").unwrap();
|
||||
let type_gen = TypeGenerator::new(
|
||||
&portable_types,
|
||||
"root",
|
||||
@@ -738,7 +738,7 @@ fn generics() {
|
||||
registry.register_type(&meta_type::<Bar>());
|
||||
let portable_types: PortableRegistry = registry.into();
|
||||
|
||||
let crate_path = "::subxt_path".into();
|
||||
let crate_path = syn::parse_str("::subxt_path").unwrap();
|
||||
let type_gen = TypeGenerator::new(
|
||||
&portable_types,
|
||||
"root",
|
||||
@@ -795,7 +795,7 @@ fn generics_nested() {
|
||||
registry.register_type(&meta_type::<Bar<bool>>());
|
||||
let portable_types: PortableRegistry = registry.into();
|
||||
|
||||
let crate_path = "::subxt_path".into();
|
||||
let crate_path = syn::parse_str("::subxt_path").unwrap();
|
||||
let type_gen = TypeGenerator::new(
|
||||
&portable_types,
|
||||
"root",
|
||||
@@ -852,7 +852,7 @@ fn generate_bitvec() {
|
||||
registry.register_type(&meta_type::<S>());
|
||||
let portable_types: PortableRegistry = registry.into();
|
||||
|
||||
let crate_path = "::subxt_path".into();
|
||||
let crate_path = syn::parse_str("::subxt_path").unwrap();
|
||||
let type_gen = TypeGenerator::new(
|
||||
&portable_types,
|
||||
"root",
|
||||
@@ -911,7 +911,7 @@ fn generics_with_alias_adds_phantom_data_marker() {
|
||||
registry.register_type(&meta_type::<UnnamedFields<bool, bool>>());
|
||||
let portable_types: PortableRegistry = registry.into();
|
||||
|
||||
let crate_path = "::subxt_path".into();
|
||||
let crate_path = syn::parse_str("::subxt_path").unwrap();
|
||||
let type_gen = TypeGenerator::new(
|
||||
&portable_types,
|
||||
"root",
|
||||
@@ -982,7 +982,7 @@ fn modules() {
|
||||
registry.register_type(&meta_type::<m::c::Foo>());
|
||||
let portable_types: PortableRegistry = registry.into();
|
||||
|
||||
let crate_path = "::subxt_path".into();
|
||||
let crate_path = syn::parse_str("::subxt_path").unwrap();
|
||||
let type_gen = TypeGenerator::new(
|
||||
&portable_types,
|
||||
"root",
|
||||
@@ -1051,7 +1051,7 @@ fn dont_force_struct_names_camel_case() {
|
||||
registry.register_type(&meta_type::<AB>());
|
||||
let portable_types: PortableRegistry = registry.into();
|
||||
|
||||
let crate_path = "::subxt_path".into();
|
||||
let crate_path = syn::parse_str("::subxt_path").unwrap();
|
||||
let type_gen = TypeGenerator::new(
|
||||
&portable_types,
|
||||
"root",
|
||||
@@ -1094,7 +1094,7 @@ fn apply_user_defined_derives_for_all_types() {
|
||||
registry.register_type(&meta_type::<A>());
|
||||
let portable_types: PortableRegistry = registry.into();
|
||||
|
||||
let crate_path = "::subxt_path".into();
|
||||
let crate_path = syn::parse_str("::subxt_path").unwrap();
|
||||
// configure derives
|
||||
let mut derives = DerivesRegistry::with_default_derives(&crate_path);
|
||||
derives.extend_for_all(
|
||||
@@ -1156,7 +1156,7 @@ fn apply_user_defined_derives_for_specific_types() {
|
||||
registry.register_type(&meta_type::<A>());
|
||||
let portable_types: PortableRegistry = registry.into();
|
||||
|
||||
let crate_path = "::subxt_path".into();
|
||||
let crate_path = syn::parse_str("::subxt_path").unwrap();
|
||||
// configure derives
|
||||
let mut derives = DerivesRegistry::with_default_derives(&crate_path);
|
||||
// for all types
|
||||
@@ -1233,7 +1233,7 @@ fn opt_out_from_default_derives() {
|
||||
registry.register_type(&meta_type::<A>());
|
||||
let portable_types: PortableRegistry = registry.into();
|
||||
|
||||
let crate_path = "::subxt_path".into();
|
||||
let crate_path = syn::parse_str("::subxt_path").unwrap();
|
||||
// configure derives
|
||||
let mut derives = DerivesRegistry::new();
|
||||
derives.extend_for_all(
|
||||
@@ -1293,7 +1293,7 @@ fn opt_out_from_default_substitutes() {
|
||||
registry.register_type(&meta_type::<S>());
|
||||
let portable_types: PortableRegistry = registry.into();
|
||||
|
||||
let crate_path = "::subxt_path".into();
|
||||
let crate_path = syn::parse_str("::subxt_path").unwrap();
|
||||
let type_gen = TypeGenerator::new(
|
||||
&portable_types,
|
||||
"root",
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
use crate::error::CodegenError;
|
||||
|
||||
use super::{
|
||||
CompositeDef, CompositeDefFields, CratePath, Derives, TypeDefParameters, TypeGenerator,
|
||||
TypeParameter,
|
||||
CompositeDef, CompositeDefFields, Derives, TypeDefParameters, TypeGenerator, TypeParameter,
|
||||
};
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{format_ident, quote};
|
||||
@@ -34,7 +33,7 @@ impl TypeDefGen {
|
||||
pub fn from_type(
|
||||
ty: &Type<PortableForm>,
|
||||
type_gen: &TypeGenerator,
|
||||
crate_path: &CratePath,
|
||||
crate_path: &syn::Path,
|
||||
should_gen_docs: bool,
|
||||
) -> Result<Self, CodegenError> {
|
||||
let derives = type_gen.type_derives(ty)?;
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
use crate::CratePath;
|
||||
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::format_ident;
|
||||
use scale_info::{form::PortableForm, Path, TypeDefPrimitive};
|
||||
@@ -121,12 +119,12 @@ pub enum TypePathType {
|
||||
Compact {
|
||||
inner: Box<TypePath>,
|
||||
is_field: bool,
|
||||
crate_path: CratePath,
|
||||
crate_path: syn::Path,
|
||||
},
|
||||
BitVec {
|
||||
bit_order_type: Box<TypePath>,
|
||||
bit_store_type: Box<TypePath>,
|
||||
crate_path: CratePath,
|
||||
crate_path: syn::Path,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
// 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.
|
||||
|
||||
//! Utilities to help with fetching and decoding metadata.
|
||||
|
||||
mod fetch_metadata;
|
||||
|
||||
// easy access to this type needed for fetching metadata:
|
||||
pub use jsonrpsee::client_transport::ws::Url;
|
||||
|
||||
pub use fetch_metadata::{
|
||||
fetch_metadata_bytes, fetch_metadata_bytes_blocking, fetch_metadata_hex,
|
||||
fetch_metadata_hex_blocking, MetadataVersion,
|
||||
};
|
||||
Reference in New Issue
Block a user