From 9f76c45cc30fddfe52379ca13eb65c33b11dc531 Mon Sep 17 00:00:00 2001 From: Guillaume Potier Date: Mon, 28 Oct 2024 16:30:52 +0100 Subject: [PATCH] Improve `forest-tool shed openrpc` output (#4943) --- CHANGELOG.md | 4 ++++ src/rpc/mod.rs | 36 +++++++++++++++++++++++++------- src/rpc/reflect/mod.rs | 14 +++++++------ src/tool/subcommands/shed_cmd.rs | 24 ++++++++++++--------- 4 files changed, 54 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c59ec50e009..ae5638103af8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,10 @@ - [#4706](https://github.com/ChainSafe/forest/issues/4706) Add support for the `Filecoin.EthSendRawTransaction` RPC method. +- [#4943](https://github.com/ChainSafe/forest/pull/4943) Add generation of + method aliases for `forest-tool shed openrpc` subcommand and sort all methods + in lexicographic order. + ### Changed ### Removed diff --git a/src/rpc/mod.rs b/src/rpc/mod.rs index d73e77e22b4f..f8c4ac553c23 100644 --- a/src/rpc/mod.rs +++ b/src/rpc/mod.rs @@ -592,16 +592,36 @@ pub fn openrpc(path: ApiPath, include: Option<&[&str]>) -> openrpc_types::OpenRP if <$ty>::API_PATHS.contains(path) { match include { Some(include) => match include.contains(&<$ty>::NAME) { - true => methods.push(openrpc_types::ReferenceOr::Item(<$ty>::openrpc( - &mut gen, - ParamStructure::ByPosition, - ))), + true => { + methods.push(openrpc_types::ReferenceOr::Item(<$ty>::openrpc( + &mut gen, + ParamStructure::ByPosition, + &<$ty>::NAME, + ))); + if let Some(alias) = &<$ty>::NAME_ALIAS { + methods.push(openrpc_types::ReferenceOr::Item(<$ty>::openrpc( + &mut gen, + ParamStructure::ByPosition, + &alias, + ))); + } + } false => {} }, - None => methods.push(openrpc_types::ReferenceOr::Item(<$ty>::openrpc( - &mut gen, - ParamStructure::ByPosition, - ))), + None => { + methods.push(openrpc_types::ReferenceOr::Item(<$ty>::openrpc( + &mut gen, + ParamStructure::ByPosition, + &<$ty>::NAME, + ))); + if let Some(alias) = &<$ty>::NAME_ALIAS { + methods.push(openrpc_types::ReferenceOr::Item(<$ty>::openrpc( + &mut gen, + ParamStructure::ByPosition, + &alias, + ))); + } + } } } }; diff --git a/src/rpc/reflect/mod.rs b/src/rpc/reflect/mod.rs index 099f0a84f13e..1185a135428a 100644 --- a/src/rpc/reflect/mod.rs +++ b/src/rpc/reflect/mod.rs @@ -150,20 +150,22 @@ pub trait RpcMethodExt: RpcMethod { } } /// Generate a full `OpenRPC` method definition for this endpoint. - fn openrpc<'de>(gen: &mut SchemaGenerator, calling_convention: ParamStructure) -> Method + fn openrpc<'de>( + gen: &mut SchemaGenerator, + calling_convention: ParamStructure, + method_name: &'static str, + ) -> Method where ::LotusJson: JsonSchema + Deserialize<'de>, { Method { - name: String::from(Self::NAME), + name: String::from(method_name), params: itertools::zip_eq(Self::PARAM_NAMES, Self::Params::schemas(gen)) .enumerate() .map(|(pos, (name, (schema, nullable)))| { let required = pos <= Self::N_REQUIRED_PARAMS; if !required && !nullable { - panic!( - "Optional parameter at position {pos} should be of an optional type. method={}, param_name={name}", Self::NAME - ); + panic!("Optional parameter at position {pos} should be of an optional type. method={method_name}, param_name={name}"); } ReferenceOr::Item(ContentDescriptor { name: String::from(name), @@ -175,7 +177,7 @@ pub trait RpcMethodExt: RpcMethod { .collect(), param_structure: Some(calling_convention), result: Some(ReferenceOr::Item(ContentDescriptor { - name: format!("{}.Result", Self::NAME), + name: format!("{}.Result", method_name), schema: gen.subschema_for::<::LotusJson>(), required: Some(!::LotusJson::optional()), ..Default::default() diff --git a/src/tool/subcommands/shed_cmd.rs b/src/tool/subcommands/shed_cmd.rs index 2aa7430c0c9c..2d31540b77f1 100644 --- a/src/tool/subcommands/shed_cmd.rs +++ b/src/tool/subcommands/shed_cmd.rs @@ -16,6 +16,7 @@ use anyhow::Context as _; use base64::{prelude::BASE64_STANDARD, Engine}; use clap::Subcommand; use futures::{StreamExt as _, TryFutureExt as _, TryStreamExt as _}; +use openrpc_types::ReferenceOr; #[derive(Subcommand)] pub enum ShedCommands { @@ -123,17 +124,20 @@ impl ShedCommands { } ShedCommands::Openrpc { include, path } => { let include = include.iter().map(String::as_str).collect::>(); - println!( - "{}", - serde_json::to_string_pretty(&crate::rpc::openrpc( - path, - match include.is_empty() { - true => None, - false => Some(&include), - } - )) - .unwrap() + + let mut openrpc_doc = crate::rpc::openrpc( + path, + match include.is_empty() { + true => None, + false => Some(&include), + }, ); + openrpc_doc.methods.sort_by(|a, b| match (a, b) { + (ReferenceOr::Item(a), ReferenceOr::Item(b)) => a.name.cmp(&b.name), + _ => std::cmp::Ordering::Equal, + }); + + println!("{}", serde_json::to_string_pretty(&openrpc_doc).unwrap()); } } Ok(())