1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
#[macro_use]
extern crate json;
use json::codegen::Generator;
use json::object::Object;
use json::JsonValue;
use std::io;
/// Custom generator that sort keys by name; based on DumpGenerator.
pub struct CustomGenerator {
code: Vec<u8>,
}
impl CustomGenerator {
pub fn new() -> Self {
CustomGenerator {
code: Vec::with_capacity(1024),
}
}
pub fn consume(self) -> String {
// Original strings were unicode, numbers are all ASCII,
// therefore this is safe.
unsafe { String::from_utf8_unchecked(self.code) }
}
}
impl Generator for CustomGenerator {
type T = Vec<u8>;
#[inline(always)]
fn get_writer(&mut self) -> &mut Vec<u8> {
&mut self.code
}
#[inline(always)]
fn write_min(&mut self, _: &[u8], min: u8) -> io::Result<()> {
self.code.push(min);
Ok(())
}
#[inline(always)]
fn write_object(&mut self, object: &Object) -> io::Result<()> {
self.write_char(b'{')?;
let mut entries: Vec<(&str, &JsonValue)> = Vec::new();
for (k, v) in object.iter() {
entries.push((k, v));
}
entries.sort_by(|(k1, _), (k2, _)| k1.partial_cmp(k2).unwrap());
let mut iter = entries.iter();
if let Some((key, value)) = iter.next() {
self.indent();
self.new_line()?;
self.write_string(key)?;
self.write_min(b": ", b':')?;
self.write_json(value)?;
} else {
self.write_char(b'}')?;
return Ok(());
}
for (key, value) in iter {
self.write_char(b',')?;
self.new_line()?;
self.write_string(key)?;
self.write_min(b": ", b':')?;
self.write_json(value)?;
}
self.dedent();
self.new_line()?;
self.write_char(b'}')
}
}
#[test]
fn object_keys_sorted() {
let o = object! {
c: null,
b: null,
a: null,
};
let mut gen = CustomGenerator::new();
gen.write_json(&o).expect("Can't fail");
let json = gen.consume();
let dump = o.dump();
assert_eq!(json, r#"{"a":null,"b":null,"c":null}"#);
assert_eq!(dump, r#"{"c":null,"b":null,"a":null}"#);
assert_ne!(json, dump);
}
|