μson (uson) is a shorthand for JSON
1# μson (uson) 2 3A compact human-readable data serialization format specially designed for shell. 4 5This format is certainly not intended to replace the classical JSON format, but brings different syntax, for use in environments with specific requirements. 6 7Main 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. 8 9This is a Rust implementation of μson. Grammar is written using [Pest](https://pest.rs/) parser. This is a port of the original [JavaScript implementation](https://github.com/burningtree/uson). 10 11* [μson Overview](#μson-overview) 12* [Rust Library](#rust-library) 13* [Command-line tool (CLI)](#command-line-tool-cli) 14 15## μson Overview 16 17* [Introduction](#introduction) 18 * [Principles](#principles) 19* [Example](#example) 20* [Basic usage](#basic-usage) 21 * [Standard types](#standard-types) 22 * [Arrays](#arrays) 23 * [Objects](#objects) 24 * [Nested objects](#nested-objects) 25 * [Type casting](#type-casting) 26 * [Custom types](#custom-types) 27 * [Comments](#comments) 28 29### Introduction 30 31#### Principles 32 33* Superset of JSON (every JSON is valid μson). 34* Whitespace is not significant. 35* String quoting `"` is optional. 36* In Array or Object, comma `,` can be replaced by whitespace ` `. 37* Assignment with colon `:` can be repeated to create nested objects (see [Nested objects](#nested-objects)). 38* You can use custom types, casting is done by `!` character (see [Type casting](#type-casting)). 39 40### Example 41 42``` 43endpoint:id:wikipedia pages:[Malta Prague "New York"] 44``` 45 46Result in JSON: 47```json 48[ 49 { 50 "endpoint": { 51 "id": "wikipedia" 52 } 53 }, 54 { 55 "pages": [ 56 "Malta", 57 "Prague", 58 "New York" 59 ] 60 } 61] 62``` 63 64### Basic usage 65 66``` 67expr1 expr2 expr3 .. 68``` 69 70Supported types: 71* false 72* null 73* true 74* array 75* object 76* number 77* string 78 79#### Standard types 80 81``` 82number:12.05 text:Banana quotedText:"John Devilseed" empty:null good:true 83``` 84 85Output: 86```json 87[ 88 { 89 "number": 12.05 90 }, 91 { 92 "text": "Banana" 93 }, 94 { 95 "quotedText": "John Devilseed" 96 }, 97 { 98 "empty": null 99 }, 100 { 101 "good": true 102 } 103] 104``` 105 106#### Arrays 107 108``` 109simple:[1 2 3] texts:[Malta Budapest "New York"] objects:[{id:1}] 110``` 111 112Output: 113```json 114[ 115 { 116 "simple": [ 117 1, 118 2, 119 3 120 ] 121 }, 122 { 123 "texts": [ 124 "Malta", 125 "Budapest", 126 "New York" 127 ] 128 }, 129 { 130 "objects": [ 131 { 132 "id": 1 133 } 134 ] 135 } 136] 137``` 138 139#### Objects 140 141``` 142obj:{name:John} {nested:[{id:42} value:"Nagano"]} 143``` 144 145Output: 146```json 147[ 148 { 149 "obj": { 150 "name": "John" 151 } 152 }, 153 { 154 "nested": [ 155 { 156 "id": 42 157 }, 158 { 159 "value": "Nagano" 160 } 161 ] 162 } 163] 164``` 165 166#### Nested objects 167 168You can use standard colon notation to expand objects: 169``` 170<key>:(<value>|(<key>:(<value>| .. ))) 171``` 172 173For example: 174``` 175cities:eu:hu:budapest:Budapest 176``` 177 178becomes: 179```json 180[ 181 { 182 "cities": { 183 "eu": { 184 "hu": { 185 "budapest": "Budapest" 186 } 187 } 188 } 189 } 190] 191``` 192 193#### Type casting 194 195If you want to return a value in specific type, you can use this syntax: 196``` 197<type>!<expr> 198``` 199 200For example, this input: 201``` 202str!42 203``` 204 205produces this output: 206```json 207["42"] 208``` 209 210You can use casting repeatedly: 211``` 212str!int!12.42 213``` 214 215output: 216```json 217["12"] 218``` 219 220##### Built-in casting types 221 222**Scalars:** 223* `str` - string 224* `int` - integer 225* `float` - float 226* `null` - null 227* `bool` - boolean 228* `date` - date & time (ISO 8601 formatting) 229 230**Data formats:** 231* `base64` - decode base64 to bytes 232* `hex` - decode hex to bytes 233* `url` - parse URL 234* `regex` - parse regular expression 235* `toml` - parse TOML data 236 237#### Custom types 238 239Custom type support is planned for future versions. 240 241#### Comments 242 243Comments begin with `#` and terminate at end of line. 244 245``` 246array:[1 2 3] # this is a comment 247``` 248 249Output: 250```json 251[ 252 { 253 "array": [ 254 1, 255 2, 256 3 257 ] 258 } 259] 260``` 261 262## Rust Library 263 264### Installation 265 266Add to your `Cargo.toml`: 267 268```toml 269[dependencies] 270uson = "0.1.0" 271``` 272 273### Usage 274 275```rust 276use uson::{parse, Value}; 277 278fn main() { 279 // Parse μson 280 let result = parse("name:John age:30 active:true").unwrap(); 281 282 // Convert to JSON 283 let json = uson::to_json("name:John age:30", true, true).unwrap(); 284 println!("{}", json); 285} 286``` 287 288### API 289 290* `uson::parse(input: &str) -> Result<Vec<Value>, ParseError>` - Parse μson string 291* `uson::to_json(input: &str, apply_types: bool, pretty: bool) -> Result<String, ParseError>` - Parse and convert to JSON 292* `uson::stringify(input: &str, apply_types: bool) -> Result<String, ParseError>` - Parse and stringify back to μson 293* `uson::apply_builtin_types(value: Value) -> Value` - Apply built-in type transformations 294 295## Command-line tool (CLI) 296 297### Installation 298 299```bash 300cargo install uson 301``` 302 303### Usage 304 305```bash 306$ uson [options] [expression] 307``` 308 309### Example 310 311```bash 312$ uson 'user:john age:42' 313``` 314 315Returns: 316```json 317[{"user":"john"},{"age":42}] 318``` 319 320### Options 321 322For pretty-printed output, use `--pretty` or `-p`: 323 324```bash 325$ uson --pretty 'name:John age:30' 326``` 327 328To read from a file, use `--file` or `-f`: 329 330```bash 331$ uson --file input.uson 332``` 333 334To apply built-in type transformations, use `--types` or `-t`: 335 336```bash 337$ uson --types 'date!"2024-01-01"' 338``` 339 340### Output Formats 341 342- JSON (default): `--json` or `-j` 343- YAML: `--yaml` or `-y` (requires `yaml` feature) 344- Query string: `--form` or `-F` (requires `form` feature) 345 346Example: 347```bash 348$ uson --yaml --pretty 'endpoint:id:wikipedia' 349``` 350 351Returns: 352```yaml 353- endpoint: 354 id: wikipedia 355``` 356 357### Streams support (pipe) 358 359If you don't specify any input then input is taken from standard input (stdin): 360 361```bash 362$ echo "a b c:[a:42]" | uson --pretty 363``` 364 365## Development 366 367```bash 368# Build 369cargo build 370 371# Run tests 372cargo test 373 374# Run compliance tests 375cargo test --test compliance 376 377# Build with all features 378cargo build --all-features 379``` 380 381## Inspiration 382 383Inspired by the original JavaScript implementation by [@burningtree](https://github.com/burningtree). 384 385## License 386 387MIT