Crate fog_human_json

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.
  • 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§

JsonEntry
Partially converted JSON value that can be completed into a NewEntry.
SignDocument
An almost completed NewDocument. Complete it by finding the appropriate IdentityKey and calling complete.
SignEntry
An almost completed NewEntry. Complete it by finding the appropriate IdentityKey and calling complete.

Enums§

DecodeError
An error that occurred while converting from JSON to a fog-pack value.
MaybeDocument
A NewDocument that may still require signing.
MaybeEntry
A NewEntry that may still require signing.
ObjectError
An error that occurred while converting from JSON to a fog-pack object, like a Document or Entry.

Functions§

doc_to_json
Convert a Document into a JSON Value.
entry_to_json
Convert an Entry into a JSON Value.
fog_to_json
Convert a fog-pack value to a JSON Value.
fogref_to_json
Convert a fog-pack ValueRef to a JSON Value.
json_to_doc
Convert a JSON value into a NewDocument.
json_to_fog
Convert a JSON Value to a fog-pack value.
json_to_query
Convert JSON into a NewQuery.
new_query_to_json
Convert a NewQuery into a JSON value. Can panic if the query is too large.
query_to_json
Convert a Query into a JSON value.