winnow-0.6.18/.cargo_vcs_info.json 0000644 00000000136 00000000001 0012451 0 ustar {
"git": {
"sha1": "132b280c1c7f243f2859ab05c3e9bd2f1c898b0c"
},
"path_in_vcs": ""
} winnow-0.6.18/Cargo.lock 0000644 00000120503 00000000001 0010425 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.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edf3ee19dbc0a46d740f6f0926bde8c50f02bdbc7b536842da28f6ac56513a8b"
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 = "doc-comment"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
[[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.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5584ba17d7ab26a8a7284f13e5bd196294dd2f2d79773cff29b9e9edef601a6"
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.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ad8c7be18cc9ec7f4d7948ad6b9df0e04fc649663e3c0ed59f304ed17ca69e9"
dependencies = [
"anstream 0.6.14",
"anstyle",
"escargot",
"normalize-line-endings",
"similar",
"snapbox-macros",
]
[[package]]
name = "snapbox-macros"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f4c14672714436c09254801c934b203196a51182a5107fb76591c7cc56424d"
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.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237"
dependencies = [
"rustix 0.37.20",
"windows-sys 0.48.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.5",
]
[[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.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
dependencies = [
"windows_aarch64_gnullvm 0.52.5",
"windows_aarch64_msvc 0.52.5",
"windows_i686_gnu 0.52.5",
"windows_i686_gnullvm",
"windows_i686_msvc 0.52.5",
"windows_x86_64_gnu 0.52.5",
"windows_x86_64_gnullvm 0.52.5",
"windows_x86_64_msvc 0.52.5",
]
[[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.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
[[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.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
[[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.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
[[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.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
[[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.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
[[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.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
[[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.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
[[package]]
name = "winnow"
version = "0.6.18"
dependencies = [
"annotate-snippets",
"anstream 0.3.2",
"anstyle",
"anyhow",
"automod",
"circular",
"criterion",
"doc-comment",
"is-terminal",
"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.6.18/Cargo.toml 0000644 00000016056 00000000001 0010457 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.6.18"
build = false
include = [
"build.rs",
"src/**/*",
"Cargo.toml",
"Cargo.lock",
"LICENSE*",
"README.md",
"benches/**/*",
"examples/**/*",
]
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]
cargo-args = [
"-Zunstable-options",
"-Zrustdoc-scrape-examples",
]
features = ["unstable-doc"]
rustdoc-args = [
"--cfg",
"docsrs",
]
[[package.metadata.release.pre-release-replacements]]
file = "CHANGELOG.md"
min = 1
replace = "{{version}}"
search = "Unreleased"
[[package.metadata.release.pre-release-replacements]]
exactly = 1
file = "CHANGELOG.md"
replace = "...{{tag_name}}"
search = '\.\.\.HEAD'
[[package.metadata.release.pre-release-replacements]]
file = "CHANGELOG.md"
min = 1
replace = "{{date}}"
search = "ReleaseDate"
[[package.metadata.release.pre-release-replacements]]
exactly = 1
file = "CHANGELOG.md"
replace = """
## [Unreleased] - ReleaseDate
"""
search = ""
[[package.metadata.release.pre-release-replacements]]
exactly = 1
file = "CHANGELOG.md"
replace = """
[Unreleased]: https://github.com/winnow-rs/winnow/compare/{{tag_name}}...HEAD"""
search = ""
[[package.metadata.release.pre-release-replacements]]
exactly = 1
file = "src/lib.rs"
replace = "blob/v{{version}}/CHANGELOG.md"
search = 'blob/v.+\..+\..+/CHANGELOG.md'
[profile.bench]
lto = true
codegen-units = 1
debug = 2
[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 = "contains_token"
path = "benches/contains_token.rs"
harness = false
[[bench]]
name = "find_slice"
path = "benches/find_slice.rs"
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 = "iter"
path = "benches/iter.rs"
harness = false
[[bench]]
name = "json"
path = "examples/json/bench.rs"
harness = false
required-features = ["std"]
[[bench]]
name = "next_slice"
path = "benches/next_slice.rs"
harness = false
[[bench]]
name = "number"
path = "benches/number.rs"
harness = false
[dependencies.anstream]
version = "0.3.2"
optional = true
[dependencies.anstyle]
version = "1.0.1"
optional = true
[dependencies.is-terminal]
version = "0.4.9"
optional = true
[dependencies.memchr]
version = "2.5"
optional = true
default-features = false
[dependencies.terminal_size]
version = "0.2.6"
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.doc-comment]
version = "0.3"
[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.0"
features = ["examples"]
[dev-dependencies.term-transcript]
version = "0.2.0"
[features]
alloc = []
debug = [
"std",
"dep:anstream",
"dep:anstyle",
"dep:is-terminal",
"dep:terminal_size",
]
default = ["std"]
simd = ["dep:memchr"]
std = [
"alloc",
"memchr?/std",
]
unstable-doc = [
"alloc",
"std",
"simd",
"unstable-recover",
]
unstable-recover = []
[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 = "warn"
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"
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]
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
winnow-0.6.18/Cargo.toml.orig 0000644 0000000 0000000 00000013210 10461020230 0014125 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",
"benches/**/*",
"examples/**/*"
]
[workspace.lints.rust]
rust_2018_idioms = { level = "warn", priority = -1 }
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 = "warn"
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"
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"
[package]
name = "winnow"
version = "0.6.18"
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"]
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]
[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", "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 = { version = "0.4.9", optional = true }
memchr = { version = "2.5", optional = true, default-features = false }
terminal_size = { version = "0.2.6", optional = true }
[dev-dependencies]
doc-comment = "0.3"
proptest = "1.2.0"
criterion = "0.5.1"
lexopt = "0.3.0"
term-transcript = "0.2.0"
snapbox = { version = "0.6.0", 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.6.18/LICENSE-MIT 0000644 0000000 0000000 00000001777 10461020230 0012711 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.6.18/README.md 0000644 0000000 0000000 00000002570 10461020230 0012524 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.6.18/benches/contains_token.rs 0000644 0000000 0000000 00000007771 10461020230 0016250 0 ustar 0000000 0000000 use criterion::black_box;
use winnow::combinator::alt;
use winnow::combinator::repeat;
use winnow::prelude::*;
use winnow::token::take_till;
use winnow::token::take_while;
fn contains_token(c: &mut criterion::Criterion) {
let data = [
("contiguous", CONTIGUOUS),
("interleaved", INTERLEAVED),
("canada", CANADA),
];
let mut group = c.benchmark_group("contains_token");
for (name, sample) in data {
let len = sample.len();
group.throughput(criterion::Throughput::Bytes(len as u64));
group.bench_with_input(criterion::BenchmarkId::new("slice", name), &len, |b, _| {
b.iter(|| black_box(parser_slice.parse_peek(black_box(sample)).unwrap()));
});
group.bench_with_input(criterion::BenchmarkId::new("array", name), &len, |b, _| {
b.iter(|| black_box(parser_array.parse_peek(black_box(sample)).unwrap()));
});
group.bench_with_input(criterion::BenchmarkId::new("tuple", name), &len, |b, _| {
b.iter(|| black_box(parser_tuple.parse_peek(black_box(sample)).unwrap()));
});
group.bench_with_input(
criterion::BenchmarkId::new("closure-or", name),
&len,
|b, _| {
b.iter(|| black_box(parser_closure_or.parse_peek(black_box(sample)).unwrap()));
},
);
group.bench_with_input(
criterion::BenchmarkId::new("closure-matches", name),
&len,
|b, _| {
b.iter(|| {
black_box(
parser_closure_matches
.parse_peek(black_box(sample))
.unwrap(),
)
});
},
);
}
group.finish();
}
fn parser_slice(input: &mut &str) -> PResult {
let contains = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'][..];
repeat(
0..,
alt((take_while(1.., contains), take_till(1.., contains))),
)
.parse_next(input)
}
fn parser_array(input: &mut &str) -> PResult {
let contains = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
repeat(
0..,
alt((take_while(1.., contains), take_till(1.., contains))),
)
.parse_next(input)
}
fn parser_tuple(input: &mut &str) -> PResult {
let contains = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
repeat(
0..,
alt((take_while(1.., contains), take_till(1.., contains))),
)
.parse_next(input)
}
fn parser_closure_or(input: &mut &str) -> PResult {
let contains = |c: char| {
c == '0'
|| c == '1'
|| c == '2'
|| c == '3'
|| c == '4'
|| c == '5'
|| c == '6'
|| c == '7'
|| c == '8'
|| c == '9'
};
repeat(
0..,
alt((take_while(1.., contains), take_till(1.., contains))),
)
.parse_next(input)
}
fn parser_closure_matches(input: &mut &str) -> PResult {
let contains = |c: char| matches!(c, '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9');
repeat(
0..,
alt((take_while(1.., contains), take_till(1.., contains))),
)
.parse_next(input)
}
const CONTIGUOUS: &str = "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";
const INTERLEAVED: &str = "0123456789abc0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab";
const CANADA: &str = include_str!("../third_party/nativejson-benchmark/data/canada.json");
criterion::criterion_group!(benches, contains_token);
criterion::criterion_main!(benches);
winnow-0.6.18/benches/find_slice.rs 0000644 0000000 0000000 00000002753 10461020230 0015324 0 ustar 0000000 0000000 use criterion::black_box;
use winnow::combinator::repeat;
use winnow::prelude::*;
use winnow::token::take_until;
fn find_slice(c: &mut criterion::Criterion) {
let empty = "";
let start_byte = "\r".repeat(100);
let start_slice = "\r\n".repeat(100);
let small = format!("{:>10}\r\n", "").repeat(100);
let large = format!("{:>10000}\r\n", "").repeat(100);
let data = [
("empty", (empty, empty)),
("start", (&start_byte, &start_slice)),
("medium", (&small, &small)),
("large", (&large, &large)),
];
let mut group = c.benchmark_group("find_slice");
for (name, samples) in data {
group.bench_with_input(
criterion::BenchmarkId::new("byte", name),
samples.0,
|b, sample| {
b.iter(|| black_box(parser_byte.parse_peek(black_box(sample)).unwrap()));
},
);
group.bench_with_input(
criterion::BenchmarkId::new("slice", name),
samples.1,
|b, sample| {
b.iter(|| black_box(parser_slice.parse_peek(black_box(sample)).unwrap()));
},
);
}
group.finish();
}
fn parser_byte(input: &mut &str) -> PResult {
repeat(0.., (take_until(0.., "\r"), "\r")).parse_next(input)
}
fn parser_slice(input: &mut &str) -> PResult {
repeat(0.., (take_until(0.., "\r\n"), "\r\n")).parse_next(input)
}
criterion::criterion_group!(benches, find_slice);
criterion::criterion_main!(benches);
winnow-0.6.18/benches/iter.rs 0000644 0000000 0000000 00000007737 10461020230 0014177 0 ustar 0000000 0000000 use criterion::black_box;
use winnow::combinator::opt;
use winnow::prelude::*;
use winnow::stream::AsChar;
use winnow::stream::Stream as _;
use winnow::token::one_of;
fn iter(c: &mut criterion::Criterion) {
let data = [
("contiguous", CONTIGUOUS.as_bytes()),
("interleaved", INTERLEAVED.as_bytes()),
("canada", CANADA.as_bytes()),
];
let mut group = c.benchmark_group("iter");
for (name, sample) in data {
let len = sample.len();
group.throughput(criterion::Throughput::Bytes(len as u64));
group.bench_with_input(
criterion::BenchmarkId::new("iterate", name),
&len,
|b, _| {
b.iter(|| black_box(iterate.parse_peek(black_box(sample)).unwrap()));
},
);
group.bench_with_input(
criterion::BenchmarkId::new("next_token", name),
&len,
|b, _| {
b.iter(|| black_box(next_token.parse_peek(black_box(sample)).unwrap()));
},
);
group.bench_with_input(
criterion::BenchmarkId::new("opt(one_of)", name),
&len,
|b, _| {
b.iter(|| black_box(opt_one_of.parse_peek(black_box(sample)).unwrap()));
},
);
group.bench_with_input(
criterion::BenchmarkId::new("take_while", name),
&len,
|b, _| {
b.iter(|| black_box(take_while.parse_peek(black_box(sample)).unwrap()));
},
);
group.bench_with_input(criterion::BenchmarkId::new("repeat", name), &len, |b, _| {
b.iter(|| black_box(repeat.parse_peek(black_box(sample)).unwrap()));
});
}
group.finish();
}
fn iterate(input: &mut &[u8]) -> PResult {
let mut count = 0;
for byte in input.iter() {
if byte.is_dec_digit() {
count += 1;
}
}
input.finish();
Ok(count)
}
fn next_token(input: &mut &[u8]) -> PResult {
let mut count = 0;
while let Some(byte) = input.next_token() {
if byte.is_dec_digit() {
count += 1;
}
}
Ok(count)
}
fn opt_one_of(input: &mut &[u8]) -> PResult {
let mut count = 0;
while !input.is_empty() {
while opt(one_of(AsChar::is_dec_digit))
.parse_next(input)?
.is_some()
{
count += 1;
}
while opt(one_of(|b: u8| !b.is_dec_digit()))
.parse_next(input)?
.is_some()
{}
}
Ok(count)
}
fn take_while(input: &mut &[u8]) -> PResult {
let mut count = 0;
while !input.is_empty() {
count += winnow::token::take_while(0.., AsChar::is_dec_digit)
.parse_next(input)?
.len();
let _ = winnow::token::take_while(0.., |b: u8| !b.is_dec_digit()).parse_next(input)?;
}
Ok(count)
}
fn repeat(input: &mut &[u8]) -> PResult {
let mut count = 0;
while !input.is_empty() {
count += winnow::combinator::repeat(0.., one_of(AsChar::is_dec_digit))
.map(|count: usize| count)
.parse_next(input)?;
winnow::combinator::repeat(0.., one_of(|b: u8| !b.is_dec_digit())).parse_next(input)?;
}
Ok(count)
}
const CONTIGUOUS: &str = "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";
const INTERLEAVED: &str = "0123456789abc0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab";
const CANADA: &str = include_str!("../third_party/nativejson-benchmark/data/canada.json");
criterion::criterion_group!(benches, iter);
criterion::criterion_main!(benches);
winnow-0.6.18/benches/next_slice.rs 0000644 0000000 0000000 00000007522 10461020230 0015361 0 ustar 0000000 0000000 use criterion::black_box;
use winnow::combinator::repeat;
use winnow::prelude::*;
use winnow::token::literal;
use winnow::token::one_of;
fn next_slice(c: &mut criterion::Criterion) {
let mut group = c.benchmark_group("next_slice");
let name = "ascii";
let sample = "h".repeat(100);
let sample = sample.as_str();
group.bench_with_input(
criterion::BenchmarkId::new("char", name),
sample,
|b, sample| {
b.iter(|| black_box(parser_ascii_char.parse_peek(black_box(sample)).unwrap()));
},
);
group.bench_with_input(
criterion::BenchmarkId::new("str", name),
sample,
|b, sample| {
b.iter(|| black_box(parser_ascii_str.parse_peek(black_box(sample)).unwrap()));
},
);
group.bench_with_input(
criterion::BenchmarkId::new("one_of", name),
sample,
|b, sample| {
b.iter(|| black_box(parser_ascii_one_of.parse_peek(black_box(sample)).unwrap()));
},
);
group.bench_with_input(
criterion::BenchmarkId::new("tag_char", name),
sample,
|b, sample| {
b.iter(|| black_box(parser_ascii_tag_char.parse_peek(black_box(sample)).unwrap()));
},
);
group.bench_with_input(
criterion::BenchmarkId::new("tag_str", name),
sample,
|b, sample| {
b.iter(|| black_box(parser_ascii_tag_str.parse_peek(black_box(sample)).unwrap()));
},
);
let name = "utf8";
let sample = "🧑".repeat(100);
let sample = sample.as_str();
group.bench_with_input(
criterion::BenchmarkId::new("char", name),
sample,
|b, sample| {
b.iter(|| black_box(parser_utf8_char.parse_peek(black_box(sample)).unwrap()));
},
);
group.bench_with_input(
criterion::BenchmarkId::new("str", name),
sample,
|b, sample| {
b.iter(|| black_box(parser_utf8_str.parse_peek(black_box(sample)).unwrap()));
},
);
group.bench_with_input(
criterion::BenchmarkId::new("one_of", name),
sample,
|b, sample| {
b.iter(|| black_box(parser_utf8_one_of.parse_peek(black_box(sample)).unwrap()));
},
);
group.bench_with_input(
criterion::BenchmarkId::new("tag_char", name),
sample,
|b, sample| {
b.iter(|| black_box(parser_utf8_tag_char.parse_peek(black_box(sample)).unwrap()));
},
);
group.bench_with_input(
criterion::BenchmarkId::new("tag_str", name),
sample,
|b, sample| {
b.iter(|| black_box(parser_utf8_tag_str.parse_peek(black_box(sample)).unwrap()));
},
);
group.finish();
}
fn parser_ascii_char(input: &mut &str) -> PResult {
repeat(0.., 'h').parse_next(input)
}
fn parser_ascii_str(input: &mut &str) -> PResult {
repeat(0.., "h").parse_next(input)
}
fn parser_ascii_one_of(input: &mut &str) -> PResult {
repeat(0.., one_of('h')).parse_next(input)
}
fn parser_ascii_tag_char(input: &mut &str) -> PResult {
repeat(0.., literal('h')).parse_next(input)
}
fn parser_ascii_tag_str(input: &mut &str) -> PResult {
repeat(0.., literal("h")).parse_next(input)
}
fn parser_utf8_char(input: &mut &str) -> PResult {
repeat(0.., '🧑').parse_next(input)
}
fn parser_utf8_str(input: &mut &str) -> PResult {
repeat(0.., "🧑").parse_next(input)
}
fn parser_utf8_one_of(input: &mut &str) -> PResult {
repeat(0.., one_of('🧑')).parse_next(input)
}
fn parser_utf8_tag_char(input: &mut &str) -> PResult {
repeat(0.., literal('🧑')).parse_next(input)
}
fn parser_utf8_tag_str(input: &mut &str) -> PResult {
repeat(0.., literal("🧑")).parse_next(input)
}
criterion::criterion_group!(benches, next_slice);
criterion::criterion_main!(benches);
winnow-0.6.18/benches/number.rs 0000644 0000000 0000000 00000003437 10461020230 0014515 0 ustar 0000000 0000000 #[macro_use]
extern crate criterion;
use criterion::Criterion;
use winnow::ascii::float;
use winnow::binary::be_u64;
use winnow::error::ErrMode;
use winnow::error::ErrorKind;
use winnow::error::InputError;
use winnow::error::ParserError;
use winnow::prelude::*;
use winnow::stream::ParseSlice;
type Stream<'i> = &'i [u8];
fn parser(i: &mut Stream<'_>) -> PResult {
be_u64.parse_next(i)
}
fn number(c: &mut Criterion) {
let data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
parser
.parse_peek(&data[..])
.expect("should parse correctly");
c.bench_function("number", move |b| {
b.iter(|| parser.parse_peek(&data[..]).unwrap());
});
}
fn float_bytes(c: &mut Criterion) {
println!(
"float_bytes result: {:?}",
float::<_, f64, InputError<_>>.parse_peek(&b"-1.234E-12"[..])
);
c.bench_function("float bytes", |b| {
b.iter(|| float::<_, f64, InputError<_>>.parse_peek(&b"-1.234E-12"[..]));
});
}
fn float_str(c: &mut Criterion) {
println!(
"float_str result: {:?}",
float::<_, f64, InputError<_>>.parse_peek("-1.234E-12")
);
c.bench_function("float str", |b| {
b.iter(|| float::<_, f64, InputError<_>>.parse_peek("-1.234E-12"));
});
}
fn std_float(input: &mut &[u8]) -> PResult {
match input.parse_slice() {
Some(n) => Ok(n),
None => Err(ErrMode::from_error_kind(input, ErrorKind::Slice)),
}
}
fn std_float_bytes(c: &mut Criterion) {
println!(
"std_float_bytes result: {:?}",
std_float.parse_peek(&b"-1.234E-12"[..])
);
c.bench_function("std_float bytes", |b| {
b.iter(|| std_float.parse_peek(&b"-1.234E-12"[..]));
});
}
criterion_group!(benches, number, float_bytes, std_float_bytes, float_str);
criterion_main!(benches);
winnow-0.6.18/examples/arithmetic/bench.rs 0000644 0000000 0000000 00000001726 10461020230 0016643 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.6.18/examples/arithmetic/main.rs 0000644 0000000 0000000 00000004065 10461020230 0016507 0 ustar 0000000 0000000 use winnow::prelude::*;
mod parser;
mod parser_ast;
mod 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::lex.parse(input)?;
println!(" {tokens:#?}");
let result = parser_lexer::expr.parse(tokens.as_slice()).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.6.18/examples/arithmetic/parser.rs 0000644 0000000 0000000 00000006630 10461020230 0017057 0 ustar 0000000 0000000 use std::str::FromStr;
use winnow::prelude::*;
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) -> PResult {
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
fn term(i: &mut &str) -> PResult {
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
fn factor(i: &mut &str) -> PResult {
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) -> PResult {
delimited('(', expr, ')').parse_next(i)
}
#[test]
fn factor_test() {
let input = "3";
let expected = Ok(("", 3));
assert_eq!(factor.parse_peek(input), expected);
let input = " 12";
let expected = Ok(("", 12));
assert_eq!(factor.parse_peek(input), expected);
let input = "537 ";
let expected = Ok(("", 537));
assert_eq!(factor.parse_peek(input), expected);
let input = " 24 ";
let expected = Ok(("", 24));
assert_eq!(factor.parse_peek(input), expected);
}
#[test]
fn term_test() {
let input = " 12 *2 / 3";
let expected = Ok(("", 8));
assert_eq!(term.parse_peek(input), expected);
let input = " 12 *2 / 3";
let expected = Ok(("", 8));
assert_eq!(term.parse_peek(input), expected);
let input = " 2* 3 *2 *2 / 3";
let expected = Ok(("", 8));
assert_eq!(term.parse_peek(input), expected);
let input = " 48 / 3/2";
let expected = Ok(("", 8));
assert_eq!(term.parse_peek(input), expected);
}
#[test]
fn expr_test() {
let input = " 1 + 2 ";
let expected = Ok(("", 3));
assert_eq!(expr.parse_peek(input), expected);
let input = " 12 + 6 - 4+ 3";
let expected = Ok(("", 17));
assert_eq!(expr.parse_peek(input), expected);
let input = " 1 + 2*3 + 4";
let expected = Ok(("", 11));
assert_eq!(expr.parse_peek(input), expected);
}
#[test]
fn parens_test() {
let input = " ( 2 )";
let expected = Ok(("", 2));
assert_eq!(expr.parse_peek(input), expected);
let input = " 2* ( 3 + 4 ) ";
let expected = Ok(("", 14));
assert_eq!(expr.parse_peek(input), expected);
let input = " 2*2 / ( 5 - 1) + 3";
let expected = Ok(("", 4));
assert_eq!(expr.parse_peek(input), expected);
}
winnow-0.6.18/examples/arithmetic/parser_ast.rs 0000644 0000000 0000000 00000013026 10461020230 0017723 0 ustar 0000000 0000000 use std::fmt;
use std::fmt::{Debug, Display, Formatter};
use std::str::FromStr;
use winnow::prelude::*;
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) -> PResult {
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)
}
fn term(i: &mut &str) -> PResult {
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)
}
fn factor(i: &mut &str) -> PResult {
delimited(
multispaces,
alt((digits.try_map(FromStr::from_str).map(Expr::Value), parens)),
multispaces,
)
.parse_next(i)
}
fn parens(i: &mut &str) -> PResult {
delimited("(", expr, ")")
.map(|e| Expr::Paren(Box::new(e)))
.parse_next(i)
}
#[test]
fn factor_test() {
let input = "3";
let expected = Ok(("", String::from("Value(3)")));
assert_eq!(factor.map(|e| format!("{e:?}")).parse_peek(input), expected);
let input = " 12";
let expected = Ok(("", String::from("Value(12)")));
assert_eq!(factor.map(|e| format!("{e:?}")).parse_peek(input), expected);
let input = "537 ";
let expected = Ok(("", String::from("Value(537)")));
assert_eq!(factor.map(|e| format!("{e:?}")).parse_peek(input), expected);
let input = " 24 ";
let expected = Ok(("", String::from("Value(24)")));
assert_eq!(factor.map(|e| format!("{e:?}")).parse_peek(input), expected);
}
#[test]
fn term_test() {
let input = " 12 *2 / 3";
let expected = Ok(("", String::from("Div(Mul(Value(12), Value(2)), Value(3))")));
assert_eq!(term.map(|e| format!("{e:?}")).parse_peek(input), expected);
let input = " 12 *2 / 3";
let expected = Ok(("", String::from("Div(Mul(Value(12), Value(2)), Value(3))")));
assert_eq!(term.map(|e| format!("{e:?}")).parse_peek(input), expected);
let input = " 2* 3 *2 *2 / 3";
let expected = Ok((
"",
String::from("Div(Mul(Mul(Mul(Value(2), Value(3)), Value(2)), Value(2)), Value(3))"),
));
assert_eq!(term.map(|e| format!("{e:?}")).parse_peek(input), expected);
let input = " 48 / 3/2";
let expected = Ok(("", String::from("Div(Div(Value(48), Value(3)), Value(2))")));
assert_eq!(term.map(|e| format!("{e:?}")).parse_peek(input), expected);
}
#[test]
fn expr_test() {
let input = " 1 + 2 ";
let expected = Ok(("", String::from("Add(Value(1), Value(2))")));
assert_eq!(expr.map(|e| format!("{e:?}")).parse_peek(input), expected);
let input = " 12 + 6 - 4+ 3";
let expected = Ok((
"",
String::from("Add(Sub(Add(Value(12), Value(6)), Value(4)), Value(3))"),
));
assert_eq!(expr.map(|e| format!("{e:?}")).parse_peek(input), expected);
let input = " 1 + 2*3 + 4";
let expected = Ok((
"",
String::from("Add(Add(Value(1), Mul(Value(2), Value(3))), Value(4))"),
));
assert_eq!(expr.map(|e| format!("{e:?}")).parse_peek(input), expected);
}
#[test]
fn parens_test() {
let input = " ( 2 )";
let expected = Ok(("", String::from("Paren(Value(2))")));
assert_eq!(expr.map(|e| format!("{e:?}")).parse_peek(input), expected);
let input = " 2* ( 3 + 4 ) ";
let expected = Ok((
"",
String::from("Mul(Value(2), Paren(Add(Value(3), Value(4))))"),
));
assert_eq!(expr.map(|e| format!("{e:?}")).parse_peek(input), expected);
let input = " 2*2 / ( 5 - 1) + 3";
let expected = Ok((
"",
String::from("Add(Div(Mul(Value(2), Value(2)), Paren(Sub(Value(5), Value(1)))), Value(3))"),
));
assert_eq!(expr.map(|e| format!("{e:?}")).parse_peek(input), expected);
}
winnow-0.6.18/examples/arithmetic/parser_lexer.rs 0000644 0000000 0000000 00000021542 10461020230 0020255 0 ustar 0000000 0000000 use std::fmt;
use std::fmt::{Debug, Display, Formatter};
use std::str::FromStr;
use winnow::prelude::*;
use winnow::{
ascii::{digit1 as digits, multispace0 as multispaces},
combinator::alt,
combinator::dispatch,
combinator::fail,
combinator::peek,
combinator::repeat,
combinator::{delimited, preceded, terminated},
token::any,
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})"),
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Token {
Value(i64),
Oper(Oper),
OpenParen,
CloseParen,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Oper {
Add,
Sub,
Mul,
Div,
}
impl winnow::stream::ContainsToken for Token {
#[inline(always)]
fn contains_token(&self, token: Token) -> bool {
*self == token
}
}
impl winnow::stream::ContainsToken for &'_ [Token] {
#[inline]
fn contains_token(&self, token: Token) -> bool {
self.iter().any(|t| *t == token)
}
}
impl winnow::stream::ContainsToken for &'_ [Token; LEN] {
#[inline]
fn contains_token(&self, token: Token) -> bool {
self.iter().any(|t| *t == token)
}
}
impl winnow::stream::ContainsToken for [Token; LEN] {
#[inline]
fn contains_token(&self, token: Token) -> bool {
self.iter().any(|t| *t == token)
}
}
#[allow(dead_code)]
pub(crate) fn expr2(i: &mut &str) -> PResult {
let tokens = lex.parse_next(i)?;
expr.parse_next(&mut tokens.as_slice())
}
pub(crate) fn lex(i: &mut &str) -> PResult> {
preceded(multispaces, repeat(1.., terminated(token, multispaces))).parse_next(i)
}
fn token(i: &mut &str) -> PResult {
dispatch! {peek(any);
'0'..='9' => digits.try_map(FromStr::from_str).map(Token::Value),
'(' => '('.value(Token::OpenParen),
')' => ')'.value(Token::CloseParen),
'+' => '+'.value(Token::Oper(Oper::Add)),
'-' => '-'.value(Token::Oper(Oper::Sub)),
'*' => '*'.value(Token::Oper(Oper::Mul)),
'/' => '/'.value(Token::Oper(Oper::Div)),
_ => fail,
}
.parse_next(i)
}
pub(crate) fn expr(i: &mut &[Token]) -> PResult {
let init = term.parse_next(i)?;
repeat(
0..,
(
one_of([Token::Oper(Oper::Add), Token::Oper(Oper::Sub)]),
term,
),
)
.fold(
move || init.clone(),
|acc, (op, val): (Token, Expr)| {
if op == Token::Oper(Oper::Add) {
Expr::Add(Box::new(acc), Box::new(val))
} else {
Expr::Sub(Box::new(acc), Box::new(val))
}
},
)
.parse_next(i)
}
fn term(i: &mut &[Token]) -> PResult {
let init = factor.parse_next(i)?;
repeat(
0..,
(
one_of([Token::Oper(Oper::Mul), Token::Oper(Oper::Div)]),
factor,
),
)
.fold(
move || init.clone(),
|acc, (op, val): (Token, Expr)| {
if op == Token::Oper(Oper::Mul) {
Expr::Mul(Box::new(acc), Box::new(val))
} else {
Expr::Div(Box::new(acc), Box::new(val))
}
},
)
.parse_next(i)
}
fn factor(i: &mut &[Token]) -> PResult {
alt((
one_of(|t| matches!(t, Token::Value(_))).map(|t| match t {
Token::Value(v) => Expr::Value(v),
_ => unreachable!(),
}),
parens,
))
.parse_next(i)
}
fn parens(i: &mut &[Token]) -> PResult {
delimited(one_of(Token::OpenParen), expr, one_of(Token::CloseParen))
.map(|e| Expr::Paren(Box::new(e)))
.parse_next(i)
}
#[test]
fn lex_test() {
let input = "3";
let expected = Ok(String::from(r#"("", [Value(3)])"#));
assert_eq!(lex.parse_peek(input).map(|e| format!("{e:?}")), expected);
let input = " 24 ";
let expected = Ok(String::from(r#"("", [Value(24)])"#));
assert_eq!(lex.parse_peek(input).map(|e| format!("{e:?}")), expected);
let input = " 12 *2 / 3";
let expected = Ok(String::from(
r#"("", [Value(12), Oper(Mul), Value(2), Oper(Div), Value(3)])"#,
));
assert_eq!(lex.parse_peek(input).map(|e| format!("{e:?}")), expected);
let input = " 2*2 / ( 5 - 1) + 3";
let expected = Ok(String::from(
r#"("", [Value(2), Oper(Mul), Value(2), Oper(Div), OpenParen, Value(5), Oper(Sub), Value(1), CloseParen, Oper(Add), Value(3)])"#,
));
assert_eq!(lex.parse_peek(input).map(|e| format!("{e:?}")), expected);
}
#[test]
fn factor_test() {
let input = "3";
let expected = Ok(String::from("Value(3)"));
let input = lex.parse(input).unwrap();
assert_eq!(factor.map(|e| format!("{e:?}")).parse(&input), expected);
let input = " 12";
let expected = Ok(String::from("Value(12)"));
let input = lex.parse(input).unwrap();
assert_eq!(factor.map(|e| format!("{e:?}")).parse(&input), expected);
let input = "537 ";
let expected = Ok(String::from("Value(537)"));
let input = lex.parse(input).unwrap();
assert_eq!(factor.map(|e| format!("{e:?}")).parse(&input), expected);
let input = " 24 ";
let expected = Ok(String::from("Value(24)"));
let input = lex.parse(input).unwrap();
assert_eq!(factor.map(|e| format!("{e:?}")).parse(&input), expected);
}
#[test]
fn term_test() {
let input = " 12 *2 / 3";
let expected = Ok(String::from("Div(Mul(Value(12), Value(2)), Value(3))"));
let input = lex.parse(input).unwrap();
assert_eq!(term.map(|e| format!("{e:?}")).parse(&input), expected);
let input = " 12 *2 / 3";
let expected = Ok(String::from("Div(Mul(Value(12), Value(2)), Value(3))"));
let input = lex.parse(input).unwrap();
assert_eq!(term.map(|e| format!("{e:?}")).parse(&input), expected);
let input = " 2* 3 *2 *2 / 3";
let expected = Ok(String::from(
"Div(Mul(Mul(Mul(Value(2), Value(3)), Value(2)), Value(2)), Value(3))",
));
let input = lex.parse(input).unwrap();
assert_eq!(term.map(|e| format!("{e:?}")).parse(&input), expected);
let input = " 48 / 3/2";
let expected = Ok(String::from("Div(Div(Value(48), Value(3)), Value(2))"));
let input = lex.parse(input).unwrap();
assert_eq!(term.map(|e| format!("{e:?}")).parse(&input), expected);
}
#[test]
fn expr_test() {
let input = " 1 + 2 ";
let expected = Ok(String::from("Add(Value(1), Value(2))"));
let input = lex.parse(input).unwrap();
assert_eq!(expr.map(|e| format!("{e:?}")).parse(&input), expected);
let input = " 12 + 6 - 4+ 3";
let expected = Ok(String::from(
"Add(Sub(Add(Value(12), Value(6)), Value(4)), Value(3))",
));
let input = lex.parse(input).unwrap();
assert_eq!(expr.map(|e| format!("{e:?}")).parse(&input), expected);
let input = " 1 + 2*3 + 4";
let expected = Ok(String::from(
"Add(Add(Value(1), Mul(Value(2), Value(3))), Value(4))",
));
let input = lex.parse(input).unwrap();
assert_eq!(expr.map(|e| format!("{e:?}")).parse(&input), expected);
}
#[test]
fn parens_test() {
let input = " ( 2 )";
let expected = Ok(String::from("Paren(Value(2))"));
let input = lex.parse(input).unwrap();
assert_eq!(expr.map(|e| format!("{e:?}")).parse(&input), expected);
let input = " 2* ( 3 + 4 ) ";
let expected = Ok(String::from(
"Mul(Value(2), Paren(Add(Value(3), Value(4))))",
));
let input = lex.parse(input).unwrap();
assert_eq!(expr.map(|e| format!("{e:?}")).parse(&input), expected);
let input = " 2*2 / ( 5 - 1) + 3";
let expected = Ok(String::from(
"Add(Div(Mul(Value(2), Value(2)), Paren(Sub(Value(5), Value(1)))), Value(3))",
));
let input = lex.parse(input).unwrap();
assert_eq!(expr.map(|e| format!("{e:?}")).parse(&input), expected);
}
winnow-0.6.18/examples/css/main.rs 0000644 0000000 0000000 00000002251 10461020230 0015141 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.6.18/examples/css/parser.rs 0000644 0000000 0000000 00000001466 10461020230 0015520 0 ustar 0000000 0000000 use winnow::combinator::seq;
use winnow::prelude::*;
use winnow::token::take_while;
#[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) -> PResult {
seq!(Color {
_: '#',
red: hex_primary,
green: hex_primary,
blue: hex_primary
})
.parse_next(input)
}
fn hex_primary(input: &mut &str) -> PResult {
take_while(2, |c: char| c.is_ascii_hexdigit())
.try_map(|input| u8::from_str_radix(input, 16))
.parse_next(input)
}
winnow-0.6.18/examples/custom_error.rs 0000644 0000000 0000000 00000003161 10461020230 0016151 0 ustar 0000000 0000000 use winnow::error::AddContext;
use winnow::error::ErrMode;
use winnow::error::ErrorKind;
use winnow::error::FromExternalError;
use winnow::error::ParserError;
use winnow::prelude::*;
use winnow::stream::Stream;
#[derive(Debug)]
pub enum CustomError {
MyError,
Winnow(I, ErrorKind),
External {
cause: Box,
input: I,
kind: ErrorKind,
},
}
impl ParserError for CustomError {
fn from_error_kind(input: &I, kind: ErrorKind) -> Self {
CustomError::Winnow(input.clone(), kind)
}
fn append(self, _: &I, _: &::Checkpoint, _: ErrorKind) -> Self {
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, kind: ErrorKind, e: E) -> Self {
CustomError::External {
cause: Box::new(e),
input: input.clone(),
kind,
}
}
}
pub fn parse<'s>(_input: &mut &'s str) -> PResult<&'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.6.18/examples/http/bench.rs 0000644 0000000 0000000 00000002021 10461020230 0015456 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.6.18/examples/http/main.rs 0000644 0000000 0000000 00000002074 10461020230 0015333 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.6.18/examples/http/parser.rs 0000644 0000000 0000000 00000006147 10461020230 0015710 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>) -> PResult<(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>) -> PResult> {
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>) -> PResult<&'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>) -> PResult<&'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>) -> PResult> {
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.6.18/examples/http/parser_streaming.rs 0000644 0000000 0000000 00000006212 10461020230 0017752 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>) -> PResult<(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>) -> PResult> {
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>) -> PResult<&'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>) -> PResult<&'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>) -> PResult> {
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.6.18/examples/ini/bench.rs 0000644 0000000 0000000 00000003367 10461020230 0015274 0 ustar 0000000 0000000 use winnow::combinator::repeat;
use winnow::prelude::*;
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>) -> PResult> {
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.6.18/examples/ini/main.rs 0000644 0000000 0000000 00000002461 10461020230 0015133 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.6.18/examples/ini/parser.rs 0000644 0000000 0000000 00000007637 10461020230 0015515 0 ustar 0000000 0000000 use std::collections::HashMap;
use std::str;
use winnow::prelude::*;
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>,
) -> PResult>> {
repeat(
0..,
separated_pair(
category,
opt(multispace),
repeat(0.., terminated(key_value, opt(multispace))),
),
)
.parse_next(i)
}
fn category<'s>(i: &mut Stream<'s>) -> PResult<&'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>) -> PResult<(&'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.6.18/examples/ini/parser_str.rs 0000644 0000000 0000000 00000012525 10461020230 0016375 0 ustar 0000000 0000000 use std::collections::HashMap;
use winnow::prelude::*;
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>,
) -> PResult>> {
repeat(0.., category_and_keys).parse_next(input)
}
fn category_and_keys<'s>(i: &mut Stream<'s>) -> PResult<(&'s str, HashMap<&'s str, &'s str>)> {
(category, keys_and_values).parse_next(i)
}
fn category<'s>(i: &mut Stream<'s>) -> PResult<&'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>) -> PResult> {
repeat(0.., key_value).parse_next(input)
}
fn key_value<'s>(i: &mut Stream<'s>) -> PResult<(&'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>) -> PResult<&'s str> {
take_while(0.., |c| c != '\r' && c != '\n').parse_next(i)
}
fn space_or_line_ending<'s>(i: &mut Stream<'s>) -> PResult<&'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.6.18/examples/iterator.rs 0000644 0000000 0000000 00000004545 10461020230 0015266 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) -> PResult<&'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 || {
match parser.parse_next(&mut data) {
// when successful, a parser returns a tuple of
// the remaining input and the output value.
// So we replace the captured input data with the
// remaining input, to be parsed on the next call
Ok(o) => Some(o),
_ => None,
}
});
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: PResult<(_, _), ()> = 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.6.18/examples/json/bench.rs 0000644 0000000 0000000 00000004551 10461020230 0015462 0 ustar 0000000 0000000 use winnow::prelude::*;
use winnow::Partial;
mod json;
mod parser;
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("basic", name), &len, |b, _| {
type Error<'i> = winnow::error::InputError>;
b.iter(|| parser::json::>.parse_peek(sample).unwrap());
});
group.bench_with_input(criterion::BenchmarkId::new("unit", name), &len, |b, _| {
type Error<'i> = ();
b.iter(|| parser::json::>.parse_peek(sample).unwrap());
});
group.bench_with_input(
criterion::BenchmarkId::new("context", name),
&len,
|b, _| {
type Error<'i> = winnow::error::ContextError>;
b.iter(|| parser::json::>.parse_peek(sample).unwrap());
},
);
group.bench_with_input(
criterion::BenchmarkId::new("dispatch", name),
&len,
|b, _| {
type Error<'i> = winnow::error::InputError>;
b.iter(|| {
parser_dispatch::json::>
.parse_peek(sample)
.unwrap()
});
},
);
group.bench_with_input(
criterion::BenchmarkId::new("streaming", name),
&len,
|b, _| {
type Error<'i> = winnow::error::InputError>;
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.6.18/examples/json/json.rs 0000644 0000000 0000000 00000000340 10461020230 0015344 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.6.18/examples/json/main.rs 0000644 0000000 0000000 00000004356 10461020230 0015332 0 ustar 0000000 0000000 mod json;
mod parser;
mod parser_dispatch;
#[allow(dead_code)]
mod parser_partial;
use winnow::error::ErrorKind;
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::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.6.18/examples/json/parser.rs 0000644 0000000 0000000 00000025754 10461020230 0015707 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},
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 -> PResult