Repository: juspay/hyperswitch
File: crates/masking/src/secret.rs (Rust)

Code before:
    }

    fn merge_field(
        &mut self,
        tag: u32,
        wire_type: prost::encoding::WireType,
        buf: &mut impl bytes::Buf,
        ctx: prost::encoding::DecodeContext,
    ) -> Result<(), prost::DecodeError> {
        if tag == 1 {
            let mut value = T::default();
            prost::Message::merge_field(&mut value, tag, wire_type, buf, ctx)?;
            *self = Self::new(value);
            Ok(())
        } else {
            prost::encoding::skip_field(wire_type, tag, buf, ctx)
        }
    }

    fn encoded_len(&self) -> usize {
        prost::Message::encoded_len(self.peek())
    }

    fn clear(&mut self) {
        *self = Self::new(T::default());
    }
}

#[cfg(test)]
#[cfg(feature = "serde")]
mod tests {
    use serde_json::json;

    use super::*;

    #[test]
    #[allow(clippy::expect_used)]
    fn test_json_mask_strategy() {
        // Create a sample JSON with different types for testing
        let original = json!({ "user": { "name": "John Doe", "email": "john@example.com", "age": 35, "verified": true }, "card": { "number": "4242424242424242", "cvv": 123, "amount": 99.99 }, "tags": ["personal", "premium"], "null_value": null, "short": "hi" });

        // Apply the JsonMaskStrategy
        let secret = Secret::<_, JsonMaskStrategy>::new(original.clone());
        let masked_str = format!("{:?}", secret);

        // Get specific values from original
        let original_obj = original.as_object().expect("Original should be an object");
        let user_obj = original_obj["user"]
            .as_object()
            .expect("User should be an object");
        let name = user_obj["name"].as_str().expect("Name should be a string");

Review comment (suggestion):
You should be able to do something like this for `encoded_len()`. And can we call `clear()` on the underlying type, instead of assigning it to `T::default()`?

```suggestion
    fn encoded_len(&self) -> usize {
        self.peek().encoded_len()
    }

    fn clear(&mut self) {
        self.peek_mut().clear()
    }
```

Code after:
    }

    fn merge_field(
        &mut self,
        tag: u32,
        wire_type: prost::encoding::WireType,
        buf: &mut impl bytes::Buf,
        ctx: prost::encoding::DecodeContext,
    ) -> Result<(), prost::DecodeError> {
        if tag == 1 {
            self.peek_mut().merge_field(tag, wire_type, buf, ctx)
        } else {
            prost::encoding::skip_field(wire_type, tag, buf, ctx)
        }
    }

    fn encoded_len(&self) -> usize {
        self.peek().encoded_len()
    }

    fn clear(&mut self) {
        self.peek_mut().clear();
    }
}

#[cfg(test)]
#[cfg(feature = "serde")]
mod tests {
    use serde_json::json;

    use super::*;

    #[test]
    #[allow(clippy::expect_used)]
    fn test_json_mask_strategy() {
        // Create a sample JSON with different types for testing
        let original = json!({ "user": { "name": "John Doe", "email": "john@example.com", "age": 35, "verified": true }, "card": { "number": "4242424242424242", "cvv": 123, "amount": 99.99 }, "tags": ["personal", "premium"], "null_value": null, "short": "hi" });

        // Apply the JsonMaskStrategy
        let secret = Secret::<_, JsonMaskStrategy>::new(original.clone());
        let masked_str = format!("{:?}", secret);

        // Get specific values from original
        let original_obj = original.as_object().expect("Original should be an object");
        let user_obj = original_obj["user"]
            .as_object()
            .expect("User should be an object");
        let name = user_obj["name"].as_str().expect("Name should be a string");
        let email = user_obj["email"]
            .as_str()
            .expect("Email should be a string");