Repository: CosmWasm/sylvia
Pull request #72 (2022-11-17 17:26:58)

Generate Migrate as struct instead of enum


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5de0b56..762e2e0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@ and this project adheres to
 [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
 ## [Unreleased]
+- Fix: Generate Migrate as struct
 
 ## [0.2.1] - 2022-10-19
 
diff --git a/sylvia-derive/src/input.rs b/sylvia-derive/src/input.rs
index d3c8421..fe6aecd 100644
--- a/sylvia-derive/src/input.rs
+++ b/sylvia-derive/src/input.rs
@@ -114,15 +114,12 @@ impl<'a> ImplInput<'a> {
 
     fn emit_messages(&self) -> TokenStream {
         let instantiate = self.emit_struct_msg(MsgType::Instantiate);
+        let migrate = self.emit_struct_msg(MsgType::Migrate);
         let exec_impl =
             self.emit_enum_msg(&Ident::new("ExecMsg", Span::mixed_site()), MsgType::Exec);
         let query_impl =
             self.emit_enum_msg(&Ident::new("QueryMsg", Span::mixed_site()), MsgType::Query);
         let reply = self.emit_enum_msg(&Ident::new("ReplyMsg", Span::mixed_site()), MsgType::Reply);
-        let migrate = self.emit_enum_msg(
-            &Ident::new("MigrateMsg", Span::mixed_site()),
-            MsgType::Migrate,
-        );
         let exec = self.emit_glue_msg(&Ident::new("ExecMsg", Span::mixed_site()), MsgType::Exec);
         let query = self.emit_glue_msg(&Ident::new("QueryMsg", Span::mixed_site()), MsgType::Query);
 
diff --git a/sylvia-derive/src/message.rs b/sylvia-derive/src/message.rs
index 439f898..9db0618 100644
--- a/sylvia-derive/src/message.rs
+++ b/sylvia-derive/src/message.rs
@@ -106,14 +106,16 @@ impl<'a> StructMessage<'a> {
         let (method, msg_attr) = if let Some(method) = methods.next() {
             method
         } else {
-            emit_error!(source.span(), "No instantiation message");
+            if ty == MsgType::Instantiate {
+                emit_error!(source.span(), "No instantiation message");
+            }
             return None;
         };
 
         if let Some((obsolete, _)) = methods.next() {
             emit_error!(
-                obsolete.span(), "More than one instantiation message";
-                note = method.span() => "Instantiation message previously defied here"
+                obsolete.span(), "More than one instantiation or migration message";
+                note = method.span() => "Instantiation/Migration message previously defined here"
             );
         }
 
@@ -140,6 +142,7 @@ impl<'a> StructMessage<'a> {
 
         match &self.msg_attr {
             Instantiate { name } => self.emit_struct(name),
+            Migrate { name } => self.emit_struct(name),
             _ => {
                 emit_error!(Span::mixed_site(), "Invalid message type");
                 quote! {}
diff --git a/sylvia-derive/src/parser.rs b/sylvia-derive/src/parser.rs
index b82ed19..b320604 100644
--- a/sylvia-derive/src/parser.rs
+++ b/sylvia-derive/src/parser.rs
@@ -99,7 +99,7 @@ pub enum MsgAttr {
     Query { resp_type: Option<Ident> },
     Instantiate { name: Ident },
     Reply,
-    Migrate,
+    Migrate { name: Ident },
 }
 
 impl MsgType {
@@ -152,12 +152,6 @@ impl PartialEq<MsgType> for MsgAttr {
 }
 
 impl MsgAttr {
-    fn parse_instantiate(content: ParseBuffer) -> Result<Self> {
-        let name = Ident::new("InstantiateMsg", content.span());
-
-        Ok(Self::Instantiate { name })
-    }
-
     fn parse_query(content: ParseBuffer) -> Result<Self> {
         if content.peek2(Ident) {
             let _: Punct = content.parse()?;
@@ -178,7 +172,7 @@ impl MsgAttr {
             Query { .. } => MsgType::Query,
             Instantiate { .. } => MsgType::Instantiate,
             Reply => MsgType::Reply,
-            Migrate => MsgType::Migrate,
+            Migrate { .. } => MsgType::Migrate,
         }
     }
 }
@@ -194,11 +188,13 @@ impl Parse for MsgAttr {
         } else if ty == "query" {
             Self::parse_query(content)
         } else if ty == "instantiate" {
-            Self::parse_instantiate(content)
+            let name = Ident::new("InstantiateMsg", content.span());
+            Ok(Self::Instantiate { name })
         } else if ty == "reply" {
             Ok(Self::Reply)
         } else if ty == "migrate" {
-            Ok(Self::Migrate)
+            let name = Ident::new("MigrateMsg", content.span());
+            Ok(Self::Migrate { name })
         } else {
             Err(Error::new(
                 ty.span(),


Test patch:
diff --git a/sylvia/tests/messages_generation.rs b/sylvia/tests/messages_generation.rs
index b52e4cf..2ba2c96 100644
--- a/sylvia/tests/messages_generation.rs
+++ b/sylvia/tests/messages_generation.rs
@@ -119,7 +119,7 @@ fn contract_messages_constructible() {
     };
     let _ = contract::InstantiateMsg {};
     let reply = contract::ReplyMsg::Reply {};
-    let migrate = contract::MigrateMsg::Migrate {};
+    let _ = contract::MigrateMsg {};
 
     // Ensure no extra variants are generated
     match no_args_exec {
@@ -135,8 +135,4 @@ fn contract_messages_constructible() {
     match reply {
         contract::ReplyMsg::Reply {} => (),
     }
-
-    match migrate {
-        contract::MigrateMsg::Migrate {} => (),
-    }
 }