From a0aa2307322cd47bbf416810ac0292925e03be87 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 19:39:49 +0200 Subject: Adding upstream version 1:7.0.3. Signed-off-by: Daniel Baumann --- rust/vendor/nom-derive/.cargo-checksum.json | 1 + rust/vendor/nom-derive/.travis.yml | 17 + rust/vendor/nom-derive/CHANGELOG.md | 138 +++ rust/vendor/nom-derive/Cargo.toml | 56 ++ rust/vendor/nom-derive/LICENSE-APACHE | 201 +++++ rust/vendor/nom-derive/LICENSE-MIT | 25 + rust/vendor/nom-derive/README.md | 118 +++ rust/vendor/nom-derive/UPGRADING.md | 69 ++ rust/vendor/nom-derive/src/docs.rs | 1271 +++++++++++++++++++++++++++ rust/vendor/nom-derive/src/helpers.rs | 75 ++ rust/vendor/nom-derive/src/lib.rs | 117 +++ rust/vendor/nom-derive/src/traits.rs | 269 ++++++ 12 files changed, 2357 insertions(+) create mode 100644 rust/vendor/nom-derive/.cargo-checksum.json create mode 100644 rust/vendor/nom-derive/.travis.yml create mode 100644 rust/vendor/nom-derive/CHANGELOG.md create mode 100644 rust/vendor/nom-derive/Cargo.toml create mode 100644 rust/vendor/nom-derive/LICENSE-APACHE create mode 100644 rust/vendor/nom-derive/LICENSE-MIT create mode 100644 rust/vendor/nom-derive/README.md create mode 100644 rust/vendor/nom-derive/UPGRADING.md create mode 100644 rust/vendor/nom-derive/src/docs.rs create mode 100644 rust/vendor/nom-derive/src/helpers.rs create mode 100644 rust/vendor/nom-derive/src/lib.rs create mode 100644 rust/vendor/nom-derive/src/traits.rs (limited to 'rust/vendor/nom-derive') diff --git a/rust/vendor/nom-derive/.cargo-checksum.json b/rust/vendor/nom-derive/.cargo-checksum.json new file mode 100644 index 0000000..e411df8 --- /dev/null +++ b/rust/vendor/nom-derive/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".travis.yml":"b316d06e27869c19edac3cf3a58c41e33340bd920a4d5f0267803fbd52d50375","CHANGELOG.md":"c17018e7dfe16f76e6a8040ef13ec083e4bfb673cb3261598213241591561306","Cargo.toml":"3edbb0a3ed40dc556c76bb71fdfb2ed1bf91b957f992daf6af8f35b5a7fbc09f","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"a5c61b93b6ee1d104af9920cf020ff3c7efe818e31fe562c72261847a728f513","README.md":"5b7691490b9651f892750a839a4e154e704d73938161fbdbf69b434fe07fafc2","UPGRADING.md":"2088acf26d55a419c62706fd6b4162c8c84b5fe9dae1b0d1d80491cc948f7347","src/docs.rs":"3307db4f80f840579af28fcd8d04852bbca55d8a4e9de38857991cd14f21225a","src/helpers.rs":"5555d6240271ffc228990d6ab361212687350b61c5601488798429abcdf44cea","src/lib.rs":"e473357938da9874ec0c5307170d0695cdce25af79b91765730128dc98b97ddc","src/traits.rs":"7dee07e78f1cc9ba29b8d8af066a662938d9bf193b7d88545361e1f3d41c0c6d"},"package":"1ff943d68b88d0b87a6e0d58615e8fa07f9fd5a1319fa0a72efc1f62275c79a7"} \ No newline at end of file diff --git a/rust/vendor/nom-derive/.travis.yml b/rust/vendor/nom-derive/.travis.yml new file mode 100644 index 0000000..6b7a3e0 --- /dev/null +++ b/rust/vendor/nom-derive/.travis.yml @@ -0,0 +1,17 @@ +language: rust +sudo: false +matrix: + include: + - rust: stable + env: + - NAME="stable" + - FEATURES='' + - rust: nightly + env: + - NAME="nightly" + - FEATURES='' +script: + - | + cargo build --verbose --features "$FEATURES" && + cargo test --verbose --features "$FEATURES" && + ([ "$BENCH" != 1 ] || cargo bench --verbose --features "$FEATURES") diff --git a/rust/vendor/nom-derive/CHANGELOG.md b/rust/vendor/nom-derive/CHANGELOG.md new file mode 100644 index 0000000..2079c6b --- /dev/null +++ b/rust/vendor/nom-derive/CHANGELOG.md @@ -0,0 +1,138 @@ +# ChangeLog + +## [Unreleased][unreleased] + +### Changed/Fixed + +### Added + +### Thanks + +## 0.10.1 + +### Changed/Fixed + +- Fix build failure caused by syn 2.0 (#47, #48) +- Set MSRV to 1.48 (caused by build dependencies) + +## 0.10.0 + +### Changed/Fixed + +- Refactor code +- Upgrade to nom 7 +- Reduce nom dependencies and features (remove bitvec) +- Fix parsing of String with generic errors enabled (#32) + +## 0.9.1 + +### Changed/Fixed + +- Special case derive functions should be public (#27) +- Fixed missing extra_args in parsing function decls (#29) + +### Added + +- Enable array fields (#26) + +### Thanks + +- @dbcfd for fixing public attribute on special-case functions +- @katyo for fixing missing extra_args +- @hammypants for arrays (#26) + +## 0.9.0 + +### Changed/Fixed + +### Added + +- Add Into attribute to convert output/error types +- Generate implementation of Parse trait when possible (closes #21) + +The code now generates 3 functions instead of one (parse): +- parse_be: parse object as big-endian +- parse_le: parse object as little-endian +- parse: default function, wraps a call to parse_be + +If the endianness of the struct is fixed, then all 3 functions are equivalent. + +### Thanks + +## 0.8.0 + +Refactor crate: + +- Split crate in two (`nom-derive` and `nom-derive-impl`) so it can export public items, in particular the `Parse` trait +- Provide implementation of `Parse` for primitive types, including primitive arrays (closes #4). Also provide example of newtype pattern to specify different implementations (#16) +- Refactor argument parsing and code generation. The AST now include all items, and does not handle most attributes as special, and generate code from top to bottom. This means that + - attributes are now all handled the same way for deriving struct and enum + - order of attributes is now important + - it is possible to specify that a field should be first parse then ignored (#18), or the parse function that will be used with `Count` (#9) + - endianness is now determined by first looking a field attribute, then object endianness. + - The `NomBE` and `NomLE` custom derive attributes have been added, and allow specifying global endianness using imports (for ex `use nom_derive::NomLE as Nom`) (#14) +- Add support for generic type parameters and better support for lifetimes and where clauses +- Add `GenericErrors` attribute, to generate a function signature with generic error type (#19) +- Add Complete attribute for top-level (#17) + +Except for the order of attributes, there should be no breaking change. + +## 0.7.2 + +- Add LengthCount attribute (#15) +- Add f32 and f64 as native types (#16) +- Rewrite error handling to raise compile errors (instead of panic) + +## 0.7.1 + +- Fix build for syn 1.0.58 (#11) + +## 0.7.0 + +- Upgrade to nom 6 + +## 0.6.3 + +- Add support for guards in Selector Patterns (#5) +- Add limited support for Unit fields in enum (#6) +- Make `parse` method public for enums too (#7) + +## 0.6.2 + +- Add ExtraArgs support for structs (top-level only) +- Allow dynamic configuration of endianness (SetEndian attribute) +- Add support for `u128`/`i128` (#3) + +## 0.6.1 + +- Add Tag attribute +- Fix type verification with Cond when using multiple attributes + +## 0.6.0 + +- Switch to nom parsing functions, do not generate macros +- Use qualified paths, caller do not have to import nom macros +- Move all attributes under the 'nom' namespace +- Add many attributes (LittleEndian, BigEndian, Map, Debug, Value, Take, + AlignAfter/AlignBefore, SkipAfter/SkipBefore, ErrorIf, etc.) +- Deprecate the `NomDeriveDebug` derive (replaced by `DebugDerive` attribute) +- Improve documentation, add many examples +- Rewrite attribute parser, now accepting a more flexible syntax + +## 0.5.0 + +- Upgrade to nom 5.0 +- The `parse` method is now public +- Upgrade dependencies (syn, quote, proc-macro2) + +## 0.4.0 + +- Add support for `Enum` parser generator + - Enums require a selector to choose the variant + - Fieldless enums (list of constants) are handled as a special case +- Add `NomDeriveDebug` attribute to display generated parser on stderr during build + +## 0.3.0 + +- Move crate to rust-bakery github project +- Add `Count` attribute diff --git a/rust/vendor/nom-derive/Cargo.toml b/rust/vendor/nom-derive/Cargo.toml new file mode 100644 index 0000000..1374d3c --- /dev/null +++ b/rust/vendor/nom-derive/Cargo.toml @@ -0,0 +1,56 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +name = "nom-derive" +version = "0.10.1" +authors = ["Pierre Chifflier "] +include = [ + "LICENSE-*", + "CHANGELOG.md", + "UPGRADING.md", + "README.md", + ".gitignore", + ".travis.yml", + "Cargo.toml", + "nom-derive-impl/Cargo.toml", + "nom-derive-impl/*.rs", + "src/*.rs", + "src/meta/*.rs", +] +description = "Custom derive nom parsers from struct" +homepage = "https://github.com/rust-bakery/nom-derive" +readme = "README.md" +keywords = [ + "parser", + "nom", +] +categories = ["parsing"] +license = "MIT/Apache-2.0" +repository = "https://github.com/rust-bakery/nom-derive.git" + +[dependencies.nom] +version = "7.0" +features = ["std"] +default-features = false + +[dependencies.nom-derive-impl] +version = "=0.10.1" + +[dependencies.rustversion] +version = "1.0" + +[dev-dependencies.pretty_assertions] +version = "0.7" + +[dev-dependencies.trybuild] +version = "1.0" diff --git a/rust/vendor/nom-derive/LICENSE-APACHE b/rust/vendor/nom-derive/LICENSE-APACHE new file mode 100644 index 0000000..16fe87b --- /dev/null +++ b/rust/vendor/nom-derive/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/rust/vendor/nom-derive/LICENSE-MIT b/rust/vendor/nom-derive/LICENSE-MIT new file mode 100644 index 0000000..290e7b9 --- /dev/null +++ b/rust/vendor/nom-derive/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2017 Pierre Chifflier + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/rust/vendor/nom-derive/README.md b/rust/vendor/nom-derive/README.md new file mode 100644 index 0000000..6bbb37f --- /dev/null +++ b/rust/vendor/nom-derive/README.md @@ -0,0 +1,118 @@ + + +# nom-derive + +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE-MIT) +[![Apache License 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](./LICENSE-APACHE) +[![docs.rs](https://docs.rs/nom-derive/badge.svg)](https://docs.rs/nom-derive) +[![Build Status](https://travis-ci.org/chifflier/nom-derive.svg?branch=master)](https://travis-ci.org/chifflier/nom-derive) +[![Crates.io Version](https://img.shields.io/crates/v/nom-derive.svg)](https://crates.io/crates/nom-derive) + +## Overview + +nom-derive is a custom derive attribute, to derive [nom] parsers automatically from the structure definition. + +It is not meant to replace [nom], but to provide a quick and easy way to generate parsers for +structures, especially for simple structures. This crate aims at simplifying common cases. +In some cases, writing the parser manually will remain more efficient. + +- [API documentation](https://docs.rs/nom-derive) +- The [docs::Nom] pseudo-module. This is the main + documentation for the `Nom` attribute, with all possible options and many examples. + +*Feedback welcome !* + +## `#[derive(Nom)]` + +This crate exposes a single custom-derive macro `Nom` which +implements `parse` for the struct it is applied to. + +The goal of this project is that: + +* `derive(Nom)` should be enough for you to derive [nom] parsers for simple + structures easily, without having to write it manually +* it allows overriding any parsing method by your own +* it allows using generated parsing functions along with handwritten parsers and + combining them without efforts +* it remains as fast as nom + +`nom-derive` adds declarative parsing to `nom`. It also allows mixing with +procedural parsing easily, making writing parsers for byte-encoded formats +very easy. + +For example: + +```rust +use nom_derive::*; + +#[derive(Nom)] +struct S { + a: u32, + b: u16, + c: u16 +} +``` + +This adds static method `parse` to `S`. The generated code looks +like: +```rust,ignore +impl S { + pub fn parse(i: &[u8]) -> nom::IResult(&[u8], S) { + let (i, a) = be_u32(i)?; + let (i, b) = be_u16(i)?; + let (i, c) = be_u16(i)?; + Ok((i, S{ a, b, c })) + } +} +``` + +To parse input, just call `let res = S::parse(input);`. + +For extensive documentation of all attributes and examples, see the documentation of [docs::Nom] +custom derive attribute. + +Many examples are provided, and more can be found in the [project +tests](https://github.com/rust-bakery/nom-derive/tree/master/tests). + +## Combinators visibility + +All inferred parsers will generate code with absolute type path, so there is no need +to add `use` statements for them. However, if you use any combinator directly (or in a `Parse` +statement, for ex.), it has to be imported as usual. + +That is probably not going to change, since +* a proc_macro cannot export items other than functions tagged with `#[proc_macro_derive]` +* there are variants of combinators with the same names (complete/streaming, bits/bytes), so + re-exporting them would create side-effects. + +## Debug tips + +* If the generated parser does not compile, add `#[nom(DebugDerive)]` to the structure. + It will dump the generated parser to `stderr`. +* If the generated parser fails at runtime, try adding `#[nom(Debug)]` to the structure or + to fields. It wraps subparsers in `dbg_dmp` and will print the field name and input to + `stderr` if the parser fails. + +[nom]: https://github.com/geal/nom + + +## Changes + +See `CHANGELOG.md`, and `UPGRADING.md` for instructions for upgrading major versions. + +## License + +Licensed under either of + + * Apache License, Version 2.0 + ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) + * MIT license + ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + +at your option. + +## Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. diff --git a/rust/vendor/nom-derive/UPGRADING.md b/rust/vendor/nom-derive/UPGRADING.md new file mode 100644 index 0000000..db5a82d --- /dev/null +++ b/rust/vendor/nom-derive/UPGRADING.md @@ -0,0 +1,69 @@ +## Upgrading to 0.9 + +### Generalization of the Parse trait + +`nom-derive` now generates an implementation of the `Parse` trait when possible (when there are no selector or extra args). +The methods `parse_be` and `parse_le` are both generated (unless endianness is fixed), and will recursively call +similarly named methods in child objects. + +There are two possibilities: + - the object can be represented (and parsed) differently, depending on the endianness + - the object always have the same representation, and does not depend on the endianness (most common case) + +If the object always have the same parsing, then the endianness should be fixed. This can be done by using the `NomBE` +or `NomLE` custom derive instead of `Nom`, or by applying the `BigEndian` or `LittleEndian` top-level attributes. + +If the object can has different representations, then the `Nom` custom derive should be used. + +Additionally, calling the parsing methods requires the `Parse` trait, so callers must import it: +```rust +use nom_derive::Parse; +``` + +### Manual implementations of the `parse` method + +If you have manually implemented or called `parse` methods, you should convert them to implementations of the `Parse` +trait. + +There are two possibilities: + - object does not depend on endianness: only the `parse` method of the trait should be implemented + - object has different representations: both `parse_be` and `parse_le` should be implemented + +For example: + +```rust +impl OspfLinkStateAdvertisement { + pub fn parse(input: &[u8]) -> IResult<&[u8], OspfLinkStateAdvertisement> { + ... + } +} +``` + +An OSPF packet is always represented as big-endian, so this becomes: + +```rust +impl<'a> Parse<&'a [u8]> for OspfLinkStateAdvertisement { + fn parse(input: &'a [u8]) -> IResult<&'a [u8], OspfLinkStateAdvertisement> { + ... + } +} +``` + +In most cases, that means only changing the `impl` statement and removing the `pub` keyword. + +## Upgrading to 0.8 + +### The Parse trait + +The trait `Parse` has been introduced in 0.8.0. This trait is used to provide a common interface, and default implementations for primitive types. + +As a consequence, it must be imported as well as the custom derive attribute: +`use nom_derive::Nom` now often becomes `use nom_derive::{Nom, Parse}` or `use nom_derive::*`. + +### Order of attributes + +`nom-derive` will now apply attributes in order of appearance to build a parse tree. + +For example, if specifying both `Count` and `Cond` attributes: +- `Count="4", Cond(a > 0)` is built as `Count(4, Cond(a> 0, T::Parse))`, which means a type `Vec>` is expected +- `Cond(a > 0), Count="4"` is built as `Cond(a> 0, Count(4, T::Parse))`, which means a type `Option>` is expected diff --git a/rust/vendor/nom-derive/src/docs.rs b/rust/vendor/nom-derive/src/docs.rs new file mode 100644 index 0000000..eb1bff1 --- /dev/null +++ b/rust/vendor/nom-derive/src/docs.rs @@ -0,0 +1,1271 @@ +//! The `docs` pseudo-module contains `nom-derive` documentation. Objects from this module +//! are only used to add documentation, and are not used in the crate. + +/// The `Nom` derive automatically generates an implementation of the [`Parse`](super::Parse) trait +/// for the structure using [nom] parsers, when possible. It will try to infer parsers for +/// primitive of known types, but also allows you to specify parsers using custom attributes. +/// +/// The code generates 3 methods: +/// - `parse_be`: parse object as big-endian +/// - `parse_le`: parse object as little-endian +/// - `parse`: default function, wraps a call to `parse_be` +/// +/// If the endianness of the struct is fixed (for ex. using the top-level `BigEndian` or +/// `LittleEndian` attributes, or the `NomBE` and `NomLE` custom derive), then the implementation +/// always uses this endianness, and all 3 functions are equivalent. +/// +/// When there are extra args or a selector, it is not possible to generate the trait +/// implementation (function signatures are different). In that case, an implementation block is +/// generate with the same 3 functions. +/// +/// Deriving parsers supports `struct` and `enum` types. +/// +/// Many examples are provided, and more can be found in the [project +/// tests](https://github.com/rust-bakery/nom-derive/tree/master/tests). +/// +/// [nom]: https://github.com/Geal/nom +/// +/// # Table of contents +/// +/// - [Attributes](#attributes) +/// - [Byteorder](#byteorder) +/// - [Deriving parsers for `Struct`](#deriving-parsers-for-struct) +/// - [Deriving parsers for `Enum`](#deriving-parsers-for-enum) +/// - [Generic Errors](#generic-errors) +/// - [Generic Type Parameters](#generic-type-parameters) +/// +/// # Attributes +/// +/// Derived parsers can be controlled using the `nom` attribute, with a sub-attribute. +/// For example, `#[nom(Value)]`. +/// +/// *Note: order of attributes is important!* +/// `~[nom(Count="4", Parse="be_u16")]` is not the same as `#[nom(Parse="be_u16", Count="4")]` (which is not valid, +/// since end-item parsing function is given before specifying that this primitive function is applied +/// multiple times). +/// +/// Most combinators support using literal strings `#[nom(Count="4")]` or +/// parenthesized values `#[nom(Count(4))]` +/// +/// To specify multiple attributes, use a comma-separated list: `#[nom(Debug, Count="4")]`. +/// +/// The available attributes are: +/// +/// | Attribute | Supports | Description +/// |-----------|------------------|------------ +/// | [AlignAfter](#alignment-and-padding) | fields | skip bytes until aligned to a multiple of the provided value, after parsing value +/// | [AlignBefore](#alignment-and-padding) | fields | skip bytes until aligned to a multiple of the provided value, before parsing value +/// | [BigEndian](#byteorder) | all | Set the endianness to big endian +/// | [Cond](#conditional-values) | fields | Used on an `Option` to read a value of type `T` only if the condition is met +/// | [Complete](#complete) | all | Transforms Incomplete into Error +/// | [Count](#count) | fields | Set the expected number of items to parse +/// | [Debug](#debug) | all | Print error message and input if parser fails (at runtime) +/// | [DebugDerive](#debugderive) | top-level | Print the generated code to stderr during build +/// | [Default](#default) | fields | Do not parse, set a field to the default value for the type +/// | [ErrorIf](#verifications) | fields | Before parsing, check condition is true and return an error if false. +/// | [Exact](#exact) | top-level | Check that input was entirely consumed by parser +/// | [GenericErrors](#generic-errors) | top-level | Change function signature to accept generic type parameter for error +/// | [If](#conditional-values) | fields | Similar to `Cond` +/// | [Ignore](#default) | fields | An alias for `default` +/// | [InputName](#input-name) | top-level | Change the internal name of input +/// | [Into](#into) | fields | Automatically converts the child parser's result to another type +/// | [LengthCount](#lengthcount) | fields | Specify a parser to get the number of items, and parse the expected number of items +/// | [LittleEndian](#byteorder) | all | Set the endianness to little endian +/// | [Map](#map) | fields | Parse field, then apply a function +/// | [Move](#alignment-and-padding) | fields | add the specified offset to current position, before parsing +/// | [MoveAbs](#alignment-and-padding) | fields | go to the specified absoluted position, before parsing +/// | [Parse](#custom-parsers) | fields | Use a custom parser function for reading from a file +/// | [PreExec](#preexec) | all | Execute Rust code before parsing field or struct +/// | [PostExec](#postexec) | all | Execute Rust code after parsing field or struct +/// | [Selector](#deriving-parsers-for-enum) | all | Used to specify the value matching an enum variant +/// | [SetEndian](#byteorder) | all | Dynamically set the endianness +/// | [SkipAfter](#alignment-and-padding) | fields | skip the specified number of bytes, after parsing +/// | [SkipBefore](#alignment-and-padding) | fields | skip the specified number of bytes, before parsing +/// | [Tag](#tag) | fields | Parse a constant pattern +/// | [Take](#take) | fields | Take `n` bytes of input +/// | [Value](#value) | fields | Store result of evaluated expression in field +/// | [Verify](#verifications) | fields | After parsing, check that condition is true and return an error if false. +/// +/// See below for examples. +/// +/// # Deriving parsers for `Struct` +/// +/// The `Nom` derive automatically generates an implementation of the [`Parse`](super::Parse) trait +/// for the structure using [nom] parsers, when possible. It will try to infer parsers for +/// primitive of known types, but also allows you to specify parsers using custom attributes. +/// +/// The code generates 3 methods: +/// - `parse_be`: parse object as big-endian +/// - `parse_le`: parse object as little-endian +/// - `parse`: default function, wraps a call to `parse_be` +/// +/// These methods are contained in a generated implementation of the `Parse` trait. +/// Note: if `ExtraArgs` is specified, the generated code cannot implement the `Parse` trait (the +/// function signatures are different because of the extra arguments). +/// +/// Import the `Nom` derive attribute: +/// +/// ```rust +/// use nom_derive::*; +/// ``` +/// and add it to structs or enums. +/// The `Parse` trait is required for primitive types (`u8`, `u16`, ...). +/// +/// For simple structures, the parsers are automatically generated: +/// +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S { +/// a: u32, +/// b: u16, +/// c: u16 +/// } +/// +/// # let input = b"\x00\x00\x00\x01\x12\x34\x56\x78"; +/// # let res = S::parse(input); +/// # assert_eq!(res, Ok((&input[8..],S{a:1,b:0x1234,c:0x5678}))); +/// ``` +/// +/// This also work for tuple structs: +/// +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug, PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S(u32); +/// # +/// # let input = b"\x00\x00\x00\x01"; +/// # let res = S::parse(input); +/// # assert_eq!(res, Ok((&input[4..],S(1)))); +/// ``` +/// +/// ## Byteorder +/// +/// By default, multiple methods are generated: one for big-endian and one for little-endian. +/// +/// The `BigEndian` or `LittleEndian` attributes can be applied to a struct to specify that it must +/// always be parsed as the given endianness. In that case, the methods `parse_be` and `parse_le` +/// will be generated as usual, but will use only the given endianness (and thus are equivalent). +/// +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug, PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// #[nom(LittleEndian)] +/// struct LittleEndianStruct { +/// a: u32, +/// b: u16, +/// c: u16 +/// } +/// +/// let input = b"\x00\x00\x00\x01\x12\x34\x56\x78"; +/// let res = LittleEndianStruct::parse(input); +/// assert_eq!(res, Ok((&input[8..], +/// LittleEndianStruct{a:0x0100_0000,b:0x3412,c:0x7856})) +/// ); +/// ``` +/// +/// It is also equivalent (and shorter) to use the `NomBE` or `NomLE` custom derive: +/// +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug, PartialEq)] // for assert_eq! +/// #[derive(NomLE)] // all fields will be parsed as little-endian +/// struct LittleEndianStruct { +/// a: u32, +/// b: u16, +/// c: u16 +/// } +/// +/// let input = b"\x00\x00\x00\x01\x12\x34\x56\x78"; +/// let res = LittleEndianStruct::parse(input); +/// assert_eq!(res, Ok((&input[8..], +/// LittleEndianStruct{a:0x0100_0000,b:0x3412,c:0x7856})) +/// ); +/// ``` +/// +/// The `BigEndian` and `LittleEndian` attributes can be specified for struct fields. +/// The corresponding field will always be parsed using the given endianness in the generated +/// `parse_be` and `parse_le` methods. +/// +/// If both per-struct and per-field attributes are present, the more specific wins. +/// +/// For example, the all fields of the following struct will be parsed as big-endian, +/// except `b`: +/// +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// #[nom(BigEndian)] +/// struct MixedEndianStruct { +/// a: u32, +/// #[nom(LittleEndian)] +/// b: u16, +/// c: u16 +/// } +/// +/// # let input = b"\x00\x00\x00\x01\x12\x34\x56\x78"; +/// # let res = MixedEndianStruct::parse(input); +/// # assert_eq!(res, Ok((&input[8..], +/// # MixedEndianStruct{a:0x1,b:0x3412,c:0x5678})) +/// # ); +/// ``` +/// +/// The `SetEndian` attribute changes the endianness of all following integer parsers to the +/// provided endianness (expected argument has type `nom::number::Endianness`). The expression +/// can be any expression or function returning an endianness, and will be evaluated once +/// at the location of the attribute. +/// +/// Only the parsers after this attribute (including it) are affected: if `SetEndian` is applied to +/// the third field of a struct having 4 fields, only the fields 3 and 4 will have dynamic +/// endianness. +/// +/// This allows dynamic (runtime) change of the endianness, at a small cost (a test is done before +/// every following integer parser). +/// However, if the argument is static or known at compilation, the compiler will remove the test +/// during optimization. +/// +/// If a `BigEndian` or `LittleEndian` is applied to a field, its definition is used prior to +/// `SetEndian`. +/// +/// For ex, to create a parse function having two arguments (`input`, and the endianness): +/// +/// ```rust +/// # use nom_derive::*; +/// # use nom::number::Endianness; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// #[nom(ExtraArgs(endian: Endianness))] +/// #[nom(SetEndian(endian))] // Set dynamically the endianness +/// struct MixedEndianStruct { +/// a: u32, +/// b: u16, +/// #[nom(BigEndian)] // Field c will always be parsed as BigEndian +/// c: u16 +/// } +/// +/// # let input = b"\x00\x00\x00\x01\x12\x34\x56\x78"; +/// let res = MixedEndianStruct::parse(input, Endianness::Big); +/// # assert_eq!(res, Ok((&input[8..], +/// # MixedEndianStruct{a:0x1,b:0x1234,c:0x5678})) +/// # ); +/// # let res = MixedEndianStruct::parse(input, Endianness::Little); +/// # assert_eq!(res, Ok((&input[8..], +/// # MixedEndianStruct{a:0x0100_0000,b:0x3412,c:0x5678})) +/// # ); +/// ``` +/// +/// # Deriving and Inferring Parsers +/// +/// `nom-derive` is also able to infer parsers for some usual types: integers, `Option`, `Vec`, etc. +/// +/// If the parser cannot be inferred, a default function will be called. It is also possible to +/// override this using the `Parse` attribute. +/// +/// Following sections give more details. +/// +/// ## Option types +/// +/// If a field is an `Option`, the generated parser is `opt(complete(T::parse))` +/// +/// For ex: +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S { +/// a: Option +/// } +/// +/// let input = b"\x00\x00\x00\x01"; +/// let res = S::parse(input); +/// assert_eq!(res, Ok((&input[4..],S{a:Some(1)}))); +/// ``` +/// +/// ## Vec types +/// +/// If a field is an `Vec`, the generated parser is `many0(complete(T::parse))` +/// +/// For ex: +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S { +/// a: Vec +/// } +/// +/// let input = b"\x00\x00\x00\x01"; +/// let res = S::parse(input); +/// assert_eq!(res, Ok((&input[4..],S{a:vec![0,1]}))); +/// ``` +/// +/// ## Count +/// +/// The `Count(n)` attribute can be used to specify the number of items to parse. +/// +/// Notes: +/// - the subparser is inferred as usual (item type must be `Vec< ... >`) +/// - the number of items (`n`) can be any expression, and will be cast to `usize` +/// +/// For ex: +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S { +/// a: u16, +/// #[nom(Count="a")] +/// b: Vec +/// } +/// # +/// # let input = b"\x00\x01\x12\x34"; +/// # let res = S::parse(input); +/// # assert_eq!(res, Ok((&input[4..],S{a:1, b:vec![0x1234]}))); +/// ``` +/// +/// ## LengthCount +/// +/// The `LengthCount="parser"` attribute can be used to specify a parser to get a number, and +/// use this number to parse an expected number of items. +/// +/// Notes: +/// - the subparser is inferred as usual (item type must be `Vec< ... >`) +/// - the length parser must return a number +/// +/// For ex: +/// ```rust +/// # use nom_derive::*; +/// # use nom::number::streaming::be_u16; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S { +/// #[nom(LengthCount="be_u16")] +/// b: Vec +/// } +/// # +/// # let input = b"\x00\x01\x12\x34"; +/// # let res = S::parse(input); +/// # assert_eq!(res, Ok((&input[4..],S{b:vec![0x1234]}))); +/// ``` +/// +/// ## Tag +/// +/// The `Tag(value)` attribute is used to parse a constant value (or "magic"). +/// +/// For ex: +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S<'a> { +/// #[nom(Tag(b"TAG"))] +/// tag: &'a[u8], +/// a: u16, +/// b: u16, +/// } +/// # +/// # let input = b"TAG\x00\x01\x12\x34"; +/// # let res = S::parse(input); +/// # assert_eq!(res, Ok((&input[7..],S{tag: b"TAG", a:1, b:0x1234}))); +/// ``` +/// +/// ## Take +/// +/// The `Take="n"` attribute can be used to take `n` bytes of input. +/// +/// Notes: +/// - the number of items (`n`) can be any expression, and will be cast to `usize` +/// +/// For ex: +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S<'a> { +/// a: u16, +/// #[nom(Take="1")] +/// b: &'a [u8], +/// } +/// # +/// # let input = b"\x00\x01\x12\x34"; +/// # let res = S::parse(input); +/// # assert_eq!(res, Ok((&input[3..],S{a:1, b:&[0x12]}))); +/// ``` +/// +/// ## Default parsing function +/// +/// If a field with type `T` is not a primitive or known type, the generated parser is +/// `T::parse(input)`. +/// +/// This function can be automatically derived, or specified as a method for the struct. +/// In that case, the function must be a static method with the same API as a +/// [nom] combinator, returning the wrapped struct when parsing succeeds. +/// +/// For example (using `Nom` derive): +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S2 { +/// c: u16 +/// } +/// +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S { +/// a: u16, +/// b: S2 +/// } +/// # +/// # let input = b"\x00\x00\x00\x01"; +/// # let res = S::parse(input); +/// # assert_eq!(res, Ok((&input[4..],S{a:0,b:S2{c:1}}))); +/// ``` +/// +/// Example (implementing the `Parse` trait manually): +/// ```rust +/// # use nom_derive::*; +/// # use nom::IResult; +/// # use nom::combinator::map; +/// # use nom::number::streaming::le_u16; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// // no Nom derive +/// struct S2 { +/// c: u16 +/// } +/// +/// impl<'a> Parse<&'a[u8]> for S2 { +/// fn parse(i:&'a [u8]) -> IResult<&'a [u8],S2> { +/// map( +/// le_u16, // little-endian +/// |c| S2{c} // return a struct S2 +/// )(i) +/// } +/// } +/// +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S { +/// a: u16, +/// b: S2 +/// } +/// # +/// # let input = b"\x00\x00\x00\x01"; +/// # let res = S::parse(input); +/// # assert_eq!(res, Ok((&input[4..],S{a:0,b:S2{c:256}}))); +/// ``` +/// +/// ## Custom parsers +/// +/// Sometimes, the default parsers generated automatically are not those you +/// want. +/// +/// The `Parse` custom attribute allows for specifying the parser that +/// will be inserted in the nom parser. +/// +/// The parser is called with input as argument, so the signature of the parser +/// must be equivalent to: +/// +/// ```rust,ignore +/// fn parser(i: &[u8]) -> IResult<&[u8], T> { +/// // ... +/// } +/// ``` +/// +/// For example, to specify the parser of a field: +/// +/// ```rust +/// # use nom_derive::*; +/// # use nom::number::streaming::le_u16; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S{ +/// #[nom(Parse="le_u16")] +/// a: u16 +/// } +/// # +/// # let input = b"\x00\x01"; +/// # let res = S::parse(input); +/// # assert_eq!(res, Ok((&input[2..],S{a:256}))); +/// ``` +/// +/// The `Parse` argument can be a complex expression: +/// ```rust +/// # use nom_derive::*; +/// # use nom::combinator::cond; +/// # use nom::number::streaming::be_u16; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S{ +/// pub a: u8, +/// #[nom(Parse="cond(a > 0,be_u16)")] +/// pub b: Option, +/// } +/// # +/// # let input = b"\x01\x00\x01"; +/// # let res = S::parse(input); +/// # assert_eq!(res, Ok((&input[3..],S{a:1,b:Some(1)}))); +/// ``` +/// Note that you are responsible from providing correct code. +/// +/// ## Default +/// +/// If a field is marked as `Ignore` (or `Default`), it will not be parsed. +/// Its value will be the default value for the field type. +/// +/// This is convenient if the structured has more fields than the serialized value. +/// +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S{ +/// pub a: u8, +/// #[nom(Ignore)] +/// pub b: Option, +/// } +/// # +/// # let input = b"\x01\x00\x01"; +/// # let res = S::parse(input); +/// # assert_eq!(res, Ok((&input[1..],S{a:1,b:None}))); +/// ``` +/// +/// ## Complete +/// +/// The `Complete` attribute transforms Incomplete into Error. +/// +/// Default is to use streaming parsers. If there are not enough bytes, error will look like +/// `Err(Error::Incomplete(Needed(5)))`. A streaming parser can use this to determine if data is missing, +/// wait for more data, then call again the parse function. +/// +/// When the parser has the entire data, it is more useful to transform this into an error to stop +/// parsing, using the `Complete` attribute. +/// +/// This attribute can be used on a specific field: +/// +/// ```rust +/// # use nom_derive::*; +/// # use nom::number::streaming::be_u8; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S{ +/// pub a: u8, +/// #[nom(Complete)] +/// pub b: u64, +/// } +/// # +/// # let input = b"\x01\x00\x01"; +/// # let res = S::parse(input).expect_err("parse error"); +/// # assert!(!res.is_incomplete()); +/// ``` +/// +/// This attribute can be also used on the entire object, applying to every fields: +/// +/// ```rust +/// # use nom_derive::*; +/// # use nom::number::streaming::be_u8; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// #[nom(Complete)] +/// struct S{ +/// pub a: u8, +/// pub b: u64, +/// } +/// # +/// # let input = b"\x01\x00\x01"; +/// # let res = S::parse(input).expect_err("parse error"); +/// # assert!(!res.is_incomplete()); +/// ``` +/// +/// ## Into +/// +/// The `Into` attribute automatically converts the child parser's output and error types to other types. +/// +/// It requires the output and error type to implement the `Into` trait. +/// +/// This attribute can be used on a specific field: +/// +/// ```rust +/// # use nom_derive::*; +/// # use nom::IResult; +/// # use nom::character::streaming::alpha1; +/// # use nom::number::streaming::be_u8; +/// # +/// fn parser1(i: &[u8]) -> IResult<&[u8], &[u8]> { +/// alpha1(i) +/// } +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S{ +/// pub a: u8, +/// #[nom(Into, Parse = "parser1")] +/// pub b: Vec, +/// } +/// # +/// # let input = b"\x01abcd\x00"; +/// # let res = S::parse(input).expect("parse error"); +/// ``` +/// +/// ## Map +/// +/// The `Map` attribute can be used to apply a function to the result +/// of the parser. +/// It is often used combined with the `Parse` attribute. +/// +/// ```rust +/// # use nom_derive::*; +/// # use nom::number::streaming::be_u8; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S{ +/// pub a: u8, +/// #[nom(Map = "|x: u8| x.to_string()", Parse="be_u8")] +/// pub b: String, +/// } +/// # +/// # let input = b"\x01\x00\x01"; +/// # let res = S::parse(input); +/// # assert_eq!(res, Ok((&input[2..],S{a:1,b:"0".to_string()}))); +/// ``` +/// +/// ## Conditional Values +/// +/// The `Cond` custom attribute allows for specifying a condition. +/// The generated parser will use the `cond!` combinator, which calls the +/// child parser only if the condition is met. +/// The type with this attribute must be an `Option` type. +/// +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S{ +/// pub a: u8, +/// #[nom(Cond="a == 1")] +/// pub b: Option, +/// } +/// # +/// # let input = b"\x01\x00\x01"; +/// # let res = S::parse(input); +/// # assert_eq!(res, Ok((&input[3..],S{a:1,b:Some(1)}))); +/// ``` +/// +/// ## Value +/// +/// The `Value` attribute does not parse data. It is used to store the result +/// of the evaluated expression in the variable. +/// +/// Previous fields can be used in the expression. +/// +/// ```rust +/// # use nom_derive::*; +/// # use nom::number::streaming::be_u8; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S{ +/// pub a: u8, +/// #[nom(Value = "a.to_string()")] +/// pub b: String, +/// } +/// # +/// # let input = b"\x01\x00\x01"; +/// # let res = S::parse(input); +/// # assert_eq!(res, Ok((&input[1..],S{a:1,b:"1".to_string()}))); +/// ``` +/// +/// ## Verifications +/// +/// The `Verify` custom attribute allows for specifying a verifying function. +/// The generated parser will use the `verify` combinator, which calls the +/// child parser only if is verifies a condition (and otherwise raises an error). +/// +/// The argument used in verify function is passed as a reference. +/// +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S{ +/// #[nom(Verify="*a == 1")] +/// pub a: u8, +/// } +/// # +/// # let input = b"\x01"; +/// # let res = S::parse(input); +/// # assert_eq!(res, Ok((&input[1..],S{a:1}))); +/// ``` +/// +/// The `ErrorIf` checks the provided condition, and return an error if the +/// test returns false. +/// The condition is tested before any parsing occurs for this field, and does not +/// change the input pointer. +/// +/// Error has type `ErrorKind::Verify` (nom). +/// +/// The argument used in verify function is passed as a reference. +/// +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S{ +/// pub a: u8, +/// #[nom(ErrorIf(a != 1))] +/// pub b: u8, +/// } +/// # +/// # let input = b"\x01\x02"; +/// # let res = S::parse(input); +/// # assert_eq!(res, Ok((&input[2..],S{a:1, b:2}))); +/// ``` +/// +/// ## Exact +/// +/// The `Exact` custom attribute adds a verification after parsing the entire element. +/// It succeeds if the input has been entirely consumed by the parser. +/// +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// #[nom(Exact)] +/// struct S{ +/// pub a: u8, +/// } +/// # +/// # let input = b"\x01\x01"; +/// # let res = S::parse(&input[1..]); +/// # assert!(res.is_ok()); +/// # let res = S::parse(input); +/// # assert!(res.is_err()); +/// ``` +/// +/// ## PreExec +/// +/// The `PreExec` custom attribute executes the provided code before parsing +/// the field or structure. +/// +/// This attribute can be specified multiple times. Statements will be executed in order. +/// +/// Note that the current input can be accessed, as a regular variable (see [InputName](#input-name)). +/// If you create a new variable with the same name, it will be used as input (resulting in +/// side-effects). +/// +/// Expected value: a valid Rust statement +/// +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S{ +/// #[nom(PreExec="let sz = i.len();")] +/// pub a: u8, +/// #[nom(Value(sz))] +/// pub sz: usize, +/// } +/// # +/// # let input = b"\x01"; +/// # let res = S::parse(input); +/// # assert_eq!(res, Ok((&input[1..],S{a:1, sz:1}))); +/// ``` +/// +/// ## PostExec +/// +/// The `PostExec` custom attribute executes the provided code after parsing +/// the field or structure. +/// +/// This attribute can be specified multiple times. Statements will be executed in order. +/// +/// Note that the current input can be accessed, as a regular variable (see [InputName](#input-name)). +/// If you create a new variable with the same name, it will be used as input (resulting in +/// side-effects). +/// +/// Expected value: a valid Rust statement +/// +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S{ +/// #[nom(PostExec="let b = a + 1;")] +/// pub a: u8, +/// #[nom(Value(b))] +/// pub b: u8, +/// } +/// # +/// # let input = b"\x01"; +/// # let res = S::parse(input); +/// # assert_eq!(res, Ok((&input[1..],S{a:1, b:2}))); +/// ``` +/// +/// If applied to the top-level element, the statement is executing after the entire element +/// is parsed. +/// +/// If parsing a structure, the built structure is available in the `struct_def` variable. +/// +/// If parsing an enum, the built structure is available in the `enum_def` variable. +/// +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(PartialEq)] // for assert_eq! +/// #[derive(Debug)] +/// #[derive(Nom)] +/// #[nom(PostExec(println!("parsing done: {:?}", struct_def);))] +/// struct S{ +/// pub a: u8, +/// pub b: u8, +/// } +/// # +/// # let input = b"\x01\x02"; +/// # let res = S::parse(input); +/// # assert_eq!(res, Ok((&input[2..],S{a:1, b:2}))); +/// ``` +/// +/// ## Alignment and Padding +/// +/// - `AlignAfter`/`AlignBefore`: skip bytes until aligned to a multiple of the provided value +/// Alignment is calculated to the start of the original parser input +/// - `SkipAfter`/`SkipBefore`: skip the specified number of bytes +/// - `Move`: add the speficied offset to current position, before parsing. Offset can be negative. +/// - `MoveAbs`: go to specified absolute position (relative to the start of original parser +/// input), before parsing +/// +/// If multiple directives are provided, they are applied in order of appearance of the +/// attribute. +/// +/// If the new position would be before the start of the slice or beyond its end, +/// an error is raised (`TooLarge` or `Incomplete`, depending on the case). +/// +/// Expected value: a valid Rust value (immediate value, or expression) +/// +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// struct S{ +/// pub a: u8, +/// #[nom(AlignBefore(4))] +/// pub b: u8, +/// } +/// # +/// # let input = b"\x01\x00\x00\x00\x02"; +/// # let res = S::parse(input); +/// # assert_eq!(res, Ok((&input[5..],S{a:1, b:2}))); +/// ``` +/// +/// # Deriving parsers for `Enum` +/// +/// The `Nom` attribute can also used to generate parser for `Enum` types. +/// The generated parser will used a value (called *selector*) to determine +/// which attribute variant is parsed. +/// Named and unnamed enums are supported. +/// +/// In addition of `derive(Nom)`, a `Selector` attribute must be used: +/// - on the structure, to specify the type of selector to match +/// - on each variant, to specify the value associated with this variant. +/// +/// Expected values: +/// - top-level: a valid Rust type +/// - fields: a valid Rust match arm expression (for ex: `0`). *Note*: this expression can +/// contain a pattern guard (for ex: `x if x > 2`) +/// +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// #[nom(Selector="u8")] +/// pub enum U1{ +/// #[nom(Selector="0")] Field1(u32), +/// #[nom(Selector="1")] Field2(Option), +/// } +/// # +/// # let input = b"\x00\x00\x00\x02"; +/// # let res = U1::parse(input, 0); +/// # assert_eq!(res, Ok((&input[4..],U1::Field1(2)))); +/// ``` +/// +/// The generated function will look like: +/// +///
+/// impl U1{
+///     pub fn parse_be(i:&[u8], selector: u8) -> IResult<&[u8],U1> {
+///         match selector {
+///             ...
+///         }
+///     }
+///     pub fn parse_le(i:&[u8], selector: u8) -> IResult<&[u8],U1> {
+///         match selector {
+///             ...
+///         }
+///     }
+///     pub fn parse(i:&[u8], selector: u8) -> IResult<&[u8],U1> {
+///         U1::parse_be(i, selector)
+///     }
+/// }
+/// 
+/// +/// Note that it is not possible to generate an implementation of the `Parse` trait, since the +/// function signature has an extra argument (the selector). +/// Except this extra argument, the generated implementation behaves the same as the trait. +/// +/// It can be called either directly (`U1::parse(n)`) or using nom +/// (`call!(U1::parse,n)`). +/// +/// The selector can be a primitive type (`u8`), or any other type implementing the `PartialEq` +/// trait. +/// +/// ```rust +/// # use nom_derive::*; +/// # +/// #[derive(Debug,PartialEq,Eq,Clone,Copy,Nom)] +/// pub struct MessageType(pub u8); +/// +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// #[nom(Selector="MessageType")] +/// pub enum U1{ +/// #[nom(Selector="MessageType(0)")] Field1(u32), +/// #[nom(Selector="MessageType(1)")] Field2(Option), +/// } +/// +/// // Example of call from a struct: +/// #[derive(Nom)] +/// pub struct S1{ +/// pub msg_type: MessageType, +/// #[nom(Parse="{ |i| U1::parse(i, msg_type) }")] +/// pub msg_value: U1 +/// } +/// # +/// # let input = b"\x00\x00\x00\x02"; +/// # let res = U1::parse(input, MessageType(0)); +/// # assert_eq!(res, Ok((&input[4..],U1::Field1(2)))); +/// ``` +/// +/// ## Default case +/// +/// By default, if no value of the selector matches the input value, a nom error +/// `ErrorKind::Switch` is raised. This can be changed by using `_` as selector +/// value for one the variants. +/// +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// #[nom(Selector="u8")] +/// pub enum U2{ +/// #[nom(Selector="0")] Field1(u32), +/// #[nom(Selector="_")] Field2(u32), +/// } +/// # +/// # let input = b"\x00\x00\x00\x02"; +/// # let res = U2::parse(input, 123); +/// # assert_eq!(res, Ok((&input[4..],U2::Field2(2)))); +/// ``` +/// +/// If the `_` selector is not the last variant, the generated code will use it +/// as the last match to avoid unreachable code. +/// +/// ## Special case: specifying parsers for fields +/// +/// Sometimes, an unnamed field requires a custom parser. In that case, the +/// *field* (not the variant) must be annotated with attribute `Parse`. +/// +/// Named fields: +/// +/// ```rust +/// # use nom_derive::*; +/// # use nom::bytes::streaming::take; +/// # +/// # #[derive(Debug,PartialEq,Eq,Clone,Copy,Nom)] +/// # pub struct MessageType(pub u8); +/// # +/// #[derive(Nom)] +/// #[nom(Selector="MessageType")] +/// pub enum U3<'a>{ +/// #[nom(Selector="MessageType(0)")] Field1{a:u32}, +/// #[nom(Selector="MessageType(1)")] Field2{ +/// #[nom(Parse="take(4 as usize)")] +/// a: &'a[u8] +/// }, +/// } +/// ``` +/// +/// Unnamed fields: +/// +/// ```rust +/// # use nom_derive::*; +/// # use nom::bytes::streaming::take; +/// # +/// # #[derive(Debug,PartialEq,Eq,Clone,Copy,Nom)] +/// # pub struct MessageType(pub u8); +/// # +/// #[derive(Nom)] +/// #[nom(Selector="MessageType")] +/// pub enum U3<'a>{ +/// #[nom(Selector="MessageType(0)")] Field1(u32), +/// #[nom(Selector="MessageType(1)")] Field2( +/// #[nom(Parse="take(4 as usize)")] &'a[u8] +/// ), +/// } +/// ``` +/// +/// ## Special case: fieldless enums +/// +/// If the entire enum is fieldless (a list of constant integer values), a +/// parser can be derived if +/// - the `Enum` has a `repr(ty)` attribute, with `ty` an integer type +/// - the `Enum` implements the `Eq` trait +/// +/// In that case, the `Selector` attribute must *not* be specified. +/// +/// Note: if `ExtraArgs` is not specified, the generated code is an implementation of the `Parse` +/// trait. +/// +/// ```rust +/// # use nom_derive::*; +/// # use nom::*; +/// # use nom::number::streaming::be_u8; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[repr(u8)] +/// #[derive(Eq,Nom)] +/// pub enum U3{ +/// A, +/// B = 2, +/// C +/// } +/// # +/// # let empty : &[u8] = b""; +/// # assert_eq!( +/// # U3::parse(b"\x00"), +/// # Ok((empty,U3::A)) +/// # ); +/// # assert!( +/// # U3::parse(b"\x01").is_err() +/// # ); +/// # assert_eq!( +/// # U3::parse(b"\x02"), +/// # Ok((empty,U3::B)) +/// # ); +/// ``` +/// +/// The generated parser will parse an element of type `ty` (as Big Endian), try +/// to match to enum values, and return an instance of `Enum` if it succeeds +/// (wrapped in an `IResult`). +/// +/// For ex, `U3::parse(b"\x02")` will return `Ok((&b""[..],U3::B))`. +/// +/// ## Input Name +/// +/// Internally, the parser will use a variable to follow the input. +/// By default, this variable is named `i`. +/// +/// This can cause problems, for example, if one field of the structure has the same name +/// +/// The internal variable name can be renamed using the `InputName` top-level attribute. +/// +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// #[nom(InputName(aaa))] +/// pub struct S { +/// pub i: u8, +/// } +/// # +/// # let empty : &[u8] = b""; +/// # assert_eq!( +/// # S::parse(b"\x00"), +/// # Ok((empty, S{i:0})) +/// # ); +/// ``` +/// +/// Note that this variable can be used as usual, for ex. to peek data +/// without advancing in the current stream, determining the length of +/// remaining bytes, etc. +/// +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// #[nom(InputName(i))] +/// pub struct S { +/// pub a: u8, +/// #[nom(Value(i.len()))] +/// pub remaining_len: usize, +/// } +/// # +/// # let empty : &[u8] = b""; +/// # assert_eq!( +/// # S::parse(b"\x00"), +/// # Ok((empty, S{a:0, remaining_len:0})) +/// # ); +/// ``` +/// +/// **This can create side-effects**: if you create a variable with the same name +/// as the input, it will shadow it. While this will is generally an error, it can +/// sometimes be useful. +/// +/// For example, to skip 2 bytes of input: +/// +/// ```rust +/// # use nom_derive::*; +/// # +/// # #[derive(Debug,PartialEq)] // for assert_eq! +/// #[derive(Nom)] +/// #[nom(InputName(i))] +/// pub struct S { +/// pub a: u8, +/// // skip 2 bytes +/// // XXX this will panic if input is smaller than 2 bytes at this points +/// #[nom(PreExec(let i = &i[2..];))] +/// pub b: u8, +/// } +/// # +/// # let empty : &[u8] = b""; +/// # assert_eq!( +/// # S::parse(b"\x00\x01\x02\x03"), +/// # Ok((empty, S{a:0, b:3})) +/// # ); +/// ``` +/// +/// ## Debug +/// +/// Errors in generated parsers may be hard to understand and debug. +/// +/// The `Debug` attribute insert calls to nom's `dbg_dmp` function, which will print +/// an error message and the input if the parser fails. This attribute can be applied to either +/// fields, or at top-level (all sub-parsers will be wrapped). +/// +/// This helps resolving parse errors (at runtime). +/// +/// ```rust +/// # use nom_derive::*; +/// # +/// #[derive(Nom)] +/// pub struct S { +/// pub a: u32, +/// #[nom(Debug)] +/// pub b: u64, +/// } +/// ``` +/// +/// ## DebugDerive +/// +/// The `DebugDerive` attribute, if applied to top-level, makes the generator print the +/// generated code to `stderr`. +/// +/// This helps resolving compiler errors. +/// +/// ```rust +/// # use nom_derive::*; +/// # +/// #[derive(Nom)] +/// #[nom(DebugDerive)] +/// pub struct S { +/// pub a: u32, +/// } +/// ``` +/// +/// # Generic Errors +/// +/// By default, `nom-derive` will use `nom`'s default error type (`(&[u8], ErrorKind)`). In most cases, +/// this will be enough for a simple parser. +/// However, there are some cases like debugging a runtime error, or using custom error types, where this +/// error type is not easy to use. +/// +/// The `GenericErrors` attribute changes the generated function signature to have a generic type parameter +/// for the error type: +/// +/// ```rust +/// # use nom_derive::*; +/// # +/// #[derive(Nom)] +/// #[nom(GenericErrors)] +/// pub struct S { +/// pub a: u32, +/// } +/// ``` +/// will generate the following code signature (simplified): +/// ```rust,ignore +/// impl <'nom, E> Parse <&'nom [u8], E> for S +/// where +/// E : nom::error::ParseError <&'nom [u8]> +/// { +/// fn parse_be(orig_i : &'nom [u8]) -> IResult <&'nom [u8], Self, E> +/// { +/// ... +/// } +/// } +/// ``` +/// +/// The `parse` method requires to give a concrete type for the error type when called: +/// ```rust,ignore +/// let res: IResult<_, _, VerboseError<_>> = S::parse_be(input); +/// let (rem, res) = res.unwrap(); +/// ``` +/// +/// This attribute has the following requirements: +/// - The error type must implement `nom::error::ParseError<&[u8]>` +/// - All subparsers must return compatible error types +/// +/// # Generic Type Parameters +/// +/// `nom-derive` supports generic type parameters in the `struct` or `enum` definition. +/// +/// Requirements: +/// - Every generic type parameter must implement the [Parse](crate::Parse) trait from this crate +/// - Note: it the generic type is not boxed, this often require the type to be `Sized` +/// +/// Example: +/// ```rust +/// # use nom_derive::*; +/// # +/// #[derive(Nom)] +/// pub struct S where T: Sized { +/// pub a: u32, +/// pub t: T, +/// } +/// ``` +/// +/// Generic type parameters can also be used with generic errors. +#[allow(non_snake_case)] +pub mod Nom {} diff --git a/rust/vendor/nom-derive/src/helpers.rs b/rust/vendor/nom-derive/src/helpers.rs new file mode 100644 index 0000000..3c8f3ff --- /dev/null +++ b/rust/vendor/nom-derive/src/helpers.rs @@ -0,0 +1,75 @@ +use crate::traits::*; +use nom::error::ParseError; +use nom::{IResult, ToUsize}; +use std::marker::PhantomData; + +#[derive(Debug, PartialEq)] +pub struct LengthData { + l: PhantomData, + pub data: D, +} + +impl LengthData { + pub const fn new(data: D) -> Self { + let l = PhantomData; + LengthData { l, data } + } +} + +impl Parse for LengthData +where + I: Clone + PartialEq + InputSlice, + E: ParseError, + L: Parse + ToUsize, +{ + fn parse(i: I) -> IResult { + let (rem, length) = L::parse(i)?; + let (rem, data) = rem.take_split(length.to_usize()); + Ok((rem, LengthData::new(data))) + } + fn parse_be(i: I) -> IResult { + let (rem, length) = L::parse_be(i)?; + let (rem, data) = rem.take_split(length.to_usize()); + Ok((rem, LengthData::new(data))) + } + fn parse_le(i: I) -> IResult { + let (rem, length) = L::parse_le(i)?; + let (rem, data) = rem.take_split(length.to_usize()); + Ok((rem, LengthData::new(data))) + } +} + +pub type LengthDataU8<'a> = LengthData; +pub type LengthDataU16<'a> = LengthData; +pub type LengthDataU32<'a> = LengthData; +pub type LengthDataU64<'a> = LengthData; + +#[cfg(test)] +mod tests { + use super::*; + use nom::error::Error; + + #[test] + fn test_parse_trait_length_data() { + let input: &[u8] = b"\x00\x02ab"; + + type T<'a> = LengthData; + let res: IResult<_, _, Error<&[u8]>> = ::parse(input); + assert_eq!( + res.unwrap(), + (b"" as &[u8], LengthData::new(b"ab" as &[u8])) + ); + } + + #[test] + fn test_parse_trait_length_data16() { + let input: &[u8] = b"\x00\x02ab"; + + type T<'a> = LengthDataU16<'a>; + let res: IResult<_, _, Error<&[u8]>> = ::parse(input); + assert_eq!( + res.unwrap(), + (b"" as &[u8], LengthData::new(b"ab" as &[u8])) + ); + } +} diff --git a/rust/vendor/nom-derive/src/lib.rs b/rust/vendor/nom-derive/src/lib.rs new file mode 100644 index 0000000..6b3751d --- /dev/null +++ b/rust/vendor/nom-derive/src/lib.rs @@ -0,0 +1,117 @@ +//! # nom-derive +//! +//! [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE-MIT) +//! [![Apache License 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](./LICENSE-APACHE) +//! [![docs.rs](https://docs.rs/nom-derive/badge.svg)](https://docs.rs/nom-derive) +//! [![Build Status](https://travis-ci.org/chifflier/nom-derive.svg?branch=master)](https://travis-ci.org/chifflier/nom-derive) +//! [![Crates.io Version](https://img.shields.io/crates/v/nom-derive.svg)](https://crates.io/crates/nom-derive) +//! +//! ## Overview +//! +//! nom-derive is a custom derive attribute, to derive [nom] parsers automatically from the structure definition. +//! +//! It is not meant to replace [nom], but to provide a quick and easy way to generate parsers for +//! structures, especially for simple structures. This crate aims at simplifying common cases. +//! In some cases, writing the parser manually will remain more efficient. +//! +//! - [API documentation](https://docs.rs/nom-derive) +//! - The [docs::Nom] pseudo-module. This is the main +//! documentation for the `Nom` attribute, with all possible options and many examples. +//! +//! *Feedback welcome !* +//! +//! ## `#[derive(Nom)]` +//! +//! This crate exposes a single custom-derive macro `Nom` which +//! implements `parse` for the struct it is applied to. +//! +//! The goal of this project is that: +//! +//! * `derive(Nom)` should be enough for you to derive [nom] parsers for simple +//! structures easily, without having to write it manually +//! * it allows overriding any parsing method by your own +//! * it allows using generated parsing functions along with handwritten parsers and +//! combining them without efforts +//! * it remains as fast as nom +//! +//! `nom-derive` adds declarative parsing to `nom`. It also allows mixing with +//! procedural parsing easily, making writing parsers for byte-encoded formats +//! very easy. +//! +//! For example: +//! +//! ```rust +//! use nom_derive::*; +//! +//! #[derive(Nom)] +//! struct S { +//! a: u32, +//! b: u16, +//! c: u16 +//! } +//! ``` +//! +//! This generates an implementation of the [`Parse`] trait to `S`. The generated code looks +//! like (code simplified): +//! ```rust,ignore +//! impl<'a> Parse<&'a> for S { +//! pub fn parse_be(i: &'a [u8]) -> nom::IResult(&'a [u8], S) { +//! let (i, a) = be_u32(i)?; +//! let (i, b) = be_u16(i)?; +//! let (i, c) = be_u16(i)?; +//! Ok((i, S{ a, b, c })) +//! } +//! pub fn parse_le(i: &'a [u8]) -> nom::IResult(&'a [u8], S) { +//! let (i, a) = le_u32(i)?; +//! let (i, b) = le_u16(i)?; +//! let (i, c) = le_u16(i)?; +//! Ok((i, S{ a, b, c })) +//! } +//! pub fn parse(i: &'a [u8]) -> nom::IResult(&'a [u8], S) { +//! S::parse_be(i) +//! } +//! } +//! ``` +//! +//! To parse input, just call `let res = S::parse_be(input);`. +//! +//! If the endianness of the struct is fixed (for ex. using the top-level `BigEndian` or +//! `LittleEndian` attributes, or the `NomBE` and `NomLE` custom derive), then the implementation +//! always uses this endianness, and all 3 functions are equivalent. +//! +//! For extensive documentation of all attributes and examples, see the documentation of [docs::Nom] +//! custom derive attribute. +//! +//! Many examples are provided, and more can be found in the [project +//! tests](https://github.com/rust-bakery/nom-derive/tree/master/tests). +//! +//! ## Combinators visibility +//! +//! All inferred parsers will generate code with absolute type path, so there is no need +//! to add `use` statements for them. However, if you use any combinator directly (or in a `Parse` +//! statement, for ex.), it has to be imported as usual. +//! +//! That is probably not going to change, since +//! * a proc_macro cannot export items other than functions tagged with `#[proc_macro_derive]` +//! * there are variants of combinators with the same names (complete/streaming, bits/bytes), so +//! re-exporting them would create side-effects. +//! +//! ## Debug tips +//! +//! * If the generated parser does not compile, add `#[nom(DebugDerive)]` to the structure. +//! It will dump the generated parser to `stderr`. +//! * If the generated parser fails at runtime, try adding `#[nom(Debug)]` to the structure or +//! to fields. It wraps subparsers in `dbg_dmp` and will print the field name and input to +//! `stderr` if the parser fails. +//! +//! [nom]: https://github.com/geal/nom + +pub mod docs; +mod helpers; +mod traits; + +pub use helpers::*; +pub use traits::*; + +pub use nom; +pub use nom_derive_impl::*; diff --git a/rust/vendor/nom-derive/src/traits.rs b/rust/vendor/nom-derive/src/traits.rs new file mode 100644 index 0000000..2e48d84 --- /dev/null +++ b/rust/vendor/nom-derive/src/traits.rs @@ -0,0 +1,269 @@ +use nom::bytes::streaming::take; +use nom::combinator::{complete, map_res, opt}; +use nom::error::{Error, FromExternalError, ParseError}; +use nom::multi::{many0, many_m_n}; +use nom::number::streaming::*; +use nom::sequence::pair; +use nom::*; +use std::convert::TryFrom; +use std::ops::RangeFrom; + +pub use nom::{InputLength, Slice}; + +pub trait InputSlice: + Slice> + InputIter + InputLength + InputTake +{ +} +impl<'a> InputSlice for &'a [u8] {} + +/// Common trait for all parsers in nom-derive +/// +/// This trait is used to provide parser implementations, usually as generic as possible for the +/// error type. Implementations are provided for common and primitive types. +/// The only required method is `parse`, but it is advised to implement the `parse_be` and `parse_le` +/// methods. Derived code will call one of these methods, depending on the field endianness. +/// +/// # Example +/// +/// A possible implementation for the type `u32` is: +/// ```rust,ignore +/// impl Parse for u32 +/// where +/// E: ParseError, +/// I: InputSlice, +/// { +/// fn parse(i: I) -> IResult { be_u32(i) } // default to big-endian +/// fn parse_be(i: I) -> IResult { be_u32(i) } +/// fn parse_le(i: I) -> IResult { le_u32(i) } +/// } +/// ``` +/// +/// # Generic type parameters and input +/// +/// Note: `I` is a generic type that is mostly equivalent to `&'a [u8]`. It is used to +/// "hide" the lifetime of the input slice `&'a [u8]` and simplify traits implementation +/// and generation of derived code. +/// +/// It is possible to implement the `Parse` trait only for `&[u8]` if the +/// implementation contains non-generic functions. +/// +/// For example, the implementation for `String` is: +/// ```rust,ignore +/// impl<'a, E> Parse<&'a [u8], E> for String +/// where +/// E: ParseError<&'a [u8]> + FromExternalError<&'a [u8], std::str::Utf8Error>, +/// { +/// fn parse(i: &'a [u8]) -> IResult<&'a [u8], Self, E> { +/// let (rem, sz) = ::parse(i)?; +/// let (rem, s) = map_res(take(sz as usize), std::str::from_utf8)(rem)?; +/// Ok((rem, s.to_owned())) +/// } +/// } +/// ``` +/// +/// # Implementing primitives or specific types +/// +/// To implement an existing type differently, or a type where implementation was not provided, a +/// common way is to use a newtype pattern: +/// +/// ```rust +/// use nom_derive::{Parse, nom}; +/// +/// use nom::IResult; +/// use nom::bytes::complete::take; +/// use nom::combinator::map_res; +/// use nom::error::{Error, FromExternalError, ParseError}; +/// +/// # #[derive(Debug, PartialEq)] +/// pub struct MyString(pub String); +/// impl<'a, E> Parse<&'a [u8], E> for MyString +/// where +/// E: ParseError<&'a [u8]> + FromExternalError<&'a [u8], std::str::Utf8Error>, +/// { +/// fn parse(i: &'a [u8]) -> IResult<&'a [u8], Self, E> { +/// let (rem, sz) = ::parse(i)?; +/// let (rem, s) = map_res(take(sz as usize), std::str::from_utf8)(rem)?; +/// Ok((rem, MyString(s.to_owned()))) +/// } +/// } +/// +/// # let input = b"\x00\x00\x00\x04test"; +/// // error type cannot be inferred by compiler and must be explicit +/// let res: IResult<_, _, Error<_>> = MyString::parse(input); +/// # assert_eq!(res, Ok((&input[8..], MyString(String::from("test"))))); +/// ``` +pub trait Parse> +where + I: InputSlice, + E: ParseError, + Self: Sized, +{ + /// Parse input, not knowing the endianness + /// + /// Usually, this means choosing between big and little-endian. + /// Default implementations for common types are big-endian. + fn parse(i: I) -> IResult; + + /// Parse input as Big-Endian + fn parse_be(i: I) -> IResult { + Self::parse(i) + } + + /// Parse input as Little-Endian + fn parse_le(i: I) -> IResult { + Self::parse(i) + } +} + +macro_rules! impl_primitive_type { + ( $ty:ty, $be_fn: ident, $le_fn: ident ) => { + impl Parse for $ty + where + E: ParseError, + I: InputSlice, + { + fn parse(i: I) -> IResult { + Self::parse_be(i) + } + fn parse_be(i: I) -> IResult { + $be_fn(i) + } + fn parse_le(i: I) -> IResult { + $le_fn(i) + } + } + }; +} + +impl_primitive_type!(i8, be_i8, le_i8); +impl_primitive_type!(i16, be_i16, le_i16); +impl_primitive_type!(i32, be_i32, le_i32); +impl_primitive_type!(i64, be_i64, le_i64); +impl_primitive_type!(i128, be_i128, le_i128); + +impl_primitive_type!(u8, be_u8, le_u8); +impl_primitive_type!(u16, be_u16, le_u16); +impl_primitive_type!(u32, be_u32, le_u32); +impl_primitive_type!(u64, be_u64, le_u64); +impl_primitive_type!(u128, be_u128, le_u128); + +impl_primitive_type!(f32, be_f32, le_f32); +impl_primitive_type!(f64, be_f64, le_f64); + +impl<'a, E> Parse<&'a [u8], E> for String +where + E: ParseError<&'a [u8]> + FromExternalError<&'a [u8], std::str::Utf8Error>, +{ + fn parse(i: &'a [u8]) -> IResult<&'a [u8], Self, E> { + let (rem, sz) = ::parse(i)?; + let (rem, s) = map_res(take(sz as usize), std::str::from_utf8)(rem)?; + Ok((rem, s.to_owned())) + } +} + +impl Parse for Option +where + I: Clone + InputSlice, + E: ParseError, + T: Parse, +{ + fn parse(i: I) -> IResult { + opt(complete(::parse))(i) + } + fn parse_be(i: I) -> IResult { + opt(complete(::parse_be))(i) + } + fn parse_le(i: I) -> IResult { + opt(complete(::parse_le))(i) + } +} + +impl Parse for Vec +where + I: Clone + PartialEq + InputSlice, + E: ParseError, + T: Parse, +{ + fn parse(i: I) -> IResult { + many0(complete(::parse))(i) + } + fn parse_be(i: I) -> IResult { + many0(complete(::parse_be))(i) + } + fn parse_le(i: I) -> IResult { + many0(complete(::parse_le))(i) + } +} + +impl Parse for (T1, T2) +where + I: Clone + PartialEq + InputSlice, + E: ParseError, + T1: Parse, + T2: Parse, +{ + fn parse(i: I) -> IResult { + pair(T1::parse, T2::parse)(i) + } + fn parse_be(i: I) -> IResult { + pair(T1::parse_be, T2::parse_be)(i) + } + fn parse_le(i: I) -> IResult { + pair(T1::parse_le, T2::parse_le)(i) + } +} + +/// *Note: this implementation uses const generics and requires rust >= 1.51* +#[rustversion::since(1.51)] +impl Parse for [T; N] +where + I: Clone + PartialEq + InputSlice, + E: ParseError + FromExternalError>, + T: Parse, +{ + fn parse(i: I) -> IResult { + map_res(many_m_n(N, N, complete(::parse)), Self::try_from)(i) + } + fn parse_be(i: I) -> IResult { + map_res(many_m_n(N, N, complete(::parse_be)), |v| { + Self::try_from(v) + })(i) + } + fn parse_le(i: I) -> IResult { + map_res(many_m_n(N, N, complete(::parse_le)), |v| { + Self::try_from(v) + })(i) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_parse_trait_vec() { + let input: &[u8] = b"\x00\x01\x02\x03"; + + type T = Vec; + let res: IResult<_, _, Error<&[u8]>> = ::parse(input); + assert_eq!(res.unwrap(), (b"" as &[u8], vec![0, 1, 2, 3])); + } + + #[test] + fn test_parse_trait_array() { + let input: &[u8] = b"\x00\x01\x02\x03"; + + type T = [u8; 4]; + let res: IResult<_, _, Error<&[u8]>> = ::parse(input); + assert_eq!(res.unwrap(), (b"" as &[u8], [0, 1, 2, 3])); + } + + #[test] + fn test_parse_trait_string() { + let input: &[u8] = b"\x00\x00\x00\x04abcd"; + + type T = String; + let res: IResult<_, _, Error<&[u8]>> = ::parse_le(input); + assert_eq!(res.unwrap(), (b"" as &[u8], String::from("abcd"))); + } +} -- cgit v1.2.3