winnow-0.7.13/.cargo_vcs_info.json 0000644 00000000136 00000000001 0012445 0 ustar {
"git": {
"sha1": "79b3941c2d1689f692e88c8392c8dfa782020f73"
},
"path_in_vcs": ""
} winnow-0.7.13/Cargo.lock 0000644 00000120555 00000000001 0010430 0 ustar # This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "anes"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
[[package]]
name = "annotate-snippets"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "086b0afab3b349e5691143adbfb26983821e3eec4ba4c51957104d372c2e1b7d"
dependencies = [
"anstyle",
"unicode-width",
]
[[package]]
name = "anstream"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon 1.0.1",
"colorchoice",
"is-terminal",
"utf8parse",
]
[[package]]
name = "anstream"
version = "0.6.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon 3.0.3",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
[[package]]
name = "anstyle-parse"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "anstyle-wincon"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188"
dependencies = [
"anstyle",
"windows-sys 0.48.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
dependencies = [
"anstyle",
"windows-sys 0.52.0",
]
[[package]]
name = "anyhow"
version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi 0.1.19",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "automod"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebb4bd301db2e2ca1f5be131c24eb8ebf2d9559bc3744419e93baf8ddea7e670"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.60",
]
[[package]]
name = "bit-set"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
dependencies = [
"bit-vec",
]
[[package]]
name = "bit-vec"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42"
[[package]]
name = "block-buffer"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e"
dependencies = [
"generic-array",
]
[[package]]
name = "bumpalo"
version = "3.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
[[package]]
name = "bytecount"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c"
[[package]]
name = "byteorder"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "cast"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
[[package]]
name = "cc"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "ciborium"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926"
dependencies = [
"ciborium-io",
"ciborium-ll",
"serde",
]
[[package]]
name = "ciborium-io"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656"
[[package]]
name = "ciborium-ll"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b"
dependencies = [
"ciborium-io",
"half",
]
[[package]]
name = "circular"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fc239e0f6cb375d2402d48afb92f76f5404fd1df208a41930ec81eda078bea"
[[package]]
name = "clap"
version = "4.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d"
dependencies = [
"clap_builder",
]
[[package]]
name = "clap_builder"
version = "4.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1"
dependencies = [
"anstyle",
"clap_lex",
]
[[package]]
name = "clap_lex"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b"
[[package]]
name = "colorchoice"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
name = "cpufeatures"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
dependencies = [
"libc",
]
[[package]]
name = "criterion"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f"
dependencies = [
"anes",
"cast",
"ciborium",
"clap",
"criterion-plot",
"is-terminal",
"itertools",
"num-traits",
"once_cell",
"oorandom",
"plotters",
"rayon",
"regex",
"serde",
"serde_derive",
"serde_json",
"tinytemplate",
"walkdir",
]
[[package]]
name = "criterion-plot"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1"
dependencies = [
"cast",
"itertools",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
dependencies = [
"cfg-if",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7"
dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
"memoffset",
"scopeguard",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
dependencies = [
"cfg-if",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "ctor"
version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
dependencies = [
"quote",
"syn 1.0.109",
]
[[package]]
name = "diff"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
[[package]]
name = "digest"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]]
name = "either"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
[[package]]
name = "errno"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
dependencies = [
"errno-dragonfly",
"libc",
"windows-sys 0.48.0",
]
[[package]]
name = "errno-dragonfly"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
dependencies = [
"cc",
"libc",
]
[[package]]
name = "escargot"
version = "0.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05a3ac187a16b5382fef8c69fd1bad123c67b7cf3932240a2d43dcdd32cded88"
dependencies = [
"log",
"once_cell",
"serde",
"serde_json",
]
[[package]]
name = "fastrand"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
dependencies = [
"instant",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "generic-array"
version = "0.14.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "getrandom"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "half"
version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
[[package]]
name = "handlebars"
version = "4.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "035ef95d03713f2c347a72547b7cd38cbc9af7cd51e6099fb62d586d4a6dee3a"
dependencies = [
"log",
"pest",
"pest_derive",
"serde",
"serde_json",
"thiserror",
]
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "hermit-abi"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
dependencies = [
"libc",
]
[[package]]
name = "hermit-abi"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
[[package]]
name = "instant"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
dependencies = [
"cfg-if",
]
[[package]]
name = "io-lifetimes"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
dependencies = [
"hermit-abi 0.3.1",
"libc",
"windows-sys 0.48.0",
]
[[package]]
name = "is-terminal"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
dependencies = [
"hermit-abi 0.3.1",
"rustix 0.38.6",
"windows-sys 0.48.0",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b52b2de84ed0341893ce61ca1af04fa54eea0a764ecc38c6855cc5db84dc1927"
dependencies = [
"is-terminal",
]
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
[[package]]
name = "js-sys"
version = "0.3.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lexopt"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baff4b617f7df3d896f97fe922b64817f6cd9a756bb81d40f8883f2f66dcb401"
[[package]]
name = "libc"
version = "0.2.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
[[package]]
name = "libm"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4"
[[package]]
name = "linux-raw-sys"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
[[package]]
name = "linux-raw-sys"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503"
[[package]]
name = "log"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "memoffset"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
dependencies = [
"autocfg",
]
[[package]]
name = "normalize-line-endings"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
[[package]]
name = "num-traits"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
dependencies = [
"autocfg",
"libm",
]
[[package]]
name = "num_cpus"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
dependencies = [
"hermit-abi 0.2.6",
"libc",
]
[[package]]
name = "once_cell"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "oorandom"
version = "11.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
[[package]]
name = "os_pipe"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a53dbb20faf34b16087a931834cba2d7a73cc74af2b7ef345a4c8324e2409a12"
dependencies = [
"libc",
"windows-sys 0.45.0",
]
[[package]]
name = "output_vt100"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "628223faebab4e3e40667ee0b2336d34a5b960ff60ea743ddfdbcf7770bcfb66"
dependencies = [
"winapi",
]
[[package]]
name = "pest"
version = "2.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "028accff104c4e513bad663bbcd2ad7cfd5304144404c31ed0a77ac103d00660"
dependencies = [
"thiserror",
"ucd-trie",
]
[[package]]
name = "pest_derive"
version = "2.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ac3922aac69a40733080f53c1ce7f91dcf57e1a5f6c52f421fadec7fbdc4b69"
dependencies = [
"pest",
"pest_generator",
]
[[package]]
name = "pest_generator"
version = "2.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d06646e185566b5961b4058dd107e0a7f56e77c3f484549fb119867773c0f202"
dependencies = [
"pest",
"pest_meta",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "pest_meta"
version = "2.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6f60b2ba541577e2a0c307c8f39d1439108120eb7903adeb6497fa880c59616"
dependencies = [
"once_cell",
"pest",
"sha2",
]
[[package]]
name = "plotters"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97"
dependencies = [
"num-traits",
"plotters-backend",
"plotters-svg",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "plotters-backend"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142"
[[package]]
name = "plotters-svg"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f"
dependencies = [
"plotters-backend",
]
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "pretty_assertions"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a25e9bcb20aa780fd0bb16b72403a9064d6b3f22f026946029acb941a50af755"
dependencies = [
"ctor",
"diff",
"output_vt100",
"yansi",
]
[[package]]
name = "proc-macro2"
version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba"
dependencies = [
"unicode-ident",
]
[[package]]
name = "proptest"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e35c06b98bf36aba164cc17cb25f7e232f5c4aeea73baa14b8a9f0d92dbfa65"
dependencies = [
"bit-set",
"bitflags 1.3.2",
"byteorder",
"lazy_static",
"num-traits",
"rand",
"rand_chacha",
"rand_xorshift",
"regex-syntax 0.6.29",
"rusty-fork",
"tempfile",
"unarray",
]
[[package]]
name = "quick-error"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
[[package]]
name = "quick-xml"
version = "0.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11bafc859c6815fbaffbbbf4229ecb767ac913fecb27f9ad4343662e9ef099ea"
dependencies = [
"memchr",
]
[[package]]
name = "quote"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_xorshift"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f"
dependencies = [
"rand_core",
]
[[package]]
name = "rayon"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b"
dependencies = [
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-utils",
"num_cpus",
]
[[package]]
name = "redox_syscall"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "regex"
version = "1.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f"
dependencies = [
"regex-syntax 0.7.2",
]
[[package]]
name = "regex-syntax"
version = "0.6.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "regex-syntax"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustix"
version = "0.37.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0"
dependencies = [
"bitflags 1.3.2",
"errno",
"io-lifetimes",
"libc",
"linux-raw-sys 0.3.8",
"windows-sys 0.48.0",
]
[[package]]
name = "rustix"
version = "0.38.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ee020b1716f0a80e2ace9b03441a749e402e86712f15f16fe8a8f75afac732f"
dependencies = [
"bitflags 2.3.3",
"errno",
"libc",
"linux-raw-sys 0.4.5",
"windows-sys 0.48.0",
]
[[package]]
name = "rusty-fork"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f"
dependencies = [
"fnv",
"quick-error",
"tempfile",
"wait-timeout",
]
[[package]]
name = "ryu"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "serde"
version = "1.0.164"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.164"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.60",
]
[[package]]
name = "serde_json"
version = "1.0.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "sha2"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "similar"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf"
[[package]]
name = "snapbox"
version = "0.6.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96dcfc4581e3355d70ac2ee14cfdf81dce3d85c85f1ed9e2c1d3013f53b3436b"
dependencies = [
"anstream 0.6.14",
"anstyle",
"escargot",
"normalize-line-endings",
"similar",
"snapbox-macros",
]
[[package]]
name = "snapbox-macros"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16569f53ca23a41bb6f62e0a5084aa1661f4814a67fa33696a79073e03a664af"
dependencies = [
"anstream 0.6.14",
]
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tempfile"
version = "3.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6"
dependencies = [
"autocfg",
"cfg-if",
"fastrand",
"redox_syscall",
"rustix 0.37.20",
"windows-sys 0.48.0",
]
[[package]]
name = "term-transcript"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d77280c9041d978e4ffedbdd19f710a1360085510c5e99dbcfec8e2f2bd4285"
dependencies = [
"atty",
"bytecount",
"handlebars",
"os_pipe",
"pretty_assertions",
"quick-xml",
"serde",
"termcolor",
"unicode-width",
]
[[package]]
name = "termcolor"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
dependencies = [
"winapi-util",
]
[[package]]
name = "terminal_size"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef"
dependencies = [
"rustix 0.38.6",
"windows-sys 0.59.0",
]
[[package]]
name = "thiserror"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "tinytemplate"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
dependencies = [
"serde",
"serde_json",
]
[[package]]
name = "typenum"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
[[package]]
name = "ucd-trie"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81"
[[package]]
name = "unarray"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
[[package]]
name = "unicode-ident"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"
[[package]]
name = "unicode-width"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
[[package]]
name = "utf8parse"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wait-timeout"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
dependencies = [
"libc",
]
[[package]]
name = "walkdir"
version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698"
dependencies = [
"same-file",
"winapi-util",
]
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.60",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.60",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
[[package]]
name = "web-sys"
version = "0.3.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
dependencies = [
"windows-targets 0.42.2",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets 0.48.1",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-targets"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
dependencies = [
"windows_aarch64_gnullvm 0.42.2",
"windows_aarch64_msvc 0.42.2",
"windows_i686_gnu 0.42.2",
"windows_i686_msvc 0.42.2",
"windows_x86_64_gnu 0.42.2",
"windows_x86_64_gnullvm 0.42.2",
"windows_x86_64_msvc 0.42.2",
]
[[package]]
name = "windows-targets"
version = "0.48.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f"
dependencies = [
"windows_aarch64_gnullvm 0.48.0",
"windows_aarch64_msvc 0.48.0",
"windows_i686_gnu 0.48.0",
"windows_i686_msvc 0.48.0",
"windows_x86_64_gnu 0.48.0",
"windows_x86_64_gnullvm 0.48.0",
"windows_x86_64_msvc 0.48.0",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6",
"windows_i686_gnullvm",
"windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
name = "windows_i686_gnu"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]]
name = "windows_i686_msvc"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
version = "0.7.13"
dependencies = [
"annotate-snippets",
"anstream 0.3.2",
"anstyle",
"anyhow",
"automod",
"circular",
"criterion",
"is_terminal_polyfill",
"lexopt",
"memchr",
"proptest",
"rustc-hash",
"snapbox",
"term-transcript",
"terminal_size",
]
[[package]]
name = "yansi"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
winnow-0.7.13/Cargo.toml 0000644 00000015402 00000000001 0010445 0 ustar # 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 = "2021"
rust-version = "1.65.0"
name = "winnow"
version = "0.7.13"
build = false
include = [
"build.rs",
"src/**/*",
"Cargo.toml",
"Cargo.lock",
"LICENSE*",
"README.md",
"examples/**/*",
]
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "A byte-oriented, zero-copy, parser combinators library"
readme = "README.md"
keywords = [
"parser",
"parser-combinators",
"parsing",
"streaming",
"bit",
]
categories = ["parsing"]
license = "MIT"
repository = "https://github.com/winnow-rs/winnow"
[package.metadata.docs.rs]
features = ["unstable-doc"]
rustdoc-args = [
"--cfg",
"docsrs",
"--generate-link-to-definition",
]
[[package.metadata.release.pre-release-replacements]]
file = "CHANGELOG.md"
search = "Unreleased"
replace = "{{version}}"
min = 1
[[package.metadata.release.pre-release-replacements]]
file = "CHANGELOG.md"
search = '\.\.\.HEAD'
replace = "...{{tag_name}}"
exactly = 1
[[package.metadata.release.pre-release-replacements]]
file = "CHANGELOG.md"
search = "ReleaseDate"
replace = "{{date}}"
min = 1
[[package.metadata.release.pre-release-replacements]]
file = "CHANGELOG.md"
search = ""
replace = """
## [Unreleased] - ReleaseDate
"""
exactly = 1
[[package.metadata.release.pre-release-replacements]]
file = "CHANGELOG.md"
search = ""
replace = """
[Unreleased]: https://github.com/winnow-rs/winnow/compare/{{tag_name}}...HEAD"""
exactly = 1
[[package.metadata.release.pre-release-replacements]]
file = "src/lib.rs"
search = 'blob/v.+\..+\..+/CHANGELOG.md'
replace = "blob/v{{version}}/CHANGELOG.md"
exactly = 1
[features]
alloc = []
debug = [
"std",
"dep:anstream",
"dep:anstyle",
"dep:is_terminal_polyfill",
"dep:terminal_size",
]
default = ["std"]
simd = ["dep:memchr"]
std = [
"alloc",
"memchr?/std",
]
unstable-doc = [
"alloc",
"std",
"simd",
"unstable-recover",
]
unstable-recover = []
[lib]
name = "winnow"
path = "src/lib.rs"
[[example]]
name = "arithmetic"
path = "examples/arithmetic/main.rs"
test = true
required-features = ["alloc"]
[[example]]
name = "css"
path = "examples/css/main.rs"
test = true
required-features = ["alloc"]
[[example]]
name = "custom_error"
path = "examples/custom_error.rs"
test = true
required-features = ["alloc"]
[[example]]
name = "http"
path = "examples/http/main.rs"
required-features = ["alloc"]
[[example]]
name = "ini"
path = "examples/ini/main.rs"
test = true
required-features = ["std"]
[[example]]
name = "iterator"
path = "examples/iterator.rs"
[[example]]
name = "json"
path = "examples/json/main.rs"
test = true
required-features = ["std"]
[[example]]
name = "json_iterator"
path = "examples/json_iterator.rs"
required-features = ["std"]
[[example]]
name = "ndjson"
path = "examples/ndjson/main.rs"
test = true
required-features = ["std"]
[[example]]
name = "s_expression"
path = "examples/s_expression/main.rs"
required-features = ["alloc"]
[[example]]
name = "string"
path = "examples/string/main.rs"
required-features = ["alloc"]
[[bench]]
name = "arithmetic"
path = "examples/arithmetic/bench.rs"
harness = false
required-features = ["alloc"]
[[bench]]
name = "http"
path = "examples/http/bench.rs"
harness = false
required-features = ["alloc"]
[[bench]]
name = "ini"
path = "examples/ini/bench.rs"
harness = false
required-features = ["std"]
[[bench]]
name = "json"
path = "examples/json/bench.rs"
harness = false
required-features = ["std"]
[dependencies.anstream]
version = "0.3.2"
optional = true
[dependencies.anstyle]
version = "1.0.1"
optional = true
[dependencies.is_terminal_polyfill]
version = "1.48.0"
optional = true
[dependencies.memchr]
version = "2.5"
optional = true
default-features = false
[dependencies.terminal_size]
version = "0.4.0"
optional = true
[dev-dependencies.annotate-snippets]
version = "0.11.3"
[dev-dependencies.anyhow]
version = "1.0.86"
[dev-dependencies.automod]
version = "1.0.14"
[dev-dependencies.circular]
version = "0.3.0"
[dev-dependencies.criterion]
version = "0.5.1"
[dev-dependencies.lexopt]
version = "0.3.0"
[dev-dependencies.proptest]
version = "1.2.0"
[dev-dependencies.rustc-hash]
version = "1.1.0"
[dev-dependencies.snapbox]
version = "0.6.21"
features = ["examples"]
[dev-dependencies.term-transcript]
version = "0.2.0"
[lints.clippy]
bool_assert_comparison = "allow"
branches_sharing_code = "allow"
checked_conversions = "warn"
collapsible_else_if = "allow"
create_dir = "warn"
dbg_macro = "warn"
debug_assert_with_mut_call = "warn"
doc_markdown = "warn"
empty_enum = "warn"
enum_glob_use = "warn"
expl_impl_clone_on_copy = "warn"
explicit_deref_methods = "warn"
explicit_into_iter_loop = "warn"
fallible_impl_from = "warn"
filter_map_next = "warn"
flat_map_option = "warn"
float_cmp_const = "warn"
fn_params_excessive_bools = "warn"
from_iter_instead_of_collect = "warn"
if_same_then_else = "allow"
implicit_clone = "warn"
imprecise_flops = "warn"
inconsistent_struct_constructor = "warn"
inefficient_to_string = "warn"
infinite_loop = "warn"
invalid_upcast_comparisons = "warn"
large_digit_groups = "warn"
large_stack_arrays = "warn"
large_types_passed_by_value = "warn"
let_and_return = "allow"
linkedlist = "warn"
lossy_float_literal = "warn"
macro_use_imports = "warn"
mem_forget = "warn"
mutex_integer = "warn"
needless_continue = "allow"
needless_for_each = "warn"
negative_feature_names = "warn"
path_buf_push_overwrite = "warn"
ptr_as_ptr = "warn"
rc_mutex = "warn"
redundant_feature_names = "warn"
ref_option_ref = "warn"
rest_pat_in_fully_bound_structs = "warn"
result_large_err = "allow"
same_functions_in_if_condition = "warn"
semicolon_if_nothing_returned = "warn"
str_to_string = "warn"
string_add = "warn"
string_add_assign = "warn"
string_lit_as_bytes = "warn"
string_to_string = "warn"
todo = "warn"
trait_duplication_in_bounds = "warn"
uninlined_format_args = "warn"
verbose_file_reads = "warn"
wildcard_imports = "allow"
zero_sized_map_values = "warn"
[lints.rust]
unnameable_types = "warn"
unreachable_pub = "warn"
unsafe_op_in_unsafe_fn = "warn"
unused_lifetimes = "warn"
unused_macro_rules = "warn"
[lints.rust.rust_2018_idioms]
level = "warn"
priority = -1
[profile.bench]
lto = true
codegen-units = 1
debug = 2
[profile.dev]
panic = "abort"
[profile.release]
lto = true
codegen-units = 1
panic = "abort"
winnow-0.7.13/Cargo.toml.orig 0000644 0000000 0000000 00000013437 10461020230 0014134 0 ustar 0000000 0000000 [workspace]
resolver = "2"
members = ["fuzz"]
[workspace.package]
repository = "https://github.com/winnow-rs/winnow"
license = "MIT"
edition = "2021"
rust-version = "1.65.0" # MSRV
include = [
"build.rs",
"src/**/*",
"Cargo.toml",
"Cargo.lock",
"LICENSE*",
"README.md",
"examples/**/*"
]
[workspace.lints.rust]
rust_2018_idioms = { level = "warn", priority = -1 }
unnameable_types = "warn"
unreachable_pub = "warn"
unsafe_op_in_unsafe_fn = "warn"
unused_lifetimes = "warn"
unused_macro_rules = "warn"
[workspace.lints.clippy]
bool_assert_comparison = "allow"
branches_sharing_code = "allow"
checked_conversions = "warn"
collapsible_else_if = "allow"
create_dir = "warn"
dbg_macro = "warn"
debug_assert_with_mut_call = "warn"
doc_markdown = "warn"
empty_enum = "warn"
enum_glob_use = "warn"
expl_impl_clone_on_copy = "warn"
explicit_deref_methods = "warn"
explicit_into_iter_loop = "warn"
fallible_impl_from = "warn"
filter_map_next = "warn"
flat_map_option = "warn"
float_cmp_const = "warn"
fn_params_excessive_bools = "warn"
from_iter_instead_of_collect = "warn"
if_same_then_else = "allow"
implicit_clone = "warn"
imprecise_flops = "warn"
inconsistent_struct_constructor = "warn"
inefficient_to_string = "warn"
infinite_loop = "warn"
invalid_upcast_comparisons = "warn"
large_digit_groups = "warn"
large_stack_arrays = "warn"
large_types_passed_by_value = "warn"
let_and_return = "allow" # sometimes good to name what you are returning
linkedlist = "warn"
lossy_float_literal = "warn"
macro_use_imports = "warn"
mem_forget = "warn"
mutex_integer = "warn"
needless_continue = "allow"
needless_for_each = "warn"
negative_feature_names = "warn"
path_buf_push_overwrite = "warn"
ptr_as_ptr = "warn"
rc_mutex = "warn"
redundant_feature_names = "warn"
ref_option_ref = "warn"
rest_pat_in_fully_bound_structs = "warn"
result_large_err = "allow"
same_functions_in_if_condition = "warn"
# self_named_module_files = "warn" # false-positives
semicolon_if_nothing_returned = "warn"
str_to_string = "warn"
string_add = "warn"
string_add_assign = "warn"
string_lit_as_bytes = "warn"
string_to_string = "warn"
todo = "warn"
trait_duplication_in_bounds = "warn"
uninlined_format_args = "warn"
verbose_file_reads = "warn"
wildcard_imports = "allow"
zero_sized_map_values = "warn"
[profile.dev]
panic = "abort"
[profile.release]
panic = "abort"
codegen-units = 1
lto = true
# debug = "line-tables-only" # requires Cargo 1.71
[package]
name = "winnow"
version = "0.7.13"
description = "A byte-oriented, zero-copy, parser combinators library"
categories = ["parsing"]
keywords = ["parser", "parser-combinators", "parsing", "streaming", "bit"]
autoexamples = false
repository.workspace = true
license.workspace = true
edition.workspace = true
rust-version.workspace = true
include.workspace = true
[package.metadata.docs.rs]
features = ["unstable-doc"]
rustdoc-args = ["--cfg", "docsrs", "--generate-link-to-definition"]
[package.metadata.release]
pre-release-replacements = [
{file="CHANGELOG.md", search="Unreleased", replace="{{version}}", min=1},
{file="CHANGELOG.md", search="\\.\\.\\.HEAD", replace="...{{tag_name}}", exactly=1},
{file="CHANGELOG.md", search="ReleaseDate", replace="{{date}}", min=1},
{file="CHANGELOG.md", search="", replace="\n## [Unreleased] - ReleaseDate\n", exactly=1},
{file="CHANGELOG.md", search="", replace="\n[Unreleased]: https://github.com/winnow-rs/winnow/compare/{{tag_name}}...HEAD", exactly=1},
{file="src/lib.rs", search="blob/v.+\\..+\\..+/CHANGELOG.md", replace="blob/v{{version}}/CHANGELOG.md", exactly=1},
]
[features]
default = ["std"]
alloc = []
std = ["alloc", "memchr?/std"]
simd = ["dep:memchr"]
debug = ["std", "dep:anstream", "dep:anstyle", "dep:is_terminal_polyfill", "dep:terminal_size"]
unstable-recover = []
unstable-doc = ["alloc", "std", "simd", "unstable-recover"]
[dependencies]
anstream = { version = "0.3.2", optional = true }
anstyle = { version = "1.0.1", optional = true }
is_terminal_polyfill = { version = "1.48.0", optional = true }
memchr = { version = "2.5", optional = true, default-features = false }
terminal_size = { version = "0.4.0", optional = true }
[dev-dependencies]
proptest = "1.2.0"
criterion = "0.5.1"
lexopt = "0.3.0"
term-transcript = "0.2.0"
snapbox = { version = "0.6.21", features = ["examples"] }
circular = "0.3.0"
rustc-hash = "1.1.0"
automod = "1.0.14"
annotate-snippets = "0.11.3"
anyhow = "1.0.86"
[profile.bench]
debug = true
lto = true
codegen-units = 1
[[example]]
name = "arithmetic"
test = true
required-features = ["alloc"]
[[example]]
name = "css"
test = true
required-features = ["alloc"]
[[example]]
name = "custom_error"
test = true
required-features = ["alloc"]
[[example]]
name = "http"
required-features = ["alloc"]
[[example]]
name = "ini"
test = true
required-features = ["std"]
[[example]]
name = "json"
test = true
required-features = ["std"]
[[example]]
name = "ndjson"
test = true
required-features = ["std"]
[[example]]
name = "json_iterator"
required-features = ["std"]
[[example]]
name = "iterator"
[[example]]
name = "s_expression"
required-features = ["alloc"]
[[example]]
name = "string"
required-features = ["alloc"]
[[bench]]
name = "arithmetic"
path = "examples/arithmetic/bench.rs"
harness = false
required-features = ["alloc"]
[[bench]]
name = "contains_token"
harness = false
[[bench]]
name = "find_slice"
harness = false
[[bench]]
name = "iter"
harness = false
[[bench]]
name = "next_slice"
harness = false
[[bench]]
name = "number"
harness = false
[[bench]]
name = "http"
path = "examples/http/bench.rs"
harness = false
required-features = ["alloc"]
[[bench]]
name = "ini"
path = "examples/ini/bench.rs"
harness = false
required-features = ["std"]
[[bench]]
name = "json"
path = "examples/json/bench.rs"
harness = false
required-features = ["std"]
[lints]
workspace = true
winnow-0.7.13/LICENSE-MIT 0000644 0000000 0000000 00000001777 10461020230 0012705 0 ustar 0000000 0000000 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.
winnow-0.7.13/README.md 0000644 0000000 0000000 00000002570 10461020230 0012520 0 ustar 0000000 0000000 # winnow, making parsing a breeze
[](LICENSE)
[](https://github.com/winnow-rs/winnow/actions/workflows/ci.yml)
[](https://coveralls.io/github/winnow-rs/winnow?branch=main)
[](https://crates.io/crates/winnow)
## About
Build up a parser for your format of choice with the building blocks provided by `winnow`.
For more details, see:
- [Tutorial](https://docs.rs/winnow/latest/winnow/_tutorial/index.html)
- [Special Topics](https://docs.rs/winnow/latest/winnow/_topic/index.html)
- [Why winnow? How does it compare to ...?](https://docs.rs/winnow/latest/winnow/_topic/why/index.html)
- [API Reference](https://docs.rs/winnow)
- [List of combinators](https://docs.rs/winnow/latest/winnow/combinator/index.html)
# Contributors
winnow is the fruit of the work of many contributors over the years, many
thanks for your help! In particular, thanks to [Geal](https://github.com/Geal)
for the original [`nom` crate](https://crates.io/crates/nom).
winnow-0.7.13/examples/arithmetic/bench.rs 0000644 0000000 0000000 00000001726 10461020230 0016637 0 ustar 0000000 0000000 mod parser;
mod parser_ast;
mod parser_lexer;
use winnow::prelude::*;
#[allow(clippy::eq_op, clippy::erasing_op)]
fn arithmetic(c: &mut criterion::Criterion) {
let data = " 2*2 / ( 5 - 1) + 3 / 4 * (2 - 7 + 567 *12 /2) + 3*(1+2*( 45 /2))";
let expected = 2 * 2 / (5 - 1) + 3 * (1 + 2 * (45 / 2));
assert_eq!(parser::expr.parse(data), Ok(expected));
assert_eq!(
parser_ast::expr.parse(data).map(|ast| ast.eval()),
Ok(expected)
);
assert_eq!(
parser_lexer::expr2.parse(data).map(|ast| ast.eval()),
Ok(expected)
);
c.bench_function("direct", |b| {
b.iter(|| parser::expr.parse(data).unwrap());
});
c.bench_function("ast", |b| {
b.iter(|| parser_ast::expr.parse(data).unwrap().eval());
});
c.bench_function("lexer", |b| {
b.iter(|| parser_lexer::expr2.parse_peek(data).unwrap());
});
}
criterion::criterion_group!(benches, arithmetic);
criterion::criterion_main!(benches);
winnow-0.7.13/examples/arithmetic/main.rs 0000644 0000000 0000000 00000004316 10461020230 0016502 0 ustar 0000000 0000000 use winnow::prelude::*;
mod parser;
mod parser_ast;
mod parser_lexer;
#[cfg(test)]
mod test_parser;
#[cfg(test)]
mod test_parser_ast;
#[cfg(test)]
mod test_parser_lexer;
fn main() -> Result<(), lexopt::Error> {
let args = Args::parse()?;
let input = args.input.as_deref().unwrap_or("1 + 1");
if let Err(err) = calc(input, args.implementation) {
println!("FAILED");
println!("{err}");
}
Ok(())
}
fn calc(
input: &str,
imp: Impl,
) -> Result<(), winnow::error::ParseError<&str, winnow::error::ContextError>> {
println!("{input} =");
match imp {
Impl::Eval => {
let result = parser::expr.parse(input)?;
println!(" {result}");
}
Impl::Ast => {
let result = parser_ast::expr.parse(input)?;
println!(" {:#?}={}", result, result.eval());
}
Impl::Lexer => {
let tokens = parser_lexer::tokens.parse(input)?;
println!(" {tokens:#?}");
let tokens = parser_lexer::Tokens::new(&tokens);
let result = parser_lexer::expr.parse(tokens).unwrap();
println!(" {:#?}={}", result, result.eval());
}
}
Ok(())
}
#[derive(Default)]
struct Args {
input: Option,
implementation: Impl,
}
enum Impl {
Eval,
Ast,
Lexer,
}
impl Default for Impl {
fn default() -> Self {
Self::Eval
}
}
impl Args {
fn parse() -> Result {
use lexopt::prelude::*;
let mut res = Args::default();
let mut args = lexopt::Parser::from_env();
while let Some(arg) = args.next()? {
match arg {
Long("impl") => {
res.implementation = args.value()?.parse_with(|s| match s {
"eval" => Ok(Impl::Eval),
"ast" => Ok(Impl::Ast),
"lexer" => Ok(Impl::Lexer),
_ => Err("expected `eval`, `ast`"),
})?;
}
Value(input) => {
res.input = Some(input.string()?);
}
_ => return Err(arg.unexpected()),
}
}
Ok(res)
}
}
winnow-0.7.13/examples/arithmetic/parser.rs 0000644 0000000 0000000 00000003416 10461020230 0017052 0 ustar 0000000 0000000 use std::str::FromStr;
use winnow::prelude::*;
use winnow::Result;
use winnow::{
ascii::{digit1 as digits, multispace0 as multispaces},
combinator::alt,
combinator::delimited,
combinator::repeat,
token::one_of,
};
// Parser definition
pub(crate) fn expr(i: &mut &str) -> Result {
let init = term.parse_next(i)?;
repeat(0.., (one_of(['+', '-']), term))
.fold(
move || init,
|acc, (op, val): (char, i64)| {
if op == '+' {
acc + val
} else {
acc - val
}
},
)
.parse_next(i)
}
// We read an initial factor and for each time we find
// a * or / operator followed by another factor, we do
// the math by folding everything
pub(crate) fn term(i: &mut &str) -> Result {
let init = factor.parse_next(i)?;
repeat(0.., (one_of(['*', '/']), factor))
.fold(
move || init,
|acc, (op, val): (char, i64)| {
if op == '*' {
acc * val
} else {
acc / val
}
},
)
.parse_next(i)
}
// We transform an integer string into a i64, ignoring surrounding whitespace
// We look for a digit suite, and try to convert it.
// If either str::from_utf8 or FromStr::from_str fail,
// we fallback to the parens parser defined above
pub(crate) fn factor(i: &mut &str) -> Result {
delimited(
multispaces,
alt((digits.try_map(FromStr::from_str), parens)),
multispaces,
)
.parse_next(i)
}
// We parse any expr surrounded by parens, ignoring all whitespace around those
fn parens(i: &mut &str) -> Result {
delimited('(', expr, ')').parse_next(i)
}
winnow-0.7.13/examples/arithmetic/parser_ast.rs 0000644 0000000 0000000 00000005374 10461020230 0017726 0 ustar 0000000 0000000 use std::fmt;
use std::fmt::{Debug, Display, Formatter};
use std::str::FromStr;
use winnow::prelude::*;
use winnow::Result;
use winnow::{
ascii::{digit1 as digits, multispace0 as multispaces},
combinator::alt,
combinator::delimited,
combinator::repeat,
token::one_of,
};
#[derive(Debug, Clone)]
pub(crate) enum Expr {
Value(i64),
Add(Box, Box),
Sub(Box, Box),
Mul(Box, Box),
Div(Box, Box),
Paren(Box),
}
impl Expr {
pub(crate) fn eval(&self) -> i64 {
match self {
Self::Value(v) => *v,
Self::Add(lhs, rhs) => lhs.eval() + rhs.eval(),
Self::Sub(lhs, rhs) => lhs.eval() - rhs.eval(),
Self::Mul(lhs, rhs) => lhs.eval() * rhs.eval(),
Self::Div(lhs, rhs) => lhs.eval() / rhs.eval(),
Self::Paren(expr) => expr.eval(),
}
}
}
impl Display for Expr {
fn fmt(&self, format: &mut Formatter<'_>) -> fmt::Result {
use Expr::{Add, Div, Mul, Paren, Sub, Value};
match *self {
Value(val) => write!(format, "{val}"),
Add(ref left, ref right) => write!(format, "{left} + {right}"),
Sub(ref left, ref right) => write!(format, "{left} - {right}"),
Mul(ref left, ref right) => write!(format, "{left} * {right}"),
Div(ref left, ref right) => write!(format, "{left} / {right}"),
Paren(ref expr) => write!(format, "({expr})"),
}
}
}
pub(crate) fn expr(i: &mut &str) -> Result {
let init = term.parse_next(i)?;
repeat(0.., (one_of(['+', '-']), term))
.fold(
move || init.clone(),
|acc, (op, val): (char, Expr)| {
if op == '+' {
Expr::Add(Box::new(acc), Box::new(val))
} else {
Expr::Sub(Box::new(acc), Box::new(val))
}
},
)
.parse_next(i)
}
pub(crate) fn term(i: &mut &str) -> Result {
let init = factor.parse_next(i)?;
repeat(0.., (one_of(['*', '/']), factor))
.fold(
move || init.clone(),
|acc, (op, val): (char, Expr)| {
if op == '*' {
Expr::Mul(Box::new(acc), Box::new(val))
} else {
Expr::Div(Box::new(acc), Box::new(val))
}
},
)
.parse_next(i)
}
pub(crate) fn factor(i: &mut &str) -> Result {
delimited(
multispaces,
alt((digits.try_map(FromStr::from_str).map(Expr::Value), parens)),
multispaces,
)
.parse_next(i)
}
fn parens(i: &mut &str) -> Result {
delimited("(", expr, ")")
.map(|e| Expr::Paren(Box::new(e)))
.parse_next(i)
}
winnow-0.7.13/examples/arithmetic/parser_lexer.rs 0000644 0000000 0000000 00000015303 10461020230 0020247 0 ustar 0000000 0000000 use std::fmt;
use std::fmt::{Debug, Display, Formatter};
use winnow::prelude::*;
use winnow::Result;
use winnow::{
ascii::{digit1 as digits, multispace0 as multispaces},
combinator::alt,
combinator::dispatch,
combinator::eof,
combinator::fail,
combinator::opt,
combinator::peek,
combinator::repeat,
combinator::{delimited, preceded, terminated},
error::ContextError,
stream::TokenSlice,
token::any,
token::literal,
token::one_of,
token::take_till,
};
/// Lex and parse
#[allow(dead_code)]
pub(crate) fn expr2(i: &mut &str) -> Result {
let tokens = tokens.parse_next(i)?;
let mut tokens = Tokens::new(&tokens);
expr.parse_next(&mut tokens)
}
#[derive(Clone, PartialEq, Eq)]
pub(crate) struct Token<'s> {
kind: TokenKind,
raw: &'s str,
}
impl fmt::Debug for Token<'_> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
// Customized for brevity for a better `winnow/debug` experience
match self.kind {
TokenKind::Value => Debug::fmt(self.raw, fmt),
TokenKind::Oper(oper) => Debug::fmt(&oper, fmt),
TokenKind::OpenParen => fmt.write_str("OpenParen"),
TokenKind::CloseParen => fmt.write_str("CloseParen"),
TokenKind::Unknown => fmt.write_str("Unknown"),
TokenKind::Eof => fmt.write_str("Eof"),
}
}
}
impl PartialEq for Token<'_> {
fn eq(&self, other: &TokenKind) -> bool {
self.kind == *other
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub(crate) enum TokenKind {
Value,
Oper(Oper),
OpenParen,
CloseParen,
Unknown,
Eof,
}
impl<'i> Parser, &'i Token<'i>, ContextError> for TokenKind {
fn parse_next(&mut self, input: &mut Tokens<'i>) -> Result<&'i Token<'i>> {
literal(*self).parse_next(input).map(|t| &t[0])
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub(crate) enum Oper {
Add,
Sub,
Mul,
Div,
}
impl winnow::stream::ContainsToken<&'_ Token<'_>> for TokenKind {
#[inline(always)]
fn contains_token(&self, token: &'_ Token<'_>) -> bool {
*self == token.kind
}
}
impl winnow::stream::ContainsToken<&'_ Token<'_>> for &'_ [TokenKind] {
#[inline]
fn contains_token(&self, token: &'_ Token<'_>) -> bool {
self.iter().any(|t| *t == token.kind)
}
}
impl winnow::stream::ContainsToken<&'_ Token<'_>> for &'_ [TokenKind; LEN] {
#[inline]
fn contains_token(&self, token: &'_ Token<'_>) -> bool {
self.iter().any(|t| *t == token.kind)
}
}
impl winnow::stream::ContainsToken<&'_ Token<'_>> for [TokenKind; LEN] {
#[inline]
fn contains_token(&self, token: &'_ Token<'_>) -> bool {
self.iter().any(|t| *t == token.kind)
}
}
/// Lex tokens
///
/// See [`expr`] to parse the tokens
pub(crate) fn tokens<'s>(i: &mut &'s str) -> Result>> {
let mut tokens: Vec<_> =
preceded(multispaces, repeat(1.., terminated(token, multispaces))).parse_next(i)?;
if let Some(eof) = opt(eof.map(|raw| Token {
kind: TokenKind::Eof,
raw,
}))
.parse_next(i)?
{
tokens.push(eof);
}
Ok(tokens)
}
fn token<'s>(i: &mut &'s str) -> Result> {
dispatch! {peek(any);
'0'..='9' => digits.value(TokenKind::Value),
'(' => '('.value(TokenKind::OpenParen),
')' => ')'.value(TokenKind::CloseParen),
'+' => '+'.value(TokenKind::Oper(Oper::Add)),
'-' => '-'.value(TokenKind::Oper(Oper::Sub)),
'*' => '*'.value(TokenKind::Oper(Oper::Mul)),
'/' => '/'.value(TokenKind::Oper(Oper::Div)),
' '| '\t'| '\r'| '\n' => fail,
_ => take_till(.., ('0'..='9', '(', ')', '+', '-', '*', '/')).value(TokenKind::Unknown),
}
.with_taken()
.map(|(kind, raw)| Token { kind, raw })
.parse_next(i)
}
#[derive(Debug, Clone)]
pub(crate) enum Expr {
Value(i64),
Add(Box, Box),
Sub(Box, Box),
Mul(Box, Box),
Div(Box, Box),
Paren(Box),
}
impl Expr {
pub(crate) fn eval(&self) -> i64 {
match self {
Self::Value(v) => *v,
Self::Add(lhs, rhs) => lhs.eval() + rhs.eval(),
Self::Sub(lhs, rhs) => lhs.eval() - rhs.eval(),
Self::Mul(lhs, rhs) => lhs.eval() * rhs.eval(),
Self::Div(lhs, rhs) => lhs.eval() / rhs.eval(),
Self::Paren(expr) => expr.eval(),
}
}
}
impl Display for Expr {
fn fmt(&self, format: &mut Formatter<'_>) -> fmt::Result {
use Expr::{Add, Div, Mul, Paren, Sub, Value};
match *self {
Value(val) => write!(format, "{val}"),
Add(ref left, ref right) => write!(format, "{left} + {right}"),
Sub(ref left, ref right) => write!(format, "{left} - {right}"),
Mul(ref left, ref right) => write!(format, "{left} * {right}"),
Div(ref left, ref right) => write!(format, "{left} / {right}"),
Paren(ref expr) => write!(format, "({expr})"),
}
}
}
pub(crate) type Tokens<'i> = TokenSlice<'i, Token<'i>>;
/// Parse the tokens lexed in [`tokens`]
pub(crate) fn expr(i: &mut Tokens<'_>) -> Result {
let init = term.parse_next(i)?;
let expr = repeat(
0..,
(
one_of([TokenKind::Oper(Oper::Add), TokenKind::Oper(Oper::Sub)]),
term,
),
)
.fold(
move || init.clone(),
|acc, (op, val): (&Token<'_>, Expr)| {
if op.kind == TokenKind::Oper(Oper::Add) {
Expr::Add(Box::new(acc), Box::new(val))
} else {
Expr::Sub(Box::new(acc), Box::new(val))
}
},
)
.parse_next(i)?;
opt(TokenKind::Eof).parse_next(i)?;
Ok(expr)
}
pub(crate) fn term(i: &mut Tokens<'_>) -> Result {
let init = factor.parse_next(i)?;
repeat(
0..,
(
one_of([TokenKind::Oper(Oper::Mul), TokenKind::Oper(Oper::Div)]),
factor,
),
)
.fold(
move || init.clone(),
|acc, (op, val): (&Token<'_>, Expr)| {
if op.kind == TokenKind::Oper(Oper::Mul) {
Expr::Mul(Box::new(acc), Box::new(val))
} else {
Expr::Div(Box::new(acc), Box::new(val))
}
},
)
.parse_next(i)
}
pub(crate) fn factor(i: &mut Tokens<'_>) -> Result {
alt((
TokenKind::Value.try_map(|t: &Token<'_>| t.raw.parse::().map(Expr::Value)),
parens,
))
.parse_next(i)
}
fn parens(i: &mut Tokens<'_>) -> Result {
delimited(TokenKind::OpenParen, expr, TokenKind::CloseParen)
.map(|e| Expr::Paren(Box::new(e)))
.parse_next(i)
}
winnow-0.7.13/examples/arithmetic/test_parser.rs 0000644 0000000 0000000 00000005213 10461020230 0020106 0 ustar 0000000 0000000 use snapbox::assert_data_eq;
use snapbox::prelude::*;
use snapbox::str;
use winnow::prelude::*;
use crate::parser::*;
#[test]
fn factor_test() {
let input = "3";
let expected = str![[r#"
Ok(
(
"",
3,
),
)
"#]];
assert_data_eq!(factor.parse_peek(input).to_debug(), expected);
let input = " 12";
let expected = str![[r#"
Ok(
(
"",
12,
),
)
"#]];
assert_data_eq!(factor.parse_peek(input).to_debug(), expected);
let input = "537 ";
let expected = str![[r#"
Ok(
(
"",
537,
),
)
"#]];
assert_data_eq!(factor.parse_peek(input).to_debug(), expected);
let input = " 24 ";
let expected = str![[r#"
Ok(
(
"",
24,
),
)
"#]];
assert_data_eq!(factor.parse_peek(input).to_debug(), expected);
}
#[test]
fn term_test() {
let input = " 12 *2 / 3";
let expected = str![[r#"
Ok(
(
"",
8,
),
)
"#]];
assert_data_eq!(term.parse_peek(input).to_debug(), expected);
let input = " 12 *2 / 3";
let expected = str![[r#"
Ok(
(
"",
8,
),
)
"#]];
assert_data_eq!(term.parse_peek(input).to_debug(), expected);
let input = " 2* 3 *2 *2 / 3";
let expected = str![[r#"
Ok(
(
"",
8,
),
)
"#]];
assert_data_eq!(term.parse_peek(input).to_debug(), expected);
let input = " 48 / 3/2";
let expected = str![[r#"
Ok(
(
"",
8,
),
)
"#]];
assert_data_eq!(term.parse_peek(input).to_debug(), expected);
}
#[test]
fn expr_test() {
let input = " 1 + 2 ";
let expected = str![[r#"
Ok(
(
"",
3,
),
)
"#]];
assert_data_eq!(expr.parse_peek(input).to_debug(), expected);
let input = " 12 + 6 - 4+ 3";
let expected = str![[r#"
Ok(
(
"",
17,
),
)
"#]];
assert_data_eq!(expr.parse_peek(input).to_debug(), expected);
let input = " 1 + 2*3 + 4";
let expected = str![[r#"
Ok(
(
"",
11,
),
)
"#]];
assert_data_eq!(expr.parse_peek(input).to_debug(), expected);
}
#[test]
fn parens_test() {
let input = " ( 2 )";
let expected = str![[r#"
Ok(
(
"",
2,
),
)
"#]];
assert_data_eq!(expr.parse_peek(input).to_debug(), expected);
let input = " 2* ( 3 + 4 ) ";
let expected = str![[r#"
Ok(
(
"",
14,
),
)
"#]];
assert_data_eq!(expr.parse_peek(input).to_debug(), expected);
let input = " 2*2 / ( 5 - 1) + 3";
let expected = str![[r#"
Ok(
(
"",
4,
),
)
"#]];
assert_data_eq!(expr.parse_peek(input).to_debug(), expected);
}
winnow-0.7.13/examples/arithmetic/test_parser_ast.rs 0000644 0000000 0000000 00000012161 10461020230 0020755 0 ustar 0000000 0000000 use snapbox::assert_data_eq;
use snapbox::prelude::*;
use snapbox::str;
use winnow::prelude::*;
use crate::parser_ast::*;
#[test]
fn factor_test() {
let input = "3";
let expected = str![[r#"
Ok(
(
"",
Value(
3,
),
),
)
"#]];
assert_data_eq!(factor.parse_peek(input).to_debug(), expected);
let input = " 12";
let expected = str![[r#"
Ok(
(
"",
Value(
12,
),
),
)
"#]];
assert_data_eq!(factor.parse_peek(input).to_debug(), expected);
let input = "537 ";
let expected = str![[r#"
Ok(
(
"",
Value(
537,
),
),
)
"#]];
assert_data_eq!(factor.parse_peek(input).to_debug(), expected);
let input = " 24 ";
let expected = str![[r#"
Ok(
(
"",
Value(
24,
),
),
)
"#]];
assert_data_eq!(factor.parse_peek(input).to_debug(), expected);
}
#[test]
fn term_test() {
let input = " 12 *2 / 3";
let expected = str![[r#"
Ok(
(
"",
Div(
Mul(
Value(
12,
),
Value(
2,
),
),
Value(
3,
),
),
),
)
"#]];
assert_data_eq!(term.parse_peek(input).to_debug(), expected);
let input = " 12 *2 / 3";
let expected = str![[r#"
Ok(
(
"",
Div(
Mul(
Value(
12,
),
Value(
2,
),
),
Value(
3,
),
),
),
)
"#]];
assert_data_eq!(term.parse_peek(input).to_debug(), expected);
let input = " 2* 3 *2 *2 / 3";
let expected = str![[r#"
Ok(
(
"",
Div(
Mul(
Mul(
Mul(
Value(
2,
),
Value(
3,
),
),
Value(
2,
),
),
Value(
2,
),
),
Value(
3,
),
),
),
)
"#]];
assert_data_eq!(term.parse_peek(input).to_debug(), expected);
let input = " 48 / 3/2";
let expected = str![[r#"
Ok(
(
"",
Div(
Div(
Value(
48,
),
Value(
3,
),
),
Value(
2,
),
),
),
)
"#]];
assert_data_eq!(term.parse_peek(input).to_debug(), expected);
}
#[test]
fn expr_test() {
let input = " 1 + 2 ";
let expected = str![[r#"
Ok(
Add(
Value(
1,
),
Value(
2,
),
),
)
"#]];
assert_data_eq!(expr.parse(input).to_debug(), expected);
let input = " 12 + 6 - 4+ 3";
let expected = str![[r#"
Ok(
Add(
Sub(
Add(
Value(
12,
),
Value(
6,
),
),
Value(
4,
),
),
Value(
3,
),
),
)
"#]];
assert_data_eq!(expr.parse(input).to_debug(), expected);
let input = " 1 + 2*3 + 4";
let expected = str![[r#"
Ok(
Add(
Add(
Value(
1,
),
Mul(
Value(
2,
),
Value(
3,
),
),
),
Value(
4,
),
),
)
"#]];
assert_data_eq!(expr.parse(input).to_debug(), expected);
}
#[test]
fn parens_test() {
let input = " ( 2 )";
let expected = str![[r#"
Ok(
Paren(
Value(
2,
),
),
)
"#]];
assert_data_eq!(expr.parse(input).to_debug(), expected);
let input = " 2* ( 3 + 4 ) ";
let expected = str![[r#"
Ok(
Mul(
Value(
2,
),
Paren(
Add(
Value(
3,
),
Value(
4,
),
),
),
),
)
"#]];
assert_data_eq!(expr.parse(input).to_debug(), expected);
let input = " 2*2 / ( 5 - 1) + 3";
let expected = str![[r#"
Ok(
Add(
Div(
Mul(
Value(
2,
),
Value(
2,
),
),
Paren(
Sub(
Value(
5,
),
Value(
1,
),
),
),
),
Value(
3,
),
),
)
"#]];
assert_data_eq!(expr.parse(input).to_debug(), expected);
}
winnow-0.7.13/examples/arithmetic/test_parser_lexer.rs 0000644 0000000 0000000 00000017131 10461020230 0021307 0 ustar 0000000 0000000 use snapbox::assert_data_eq;
use snapbox::prelude::*;
use snapbox::str;
use winnow::prelude::*;
use crate::parser_lexer::*;
#[test]
fn lex_test() {
let input = "3";
let expected = str![[r#"
Ok(
(
"",
[
"3",
Eof,
],
),
)
"#]];
assert_data_eq!(tokens.parse_peek(input).to_debug(), expected);
let input = " 24 ";
let expected = str![[r#"
Ok(
(
"",
[
"24",
Eof,
],
),
)
"#]];
assert_data_eq!(tokens.parse_peek(input).to_debug(), expected);
let input = " 12 *2 / 3";
let expected = str![[r#"
Ok(
(
"",
[
"12",
Mul,
"2",
Div,
"3",
Eof,
],
),
)
"#]];
assert_data_eq!(tokens.parse_peek(input).to_debug(), expected);
let input = " 2*2 / ( 5 - 1) + 3";
let expected = str![[r#"
Ok(
(
"",
[
"2",
Mul,
"2",
Div,
OpenParen,
"5",
Sub,
"1",
CloseParen,
Add,
"3",
Eof,
],
),
)
"#]];
assert_data_eq!(tokens.parse_peek(input).to_debug(), expected);
}
#[test]
fn factor_test() {
let input = "3";
let expected = str![[r#"
Ok(
(
[
Eof,
],
Value(
3,
),
),
)
"#]];
let input = tokens.parse(input).unwrap();
let input = Tokens::new(&input);
assert_data_eq!(factor.parse_peek(input).to_debug(), expected);
let input = " 12";
let expected = str![[r#"
Ok(
(
[
Eof,
],
Value(
12,
),
),
)
"#]];
let input = tokens.parse(input).unwrap();
let input = Tokens::new(&input);
assert_data_eq!(factor.parse_peek(input).to_debug(), expected);
let input = "537 ";
let expected = str![[r#"
Ok(
(
[
Eof,
],
Value(
537,
),
),
)
"#]];
let input = tokens.parse(input).unwrap();
let input = Tokens::new(&input);
assert_data_eq!(factor.parse_peek(input).to_debug(), expected);
let input = " 24 ";
let expected = str![[r#"
Ok(
(
[
Eof,
],
Value(
24,
),
),
)
"#]];
let input = tokens.parse(input).unwrap();
let input = Tokens::new(&input);
assert_data_eq!(factor.parse_peek(input).to_debug(), expected);
}
#[test]
fn term_test() {
let input = " 12 *2 / 3";
let expected = str![[r#"
Ok(
(
[
Eof,
],
Div(
Mul(
Value(
12,
),
Value(
2,
),
),
Value(
3,
),
),
),
)
"#]];
let input = tokens.parse(input).unwrap();
let input = Tokens::new(&input);
assert_data_eq!(term.parse_peek(input).to_debug(), expected);
let input = " 12 *2 / 3";
let expected = str![[r#"
Ok(
(
[
Eof,
],
Div(
Mul(
Value(
12,
),
Value(
2,
),
),
Value(
3,
),
),
),
)
"#]];
let input = tokens.parse(input).unwrap();
let input = Tokens::new(&input);
assert_data_eq!(term.parse_peek(input).to_debug(), expected);
let input = " 2* 3 *2 *2 / 3";
let expected = str![[r#"
Ok(
(
[
Eof,
],
Div(
Mul(
Mul(
Mul(
Value(
2,
),
Value(
3,
),
),
Value(
2,
),
),
Value(
2,
),
),
Value(
3,
),
),
),
)
"#]];
let input = tokens.parse(input).unwrap();
let input = Tokens::new(&input);
assert_data_eq!(term.parse_peek(input).to_debug(), expected);
let input = " 48 / 3/2";
let expected = str![[r#"
Ok(
(
[
Eof,
],
Div(
Div(
Value(
48,
),
Value(
3,
),
),
Value(
2,
),
),
),
)
"#]];
let input = tokens.parse(input).unwrap();
let input = Tokens::new(&input);
assert_data_eq!(term.parse_peek(input).to_debug(), expected);
}
#[test]
fn expr_test() {
let input = " 1 + 2 ";
let expected = str![[r#"
Ok(
Add(
Value(
1,
),
Value(
2,
),
),
)
"#]];
let input = tokens.parse(input).unwrap();
let input = Tokens::new(&input);
assert_data_eq!(expr.parse(input).to_debug(), expected);
let input = " 12 + 6 - 4+ 3";
let expected = str![[r#"
Ok(
Add(
Sub(
Add(
Value(
12,
),
Value(
6,
),
),
Value(
4,
),
),
Value(
3,
),
),
)
"#]];
let input = tokens.parse(input).unwrap();
let input = Tokens::new(&input);
assert_data_eq!(expr.parse(input).to_debug(), expected);
let input = " 1 + 2*3 + 4";
let expected = str![[r#"
Ok(
Add(
Add(
Value(
1,
),
Mul(
Value(
2,
),
Value(
3,
),
),
),
Value(
4,
),
),
)
"#]];
let input = tokens.parse(input).unwrap();
let input = Tokens::new(&input);
assert_data_eq!(expr.parse(input).to_debug(), expected);
}
#[test]
fn parens_test() {
let input = " ( 2 )";
let expected = str![[r#"
Ok(
Paren(
Value(
2,
),
),
)
"#]];
let input = tokens.parse(input).unwrap();
let input = Tokens::new(&input);
assert_data_eq!(expr.parse(input).to_debug(), expected);
let input = " 2* ( 3 + 4 ) ";
let expected = str![[r#"
Ok(
Mul(
Value(
2,
),
Paren(
Add(
Value(
3,
),
Value(
4,
),
),
),
),
)
"#]];
let input = tokens.parse(input).unwrap();
let input = Tokens::new(&input);
assert_data_eq!(expr.parse(input).to_debug(), expected);
let input = " 2*2 / ( 5 - 1) + 3";
let expected = str![[r#"
Ok(
Add(
Div(
Mul(
Value(
2,
),
Value(
2,
),
),
Paren(
Sub(
Value(
5,
),
Value(
1,
),
),
),
),
Value(
3,
),
),
)
"#]];
let input = tokens.parse(input).unwrap();
let input = Tokens::new(&input);
assert_data_eq!(expr.parse(input).to_debug(), expected);
}
winnow-0.7.13/examples/css/main.rs 0000644 0000000 0000000 00000002251 10461020230 0015135 0 ustar 0000000 0000000 use winnow::prelude::*;
mod parser;
use parser::hex_color;
fn main() -> Result<(), lexopt::Error> {
let args = Args::parse()?;
let input = args.input.as_deref().unwrap_or("#AAAAAA");
println!("{input} =");
match hex_color.parse(input) {
Ok(result) => {
println!(" {result:?}");
}
Err(err) => {
println!(" {err}");
}
}
Ok(())
}
#[derive(Default)]
struct Args {
input: Option,
}
impl Args {
fn parse() -> Result {
use lexopt::prelude::*;
let mut res = Args::default();
let mut args = lexopt::Parser::from_env();
while let Some(arg) = args.next()? {
match arg {
Value(input) => {
res.input = Some(input.string()?);
}
_ => return Err(arg.unexpected()),
}
}
Ok(res)
}
}
#[test]
fn parse_color() {
assert_eq!(
hex_color.parse_peek("#2F14DF"),
Ok((
"",
parser::Color {
red: 47,
green: 20,
blue: 223,
}
))
);
}
winnow-0.7.13/examples/css/parser.rs 0000644 0000000 0000000 00000001510 10461020230 0015502 0 ustar 0000000 0000000 use winnow::combinator::seq;
use winnow::prelude::*;
use winnow::token::take_while;
use winnow::Result;
#[derive(Debug, Eq, PartialEq)]
pub(crate) struct Color {
pub(crate) red: u8,
pub(crate) green: u8,
pub(crate) blue: u8,
}
impl std::str::FromStr for Color {
// The error must be owned
type Err = String;
fn from_str(s: &str) -> Result {
hex_color.parse(s).map_err(|e| e.to_string())
}
}
pub(crate) fn hex_color(input: &mut &str) -> Result {
seq!(Color {
_: '#',
red: hex_primary,
green: hex_primary,
blue: hex_primary
})
.parse_next(input)
}
fn hex_primary(input: &mut &str) -> Result {
take_while(2, |c: char| c.is_ascii_hexdigit())
.try_map(|input| u8::from_str_radix(input, 16))
.parse_next(input)
}
winnow-0.7.13/examples/custom_error.rs 0000644 0000000 0000000 00000002765 10461020230 0016156 0 ustar 0000000 0000000 use winnow::error::AddContext;
use winnow::error::ErrMode;
use winnow::error::FromExternalError;
use winnow::error::ParserError;
use winnow::prelude::*;
use winnow::stream::Stream;
#[derive(Debug)]
pub enum CustomError {
MyError,
Winnow(I),
External {
cause: Box,
input: I,
},
}
impl ParserError for CustomError {
type Inner = Self;
fn from_input(input: &I) -> Self {
CustomError::Winnow(input.clone())
}
fn into_inner(self) -> Result {
Ok(self)
}
}
impl AddContext for CustomError {
#[inline]
fn add_context(
self,
_input: &I,
_token_start: &::Checkpoint,
_context: C,
) -> Self {
self
}
}
impl FromExternalError
for CustomError
{
#[inline]
fn from_external_error(input: &I, e: E) -> Self {
CustomError::External {
cause: Box::new(e),
input: input.clone(),
}
}
}
pub fn parse<'s>(_input: &mut &'s str) -> ModalResult<&'s str, CustomError<&'s str>> {
Err(ErrMode::Backtrack(CustomError::MyError))
}
fn main() {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let err = parse.parse_next(&mut "").unwrap_err();
assert!(matches!(err, ErrMode::Backtrack(CustomError::MyError)));
}
}
winnow-0.7.13/examples/http/bench.rs 0000644 0000000 0000000 00000002021 10461020230 0015452 0 ustar 0000000 0000000 mod parser;
mod parser_streaming;
fn one_test(c: &mut criterion::Criterion) {
let data = &b"GET / HTTP/1.1
Host: www.reddit.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:15.0) Gecko/20100101 Firefox/15.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
"[..];
let mut http_group = c.benchmark_group("http");
http_group.throughput(criterion::Throughput::Bytes(data.len() as u64));
http_group.bench_with_input(
criterion::BenchmarkId::new("complete", data.len()),
data,
|b, data| {
b.iter(|| parser::parse(data).unwrap());
},
);
http_group.bench_with_input(
criterion::BenchmarkId::new("streaming", data.len()),
data,
|b, data| {
b.iter(|| parser_streaming::parse(data).unwrap());
},
);
http_group.finish();
}
criterion::criterion_group!(http, one_test);
criterion::criterion_main!(http);
winnow-0.7.13/examples/http/main.rs 0000644 0000000 0000000 00000002074 10461020230 0015327 0 ustar 0000000 0000000 mod parser;
fn main() -> Result<(), lexopt::Error> {
let args = Args::parse()?;
let input = args.input.as_deref().unwrap_or(
"GET / HTTP/1.1
Host: www.reddit.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:15.0) Gecko/20100101 Firefox/15.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
",
);
if let Some(result) = parser::parse(input.as_bytes()) {
println!(" {result:#?}");
}
Ok(())
}
#[derive(Default)]
struct Args {
input: Option,
}
impl Args {
fn parse() -> Result {
use lexopt::prelude::*;
let mut res = Args::default();
let mut args = lexopt::Parser::from_env();
while let Some(arg) = args.next()? {
match arg {
Value(input) => {
res.input = Some(input.string()?);
}
_ => return Err(arg.unexpected()),
}
}
Ok(res)
}
}
winnow-0.7.13/examples/http/parser.rs 0000644 0000000 0000000 00000006173 10461020230 0015703 0 ustar 0000000 0000000 use winnow::combinator::seq;
use winnow::prelude::*;
use winnow::{ascii::line_ending, combinator::repeat, token::take_while};
pub(crate) type Stream<'i> = &'i [u8];
#[rustfmt::skip]
#[derive(Debug)]
#[allow(dead_code)]
pub(crate) struct Request<'a> {
method: &'a [u8],
uri: &'a [u8],
version: &'a [u8],
}
#[derive(Debug)]
#[allow(dead_code)]
pub(crate) struct Header<'a> {
name: &'a [u8],
value: Vec<&'a [u8]>,
}
pub(crate) fn parse(data: &[u8]) -> Option, Vec>)>> {
let mut buf = data;
let mut v = Vec::new();
loop {
match request(&mut buf) {
Ok(r) => {
v.push(r);
if buf.is_empty() {
//println!("{}", i);
break;
}
}
Err(e) => {
println!("error: {e:?}");
return None;
}
}
}
Some(v)
}
fn request<'s>(input: &mut Stream<'s>) -> ModalResult<(Request<'s>, Vec>)> {
let req = request_line(input)?;
let h = repeat(1.., message_header).parse_next(input)?;
let _ = line_ending.parse_next(input)?;
Ok((req, h))
}
fn request_line<'s>(input: &mut Stream<'s>) -> ModalResult> {
seq!( Request {
method: take_while(1.., is_token),
_: take_while(1.., is_space),
uri: take_while(1.., is_not_space),
_: take_while(1.., is_space),
version: http_version,
_: line_ending,
})
.parse_next(input)
}
fn http_version<'s>(input: &mut Stream<'s>) -> ModalResult<&'s [u8]> {
let _ = "HTTP/".parse_next(input)?;
let version = take_while(1.., is_version).parse_next(input)?;
Ok(version)
}
fn message_header_value<'s>(input: &mut Stream<'s>) -> ModalResult<&'s [u8]> {
let _ = take_while(1.., is_horizontal_space).parse_next(input)?;
let data = take_while(1.., till_line_ending).parse_next(input)?;
let _ = line_ending.parse_next(input)?;
Ok(data)
}
fn message_header<'s>(input: &mut Stream<'s>) -> ModalResult> {
seq!(Header {
name: take_while(1.., is_token),
_: ':',
value: repeat(1.., message_header_value),
})
.parse_next(input)
}
#[rustfmt::skip]
#[allow(clippy::match_same_arms)]
#[allow(clippy::match_like_matches_macro)]
fn is_token(c: u8) -> bool {
match c {
128..=255 => false,
0..=31 => false,
b'(' => false,
b')' => false,
b'<' => false,
b'>' => false,
b'@' => false,
b',' => false,
b';' => false,
b':' => false,
b'\\' => false,
b'"' => false,
b'/' => false,
b'[' => false,
b']' => false,
b'?' => false,
b'=' => false,
b'{' => false,
b'}' => false,
b' ' => false,
_ => true,
}
}
fn is_version(c: u8) -> bool {
c.is_ascii_digit() || c == b'.'
}
fn till_line_ending(c: u8) -> bool {
c != b'\r' && c != b'\n'
}
fn is_space(c: u8) -> bool {
c == b' '
}
fn is_not_space(c: u8) -> bool {
c != b' '
}
fn is_horizontal_space(c: u8) -> bool {
c == b' ' || c == b'\t'
}
winnow-0.7.13/examples/http/parser_streaming.rs 0000644 0000000 0000000 00000006236 10461020230 0017754 0 ustar 0000000 0000000 use winnow::combinator::seq;
use winnow::{
ascii::line_ending, combinator::repeat, prelude::*, stream::Partial, token::take_while,
};
pub(crate) type Stream<'i> = Partial<&'i [u8]>;
#[rustfmt::skip]
#[derive(Debug)]
#[allow(dead_code)]
pub(crate) struct Request<'a> {
method: &'a [u8],
uri: &'a [u8],
version: &'a [u8],
}
#[derive(Debug)]
#[allow(dead_code)]
pub(crate) struct Header<'a> {
name: &'a [u8],
value: Vec<&'a [u8]>,
}
pub(crate) fn parse(data: &[u8]) -> Option, Vec>)>> {
let mut buf = Partial::new(data);
let mut v = Vec::new();
loop {
match request(&mut buf) {
Ok(r) => {
v.push(r);
if buf.is_empty() {
//println!("{}", i);
break;
}
}
Err(e) => {
println!("error: {e:?}");
return None;
}
}
}
Some(v)
}
fn request<'s>(input: &mut Stream<'s>) -> ModalResult<(Request<'s>, Vec>)> {
let req = request_line(input)?;
let h = repeat(1.., message_header).parse_next(input)?;
let _ = line_ending.parse_next(input)?;
Ok((req, h))
}
fn request_line<'s>(input: &mut Stream<'s>) -> ModalResult> {
seq!( Request {
method: take_while(1.., is_token),
_: take_while(1.., is_space),
uri: take_while(1.., is_not_space),
_: take_while(1.., is_space),
version: http_version,
_: line_ending,
})
.parse_next(input)
}
fn http_version<'s>(input: &mut Stream<'s>) -> ModalResult<&'s [u8]> {
let _ = "HTTP/".parse_next(input)?;
let version = take_while(1.., is_version).parse_next(input)?;
Ok(version)
}
fn message_header_value<'s>(input: &mut Stream<'s>) -> ModalResult<&'s [u8]> {
let _ = take_while(1.., is_horizontal_space).parse_next(input)?;
let data = take_while(1.., till_line_ending).parse_next(input)?;
let _ = line_ending.parse_next(input)?;
Ok(data)
}
fn message_header<'s>(input: &mut Stream<'s>) -> ModalResult> {
seq!(Header {
name: take_while(1.., is_token),
_: ':',
value: repeat(1.., message_header_value),
})
.parse_next(input)
}
#[rustfmt::skip]
#[allow(clippy::match_same_arms)]
#[allow(clippy::match_like_matches_macro)]
fn is_token(c: u8) -> bool {
match c {
128..=255 => false,
0..=31 => false,
b'(' => false,
b')' => false,
b'<' => false,
b'>' => false,
b'@' => false,
b',' => false,
b';' => false,
b':' => false,
b'\\' => false,
b'"' => false,
b'/' => false,
b'[' => false,
b']' => false,
b'?' => false,
b'=' => false,
b'{' => false,
b'}' => false,
b' ' => false,
_ => true,
}
}
fn is_version(c: u8) -> bool {
c.is_ascii_digit() || c == b'.'
}
fn till_line_ending(c: u8) -> bool {
c != b'\r' && c != b'\n'
}
fn is_space(c: u8) -> bool {
c == b' '
}
fn is_not_space(c: u8) -> bool {
c != b' '
}
fn is_horizontal_space(c: u8) -> bool {
c == b' ' || c == b'\t'
}
winnow-0.7.13/examples/ini/bench.rs 0000644 0000000 0000000 00000003412 10461020230 0015257 0 ustar 0000000 0000000 use winnow::combinator::repeat;
use winnow::prelude::*;
use winnow::Result;
mod parser;
mod parser_str;
fn bench_ini(c: &mut criterion::Criterion) {
let str = "[owner]
name=John Doe
organization=Acme Widgets Inc.
[database]
server=192.0.2.62
port=143
file=payroll.dat
\0";
let mut group = c.benchmark_group("ini");
group.throughput(criterion::Throughput::Bytes(str.len() as u64));
group.bench_function(criterion::BenchmarkId::new("bytes", str.len()), |b| {
b.iter(|| parser::categories.parse_peek(str.as_bytes()).unwrap());
});
group.bench_function(criterion::BenchmarkId::new("str", str.len()), |b| {
b.iter(|| parser_str::categories.parse_peek(str).unwrap());
});
}
fn bench_ini_keys_and_values(c: &mut criterion::Criterion) {
let str = "server=192.0.2.62
port=143
file=payroll.dat
\0";
fn acc<'s>(i: &mut parser::Stream<'s>) -> Result> {
repeat(0.., parser::key_value).parse_next(i)
}
let mut group = c.benchmark_group("ini keys and values");
group.throughput(criterion::Throughput::Bytes(str.len() as u64));
group.bench_function(criterion::BenchmarkId::new("bytes", str.len()), |b| {
b.iter(|| acc.parse_peek(str.as_bytes()).unwrap());
});
}
fn bench_ini_key_value(c: &mut criterion::Criterion) {
let str = "server=192.0.2.62\n";
let mut group = c.benchmark_group("ini key value");
group.throughput(criterion::Throughput::Bytes(str.len() as u64));
group.bench_function(criterion::BenchmarkId::new("bytes", str.len()), |b| {
b.iter(|| parser::key_value.parse_peek(str.as_bytes()).unwrap());
});
}
criterion::criterion_group!(
benches,
bench_ini,
bench_ini_keys_and_values,
bench_ini_key_value
);
criterion::criterion_main!(benches);
winnow-0.7.13/examples/ini/main.rs 0000644 0000000 0000000 00000002461 10461020230 0015127 0 ustar 0000000 0000000 use winnow::prelude::*;
mod parser;
mod parser_str;
fn main() -> Result<(), lexopt::Error> {
let args = Args::parse()?;
let input = args.input.as_deref().unwrap_or("1 + 1");
if args.binary {
match parser::categories.parse(input.as_bytes()) {
Ok(result) => {
println!(" {result:?}");
}
Err(err) => {
println!(" {err:?}");
}
}
} else {
match parser_str::categories.parse(input) {
Ok(result) => {
println!(" {result:?}");
}
Err(err) => {
println!(" {err}");
}
}
}
Ok(())
}
#[derive(Default)]
struct Args {
input: Option,
binary: bool,
}
impl Args {
fn parse() -> Result {
use lexopt::prelude::*;
let mut res = Args::default();
let mut args = lexopt::Parser::from_env();
while let Some(arg) = args.next()? {
match arg {
Long("binary") => {
res.binary = true;
}
Value(input) => {
res.input = Some(input.string()?);
}
_ => return Err(arg.unexpected()),
}
}
Ok(res)
}
}
winnow-0.7.13/examples/ini/parser.rs 0000644 0000000 0000000 00000007660 10461020230 0015505 0 ustar 0000000 0000000 use std::collections::HashMap;
use std::str;
use winnow::prelude::*;
use winnow::Result;
use winnow::{
ascii::{alphanumeric1 as alphanumeric, multispace0 as multispace, space0 as space},
combinator::opt,
combinator::repeat,
combinator::{delimited, separated_pair, terminated},
token::take_while,
};
pub(crate) type Stream<'i> = &'i [u8];
pub(crate) fn categories<'s>(
i: &mut Stream<'s>,
) -> Result>> {
repeat(
0..,
separated_pair(
category,
opt(multispace),
repeat(0.., terminated(key_value, opt(multispace))),
),
)
.parse_next(i)
}
fn category<'s>(i: &mut Stream<'s>) -> Result<&'s str> {
delimited('[', take_while(0.., |c| c != b']'), ']')
.try_map(str::from_utf8)
.parse_next(i)
}
pub(crate) fn key_value<'s>(i: &mut Stream<'s>) -> Result<(&'s str, &'s str)> {
let key = alphanumeric.try_map(str::from_utf8).parse_next(i)?;
let _ = (opt(space), '=', opt(space)).parse_next(i)?;
let val = take_while(0.., |c| c != b'\n' && c != b';')
.try_map(str::from_utf8)
.parse_next(i)?;
let _ = opt((';', take_while(0.., |c| c != b'\n'))).parse_next(i)?;
Ok((key, val))
}
#[test]
fn parse_category_test() {
let ini_file = &b"[category]
parameter=value
key = value2"[..];
let ini_without_category = &b"\n\nparameter=value
key = value2"[..];
let res = category.parse_peek(ini_file);
println!("{res:?}");
match res {
Ok((i, o)) => println!("i: {:?} | o: {:?}", str::from_utf8(i), o),
_ => println!("error"),
}
assert_eq!(res, Ok((ini_without_category, "category")));
}
#[test]
fn parse_key_value_test() {
let ini_file = &b"parameter=value
key = value2"[..];
let ini_without_key_value = &b"\nkey = value2"[..];
let res = key_value.parse_peek(ini_file);
println!("{res:?}");
match res {
Ok((i, (o1, o2))) => println!("i: {:?} | o: ({:?},{:?})", str::from_utf8(i), o1, o2),
_ => println!("error"),
}
assert_eq!(res, Ok((ini_without_key_value, ("parameter", "value"))));
}
#[test]
fn parse_key_value_with_space_test() {
let ini_file = &b"parameter = value
key = value2"[..];
let ini_without_key_value = &b"\nkey = value2"[..];
let res = key_value.parse_peek(ini_file);
println!("{res:?}");
match res {
Ok((i, (o1, o2))) => println!("i: {:?} | o: ({:?},{:?})", str::from_utf8(i), o1, o2),
_ => println!("error"),
}
assert_eq!(res, Ok((ini_without_key_value, ("parameter", "value"))));
}
#[test]
fn parse_key_value_with_comment_test() {
let ini_file = &b"parameter=value;abc
key = value2"[..];
let ini_without_key_value = &b"\nkey = value2"[..];
let res = key_value.parse_peek(ini_file);
println!("{res:?}");
match res {
Ok((i, (o1, o2))) => println!("i: {:?} | o: ({:?},{:?})", str::from_utf8(i), o1, o2),
_ => println!("error"),
}
assert_eq!(res, Ok((ini_without_key_value, ("parameter", "value"))));
}
#[test]
fn parse_multiple_categories_test() {
let ini_file = &b"[abcd]
parameter=value;abc
key = value2
[category]
parameter3=value3
key4 = value4
"[..];
let ini_after_parser = &b""[..];
let res = categories.parse_peek(ini_file);
//println!("{:?}", res);
match res {
Ok((i, ref o)) => println!("i: {:?} | o: {:?}", str::from_utf8(i), o),
_ => println!("error"),
}
let mut expected_1: HashMap<&str, &str> = HashMap::new();
expected_1.insert("parameter", "value");
expected_1.insert("key", "value2");
let mut expected_2: HashMap<&str, &str> = HashMap::new();
expected_2.insert("parameter3", "value3");
expected_2.insert("key4", "value4");
let mut expected_h: HashMap<&str, HashMap<&str, &str>> = HashMap::new();
expected_h.insert("abcd", expected_1);
expected_h.insert("category", expected_2);
assert_eq!(res, Ok((ini_after_parser, expected_h)));
}
winnow-0.7.13/examples/ini/parser_str.rs 0000644 0000000 0000000 00000012542 10461020230 0016370 0 ustar 0000000 0000000 use std::collections::HashMap;
use winnow::prelude::*;
use winnow::Result;
use winnow::{
ascii::{alphanumeric1 as alphanumeric, space0 as space},
combinator::opt,
combinator::repeat,
combinator::{delimited, terminated},
token::{take_till, take_while},
};
pub(crate) type Stream<'i> = &'i str;
pub(crate) fn categories<'s>(
input: &mut Stream<'s>,
) -> Result>> {
repeat(0.., category_and_keys).parse_next(input)
}
fn category_and_keys<'s>(i: &mut Stream<'s>) -> Result<(&'s str, HashMap<&'s str, &'s str>)> {
(category, keys_and_values).parse_next(i)
}
fn category<'s>(i: &mut Stream<'s>) -> Result<&'s str> {
terminated(
delimited('[', take_while(0.., |c| c != ']'), ']'),
opt(take_while(1.., [' ', '\r', '\n'])),
)
.parse_next(i)
}
fn keys_and_values<'s>(input: &mut Stream<'s>) -> Result> {
repeat(0.., key_value).parse_next(input)
}
fn key_value<'s>(i: &mut Stream<'s>) -> Result<(&'s str, &'s str)> {
let key = alphanumeric.parse_next(i)?;
let _ = (opt(space), "=", opt(space)).parse_next(i)?;
let val = take_till(0.., is_line_ending_or_comment).parse_next(i)?;
let _ = opt(space).parse_next(i)?;
let _ = opt((";", till_line_ending)).parse_next(i)?;
let _ = opt(space_or_line_ending).parse_next(i)?;
Ok((key, val))
}
fn is_line_ending_or_comment(chr: char) -> bool {
chr == ';' || chr == '\n'
}
fn till_line_ending<'s>(i: &mut Stream<'s>) -> Result<&'s str> {
take_while(0.., |c| c != '\r' && c != '\n').parse_next(i)
}
fn space_or_line_ending<'s>(i: &mut Stream<'s>) -> Result<&'s str> {
take_while(1.., [' ', '\r', '\n']).parse_next(i)
}
#[test]
fn parse_category_test() {
let ini_file = "[category]
parameter=value
key = value2";
let ini_without_category = "parameter=value
key = value2";
let res = category.parse_peek(ini_file);
println!("{res:?}");
match res {
Ok((i, o)) => println!("i: {i} | o: {o:?}"),
_ => println!("error"),
}
assert_eq!(res, Ok((ini_without_category, "category")));
}
#[test]
fn parse_key_value_test() {
let ini_file = "parameter=value
key = value2";
let ini_without_key_value = "key = value2";
let res = key_value.parse_peek(ini_file);
println!("{res:?}");
match res {
Ok((i, (o1, o2))) => println!("i: {i} | o: ({o1:?},{o2:?})"),
_ => println!("error"),
}
assert_eq!(res, Ok((ini_without_key_value, ("parameter", "value"))));
}
#[test]
fn parse_key_value_with_space_test() {
let ini_file = "parameter = value
key = value2";
let ini_without_key_value = "key = value2";
let res = key_value.parse_peek(ini_file);
println!("{res:?}");
match res {
Ok((i, (o1, o2))) => println!("i: {i} | o: ({o1:?},{o2:?})"),
_ => println!("error"),
}
assert_eq!(res, Ok((ini_without_key_value, ("parameter", "value"))));
}
#[test]
fn parse_key_value_with_comment_test() {
let ini_file = "parameter=value;abc
key = value2";
let ini_without_key_value = "key = value2";
let res = key_value.parse_peek(ini_file);
println!("{res:?}");
match res {
Ok((i, (o1, o2))) => println!("i: {i} | o: ({o1:?},{o2:?})"),
_ => println!("error"),
}
assert_eq!(res, Ok((ini_without_key_value, ("parameter", "value"))));
}
#[test]
fn parse_multiple_keys_and_values_test() {
let ini_file = "parameter=value;abc
key = value2
[category]";
let ini_without_key_value = "[category]";
let res = keys_and_values.parse_peek(ini_file);
println!("{res:?}");
match res {
Ok((i, ref o)) => println!("i: {i} | o: {o:?}"),
_ => println!("error"),
}
let mut expected: HashMap<&str, &str> = HashMap::new();
expected.insert("parameter", "value");
expected.insert("key", "value2");
assert_eq!(res, Ok((ini_without_key_value, expected)));
}
#[test]
fn parse_category_then_multiple_keys_and_values_test() {
//FIXME: there can be an empty line or a comment line after a category
let ini_file = "[abcd]
parameter=value;abc
key = value2
[category]";
let ini_after_parser = "[category]";
let res = category_and_keys.parse_peek(ini_file);
println!("{res:?}");
match res {
Ok((i, ref o)) => println!("i: {i} | o: {o:?}"),
_ => println!("error"),
}
let mut expected_h: HashMap<&str, &str> = HashMap::new();
expected_h.insert("parameter", "value");
expected_h.insert("key", "value2");
assert_eq!(res, Ok((ini_after_parser, ("abcd", expected_h))));
}
#[test]
fn parse_multiple_categories_test() {
let ini_file = "[abcd]
parameter=value;abc
key = value2
[category]
parameter3=value3
key4 = value4
";
let res = categories.parse_peek(ini_file);
//println!("{:?}", res);
match res {
Ok((i, ref o)) => println!("i: {i} | o: {o:?}"),
_ => println!("error"),
}
let mut expected_1: HashMap<&str, &str> = HashMap::new();
expected_1.insert("parameter", "value");
expected_1.insert("key", "value2");
let mut expected_2: HashMap<&str, &str> = HashMap::new();
expected_2.insert("parameter3", "value3");
expected_2.insert("key4", "value4");
let mut expected_h: HashMap<&str, HashMap<&str, &str>> = HashMap::new();
expected_h.insert("abcd", expected_1);
expected_h.insert("category", expected_2);
assert_eq!(res, Ok(("", expected_h)));
}
winnow-0.7.13/examples/iterator.rs 0000644 0000000 0000000 00000004052 10461020230 0015253 0 ustar 0000000 0000000 use std::collections::HashMap;
use std::iter::Iterator;
use winnow::ascii::alphanumeric1;
use winnow::combinator::iterator;
use winnow::combinator::{separated_pair, terminated};
use winnow::prelude::*;
fn main() {
let mut data = "abcabcabcabc";
fn parser<'s>(i: &mut &'s str) -> ModalResult<&'s str> {
"abc".parse_next(i)
}
// `from_fn` (available from Rust 1.34) can create an iterator
// from a closure
let it = std::iter::from_fn(move || parser.parse_next(&mut data).ok());
for value in it {
println!("parser returned: {value}");
}
println!("\n********************\n");
let mut data = "abcabcabcabc";
// if `from_fn` is not available, it is possible to fold
// over an iterator of functions
let res = std::iter::repeat(parser)
.take(3)
.try_fold(Vec::new(), |mut acc, mut parser| {
parser.parse_next(&mut data).map(|o| {
acc.push(o);
acc
})
});
// will print "parser iterator returned: Ok(("abc", ["abc", "abc", "abc"]))"
println!("\nparser iterator returned: {res:?}");
println!("\n********************\n");
let data = "key1:value1,key2:value2,key3:value3,;";
// `winnow::combinator::iterator` will return an iterator
// producing the parsed values. Compared to the previous
// solutions:
// - we can work with a normal iterator like `from_fn`
// - we can get the remaining input afterwards, like with the `try_fold` trick
let mut winnow_it = iterator(
data,
terminated(separated_pair(alphanumeric1, ":", alphanumeric1), ","),
);
let res = winnow_it
.map(|(k, v)| (k.to_uppercase(), v))
.collect::>();
let parser_result: ModalResult<(_, _), ()> = winnow_it.finish();
let (remaining_input, ()) = parser_result.unwrap();
// will print "iterator returned {"key1": "value1", "key3": "value3", "key2": "value2"}, remaining input is ';'"
println!("iterator returned {res:?}, remaining input is '{remaining_input}'");
}
winnow-0.7.13/examples/json/bench.rs 0000644 0000000 0000000 00000004570 10461020230 0015457 0 ustar 0000000 0000000 use winnow::prelude::*;
use winnow::Partial;
mod json;
mod parser_alt;
mod parser_dispatch;
mod parser_partial;
fn json_bench(c: &mut criterion::Criterion) {
let data = [("small", SMALL), ("canada", CANADA)];
let mut group = c.benchmark_group("json");
for (name, sample) in data {
let len = sample.len();
group.throughput(criterion::Throughput::Bytes(len as u64));
group.bench_with_input(
criterion::BenchmarkId::new("dispatch", name),
&len,
|b, _| {
type Error = winnow::error::ErrMode;
b.iter(|| parser_dispatch::json::.parse_peek(sample).unwrap());
},
);
group.bench_with_input(
criterion::BenchmarkId::new("modeless", name),
&len,
|b, _| {
type Error = winnow::error::ContextError;
b.iter(|| parser_dispatch::json::.parse_peek(sample).unwrap());
},
);
group.bench_with_input(
criterion::BenchmarkId::new("empty-error", name),
&len,
|b, _| {
type Error<'i> = winnow::error::EmptyError;
b.iter(|| {
parser_dispatch::json::>
.parse_peek(sample)
.unwrap()
});
},
);
group.bench_with_input(criterion::BenchmarkId::new("alt", name), &len, |b, _| {
type Error = winnow::error::ContextError;
b.iter(|| parser_alt::json::.parse_peek(sample).unwrap());
});
group.bench_with_input(
criterion::BenchmarkId::new("streaming", name),
&len,
|b, _| {
type Error = winnow::error::ContextError;
b.iter(|| {
parser_partial::json::
.parse_peek(Partial::new(sample))
.unwrap()
});
},
);
}
group.finish();
}
const SMALL: &str = " { \"a\"\t: 42,
\"b\": [ \"x\", \"y\", 12 ,\"\\u2014\", \"\\uD83D\\uDE10\"] ,
\"c\": { \"hello\" : \"world\"
}
} ";
const CANADA: &str = include_str!("../../third_party/nativejson-benchmark/data/canada.json");
criterion::criterion_group!(benches, json_bench,);
criterion::criterion_main!(benches);
winnow-0.7.13/examples/json/json.rs 0000644 0000000 0000000 00000000340 10461020230 0015340 0 ustar 0000000 0000000 use std::collections::HashMap;
#[derive(Debug, PartialEq, Clone)]
pub(crate) enum JsonValue {
Null,
Boolean(bool),
Str(String),
Num(f64),
Array(Vec),
Object(HashMap),
}
winnow-0.7.13/examples/json/main.rs 0000644 0000000 0000000 00000004371 10461020230 0015323 0 ustar 0000000 0000000 mod json;
mod parser_alt;
mod parser_dispatch;
#[allow(dead_code)]
mod parser_partial;
use winnow::error::EmptyError;
use winnow::prelude::*;
fn main() -> Result<(), lexopt::Error> {
let args = Args::parse()?;
let data = args.input.as_deref().unwrap_or(if args.invalid {
" { \"a\"\t: 42,
\"b\": [ \"x\", \"y\", 12 ] ,
\"c\": { 1\"hello\" : \"world\"
}
} "
} else {
" { \"a\"\t: 42,
\"b\": [ \"x\", \"y\", 12 ] ,
\"c\": { \"hello\" : \"world\"
}
} "
});
let result = match args.implementation {
Impl::Naive => parser_alt::json::.parse(data),
Impl::Dispatch => parser_dispatch::json::.parse(data),
};
match result {
Ok(json) => {
println!("{json:#?}");
}
Err(err) => {
if args.pretty {
println!("{err}");
} else {
println!("{err:#?}");
}
}
}
Ok(())
}
#[derive(Default)]
struct Args {
input: Option,
invalid: bool,
pretty: bool,
implementation: Impl,
}
enum Impl {
Naive,
Dispatch,
}
impl Default for Impl {
fn default() -> Self {
Self::Naive
}
}
impl Args {
fn parse() -> Result {
use lexopt::prelude::*;
let mut res = Args::default();
let mut args = lexopt::Parser::from_env();
while let Some(arg) = args.next()? {
match arg {
Long("invalid") => {
res.invalid = true;
}
Long("pretty") => {
// Only case where pretty matters
res.pretty = true;
res.invalid = true;
}
Long("impl") => {
res.implementation = args.value()?.parse_with(|s| match s {
"naive" => Ok(Impl::Naive),
"dispatch" => Ok(Impl::Dispatch),
_ => Err("expected `naive`, `dispatch`"),
})?;
}
Value(input) => {
res.input = Some(input.string()?);
}
_ => return Err(arg.unexpected()),
}
}
Ok(res)
}
}
winnow-0.7.13/examples/json/parser_alt.rs 0000644 0000000 0000000 00000026007 10461020230 0016533 0 ustar 0000000 0000000 use std::collections::HashMap;
use std::str;
use winnow::prelude::*;
use winnow::{
ascii::float,
combinator::alt,
combinator::cut_err,
combinator::{delimited, preceded, separated_pair, terminated},
combinator::{repeat, separated},
error::{AddContext, ParserError, StrContext},
token::{any, none_of, take, take_while},
};
use crate::json::JsonValue;
pub(crate) type Stream<'i> = &'i str;
/// The root element of a JSON parser is any value
///
/// A parser has the following signature:
/// `&mut Stream -> ModalResult