Crate fog_human_json
source ·Expand description
This crate provides functions to go back and forth between fog-pack and JSON, making it relatively easy for users to view pretty-printed fog-pack values and edit them with existing JSON tooling. A common complaint with binary data formats like fog-pack is that reading them is painful, and lowering that pain with JSON is exactly what this crate is for.
This is not a crate for turning regular JSON into fog-pack data. It uses a number of special string prefixes to encode fog-pack types in JSON, which can interfere with arbitrary JSON-to-fog conversions.
So, what does this actually do for conversion? Well, it takes each fog-pack type
and either directly converts it to a corresponding JSON type, or it specially
encodes it in a string that starts with $fog-
. So a 32-bit floating point
value could be specifically encoded as $fog-F32: 1.23
. The full list of types
is:
- Str: A regular string. This is just prepended so fog-pack strings that start
with
$fog-
won’t get caught by the parser. - Bin: Encodes the binary data as Base64 using the “standard” encoding (bonus
symbols of
+/
, no padding used, padding is accepted when parsing). - F32Hex / F64Hex: Encodes a binary32/64 IEEE floating-point value in big-endian hex. The fog-to-json process should only do this when writing out a NaN or Infinity.
- F32 / F64 / Int: Prints a standard JSON Number, but includes the type
information. This done by telling the converter to do it specifically, by a
user adding type information, or by the converter for any F32 value (as
serde_json
will always use F64 for floating-point). - Time: Encodes the time as a RFC 3339 formatted string.
- Hash / Identity / StreamId / LockId: Encodes the corresponding primitive as a base58 string (in the Bitcoin base58 style).
- DataLockbox / IdentityLockbox / StreamLockbox / LockLockbox: Encodes the corresponding lockbox as Base64 data, just like with the “Bin” type.
That covers conversion between fog-pack Values and JSON values, but not Documents and Entries. Those are converted into JSON objects with the following key-value pairs:
- Documents:
- “schema”: If present, a
$fog-Hash:HASH
with the schema. - “signer”: If present, a
$fog-Identity:IDENTITY
with the signer’s Identity. - “compression”: If not present, uses default compression. If present and null, no compression is used. If set to a number between 0-255, uses that as the compression level.
- “data”: The document content. Must be present.
- “schema”: If present, a
- Entries:
- “parent”: Parent document’s hash.
- “key”: Entry’s string key.
- “signer”: If present, holds the signer’s Identity.
- “compression”: If not present, uses default compression. If present and null, no compression is used. If set to a number between 0 & 255, uses that as the compression level.
- “data”: The entry content. Must be present.
When going from JSON to a Document or Entry, if there’s a “signer” specified, an intermediate
struct will be provided that must be signed by a
IdentityKey
that matches the signer.
As an example, let’s take a struct that looks the one below, put it into a document, and look at the resulting JSON:
use fog_pack::{types::*, schema::NoSchema};
use fog_human_json::*;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
struct Test {
boolean: bool,
int: i64,
float32: f32,
float64: f64,
#[serde(with = "serde_bytes")]
bin: Vec<u8>,
string: String,
array: Vec<u32>,
map: BTreeMap<String, u32>,
time: Timestamp,
hash: Hash,
id: Identity,
}
// ... Fill it up with some data ...
let test: Test = test;
let doc = fog_pack::document::NewDocument::new(None, &test).unwrap();
let doc = NoSchema::validate_new_doc(doc).unwrap();
let json_val = doc_to_json(&doc);
let json_raw = serde_json::to_string_pretty(&json_val).expect("JSON Value to raw string");
The resulting JSON could look something like:
{
"data": {
"array": [ 0, 1, 2, 3, 4 ],
"bin": "$fog-Bin:AAECAwQ",
"boolean": false,
"float32": "$fog-F32:0.0",
"float64": 0.0,
"hash": "$fog-Hash:R7KEBd4fxeYgDtoivjDUK97HwEcL7k7hm3qjPhZFEhzL",
"id": "$fog-Identity:T4MvqAy6RVR2J8efJzgQW9xN9Z8avJBFEmefuSnBMWQP",
"int": -12345,
"lock": "$fog-LockId:ME7DmA9ADSYE6sq8SRvQ2ncd1kosQZoZqG7XiCFX55Uz",
"map": {
"a": 1,
"b": 2,
"c": 3
},
"stream_id": "$fog-StreamId:U4sLqPrtAgzKbUVnr47PcgPT2Rq3D9kBqrvhZ9NvCTvq",
"string": "hello",
"time": "$fog-Time:2023-07-12T17:33:13.454466675Z"
}
}
Structs
- Partially converted JSON value that can be completed into a NewEntry.
- An almost completed
NewDocument
. Complete it by finding the appropriateIdentityKey
and callingcomplete
. - An almost completed
NewEntry
. Complete it by finding the appropriateIdentityKey
and callingcomplete
.
Enums
- An error that occurred while converting from JSON to a fog-pack value.
- A
NewDocument
that may still require signing. - A
NewEntry
that may still require signing. - An error that occurred while converting from JSON to a fog-pack object, like a Document or Entry.
Functions
- Convert a Document into a JSON Value.
- Convert an Entry into a JSON Value.
- Convert a fog-pack value to a JSON Value.
- Convert a fog-pack ValueRef to a JSON Value.
- Convert a JSON value into a
NewDocument
. - Convert a JSON Value to a fog-pack value.
- Convert JSON into a
NewQuery
. - Convert a
NewQuery
into a JSON value. Can panic if the query is too large. - Convert a
Query
into a JSON value.