cbor-cli 0.7.0

Encode, decode, and inspect CBOR (RFC 8949) from the command line. Convert between CBOR, JSON, YAML, and TOML via serde, with streaming support for CBOR sequences.
Documentation
# cbor

A command-line tool for encoding and decoding [CBOR] (Concise Binary Object
Representation, [RFC 8949]) using [serde]. Convert between CBOR and JSON, YAML,
and TOML, inspect the contents of CBOR files, and pipe it all through standard
Unix tools.

[CBOR]: https://cbor.io
[RFC 8949]: https://www.rfc-editor.org/rfc/rfc8949.html
[serde]: https://serde.rs

CBOR is a compact binary data format with a data model close to JSON's but with
smaller payloads, richer types (byte strings, bignums, tags), and fast binary
parsing. `cbor` makes working with it as easy as `jq`/`yq` make working with
their formats.

## Why

- **Pipe-friendly.** Reads files or stdin, writes stdout. Composes with `cat`,
  `curl`, `grep`, and friends.
- **Multi-format.** Convert JSON, YAML, TOML, and CBOR freely — all four
  directions.
- **Streaming.** Handles arbitrarily long inputs one item at a time, and
  supports CBOR sequences (multiple concatenated items in one stream,
  [RFC 8742]).
- **Schema-less.** Works on any data via serde's dynamic `Value` type. No
  structs, no setup.
- **Deep inspection.** Renders CBOR in Concise Diagnostic Notation
  ([RFC 8949 §8]) — human-readable, standard, and CBOR-aware (byte strings,
  tags, bignums).
- **Delimiters.** Custom output delimiters for joining multiple items.

[RFC 8742]: https://www.rfc-editor.org/rfc/rfc8742.html
[RFC 8949 §8]: https://www.rfc-editor.org/rfc/rfc8949.html#name-diagnostic-notation

## Installation

### Homebrew

```bash
brew tap ironspecs/cbor
brew install cbor-cli
```

### Cargo

```bash
cargo install cbor-cli
```

### Debian

Installs the public key, downloads the latest `.deb` file, and installs it:

```bash
curl -sSL https://raw.githubusercontent.com/ironspecs/cbor-cli/main/install-cbor-deb.sh | sh
```

### Build from source

```bash
git clone https://github.com/ironspecs/cbor-cli
cd cbor-cli
cargo build --release
# Binary is at target/release/cbor
```

## Usage

The three subcommands are designed to chain:

```
import   convert JSON/YAML/TOML/CBOR  ->  CBOR
export   convert CBOR                 ->  JSON/YAML/TOML/CBOR
inspect  render CBOR                  ->  Concise Diagnostic Notation
```

### Import (encode to CBOR)

```bash
cbor import data.json > data.cbor
```

Format is auto-detected from the file extension (`.json`, `.yaml`, `.yml`, `.toml`). To force it, or when reading
from stdin:

```bash
cat data.json | cbor import --format=json > data.cbor
```

### Export (decode from CBOR)

```bash
cbor export --format=json data.cbor > data.json

# Pretty-printed JSON
cbor export --format=json --pretty data.cbor
```

### Convert between formats

Because both commands stream, you can chain them to convert any format to any
other through CBOR as an intermediate:

```bash
# JSON -> YAML
cbor import data.json | cbor export --format=yaml > data.yaml

# YAML -> TOML
cbor import data.yaml | cbor export --format=toml > data.toml
```

### Inspect (debug)

`inspect` renders each CBOR item in Concise Diagnostic Notation — a
human-readable form that preserves CBOR-specific details JSON debug output
would lose, like byte strings:

```bash
$ cbor import data.json | cbor inspect
{"name": "cbor", "types": [1, 2, 3]}
```

Inspect a CBOR file directly:

```bash
cbor inspect data.cbor
```

CDN distinguishes CBOR types that JSON can't represent:

| CBOR type              | CDN output         |
| ---------------------- | ------------------ |
| Byte string            | `h'0102'`          |
| Tagged unsigned bignum | `16909060`         |
| Integer                | `42`               |
| Text string            | `"hello"`          |
| Array                  | `[1, 2, 3]`        |
| Map                    | `{"a": "b"}`       |
| Null                   | `null`             |
| Boolean                | `true` / `false`   |

### Multiple files and streams

Pass multiple files; each is processed in turn:

```bash
cbor import a.json b.json > combined.cbor
```

Concatenated items from stdin are supported too — useful for CBOR sequences
and for joining multiple JSON documents:

```bash
cat a.json b.json | cbor import --format=json > combined.cbor
```

### Custom delimiters

When exporting multiple items, join them with a custom delimiter. The default
is `\n` (for YAML, the document separator `---`):

```bash
# Comma-separated JSON values
cbor export --format=json --delimiter=',' data.cbor

# Shorthand
cbor -d=',' export data.cbor
```

The escapes `\n` and `\t` are interpreted literally.

## Full reference

```
cbor [OPTIONS] [COMMAND]

Commands:
  inspect  Deep inspection of CBOR files, for debugging, learning, or repairing
  import   Convert a file of some other type to CBOR
  export   Convert CBOR files to some other type
  help     Print help for a command

Options:
  -v, --verbose...             Increase verbosity (repeatable)
  -d, --delimiter <DELIMITER>  Delimiter between multiple output items
  -h, --help                   Print help
  -V, --version                Print version
```

Each subcommand has its own `--help`:

```bash
cbor import --help
cbor export --help
cbor inspect --help
```

## Library

The core conversion functions are exposed as a library, in case you want to
embed them in another Rust project:

```rust
use cbor_cli::import::import_from_reader;

// Convert a JSON stream to CBOR.
let json = br#"{"key": "value"}"#;
let mut cbor = Vec::new();
import_from_reader("json", &json[..], &mut cbor).unwrap();
```

Library functions return `anyhow::Result`, so errors propagate naturally:

```rust
use anyhow::Context;
use cbor_cli::export::export_from_reader;

export_from_reader("json", "\n", false, &cbor[..], &mut writer)
    .context("Failed to export data.cbor")?;
```

See the `src/` modules for the full API surface:

| Module   | Purpose                                            |
| -------- | -------------------------------------------------- |
| `import` | Encode JSON/YAML/TOML/CBOR streams to CBOR         |
| `export` | Decode CBOR streams to JSON/YAML/TOML/CBOR         |
| `inspect`| Render CBOR as Concise Diagnostic Notation         |
| `files`  | Path helpers: format detection, existence checks   |
| `config` | CLI definition (clap)                              |

## Standards

- [RFC 8949] — Concise Binary Object Representation
- [RFC 8742] — CBOR Sequences (concatenated items in one stream)
- [RFC 8949 §8] — Concise Diagnostic Notation

## Development

```bash
cargo test      # run the test suite
cargo clippy    # lints
cargo fmt       # formatting
cargo run --    # build and run in one step
```

Examples of every supported conversion are in `examples/test.sh`.

### Building release packages

Cross-compilation and Debian packaging are configured in
`.github/workflows/rust_build.yml`. Local `.deb` build:

```bash
cargo install cargo-deb
rustup target add i686-unknown-linux-gnu
cargo deb --target=i686-unknown-linux-gnu
```

## License

Apache-2.0. See [LICENSE](LICENSE).