μson (uson) is a shorthand for JSON
Rust 95.6%
Makefile 1.5%
Other 3.0%
1 1 0

Clone this repository

https://tangled.org/tree.fail/uson-rs
git@tangled.org:tree.fail/uson-rs

For self-hosted knots, clone URLs may differ based on your setup.

README.md

μson (uson)#

A compact human-readable data serialization format specially designed for shell.

This format is certainly not intended to replace the classical JSON format, but brings different syntax, for use in environments with specific requirements.

Main advantage should be in better writability (mostly in the command line), because it uses less expressive syntax. The purpose is not to create a format that is as small as possible in terms of byte size.

This is a Rust implementation of μson. Grammar is written using Pest parser. This is a port of the original JavaScript implementation.

μson Overview#

Introduction#

Principles#

  • Superset of JSON (every JSON is valid μson).
  • Whitespace is not significant.
  • String quoting " is optional.
  • In Array or Object, comma , can be replaced by whitespace .
  • Assignment with colon : can be repeated to create nested objects (see Nested objects).
  • You can use custom types, casting is done by ! character (see Type casting).

Example#

endpoint:id:wikipedia pages:[Malta Prague "New York"]

Result in JSON:

[
  {
    "endpoint": {
      "id": "wikipedia"
    }
  },
  {
    "pages": [
      "Malta",
      "Prague",
      "New York"
    ]
  }
]

Basic usage#

expr1 expr2 expr3 ..

Supported types:

  • false
  • null
  • true
  • array
  • object
  • number
  • string

Standard types#

number:12.05 text:Banana quotedText:"John Devilseed" empty:null good:true

Output:

[
  {
    "number": 12.05
  },
  {
    "text": "Banana"
  },
  {
    "quotedText": "John Devilseed"
  },
  {
    "empty": null
  },
  {
    "good": true
  }
]

Arrays#

simple:[1 2 3] texts:[Malta Budapest "New York"] objects:[{id:1}]

Output:

[
  {
    "simple": [
      1,
      2,
      3
    ]
  },
  {
    "texts": [
      "Malta",
      "Budapest",
      "New York"
    ]
  },
  {
    "objects": [
      {
        "id": 1
      }
    ]
  }
]

Objects#

obj:{name:John} {nested:[{id:42} value:"Nagano"]}

Output:

[
  {
    "obj": {
      "name": "John"
    }
  },
  {
    "nested": [
      {
        "id": 42
      },
      {
        "value": "Nagano"
      }
    ]
  }
]

Nested objects#

You can use standard colon notation to expand objects:

<key>:(<value>|(<key>:(<value>| .. )))

For example:

cities:eu:hu:budapest:Budapest

becomes:

[
  {
    "cities": {
      "eu": {
        "hu": {
          "budapest": "Budapest"
        }
      }
    }
  }
]

Type casting#

If you want to return a value in specific type, you can use this syntax:

<type>!<expr>

For example, this input:

str!42

produces this output:

["42"]

You can use casting repeatedly:

str!int!12.42

output:

["12"]
Built-in casting types#

Scalars:

  • str - string
  • int - integer
  • float - float
  • null - null
  • bool - boolean
  • date - date & time (ISO 8601 formatting)

Data formats:

  • base64 - decode base64 to bytes
  • hex - decode hex to bytes
  • url - parse URL
  • regex - parse regular expression
  • toml - parse TOML data

Custom types#

Custom type support is planned for future versions.

Comments#

Comments begin with # and terminate at end of line.

array:[1 2 3] # this is a comment

Output:

[
  {
    "array": [
      1,
      2,
      3
    ]
  }
]

Rust Library#

Installation#

Add to your Cargo.toml:

[dependencies]
uson = "0.1.0"

Usage#

use uson::{parse, Value};

fn main() {
    // Parse μson
    let result = parse("name:John age:30 active:true").unwrap();
    
    // Convert to JSON
    let json = uson::to_json("name:John age:30", true, true).unwrap();
    println!("{}", json);
}

API#

  • uson::parse(input: &str) -> Result<Vec<Value>, ParseError> - Parse μson string
  • uson::to_json(input: &str, apply_types: bool, pretty: bool) -> Result<String, ParseError> - Parse and convert to JSON
  • uson::stringify(input: &str, apply_types: bool) -> Result<String, ParseError> - Parse and stringify back to μson
  • uson::apply_builtin_types(value: Value) -> Value - Apply built-in type transformations

Command-line tool (CLI)#

Installation#

cargo install uson

Usage#

$ uson [options] [expression]

Example#

$ uson 'user:john age:42'

Returns:

[{"user":"john"},{"age":42}]

Options#

For pretty-printed output, use --pretty or -p:

$ uson --pretty 'name:John age:30'

To read from a file, use --file or -f:

$ uson --file input.uson

To apply built-in type transformations, use --types or -t:

$ uson --types 'date!"2024-01-01"'

Output Formats#

  • JSON (default): --json or -j
  • YAML: --yaml or -y (requires yaml feature)
  • Query string: --form or -F (requires form feature)

Example:

$ uson --yaml --pretty 'endpoint:id:wikipedia'

Returns:

- endpoint:
    id: wikipedia

Streams support (pipe)#

If you don't specify any input then input is taken from standard input (stdin):

$ echo "a b c:[a:42]" | uson --pretty

Development#

# Build
cargo build

# Run tests
cargo test

# Run compliance tests
cargo test --test compliance

# Build with all features
cargo build --all-features

Inspiration#

Inspired by the original JavaScript implementation by @burningtree.

License#

MIT