use std::str::FromStr; use near_sdk::{ near, serde::{ self, de::{self, DeserializeOwned}, Deserialize, Serialize, }, serde_json, }; #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] #[near(serializers = [])] pub struct WithRawString { pub raw: String, pub parsed: T, } impl WithRawString { /// # Panics /// /// - If serialization fails. pub fn from_parsed(value: T) -> Self where T: Serialize, { #[allow(clippy::unwrap_used, reason = "This method panics")] let raw = serde_json::to_string(&value).unwrap(); Self { raw, parsed: value } } } impl FromStr for WithRawString { type Err = serde_json::Error; fn from_str(raw: &str) -> Result { Self::try_from(raw.to_string()) } } impl TryFrom for WithRawString { type Error = serde_json::Error; fn try_from(raw: String) -> Result { let mut d = serde_json::Deserializer::from_str(&r#raw); let parsed: T = Deserialize::deserialize(&mut d)?; Ok(Self { raw, parsed }) } } impl<'de, T: DeserializeOwned> Deserialize<'de> for WithRawString { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { let raw: String = Deserialize::deserialize(deserializer)?; Self::try_from(raw).map_err(de::Error::custom) } } impl Serialize for WithRawString { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { Serialize::serialize(&self.raw, serializer) } } impl schemars::JsonSchema for WithRawString { fn schema_name() -> String { T::schema_name() } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } }