rain_metadata/meta/
normalize.rs1use super::{
2 KnownMeta,
3 super::error::Error,
4 types::{authoring::v1::AuthoringMeta, authoring::v2::AuthoringMetaV2},
5};
6
7impl KnownMeta {
8 pub fn normalize(&self, data: &[u8]) -> Result<Vec<u8>, Error> {
10 Ok(match self {
11 KnownMeta::AuthoringMetaV1 => {
12 match AuthoringMeta::abi_decode(data) {
16 Ok(am) => am.abi_encode_validate()?,
17 _ => AuthoringMeta::abi_encode_validate(
18 &serde_json::from_str::<AuthoringMeta>(std::str::from_utf8(data)?)?,
19 )?,
20 }
21 }
22 KnownMeta::AuthoringMetaV2 => {
23 AuthoringMetaV2::abi_decode_validate(data)
27 .map_err(|e| Error::InvalidInput(e.to_string()))?;
28 data.to_vec()
29 }
30 _ => data.to_vec(),
33 })
34 }
35}
36
37#[cfg(all(test, not(target_family = "wasm")))]
38mod tests {
39 use alloy::sol_types::SolValue;
40 use crate::error::Error;
41 use crate::meta::types::authoring::v1::{AuthoringMeta, AuthoringMetaItem};
42 use crate::meta::types::authoring::v2::AuthoringMetaV2Sol;
43 use crate::meta::KnownMeta;
44
45 fn authoring_meta_v2_abi(word: [u8; 32], description: &str) -> Vec<u8> {
46 vec![AuthoringMetaV2Sol {
47 word: word.into(),
48 description: description.to_string(),
49 }]
50 .abi_encode()
51 }
52
53 #[test]
57 fn test_normalize_op_v1_is_a_passthrough() {
58 let bytes = b"{ \"name\" : \"add\" }";
59 assert_eq!(KnownMeta::OpV1.normalize(bytes).unwrap(), bytes.to_vec());
60 }
61
62 #[test]
66 fn test_normalize_solidity_abi_v2_is_a_passthrough() {
67 let inputs: [&[u8]; 3] = [b"[ ]", b"not json at all", &[0xff, 0xfe]];
68 for bytes in inputs {
69 assert_eq!(
70 KnownMeta::SolidityAbiV2.normalize(bytes).unwrap(),
71 bytes.to_vec()
72 );
73 }
74 }
75
76 #[test]
80 fn test_normalize_interpreter_caller_meta_v1_is_a_passthrough() {
81 let bytes = br#"{"name":"Test Caller","abiName":"TestCaller","methods":[]}"#;
82 assert_eq!(
83 KnownMeta::InterpreterCallerMetaV1.normalize(bytes).unwrap(),
84 bytes.to_vec()
85 );
86 }
87
88 #[test]
90 fn test_normalize_passthrough_for_binary_metas() {
91 let data = vec![0x00, 0x01, 0xff];
92 assert_eq!(
93 KnownMeta::ExpressionDeployerV2BytecodeV1
94 .normalize(&data)
95 .unwrap(),
96 data
97 );
98 }
99
100 fn sample_authoring_meta() -> AuthoringMeta {
101 serde_json::from_str(
102 r#"[{"word":"stack","description":"Copies an existing value from the stack.","operandParserOffset":16}]"#,
103 )
104 .unwrap()
105 }
106
107 #[test]
110 fn test_normalize_authoring_meta_v1_abi_path() {
111 let authoring_meta = sample_authoring_meta();
112 let abi = authoring_meta.abi_encode_validate().unwrap();
113 let normalized = KnownMeta::AuthoringMetaV1.normalize(&abi).unwrap();
114 assert_eq!(normalized, abi);
115 }
116
117 #[test]
120 fn test_normalize_authoring_meta_v1_abi_invalid_rejected() {
121 let invalid = AuthoringMeta(vec![AuthoringMetaItem {
122 word: "NOTKEBAB".to_string(),
123 operand_parser_offset: 0,
124 description: "some description".to_string(),
125 }]);
126 let abi = invalid.abi_encode().unwrap();
128 let result = KnownMeta::AuthoringMetaV1.normalize(&abi);
129 assert!(matches!(result, Err(Error::ValidationErrors(_))));
130 }
131
132 #[test]
135 fn test_normalize_authoring_meta_v1_json_fallback() {
136 let json = r#"[{"word":"stack","description":"Copies an existing value from the stack.","operandParserOffset":16}]"#;
137 let expected = sample_authoring_meta().abi_encode_validate().unwrap();
138 let normalized = KnownMeta::AuthoringMetaV1
139 .normalize(json.as_bytes())
140 .unwrap();
141 assert_eq!(normalized, expected);
142 assert_ne!(normalized, json.as_bytes().to_vec());
143 }
144
145 #[test]
148 fn test_normalize_authoring_meta_v2_abi_passthrough() {
149 let mut word = [0u8; 32];
150 word[..5].copy_from_slice(b"stack");
151 let abi = authoring_meta_v2_abi(word, "Copies an existing value from the stack.");
152 assert_eq!(KnownMeta::AuthoringMetaV2.normalize(&abi).unwrap(), abi);
153 }
154
155 #[test]
158 fn test_normalize_authoring_meta_v2_rejects_arbitrary_bytes() {
159 assert!(matches!(
160 KnownMeta::AuthoringMetaV2.normalize(&[0xde, 0xad]),
161 Err(Error::InvalidInput(_))
162 ));
163 assert!(matches!(
164 KnownMeta::AuthoringMetaV2.normalize(b"[]"),
165 Err(Error::InvalidInput(_))
166 ));
167 }
168
169 #[test]
172 fn test_normalize_authoring_meta_v2_rejects_non_utf8_word() {
173 let mut word = [0u8; 32];
174 word[0] = 0xc3;
176 word[1] = 0x28;
177 let abi = authoring_meta_v2_abi(word, "bad word bytes");
178 assert!(matches!(
179 KnownMeta::AuthoringMetaV2.normalize(&abi),
180 Err(Error::InvalidInput(_))
181 ));
182 }
183
184 #[test]
187 fn test_normalize_authoring_meta_v2_rejects_a_word_outside_the_grammar() {
188 let mut word = [0u8; 32];
189 word[..3].copy_from_slice(b"BAD");
190 let abi = authoring_meta_v2_abi(word, "fine");
191 assert!(matches!(
192 KnownMeta::AuthoringMetaV2.normalize(&abi),
193 Err(Error::InvalidInput(_))
194 ));
195 }
196
197 #[test]
200 fn test_normalize_default_arm_passthrough() {
201 let data = b"some dotrain text".to_vec();
202 assert_eq!(KnownMeta::DotrainV1.normalize(&data).unwrap(), data);
203 let binary = vec![0xffu8, 0x00, 0x01];
204 assert_eq!(KnownMeta::RainlangV1.normalize(&binary).unwrap(), binary);
205 }
206}