Skip to content

Commit

Permalink
Add --derive-for-type to cli (#708)
Browse files Browse the repository at this point in the history
* Add `--derive-for-type` to cli

* Remove clippy warnings
  • Loading branch information
fmiguelgarcia authored Nov 23, 2022
1 parent 702e87e commit a80d6cf
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 21 deletions.
42 changes: 31 additions & 11 deletions cli/src/commands/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,38 +28,52 @@ pub struct Opts {
/// Additional derives
#[clap(long = "derive")]
derives: Vec<String>,
/// Additional derives for a given type.
///
/// Example `--derive-for-type my_module::my_type=serde::Serialize`.
#[clap(long = "derive-for-type", value_parser = derive_for_type_parser)]
derives_for_type: Vec<(String, String)>,
/// The `subxt` crate access path in the generated code.
/// Defaults to `::subxt`.
#[clap(long = "crate")]
crate_path: Option<String>,
}

fn derive_for_type_parser(src: &str) -> Result<(String, String), String> {
let (ty, derive) = src
.split_once('=')
.ok_or_else(|| String::from("Invalid pattern for `derive-for-type`. It should be `type=derive`, like `my_type=serde::Serialize`"))?;

Ok((ty.to_string(), derive.to_string()))
}

pub async fn run(opts: Opts) -> color_eyre::Result<()> {
if let Some(file) = opts.file.as_ref() {
let bytes = if let Some(file) = opts.file.as_ref() {
if opts.url.is_some() {
eyre::bail!("specify one of `--url` or `--file` but not both")
};

let mut file = fs::File::open(file)?;
let mut bytes = Vec::new();
file.read_to_end(&mut bytes)?;
codegen(&bytes, opts.derives, opts.crate_path)?;
return Ok(())
}
bytes
} else {
let url = opts.url.unwrap_or_else(|| {
"http://localhost:9933"
.parse::<Uri>()
.expect("default url is valid")
});
subxt_codegen::utils::fetch_metadata_bytes(&url).await?
};

let url = opts.url.unwrap_or_else(|| {
"http://localhost:9933"
.parse::<Uri>()
.expect("default url is valid")
});
let bytes = subxt_codegen::utils::fetch_metadata_bytes(&url).await?;
codegen(&bytes, opts.derives, opts.crate_path)?;
codegen(&bytes, opts.derives, opts.derives_for_type, opts.crate_path)?;
Ok(())
}

fn codegen(
metadata_bytes: &[u8],
raw_derives: Vec<String>,
derives_for_type: Vec<(String, String)>,
crate_path: Option<String>,
) -> color_eyre::Result<()> {
let item_mod = syn::parse_quote!(
Expand All @@ -75,6 +89,12 @@ fn codegen(
let mut derives = DerivesRegistry::new(&crate_path);
derives.extend_for_all(p.into_iter());

for (ty, derive) in derives_for_type.into_iter() {
let ty = syn::parse_str(&ty)?;
let derive = syn::parse_str(&derive)?;
derives.extend_for_type(ty, std::iter::once(derive), &crate_path)
}

let runtime_api = subxt_codegen::generate_runtime_api_from_bytes(
item_mod,
metadata_bytes,
Expand Down
2 changes: 1 addition & 1 deletion examples/examples/storage_iterating.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {

println!("\nExample 1. Obtained keys:");
while let Some((key, value)) = iter.next().await? {
println!("Key: 0x{}", hex::encode(&key));
println!("Key: 0x{}", hex::encode(key));
println!(" Value: {}", value);
}
}
Expand Down
2 changes: 1 addition & 1 deletion macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ pub fn subxt(args: TokenStream, input: TokenStream) -> TokenStream {
let path = root_path.join(rest_of_path);
subxt_codegen::generate_runtime_api_from_path(
item_mod,
&path,
path,
derives_registry,
crate_path,
)
Expand Down
4 changes: 2 additions & 2 deletions testing/test-runtime/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ async fn run() {
// Save metadata to a file:
let out_dir = env::var_os("OUT_DIR").unwrap();
let metadata_path = Path::new(&out_dir).join("metadata.scale");
fs::write(&metadata_path, &metadata_bytes.0).expect("Couldn't write metadata output");
fs::write(&metadata_path, metadata_bytes.0).expect("Couldn't write metadata output");

// Write out our expression to generate the runtime API to a file. Ideally, we'd just write this code
// in lib.rs, but we must pass a string literal (and not `concat!(..)`) as an arg to `runtime_metadata_path`,
Expand All @@ -101,7 +101,7 @@ async fn run() {
.expect("Path to metadata should be stringifiable")
);
let runtime_path = Path::new(&out_dir).join("runtime.rs");
fs::write(&runtime_path, runtime_api_contents)
fs::write(runtime_path, runtime_api_contents)
.expect("Couldn't write runtime rust output");

let substrate_path =
Expand Down
8 changes: 4 additions & 4 deletions testing/ui-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,21 @@ fn ui_tests() {
t.pass("src/correct/*.rs");

// Check that storage maps with no keys are handled properly.
t.pass(&m.path_to_ui_test_for_metadata(
t.pass(m.path_to_ui_test_for_metadata(
"storage_map_no_keys",
storage::metadata_storage_map_no_keys(),
));

// Test that the codegen can handle the different types of DispatchError.
t.pass(&m.path_to_ui_test_for_metadata(
t.pass(m.path_to_ui_test_for_metadata(
"named_field_dispatch_error",
dispatch_errors::metadata_named_field_dispatch_error(),
));
t.pass(&m.path_to_ui_test_for_metadata(
t.pass(m.path_to_ui_test_for_metadata(
"legacy_dispatch_error",
dispatch_errors::metadata_legacy_dispatch_error(),
));
t.pass(&m.path_to_ui_test_for_metadata(
t.pass(m.path_to_ui_test_for_metadata(
"array_dispatch_error",
dispatch_errors::metadata_array_dispatch_error(),
));
Expand Down
4 changes: 2 additions & 2 deletions testing/ui-tests/src/utils/metadata_test_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ impl MetadataTestRunner {

std::fs::create_dir_all(&tmp_dir).expect("could not create tmp ui test dir");
// Write metadata to tmp folder:
std::fs::write(&tmp_metadata_path, &encoded_metadata).unwrap();
std::fs::write(&tmp_metadata_path, encoded_metadata).unwrap();
// Write test file to tmp folder (it'll be moved by trybuild):
std::fs::write(&tmp_rust_path, &rust_file).unwrap();
std::fs::write(&tmp_rust_path, rust_file).unwrap();

tmp_rust_path
}
Expand Down

0 comments on commit a80d6cf

Please sign in to comment.