Expand description
JSON text into a Builder and back out of a Value.
The typed API never comes through here: a struct is serialized straight into
the encoding and read straight back out, and text would be two conversions
nobody asked for. This is for the other door. JSON.SET arrives with a
bulk string that is JSON text and JSON.GET has to hand one back, so the
whole JSON.* surface stands on these two functions and neither of them can
be a dependency, because a JSON parser is where a compatibility claim goes to
die and this one has to agree with RedisJSON down to the byte.
use yo_doc::{Builder, Value};
let mut b = Builder::new();
b.json(br#"{"name": "a wrench", "price": 12.5, "tags": ["hand", "steel"]}"#)?;
let doc = b.finish()?.to_vec();
let v = Value::new(&doc).expect("readable");
assert_eq!(v.get(b"price").unwrap().as_float(), Some(12.5));
// Key order, not the order the text had them in. See below.
assert_eq!(v.to_json()?, br#"{"name":"a wrench","tags":["hand","steel"],"price":12.5}"#);§What the parser accepts
RFC 8259 and nothing else. No trailing commas, no comments, no unquoted
keys, no single quoted strings, no leading plus, no leading zero, no bare
NaN or Infinity. Every one of those is something some parser somewhere
allows, and accepting one of them means a document that loads here and is
refused by a real Redis, which is a divergence that nobody would think to
look for. Being strict is the only setting that can be checked.
A number without a fraction or an exponent that fits in an i64 is stored as
an integer and everything else is stored as a float, which is the same split
RedisJSON makes and the reason 1 comes back as 1 rather than as 1.0.
An integer literal too big for an i64 becomes a float, and loses precision
the way it would anywhere else. So does -0, which is a number an integer
cannot hold and a double can.
§Two things the writer does that are worth knowing
An object comes out in key order, which is by length first and then by
bytes, so name comes before price and not after it. Members are stored
sorted because that is what makes a lookup a binary search, so the order a
client wrote them in is not kept anywhere and cannot be handed back.
RedisJSON keeps it. That shows up on any document with more than one key and
it belongs in the divergence register rather than in a footnote.
A float is printed as the shortest text that reads back as the same
double, with a .0 added when it would otherwise look like an integer.
Without that, a document that went out and came back would change type on
every round trip, which is the sort of thing that only shows up three
services downstream.
Structs§
- Format
- How a document is laid out when it is written as text.
Functions§
- from_
json - One JSON document, as the bytes it encodes to.
- write_
resp_ float - A double, the way
JSON.RESPwrites one, which is not the way JSON does.