Add support for serializing hex strings without quotes
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_rawconfiguration option - Helper function to validate hex string format
- Comprehensive test suite covering various cases
- Full backward compatibility (can be disabled via config)
Benefits
- Consistency: Serialization now matches RON's existing parsing capabilities
- Readability: Hex numbers without quotes are more readable and familiar
- Configurability: The feature can be enabled/disabled as needed
- 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
I didn't know we supported parsing integers from hex strings ... can you add a test for that?
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.
@aljen Thank you for submitting the PR! I've left some thoughts above :)
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 :)
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?