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

Enums

Functions