diff --git a/crates/metadata/src/specs.rs b/crates/metadata/src/specs.rs index 437916cd56e..ad599de8c47 100644 --- a/crates/metadata/src/specs.rs +++ b/crates/metadata/src/specs.rs @@ -14,7 +14,10 @@ #![allow(clippy::new_ret_no_self)] -use crate::serde_hex; +use crate::{ + serde_hex, + utils::trim_extra_whitespace, +}; #[cfg(not(feature = "std"))] use alloc::{ format, @@ -367,7 +370,10 @@ impl ConstructorSpecBuilder { { let mut this = self; debug_assert!(this.spec.docs.is_empty()); - this.spec.docs = docs.into_iter().map(str::trim).collect::>(); + this.spec.docs = docs + .into_iter() + .map(trim_extra_whitespace) + .collect::>(); this } } @@ -586,7 +592,10 @@ impl MessageSpecBuilder { { let mut this = self; debug_assert!(this.spec.docs.is_empty()); - this.spec.docs = docs.into_iter().collect::>(); + this.spec.docs = docs + .into_iter() + .map(trim_extra_whitespace) + .collect::>(); this } } diff --git a/crates/metadata/src/tests.rs b/crates/metadata/src/tests.rs index 44d5d8492de..6f782407261 100644 --- a/crates/metadata/src/tests.rs +++ b/crates/metadata/src/tests.rs @@ -176,6 +176,7 @@ fn spec_contract_json() { ) } +/// Tests correct trimming of a simple comment with extra spaces #[test] fn trim_docs() { // given @@ -206,3 +207,49 @@ fn trim_docs() { ); assert_eq!(deserialized.docs, compact_spec.docs); } + +/// Tests correct trimming of a complex comment with a code snippet +#[test] +fn trim_docs_with_code() { + // given + let label = "foo"; + let cs = ConstructorSpec::from_label(label) + .selector(123_456_789u32.to_be_bytes()) + .docs(vec![ + " Example ", + " ```", + " fn test() {", + " \"Hello, World\"", + " }", + " ```", + ]) + .payable(Default::default()) + .done(); + let mut registry = Registry::new(); + let compact_spec = cs.into_portable(&mut registry); + + // when + let json = serde_json::to_value(&compact_spec).unwrap(); + let deserialized: ConstructorSpec = + serde_json::from_value(json.clone()).unwrap(); + + // then + assert_eq!( + json, + json!({ + "label": "foo", + "payable": false, + "selector": "0x075bcd15", + "args": [], + "docs": [ + "Example", + "```", + "fn test() {", + " \"Hello, World\"", + "}", + "```" + ] + }) + ); + assert_eq!(deserialized.docs, compact_spec.docs); +} diff --git a/crates/metadata/src/utils.rs b/crates/metadata/src/utils.rs index e09458c3e13..225d532b989 100644 --- a/crates/metadata/src/utils.rs +++ b/crates/metadata/src/utils.rs @@ -13,6 +13,7 @@ // limitations under the License. use crate::serde_hex; +use std::str; /// Serializes the given bytes as byte string. pub fn serialize_as_byte_str(bytes: &[u8], serializer: S) -> Result @@ -56,3 +57,12 @@ where deserializer.deserialize_str(Visitor) } + +/// Strips a single whitespace at the start and removes trailing spaces +pub fn trim_extra_whitespace(item: &str) -> &str { + if let Some(stripped) = item.strip_prefix(' ') { + stripped.trim_end() + } else { + item.trim_end() + } +}