diff --git a/Cargo.lock b/Cargo.lock index 823804258..8549fb989 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -942,6 +942,7 @@ dependencies = [ "anyhow", "askama", "clap", + "cosmwasm-schema", "cw-schema", "either", "frunk", diff --git a/packages/cw-schema-codegen/Cargo.toml b/packages/cw-schema-codegen/Cargo.toml index aa004d950..5acc60be6 100644 --- a/packages/cw-schema-codegen/Cargo.toml +++ b/packages/cw-schema-codegen/Cargo.toml @@ -9,6 +9,7 @@ publish = false anyhow = "1.0.89" askama = { version = "0.12.1", default-features = false } clap = { version = "4.5.18", features = ["derive"] } +cosmwasm-schema = { version = "=2.2.0-rc.1", path = "../schema" } cw-schema = { version = "=2.2.0-rc.1", path = "../cw-schema" } either = "1.13.0" frunk = "0.4.3" diff --git a/packages/cw-schema-codegen/src/main.rs b/packages/cw-schema-codegen/src/main.rs index 7331768ef..86cd7a2b4 100644 --- a/packages/cw-schema-codegen/src/main.rs +++ b/packages/cw-schema-codegen/src/main.rs @@ -6,6 +6,7 @@ extern crate log; use clap::{Parser, ValueEnum}; use std::{ + collections::HashSet, fs::{self, File}, io::{self, Write}, path::PathBuf, @@ -49,9 +50,38 @@ impl Opts { } } +fn generate_defs( + output: &mut W, + language: Language, + schema: &cw_schema::Schema, +) -> anyhow::Result<()> +where + W: io::Write, +{ + let cw_schema::Schema::V1(schema) = schema else { + bail!("Only schema version 1 is supported") + }; + + schema.definitions.iter().try_for_each(|node| { + debug!("Processing node: {node:?}"); + + match language { + Language::Rust => cw_schema_codegen::rust::process_node(output, schema, node), + Language::Typescript => { + cw_schema_codegen::typescript::process_node(output, schema, node) + } + Language::Go | Language::Python => todo!(), + } + })?; + + Ok(()) +} + fn main() -> anyhow::Result<()> { simple_logger::SimpleLogger::new() .without_timestamps() + .with_level(log::LevelFilter::Info) + .env() .init()?; let opts: Opts = Opts::parse(); @@ -70,24 +100,40 @@ fn main() -> anyhow::Result<()> { ); let schema = fs::read_to_string(&opts.file)?; - let schema: cw_schema::Schema = serde_json::from_str(&schema)?; - let cw_schema::Schema::V1(schema) = schema else { - bail!("Unsupported schema version"); - }; + let schema: cosmwasm_schema::JsonCwApi = serde_json::from_str(&schema)?; let mut output = opts.output()?; - schema.definitions.iter().try_for_each(|node| { - debug!("Processing node: {node:?}"); + if let Some(ref instantiate) = schema.instantiate { + generate_defs(&mut output, opts.language, instantiate)?; + } - match opts.language { - Language::Rust => cw_schema_codegen::rust::process_node(&mut output, &schema, node), - Language::Typescript => { - cw_schema_codegen::typescript::process_node(&mut output, &schema, node) - } - Language::Go | Language::Python => todo!(), + if let Some(ref execute) = schema.execute { + generate_defs(&mut output, opts.language, execute)?; + } + + if let Some(ref query) = schema.query { + generate_defs(&mut output, opts.language, query)?; + } + + if let Some(ref migrate) = schema.migrate { + generate_defs(&mut output, opts.language, migrate)?; + } + + if let Some(ref sudo) = schema.sudo { + generate_defs(&mut output, opts.language, sudo)?; + } + + if let Some(ref responses) = schema.responses { + let responses = responses + .iter() + .map(|(_name, response)| response) + .collect::>(); + + for response in responses { + generate_defs(&mut output, opts.language, response)?; } - })?; + } Ok(()) } diff --git a/packages/cw-schema-codegen/src/rust/mod.rs b/packages/cw-schema-codegen/src/rust/mod.rs index 95c5ac2aa..4f2dc307c 100644 --- a/packages/cw-schema-codegen/src/rust/mod.rs +++ b/packages/cw-schema-codegen/src/rust/mod.rs @@ -41,10 +41,10 @@ fn expand_node_name<'a>( cw_schema::NodeType::Enum { .. } => node.name.as_ref().into(), cw_schema::NodeType::Decimal { precision, signed } => todo!(), - cw_schema::NodeType::Address => todo!(), - cw_schema::NodeType::Checksum => todo!(), + cw_schema::NodeType::Address => "cosmrs::AccountId".into(), + cw_schema::NodeType::Checksum => "cosmrs::tendermint::Hash".into(), cw_schema::NodeType::HexBinary => todo!(), - cw_schema::NodeType::Timestamp => todo!(), + cw_schema::NodeType::Timestamp => "cosmrs::tendermint::Time".into(), cw_schema::NodeType::Unit => Cow::Borrowed("()"), } } diff --git a/packages/cw-schema-codegen/src/typescript/mod.rs b/packages/cw-schema-codegen/src/typescript/mod.rs index 19c6d955a..74f3d9e00 100644 --- a/packages/cw-schema-codegen/src/typescript/mod.rs +++ b/packages/cw-schema-codegen/src/typescript/mod.rs @@ -19,11 +19,7 @@ fn expand_node_name<'a>( cw_schema::NodeType::Double => "number".into(), cw_schema::NodeType::Boolean => "boolean".into(), cw_schema::NodeType::String => "string".into(), - cw_schema::NodeType::Integer { signed, precision } => { - "string".into() - /*let ty = if signed { "i" } else { "u" }; - format!("{ty}{precision}").into()*/ - } + cw_schema::NodeType::Integer { .. } => "string".into(), cw_schema::NodeType::Binary => "Uint8Array".into(), cw_schema::NodeType::Optional { inner } => { let inner = &schema.definitions[inner]; @@ -41,8 +37,8 @@ fn expand_node_name<'a>( } cw_schema::NodeType::Enum { .. } => node.name.as_ref().into(), - cw_schema::NodeType::Decimal { precision, signed } => todo!(), - cw_schema::NodeType::Address => todo!(), + cw_schema::NodeType::Decimal { .. } => "string".into(), + cw_schema::NodeType::Address => "string".into(), cw_schema::NodeType::Checksum => todo!(), cw_schema::NodeType::HexBinary => todo!(), cw_schema::NodeType::Timestamp => todo!(), @@ -51,12 +47,8 @@ fn expand_node_name<'a>( } fn prepare_docs(desc: Option<&str>) -> Cow<'_, [Cow<'_, str>]> { - desc.map(|desc| { - desc.lines() - .map(|line| line.replace('"', "\\\"").into()) - .collect() - }) - .unwrap_or(Cow::Borrowed(&[])) + desc.map(|desc| desc.lines().map(Into::into).collect()) + .unwrap_or(Cow::Borrowed(&[])) } pub fn process_node( diff --git a/packages/cw-schema/src/lib.rs b/packages/cw-schema/src/lib.rs index 659e68e2f..8aaa809b9 100644 --- a/packages/cw-schema/src/lib.rs +++ b/packages/cw-schema/src/lib.rs @@ -19,7 +19,7 @@ pub type DefinitionReference = usize; mod default_impls; #[skip_serializing_none] -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)] #[cfg_attr(feature = "std", derive(::schemars::JsonSchema))] #[serde(rename_all = "camelCase")] pub struct StructProperty { @@ -28,7 +28,7 @@ pub struct StructProperty { } #[skip_serializing_none] -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)] #[cfg_attr(feature = "std", derive(::schemars::JsonSchema))] #[serde(rename_all = "camelCase", untagged)] pub enum StructType { @@ -42,7 +42,7 @@ pub enum StructType { } #[skip_serializing_none] -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)] #[cfg_attr(feature = "std", derive(::schemars::JsonSchema))] #[serde(rename_all = "camelCase")] pub struct EnumCase { @@ -52,7 +52,7 @@ pub struct EnumCase { } #[skip_serializing_none] -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)] #[cfg_attr(feature = "std", derive(::schemars::JsonSchema))] #[serde(rename_all = "camelCase", tag = "type")] pub enum EnumValue { @@ -66,7 +66,7 @@ pub enum EnumValue { } #[skip_serializing_none] -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)] #[cfg_attr(feature = "std", derive(::schemars::JsonSchema))] #[serde(rename_all = "camelCase", tag = "type")] pub enum NodeType { @@ -113,7 +113,7 @@ pub enum NodeType { } #[skip_serializing_none] -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)] #[cfg_attr(feature = "std", derive(::schemars::JsonSchema))] #[serde(rename_all = "camelCase")] pub struct Node { @@ -124,7 +124,7 @@ pub struct Node { } #[skip_serializing_none] -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)] #[cfg_attr(feature = "std", derive(::schemars::JsonSchema))] #[serde(rename_all = "camelCase")] pub struct SchemaV1 { @@ -133,7 +133,7 @@ pub struct SchemaV1 { } #[skip_serializing_none] -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +#[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)] #[cfg_attr(feature = "std", derive(::schemars::JsonSchema))] #[serde(rename_all = "camelCase", tag = "type")] #[non_exhaustive] diff --git a/packages/schema/src/idl.rs b/packages/schema/src/idl.rs index 9f838fbcf..6177636d6 100644 --- a/packages/schema/src/idl.rs +++ b/packages/schema/src/idl.rs @@ -98,17 +98,17 @@ impl Api { } /// A JSON representation of a contract's API. -#[derive(serde::Serialize)] +#[derive(serde::Deserialize, serde::Serialize)] pub struct JsonCwApi { - contract_name: String, - contract_version: String, - idl_version: String, - instantiate: Option, - execute: Option, - query: Option, - migrate: Option, - sudo: Option, - responses: Option>, + pub contract_name: String, + pub contract_version: String, + pub idl_version: String, + pub instantiate: Option, + pub execute: Option, + pub query: Option, + pub migrate: Option, + pub sudo: Option, + pub responses: Option>, } impl JsonCwApi { diff --git a/packages/schema/src/lib.rs b/packages/schema/src/lib.rs index 9b5381d08..628eb1ed3 100644 --- a/packages/schema/src/lib.rs +++ b/packages/schema/src/lib.rs @@ -97,3 +97,6 @@ pub use cosmwasm_schema_derive::write_api; pub use cw_schema; pub use schemars; pub use serde; + +#[doc(hidden)] +pub use self::idl::JsonCwApi;