{"id":13837897,"url":"https://github.com/kamadorueda/nixel","last_synced_at":"2025-05-09T00:06:27.106Z","repository":{"id":56824519,"uuid":"477263684","full_name":"kamadorueda/nixel","owner":"kamadorueda","description":"Parser for the Nix Expressions Language","archived":false,"fork":false,"pushed_at":"2022-11-25T23:09:43.000Z","size":37933,"stargazers_count":95,"open_issues_count":1,"forks_count":3,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-05-09T00:06:15.615Z","etag":null,"topics":["abstract-syntax-tree","concrete-syntax-trees","lexer","nix","nixos","parser"],"latest_commit_sha":null,"homepage":"","language":"Nix","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kamadorueda.png","metadata":{"funding":{"github":"kamadorueda","patreon":null,"open_collective":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null},"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-04-03T07:02:12.000Z","updated_at":"2025-04-19T12:57:03.000Z","dependencies_parsed_at":"2022-09-01T13:11:15.698Z","dependency_job_id":null,"html_url":"https://github.com/kamadorueda/nixel","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kamadorueda%2Fnixel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kamadorueda%2Fnixel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kamadorueda%2Fnixel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kamadorueda%2Fnixel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kamadorueda","download_url":"https://codeload.github.com/kamadorueda/nixel/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253166518,"owners_count":21864476,"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":["abstract-syntax-tree","concrete-syntax-trees","lexer","nix","nixos","parser"],"created_at":"2024-08-04T15:01:29.737Z","updated_at":"2025-05-09T00:06:27.086Z","avatar_url":"https://github.com/kamadorueda.png","language":"Nix","funding_links":["https://github.com/sponsors/kamadorueda"],"categories":["Nix"],"sub_categories":[],"readme":"\u003c!--\nSPDX-FileCopyrightText: 2022 Kevin Amado \u003ckamadorueda@gmail.com\u003e\n\nSPDX-License-Identifier: GPL-3.0-only\n--\u003e\n\n\u003ch1 align=\"center\"\u003e🐉 NixEL\u003c/h2\u003e\n\n\u003cp align=\"center\"\u003eParser for the Nix Expressions Language.\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://buildkite.com/kamadorueda/nixel\"\u003e\n    \u003cimg\n      alt=\"CI/CD\"\n      src=\"https://badge.buildkite.com/e6a10842c4ea84190bee67360062b18a7e0c548f66ed0886a6.svg?branch=main\"\n    \u003e\n    \u003c/img\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://docs.rs/nixel\"\u003e\n    \u003cimg\n      alt=\"Documentation\"\n      src=\"https://img.shields.io/docsrs/nixel?color=brightgreen\"\n    \u003e\n    \u003c/img\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://coveralls.io/github/kamadorueda/nixel?branch=main\"\u003e\n    \u003cimg\n      alt=\"Coverage\"\n      src=\"https://coveralls.io/repos/github/kamadorueda/nixel/badge.svg?branch=main\"\n    \u003e\n    \u003c/img\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://crates.io/crates/nixel\"\u003e\n    \u003cimg\n      alt=\"Version\"\n      src=\"https://img.shields.io/crates/v/nixel?color=brightgreen\"\n    \u003e\n    \u003c/img\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://spdx.org/licenses/GPL-3.0-only.html\"\u003e\n    \u003cimg\n      alt=\"License\"\n      src=\"https://img.shields.io/crates/l/nixel?color=brightgreen\"\n    \u003e\n    \u003c/img\u003e\n  \u003c/a\u003e\n  \u003c!-- \u003ca href=\"https://crates.io/crates/santiago\"\u003e\n    \u003cimg\n      alt=\"Downloads\"\n      src=\"https://img.shields.io/crates/d/santiago\"\n    \u003e\n    \u003c/img\u003e\n  \u003c/a\u003e --\u003e\n\n\u003c/p\u003e\n\n## Features\n\n- ✔️ **Fast**\n\n  It parses all the files in [Nixpkgs](https://github.com/NixOS/nixpkgs)\n  in under 25 seconds, single-threaded.\n  [^benchmark-specs]\n\n  It's written in [Rust](https://www.rust-lang.org/)\n  and a little bit of [C++](https://isocpp.org/),\n  [Flex](https://github.com/westes/flex)\n  and [GNU Bison](https://www.gnu.org/software/bison/).\n\n- ✔️ **Correct**\n\n  This library is a copy-paste of the original\n  [lexer](https://github.com/NixOS/nix/blob/dd1970c233a82328445b69e903574e14115ee933/src/libexpr/lexer.l)\n  and [parser](https://github.com/NixOS/nix/blob/dd1970c233a82328445b69e903574e14115ee933/src/libexpr/parser.y)\n  of Nix,\n  with some types adapted for better ergonomy.\n\n  No parser can get closer to the original implementation than this.\n\n- ✔️ **Reliable**\n\n  High coverage, battle-tested, and memory-safe[^memory-safe].\n\n- ✔️ **Useful**\n\n  It gives you comments, whitespace, starting and end positions,\n  automatic string un-escaping, multiline string indentation handling,\n  a typed API,\n  and everything you need to parse the Nix language!\n\n## Usage\n\nYou can check out the documentation at [docs.rs/nixel](https://docs.rs/nixel).\n\nThis is a full usage example:\n\n```rust\nlet input: String = String::from(\n    r#\"\n        # Greet the user\n        \"Hello, World!\"\n        # Bye!\n    \"#,\n);\n\nlet parsed: nixel::Parsed = nixel::parse(input);\n\nmatch \u0026*parsed.expression {\n    nixel::Expression::String(string) =\u003e {\n        assert_eq!(\n            \u0026string.span,\n            \u0026nixel::Span {\n                start: nixel::Position { line: 3, column: 9 }.into(),\n                end: nixel::Position { line: 3, column: 24 }.into(),\n            }\n            .into()\n        );\n        assert_eq!(\n            \u0026parsed.trivia_before(\u0026string.span.start)[1],\n            \u0026nixel::Trivia::Comment(nixel::TriviaComment {\n                content: \"# Greet the user\".into(),\n                span: nixel::Span {\n                    start: nixel::Position { line: 2, column: 9 }.into(),\n                    end: nixel::Position { line: 2, column: 25 }.into(),\n                }\n                .into()\n            })\n        );\n        assert_eq!(\n            \u0026string.parts[0],\n            \u0026nixel::Part::Raw(nixel::PartRaw {\n                content: \"Hello, World!\".into(),\n                span: nixel::Span {\n                    start: nixel::Position { line: 3, column: 10 }.into(),\n                    end: nixel::Position { line: 3, column: 23 }.into(),\n                }\n                .into()\n            })\n        );\n        assert_eq!(\n            \u0026parsed.trivia_after(\u0026string.span.end)[1],\n            \u0026nixel::Trivia::Comment(nixel::TriviaComment {\n                content: \"# Bye!\".into(),\n                span: nixel::Span {\n                    start: nixel::Position { line: 4, column: 9 }.into(),\n                    end: nixel::Position { line: 4, column: 15 }.into(),\n                }\n                .into()\n            })\n        );\n    },\n    expression =\u003e unreachable!(\"Expected a String, got: {expression:#?}\"),\n}\n```\n\nOr from the CLI using Rust's Debug trait:\n\n```sh\n$ echo '1 + 2' | nix run github:kamadorueda/nixel -- --format=debug\n\nBinaryOperation(\n    BinaryOperation {\n        left: Integer(\n            Integer {\n                value: \"1\",\n                span: Span {\n                    start: Position {\n                        line: 1,\n                        column: 1,\n                    },\n                    end: Position {\n                        line: 1,\n                        column: 2,\n                    },\n                },\n            },\n        ),\n        operator: Addition,\n        right: Integer(\n            Integer {\n                value: \"2\",\n                span: Span {\n                    start: Position {\n                        line: 1,\n                        column: 5,\n                    },\n                    end: Position {\n                        line: 1,\n                        column: 6,\n                    },\n                },\n            },\n        ),\n    },\n)\n```\n\nOr from the CLI using JSON format:\n\n```sh\n$ echo '1 + 2' | nix run github:kamadorueda/nixel -- --format=json\n\n{\n  \"BinaryOperation\": {\n    \"left\": {\n      \"Integer\": {\n        \"value\": \"1\",\n        \"span\": {\n          \"start\": {\n            \"line\": 1,\n            \"column\": 1\n          },\n          \"end\": {\n            \"line\": 1,\n            \"column\": 2\n          }\n        }\n      }\n    },\n    \"operator\": \"Addition\",\n    \"right\": {\n      \"Integer\": {\n        \"value\": \"2\",\n        \"span\": {\n          \"start\": {\n            \"line\": 1,\n            \"column\": 5\n          },\n          \"end\": {\n            \"line\": 1,\n            \"column\": 6\n          }\n        }\n      }\n    }\n  }\n}\n```\n\nYou can check out more examples\nin the [tests](https://github.com/kamadorueda/nixel/tree/main/tests/cases) folder.\n\n## Alternatives\n\n- [rnix-parser](https://github.com/nix-community/rnix-parser).\n\n## License\n\nPlease read [LICENSE.md](./LICENSE.md).\n\n## Footnotes\n\n[^benchmark-specs]:\n    Running on a [machine](https://github.com/kamadorueda/machine) with:\n\n    - CPU: 4 physical, 4 logical, 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz\n    - MHz: from 400 to 4700 MHz\n    - BogoMips: 5606.40\n    - Cache L3: 12 MiB\n\n    The following command takes around 1 minute:\n\n    ```bash\n    $ nix build --system x86_64-linux\n    $ time find /data/nixpkgs -type f -name '*.nix' \\\n      -exec ./result/bin/nixel --format=none {} \\;\n\n    real  0m24.293s\n    user  0m15.066s\n    sys   0m8.955s\n    ```\n\n[^memory-safe]:\n    Tested under real-life workloads using [Valgrind](https://valgrind.org/),\n    and by running an infinite loop of parsing cycles over Nixpkgs :).\n\n    ```bash\n    $ nix build --system x86_64-linux\n    $ valgrind ./result/bin/nixel $file\n\n      LEAK SUMMARY:\n        definitely lost: 0 bytes in 0 blocks\n        indirectly lost: 0 bytes in 0 blocks\n          possibly lost: 0 bytes in 0 blocks\n             suppressed: 0 bytes in 0 blocks\n    ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkamadorueda%2Fnixel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkamadorueda%2Fnixel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkamadorueda%2Fnixel/lists"}