ron icon indicating copy to clipboard operation
ron copied to clipboard

Add support for serializing hex strings without quotes

Open aljen opened this issue 1 year ago • 5 comments

Problem

Currently, RON supports parsing hex numbers in both quoted and unquoted form:

number: 0x1234    // works fine
number: 4660  // also works

However, when serializing such values, they are always wrapped in quotes:

pub fn as_hex_u16<S>(value: &u16, serializer: S) -> Result<S::Ok, S::Error>
where
    S: Serializer,
{
    serializer.serialize_str(&format!("0x{:04X}", value))
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct AddressRange {
    #[serde(serialize_with = "as_hex_u16")]
    pub start: u16,
    #[serde(serialize_with = "as_hex_u16")]
    pub end: u16,
    pub length: u16,
}
start: "0x1234",
end: "0x1235"
length: 2

This creates an inconsistency between parsing and serialization capabilities, and makes the serialized output less elegant, especially in configuration files where hex numbers are commonly used (e.g., for colors, flags, or memory addresses).

Solution

This PR adds a new configuration option hex_as_raw (default: true) to PrettyConfig that allows hex strings to be serialized without quotes. When enabled:

// Input
let val = "0x1234";
let config = PrettyConfig::new().hex_as_raw(true);
to_string_pretty(&val, config)?;
// Output
number: 0x1234

Number is serialised clean and consistent with parsing capabilities.

The implementation includes:

  • New hex_as_raw configuration option
  • Helper function to validate hex string format
  • Comprehensive test suite covering various cases
  • Full backward compatibility (can be disabled via config)

Benefits

  1. Consistency: Serialization now matches RON's existing parsing capabilities
  2. Readability: Hex numbers without quotes are more readable and familiar
  3. Configurability: The feature can be enabled/disabled as needed
  4. Safety: Only valid hex strings (0x[0-9a-fA-F]+) are serialized without quotes

This enhancement makes RON's handling of hex numbers more elegant and consistent :)

  • [X] I've included my change in CHANGELOG.md

aljen avatar Dec 11 '24 22:12 aljen

I didn't know we supported parsing integers from hex strings ... can you add a test for that?

juntyr avatar Dec 12 '24 06:12 juntyr

I'm not sure if I'm in favor of this proposed change so far. If the goal is to be able to serialize all integers in binary, octal, or hex notation, I'd happily accept a proposal for that.

If you only want to serialize specific integers as hex, there is a (hacky) workaround that should work already. You could define a serde serialize_with function that first formats the number as a hex string, then constructs a RawValue from it, and then serializes that. It's not very efficient but it would already work in user code.

juntyr avatar Dec 12 '24 06:12 juntyr

@aljen Thank you for submitting the PR! I've left some thoughts above :)

juntyr avatar Dec 12 '24 06:12 juntyr

I didn't know we supported parsing integers from hex strings ... can you add a test for that?

You're right, it was late, I was thinking about parsing hex value as an integer, not a string - fixed in description, sorry for confusion =)

Sorry for long time to reply, I was on holiday vacations :)

aljen avatar Jan 06 '25 10:01 aljen

No worries, happy New Year!

Do you want this PR to go in the suggested direction of serialising all integers as hex / octal / binary? It would require a small rewrite in this case.

If it's just about serialising a few values in hex, have you tried out the hack using raw values?

juntyr avatar Jan 06 '25 10:01 juntyr