pub mod ron {
    //! Wrap T in RonCodec<T> that when serialized, always serializes to a [ron] string.

    #[derive(Debug, Clone)]
    pub struct RonCodec<T> {
        t: T,
    }

    impl<T> RonCodec<T> {
        pub fn into_inner(self) -> T {
            self.t
        }

        pub fn new(t: T) -> Self {
            Self { t }
        }
    }

    impl<T> std::ops::Deref for RonCodec<T> {
        type Target = T;

        fn deref(&self) -> &Self::Target {
            &self.t
        }
    }

    impl<T> serde::Serialize for RonCodec<T>
    where
        T: serde::Serialize,
    {
        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            let serialized = ron::to_string(&self.t).map_err(serde::ser::Error::custom)?;
            serializer.serialize_str(&serialized)
        }
    }

    impl<'de, T> serde::Deserialize<'de> for RonCodec<T>
    where
        T: serde::de::DeserializeOwned + 'static,
    {
        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            let s = String::deserialize(deserializer)?;
            let t: T = ron::from_str(&s).map_err(serde::de::Error::custom)?;
            Ok(Self { t })
        }
    }

    #[cfg(test)]
    mod tests {
        use super::RonCodec;
        use serde::Deserialize;
        use serde::Serialize;

        #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
        struct TestStruct {
            name: String,
            value: i32,
        }

        #[test]
        fn test_ron_codec() {
            let original = TestStruct {
                name: "Test".to_string(),
                value: 42,
            };

            // Wrap in RonCodec
            let wrapped = RonCodec::new(original.clone());

            // Serialize
            let serialized = serde_json::to_string(&wrapped).expect("Serialization failed");
            println!("Serialized: {}", serialized);

            // Deserialize
            let deserialized: RonCodec<TestStruct> = serde_json::from_str(&serialized).expect("Deserialization failed");

            // Compare
            assert_eq!(deserialized.into_inner(), original);
        }
    }
}
