{"id":27697120,"url":"https://github.com/spyoungtech/json-five-rs","last_synced_at":"2025-04-25T15:28:09.463Z","repository":{"id":274727514,"uuid":"904593442","full_name":"spyoungtech/json-five-rs","owner":"spyoungtech","description":"JSON5 in Rust","archived":false,"fork":false,"pushed_at":"2025-02-21T00:48:01.000Z","size":156,"stargazers_count":3,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-06T15:51:31.087Z","etag":null,"topics":["json","json5","json5-parser","rust-crate"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/spyoungtech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-17T07:34:04.000Z","updated_at":"2025-02-21T20:04:05.000Z","dependencies_parsed_at":"2025-01-29T02:28:01.704Z","dependency_job_id":"dfcf1541-ae05-49ba-b434-9f59fcc61e54","html_url":"https://github.com/spyoungtech/json-five-rs","commit_stats":null,"previous_names":["spyoungtech/json-five-rs"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spyoungtech%2Fjson-five-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spyoungtech%2Fjson-five-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spyoungtech%2Fjson-five-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spyoungtech%2Fjson-five-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/spyoungtech","download_url":"https://codeload.github.com/spyoungtech/json-five-rs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250843507,"owners_count":21496396,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["json","json5","json5-parser","rust-crate"],"created_at":"2025-04-25T15:28:08.058Z","updated_at":"2025-04-25T15:28:09.454Z","avatar_url":"https://github.com/spyoungtech.png","language":"Rust","readme":"# json-five-rs\n\nThis project provides a handwritten JSON5 tokenizer and recursive descent parser compatible with `serde`.\n\n[![Crates.io Version](https://img.shields.io/crates/v/json-five)](https://crates.io/crates/json-five/) [![docs.rs](https://img.shields.io/docsrs/json-five)](https://docs.rs/json-five/latest/json_five/)\n\n# Key Features\n\n- Compatible with `serde` data model\n- Supports round-trip use cases with preservation/editing of whitespace and comments\n- Supports formatting (indent, compact formats, etc.) in serialization\n- Supports both model-based (AST) edits and token-based round-tripping\n- Performance-focused default tokenizer/parser that avoids copying input\n- Ergonomics-focused round-trip tokenizer/parser that produce structures with solely owned types for ease of editing\n- Supports basic parsing and serialization without `serde` (you may disable the default `serde` feature!)\n\n# Usage\n\nYou can use this lib with `serde` in the typical way:\n```rust\nuse json_five::from_str;\nuse serde::Deserialize;\n#[derive(Debug, PartialEq, Deserialize)]\nstruct MyData {\n    name: String,\n    count: i64,\n    maybe: Option\u003cf64\u003e,\n}\n\nfn main() {\n    let source = r#\"\n    // A possible JSON5 input\n    {\n      name: 'Hello',\n      count: 42,\n      maybe: null\n    }\n\"#;\n\n    let parsed = from_str::\u003cMyData\u003e(source).unwrap();\n    let expected = MyData {name: \"Hello\".to_string(), count: 42, maybe: None};\n    assert_eq!(parsed, expected);\n}\n```\n\nSerializing also works in the usual way. The re-exported `to_string` function comes from the `ser` module and works \nhow you'd expect with default formatting.\n\n```rust\nuse serde::Serialize;\nuse json_five::to_string;\n#[derive(Serialize)]\nstruct Test {\n    int: u32,\n    seq: Vec\u003c\u0026'static str\u003e,\n}\nlet test = Test {\n    int: 1,\n    seq: vec![\"a\", \"b\"],\n};\n\nlet serialized = to_string(\u0026test).unwrap();\n\nlet expected = r#\"{\"int\": 1, \"seq\": [\"a\", \"b\"]}\"#;\nassert_eq!(serialized, expected);\n```\n\nYou may also use the `to_string_formatted` with a `FormatConfiguration` to control the output format, including \nindentation, trailing commas, and key/item separators. A few useful constructors are available, including \n`::compact()` for the most compact format (no whitespace).\n\n```rust\nuse serde::Serialize;\nuse json_five::{to_string_formatted, FormatConfiguration, TrailingComma};\n#[derive(Serialize)]\nstruct Test {\n    int: u32,\n    seq: Vec\u003c\u0026'static str\u003e,\n}\nlet test = Test {\n    int: 1,\n    seq: vec![\"a\", \"b\"],\n};\n\nlet config = FormatConfiguration::with_indent(4, TrailingComma::ALL);\nlet formatted_doc = to_string_formatted(\u0026test, config).unwrap();\n\nlet expected = r#\"{\n    \"int\": 1,\n    \"seq\": [\n        \"a\",\n        \"b\",\n    ],\n}\"#;\n\nassert_eq!(formatted_doc, expected);\n```\n\nTip: you may use `serde_json::Value` as a target type for deserializing arbitrary JSON5 documents. In the future \nthis crate may provide an equivalent type directly (or maybe vendor this).\n\n## Examples\n\nSee the `examples/` directory for examples of programs that utilize round-tripping features.\n\n- `examples/json5-doublequote-fixer` gives an example of tokenization-based round-tripping edits\n- `examples/json5-trailing-comma-formatter` gives an example of model-based round-tripping edits\n\n\n# Benchmarking\n\nBenchmarks are available in the `benches/` directory. Test data is in the `data/` directory. A couple of benchmarks use\nbig files that are not committed to this repo. So run `./data/setupdata.sh` to download the required data files\nso that you don't skip the big benchmarks. The benchmarks compare `json_five` (this crate) to\n[serde_json](https://github.com/serde-rs/json) and [json5-rs](https://github.com/callum-oakley/json5-rs).\n\nNotwithstanding the general caveats of benchmarks, in initial testing, `json_five` definitively outperforms `json5-rs`.\nIn typical scenarios observations have been 3-4x performance, and up to 20x faster in some synthetic tests. \nAt time of writing (pre- v0) no performance optimizations have been done. I expect performance to improve, \nif at least marginally, in the future.\n\nThese benchmarks were run on Windows on an i9-10900K with rustc 1.83.0 (90b35a623 2024-11-26). This table won't be updated unless significant changes happen.\n\n\n| test                       | json_five | json5     | serde_json |\n|----------------------------|-----------|-----------|------------|\n| big (25MB)                 | 580.31 ms | 3.0861 s  | 150.39 ms  |\n| medium-ascii (5MB)         | 199.88 ms | 706.94 ms | 59.008 ms  |\n| empty                      | 228.62 ns | 708.00 ns | 38.786 ns  |\n| arrays                     | 578.24 ns | 1.3228 µs | 100.95 ns  |\n| objects                    | 922.91 ns | 2.0748 µs | 205.75 ns  |\n| nested-array               | 22.990 µs | 29.356 µs | 5.0483 µs  |\n| nested-objects             | 50.659 µs | 132.75 µs | 14.755 µs  |\n| string                     | 421.17 ns | 3.5691 µs | 91.051 ns  |\n| number                     | 238.75 ns | 779.13 ns | 36.179 ns  |\n| deserialize (size 10)      | 6.9898µs  | 58.398µs  | 886.33ns   |\n| deserialize (size 100)     | 66.005µs  | 830.79µs  | 9.9705µs   |\n| deserialize (size 1000)    | 599.39µs  | 8.4952ms  | 69.110µs   |\n| deserialize (size 10000)   | 5.9841ms  | 82.591ms  | 734.40µs   |\n| deserialize (size 100000)  | 66.841ms  | 955.37ms  | 11.638ms   |\n| deserialize (size 1000000) | 674.13ms  | 9.5758s   | 119.03ms   |\n| serialize (size 10)        | 2.3496µs  | 48.915µs  | 891.85ns   |\n| serialize (size 100)       | 19.602µs  | 458.98µs  | 6.7109µs   |\n| serialize (size 1000)      | 194.19µs  | 4.6035ms  | 62.667µs   |\n| serialize (size 10000)     | 2.2104ms  | 47.253ms  | 761.10µs   |\n| serialize (size 100000)    | 24.418ms  | 502.35ms  | 11.410ms   |\n| serialize (size 1000000)   | 245.26ms  | 4.6211s   | 115.84ms   |\n\n\n\n\n# Notes\n\n## Status\n\nThis project is in **very** early phases. While the crate is usable right now, more thorough testing is needed to \nensure that the tokenizer/parser rejects invalid documents.\n\nQuestions, discussions, and contributions are welcome. Right now, things are moving fast, so the best way to contribute \nis likely to just [open an issue](https://github.com/spyoungtech/json-five-rs/issues).\n\nExpect breaking changes for now, even in patch releases.\n\n## Serde is optional\n\nUsing `serde` is actually optional. Some use cases may not require the use of serde's various deserialization methods \nand may only need to rely on the tokenizer and/or AST tree features. By default, the serde feature is enabled, \nbut this can be disabled. Even without the `serde` feature, the parser modules provide functions and methods for \nparsing and serialization, including the ability to customize the style.\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspyoungtech%2Fjson-five-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspyoungtech%2Fjson-five-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspyoungtech%2Fjson-five-rs/lists"}