Skip to main content

rain_metadata/meta/
normalize.rs

1use super::{
2    KnownMeta,
3    super::error::Error,
4    types::{
5        op::v1::OpMeta, authoring::v1::AuthoringMeta, solidity_abi::v2::SolidityAbiMeta,
6        interpreter_caller::v1::InterpreterCallerMeta,
7    },
8};
9
10fn normalize_json<'de, T>(data: &'de [u8]) -> Result<Vec<u8>, Error>
11where
12    T: serde::Deserialize<'de> + serde::Serialize + validator::Validate,
13{
14    let parsed = serde_json::from_str::<T>(std::str::from_utf8(data)?)?;
15    parsed.validate()?;
16    Ok(serde_json::to_string(&parsed)?.as_bytes().to_vec())
17}
18
19impl KnownMeta {
20    /// normalizes meta types and also performs validation on those that need validation
21    pub fn normalize(&self, data: &[u8]) -> Result<Vec<u8>, Error> {
22        Ok(match self {
23            KnownMeta::OpV1 => normalize_json::<OpMeta>(data)?,
24            KnownMeta::SolidityAbiV2 => normalize_json::<SolidityAbiMeta>(data)?,
25            KnownMeta::InterpreterCallerMetaV1 => normalize_json::<InterpreterCallerMeta>(data)?,
26            KnownMeta::AuthoringMetaV1 => {
27                // for AuthoringMeta since it can be a json or abi encoded bytes, we try to abi
28                // decode first and then json deserialize if that fails, if either succeeds
29                // then the result of that will be abi encoded with validation
30                match AuthoringMeta::abi_decode(data) {
31                    Ok(am) => am.abi_encode_validate()?,
32                    _ => AuthoringMeta::abi_encode_validate(
33                        &serde_json::from_str::<AuthoringMeta>(std::str::from_utf8(data)?)?,
34                    )?,
35                }
36            }
37            // rest of meta types are only pure bytes (ut8 strings or binary)
38            // so no normalization/validation can happen for them at this level
39            _ => data.to_vec(),
40        })
41    }
42}