# Remarshal Convert between CBOR, JSON, MessagePack, TOML, and YAML. When installed, Remarshal provides the command-line command `remarshal` as well as the short commands {cbor,json,msgpack,toml,yaml}2{cbor,json,msgpack,toml,yaml}. You can use these commands to convert between formats, reformat, and detect errors. ## Known limitations and quirks There are limitations on what data can be converted between what formats. - CBOR, MessagePack, and YAML with binary fields cannot be converted to JSON or TOML. Binary fields can be converted between CBOR, MessagePack, and YAML. - The following date-time value conversions are possible: - Local dates are converted between [CBOR RFC 8943](https://www.rfc-editor.org/rfc/rfc8943.html) dates (tag 1004), [TOML Local Dates](https://toml.io/en/v1.0.0#local-date), and [YAML timestamps](https://yaml.org/type/timetamp.html) without a time or a time zone. - Local date-time is converted between [TOML Local Date-Time](https://toml.io/en/v1.0.0#local-date-time) and [YAML timestamps](https://yaml.org/type/timestamp.html) without a time zone. - Date-time with a time zone is converted between [CBOR standard date-time strings](https://www.rfc-editor.org/rfc/rfc8949.html#stringdatetimesect) (tag 0), the [MessagePack Timestamp extension type](https://github.com/msgpack/msgpack/blob/master/spec.md#timestamp-extension-type), [TOML Offset Date-Times](https://toml.io/en/v1.0.0#offset-date-time), and [YAML timestamps](https://yaml.org/type/timestamp.html) with a time zone. - [TOML Local Time](https://toml.io/en/v1.0.0#local-time) cannot be converted to a date-time in another format. - All date-time types can be converted to JSON with the `-k`/`--stringify` option, which turns them into strings. - Contrary to the [YAML timestamp draft spec](https://yaml.org/type/timestamp.html), Remarshal converts YAML dates to TOML Local Dates instead of TOML Offset Dates in the UTC time zone. It converts TOML Local Dates to YAML dates. ## Installation You will need Python 3.8 or later. Earlier versions of Python 3 will not work. The recommended way to run Remarshal is to install the latest release [from PyPI](https://pypi.org/project/remarshal/) with [pipx](https://github.com/pypa/pipx). ```sh pipx install remarshal ``` Regular installation is not mandatory. The command ```sh pipx run remarshal [arg ...] ``` will download Remarshal and run it from a temporary location. It will cache the downloaded version for up to 14 days. Remarshal will not be automatically upgraded during this period. You can also install Remarshal using pip. ```sh python3 -m pip install --user remarshal ``` It is possible to install the current development version of Remarshal. Prefer releases unless you have a reason to run the development version. ```sh pipx install git+https://github.com/remarshal-project/remarshal ``` ## Usage ``` usage: remarshal [-h] [-v] [-i ] [--if {cbor,json,msgpack,toml,yaml}] [--json-indent ] [-k] [--max-values ] [-o ] [--of {cbor,json,msgpack,toml,yaml}] [-s] [--unwrap ] [--verbose] [--wrap ] [--yaml-indent ] [--yaml-style {,',",|,>}] [--yaml-width ] [input] [output] Convert between CBOR, JSON, MessagePack, TOML, and YAML. positional arguments: input input file output output file options: -h, --help show this help message and exit -v, --version show program's version number and exit -i , --input input file --if {cbor,json,msgpack,toml,yaml}, --input-format {cbor,json,msgpack,toml,yaml}, -f {cbor,json,msgpack,toml,yaml}, --from {cbor,json,msgpack,toml,yaml} input format --json-indent JSON indentation -k, --stringify turn into strings: boolean and null keys and date-time keys and values for JSON; boolean, date-time, and null keys and null values for TOML --max-values maximum number of values in input data (default 1000000, negative for unlimited) -o , --output output file --of {cbor,json,msgpack,toml,yaml}, --output-format {cbor,json,msgpack,toml,yaml}, -t {cbor,json,msgpack,toml,yaml}, --to {cbor,json,msgpack,toml,yaml} output format -s, --sort-keys sort JSON and TOML keys instead of preserving key order --unwrap only output the data stored under the given key --verbose print debug information when an error occurs --wrap wrap the data in a map type with the given key --yaml-indent YAML indentation --yaml-style {,',",|,>} YAML formatting style --yaml-width YAML line width for long strings ``` Instead of `remarshal` with format arguments, you can use a short command {cbor,json,msgpack,toml,yaml}2{cbor,json,msgpack,toml,yaml}. The `remarshal` command and the short commands exit with status 0 on success, 1 on operational failure, and 2 on failure to parse the command line. If no input argument `input`/`-i input` is given or its value is `-`, Remarshal reads input data from standard input. Similarly, with no `output`/`-o output` or an output argument that is `-`, Remarshal writes the result to standard output. ### Wrappers The options `--wrap` and `--unwrap` are available to solve the problem of converting CBOR, JSON, MessagePack, and YAML data to TOML when the top-level element of the data is not of a dictionary type (i.e., not a map in CBOR and MessagePack, an object in JSON, or an associative array in YAML). You cannot represent such data as TOML directly; the data must be wrapped in a dictionary first. Passing the option `--wrap some-key` to `remarshal` or one of its short commands wraps the input data in a "wrapper" dictionary with one key, `some-key`, with the input data as its value. The option `--unwrap some-key` does the opposite: it converts to the target format and outputs only the value stored under the key `some-key` in the top-level dictionary element of the input data; the rest of the input is discarded. If the top-level element is not a dictionary or does not have the key `some-key`, `--unwrap some-key` causes an error. The following shell transcript demonstrates the problem and how `--wrap` and `--unwrap` solve it: ``` $ echo '[{"a":"b"},{"c":[1,2,3]}]' | remarshal --if json --of toml Error: cannot convert non-dictionary data to TOML; use "--wrap" to wrap it in a dictionary $ echo '[{"a":"b"},{"c":[1,2,3]}]' \ | remarshal --if json --of toml --wrap main [[main]] a = "b" [[main]] c = [1, 2, 3] $ echo '[{"a":"b"},{"c":[1,2,3]}]' \ | remarshal --if json --wrap main - test.toml $ remarshal test.toml --of json {"main":[{"a":"b"},{"c":[1,2,3]}]} $ remarshal test.toml --of json --unwrap main [{"a":"b"},{"c":[1,2,3]}] ``` ## Examples ``` $ remarshal example.toml --of yaml title: TOML Example owner: name: Tom Preston-Werner organization: GitHub bio: "GitHub Cofounder & CEO\nLikes tater tots and beer." dob: 1979-05-27 07:32:00+00:00 database: server: 192.168.1.1 ports: - 8001 - 8001 - 8002 connection_max: 5000 enabled: true servers: alpha: ip: 10.0.0.1 dc: eqdc10 beta: ip: 10.0.0.2 dc: eqdc10 country: 中国 clients: data: - - gamma - delta - - 1 - 2 hosts: - alpha - omega products: - name: Hammer sku: 738594937 - name: Nail sku: 284758393 color: gray ``` ``` $ curl -f 'https://archive-api.open-meteo.com/v1/era5?latitude=50.43&longitude=30.52&start_date=2014-10-05&end_date=2014-10-05&hourly=temperature_2m' \ | remarshal --from json --to toml \ | taplo fmt - \ ; latitude = 50.439365 longitude = 30.476192 generationtime_ms = 0.04291534423828125 utc_offset_seconds = 0 timezone = "GMT" timezone_abbreviation = "GMT" elevation = 147.0 [hourly_units] time = "iso8601" temperature_2m = "°C" [hourly] time = [ "2014-10-05T00:00", "2014-10-05T01:00", "2014-10-05T02:00", "2014-10-05T03:00", "2014-10-05T04:00", "2014-10-05T05:00", "2014-10-05T06:00", "2014-10-05T07:00", "2014-10-05T08:00", "2014-10-05T09:00", "2014-10-05T10:00", "2014-10-05T11:00", "2014-10-05T12:00", "2014-10-05T13:00", "2014-10-05T14:00", "2014-10-05T15:00", "2014-10-05T16:00", "2014-10-05T17:00", "2014-10-05T18:00", "2014-10-05T19:00", "2014-10-05T20:00", "2014-10-05T21:00", "2014-10-05T22:00", "2014-10-05T23:00", ] temperature_2m = [ 5.7, 5.3, 5.0, 4.8, 4.6, 4.6, 7.0, 8.9, 10.8, 12.2, 13.3, 13.9, 13.9, 13.7, 13.3, 12.3, 11.1, 10.2, 9.4, 8.5, 8.2, 7.9, 8.0, 7.8, ] ``` (This example uses [`taplo fmt`](https://taplo.tamasfe.dev/cli/usage/formatting.html) to reformat the TOML and break up long lines containing the arrays. Remarshal does not limit TOML line length.) ## License MIT. See the file [`LICENSE`](LICENSE). `example.toml` from . `example.json`, `example.msgpack`, `example.cbor`, `example.yml`, `tests/bin.msgpack`, and `tests/bin.yml` are derived from it.