diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:41 +0000 |
commit | 10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 (patch) | |
tree | bdffd5d80c26cf4a7a518281a204be1ace85b4c1 /vendor/toml_edit | |
parent | Releasing progress-linux version 1.70.0+dfsg1-9~progress7.99u1. (diff) | |
download | rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.tar.xz rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.zip |
Merging upstream version 1.70.0+dfsg2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/toml_edit')
317 files changed, 16723 insertions, 0 deletions
diff --git a/vendor/toml_edit/.cargo-checksum.json b/vendor/toml_edit/.cargo-checksum.json new file mode 100644 index 000000000..9a079735b --- /dev/null +++ b/vendor/toml_edit/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.lock":"6c1d51bd2063ab9511da1b01b7d44423c1adb46111989bc23df68968962437ca","Cargo.toml":"0a38d1a10f3129b47bf34093d7e308b8166fdabc74c26d261b50058dd2069b37","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"4ba025b28a1ea4c063512d92a206a0510972cd98daec7c6a64ab846ce8e3702d","README.md":"61071236d49e09b94cda5955f5d61a6196b192b11a990883d458dc6e3d72da6f","examples/visit.rs":"657756caba28aa87a8b10104aba704fd2365579c57a293bc572a8d72173ba174","src/array.rs":"3cd87f817f47b44688157f7ce52b303987c4091a21d3075c1022bc6d63ae7096","src/array_of_tables.rs":"2523e482cb10dd84c135141324fa6ecb6f5bccc6c08c6d96ff65abfb7cfbf8d9","src/de/array.rs":"7969d28e98e366cd16c9ed74128404a147a2b787c54d0450594811a92d17b310","src/de/datetime.rs":"a29e76372fc382686c31ee93fd54c749ea3d775c8d4fcc2b2643f9464ea23730","src/de/key.rs":"f8a977fe08e1f929e599f2216734db678ca6ec9fb7f6860b75f1cdfc628b52c6","src/de/mod.rs":"b7344ac410b21b2c82eb88782f48979d6f850a778a19bb2eea7228e834374d2f","src/de/spanned.rs":"5c959639bf4b3d19c6b18e625a57b28b311164bf7b191bbc4d30aa97b7239679","src/de/table.rs":"b1f0f95ea502126b8707ba945596f3c47d83d46680622899334567df1b58df1d","src/de/table_enum.rs":"879a78836ac3b00ab35b9cd72a08fb8486a6c4ae05c779481ae9fcb9546b8390","src/de/value.rs":"536d18bba54f335f4fe0f387888c1406e60cf7ed4a0afbf2b00b97d33378c91d","src/document.rs":"7882374aa62978cac3752f346253399f281121a544927feed2882ed9a008361d","src/encode.rs":"f6f02ca91509b024984a5543f9a3dacaa7270083e63aa37dff164c9651264bc6","src/index.rs":"34ed0a4cc0cd55ce29885ed8123cc7c09c8ba3b9aa8d3b0b47554c1a41d31577","src/inline_table.rs":"871cfc66cf6c87bfaece0d4725e4a6abe640f5911c3b9c97e617e01293dabd1f","src/internal_string.rs":"8c84f94363ed012eb7114c6b3f6b371155d0ce740ce44ec9d315aedf048c1d11","src/item.rs":"78c5d9e6c714483816f090d419db641977c9dfaf7dd3e9613f6eee10633173f2","src/key.rs":"c2baccdb585879b2ae0fdb98084b8745f23c0f9e33a3220413b2b8a717e7ce4d","src/lib.rs":"3ff2ffd3366e495278fd7b3118ea54b7d09534380396a75b46c409e3c563c67c","src/parser/array.rs":"070931c73b68d781888650511c743c6a8897aea6ab472e81bf3d0e31ff7b7aa1","src/parser/datetime.rs":"8b5ae8accaacc063f0ee2810742eeb2a9ae9950aadd0871ad580a6e030190479","src/parser/document.rs":"34ebc30ddb2a9bbedc3c43885135af1e20a3408d75d5eac6a028757c0c797e44","src/parser/errors.rs":"cb2ad82becb39790cc500e514cc1df745a956a5de7c13890853c46eaa1c89f10","src/parser/inline_table.rs":"751260f5957914cc2ee73db2b5fca008b831ff94bda1d6eb578cf78fcb685d17","src/parser/key.rs":"5b8c6d9cbbc137aed39b91223072a4b8b58088be04e157cae1e909d0697f9662","src/parser/macros.rs":"4a6ab77702619d934e2b511565f710c272f66c211a709b39c1cee5eb5098dfcd","src/parser/mod.rs":"ad8f06fe304fd87d0e927cd05bdd80258f0b4f571d553e08627e0c563e2c19a6","src/parser/numbers.rs":"ee52d040904212d7bd9ff9f402a3dce7bfb440bfbbd9aa3771356b18836100f4","src/parser/state.rs":"8b7ba46e124007c3dfdf894d881768f2dd0895749e217e2b1fedb86d9281b8b2","src/parser/strings.rs":"86e806be525409ea95c53278c61e38b30bede8fa77a87f0b3772b10345d45d05","src/parser/table.rs":"1197eb3b42b7028d023186bd18833b27fabd7dc290ff9c1129b75982101a8930","src/parser/trivia.rs":"c6dcdd041deaaa3d29041826739f303d7cdd394800cc874a3bcdf5201132cc14","src/parser/value.rs":"3d051eb18e5c621a130e3ab7af42b3d06ef1e92e6204c85d5fd78270a9596d81","src/raw_string.rs":"dcec7da0aab75a5ff5891a0b4a22265ed47c17f9d802ec135e40f2bb1b0a7c60","src/repr.rs":"68356f3b89cd76b75bd9f78b6fbd31fbcc96d8195a7118d286dca92950adaee4","src/ser/array.rs":"5fb55303365bf6991f7af523931d1a046e88d3125c099317e12a7d4f592321a8","src/ser/key.rs":"9bad3bee90876c5c54aaa5caee92bfe30d79a100615902118b35b3ceb40b524e","src/ser/map.rs":"700ddcac68f1cb92969bb8e3168d9ad5d1e1b545d68cc7711f0eb58cf41d9f8c","src/ser/mod.rs":"9b37c484e6ac281a40260206e8cb5bec9e2dab09126c9a2010a52786fbf7df78","src/ser/pretty.rs":"9a9f6d43b2eab487de8af216b9950c93318c9ee6a91f4707ffa41e2ee492c902","src/ser/value.rs":"f4d0bedf847cec29096f075995f31b6976539611f4da722e2a263f602bbc7ed0","src/table.rs":"91ea4d3111eb58aaad478d152773fc9ef8cd77a375c83d700eb83a48bf2fbc6e","src/value.rs":"881f7aee14ef968f5f843ccbbaa648117ceac2148df6e09d171f41c174d35dd9","src/visit.rs":"34b49c3091a6ef7c1513429f8290c26989da25cec496d3993abf33fa65ebfc58","src/visit_mut.rs":"b184d7bb94038fdc2e0fee8689112f01377d9f8c05ffafb8a1f5f2263e80ee27","tests/decoder.rs":"8093389d542f50974d6a606321b0413941709ac2cbdef48934b60088bb21e3a3","tests/decoder_compliance.rs":"a06a10a2b89758ef08dda24c4475d13638b7c31e8872ed6edc6919d5b9910bd4","tests/encoder.rs":"c84dd8e14ade77a4d55f932418567196e188fe65d3957408b9ce07c2c27c4da0","tests/encoder_compliance.rs":"643b529e2f4762b2ce98e041dffa5d4b87fee5942996e093afa5b8494e02a3c0","tests/fixtures/invalid/array/double-comma-1.stderr":"abfcc7bc82100306faf21d3636f0ae684d0fbc5e9ea89032e6cd39ecfcb92c84","tests/fixtures/invalid/array/double-comma-2.stderr":"56bd3cecd5b5ec4204d206f07751c34e1e65bee7aa108ca74ef7a8cb1aaaea43","tests/fixtures/invalid/array/extending-table.stderr":"a6c077cb49c41a9d10aca0bac6c571e570f0a772c6311d6a835f9cc46f4ab7cd","tests/fixtures/invalid/array/missing-separator.stderr":"eb38b2683f119d8b9b8c6b8ffd46da784112565ef1033febbe59469e14baea76","tests/fixtures/invalid/array/no-close-2.stderr":"214a9c5953175709a068433f0a594e0cf2be88d633905dc6e9047894b5249e4e","tests/fixtures/invalid/array/no-close-table-2.stderr":"5a2b4bf9026aa20c749551cd77458c5ffba008b5b235fa05fb7c756917018eb8","tests/fixtures/invalid/array/no-close-table.stderr":"545ad4381d5a007a6cd940a4523ae2f629617d298611c0898283a1c4783604cb","tests/fixtures/invalid/array/no-close.stderr":"85935faa2e3a57c4f0a7d519629630a96826ce4f217650972cd070fb7dca23a2","tests/fixtures/invalid/array/tables-1.stderr":"f105a34c2d87b61160881eeb09b7f54d244ba2a222d32fbfc755091939942247","tests/fixtures/invalid/array/tables-2.stderr":"77010599d1d61a34119a99acea7d84162d217df93bca01aed3ae73f1eb62dafe","tests/fixtures/invalid/array/text-after-array-entries.stderr":"391ee42f4fa3a7ec51ba1b90e69f1d9278c105426fe66ae1f80e65d7fb6ed379","tests/fixtures/invalid/array/text-before-array-separator.stderr":"7292ebcb8c9c8aaa4041279af5414de3e710977cac948988cdc8b0947223b62b","tests/fixtures/invalid/array/text-in-array.stderr":"0486e3ec5d299e39c61380a2ed8826d886edb730f6d9555a765e4314da7f5b68","tests/fixtures/invalid/bool/almost-false-with-extra.stderr":"0a14178172a5e9ed65a7d551870b4df768e7cfb39f7b66a2ac0643e2aa8374af","tests/fixtures/invalid/bool/almost-false.stderr":"ed5307c42046d6adf0bf4c3d1aa1c75faa23a46029d5e229f0c2ab4db068df1c","tests/fixtures/invalid/bool/almost-true-with-extra.stderr":"6e4dc09948a38c284f5bc52e011322a2c0182ee2f35c772d460fa15a76461d2d","tests/fixtures/invalid/bool/almost-true.stderr":"86b33938625e15e30d4166b4e81f89c669e84c5b96c2cf708d84dbf628536e07","tests/fixtures/invalid/bool/just-f.stderr":"657f90406495c748243b526e1e01737c418453a1a5ad12ff0400631e9fdaf859","tests/fixtures/invalid/bool/just-t.stderr":"8a8f5aa45b0d0acd13f121caafa85a52a8d17f1bd81542d21d3a5ff07f460b60","tests/fixtures/invalid/bool/mixed-case.stderr":"2e9a16757a17c7e604e081584e6f015ecffb0fd7b6ed969a1fe2096c09e7155c","tests/fixtures/invalid/bool/starting-same-false.stderr":"87069893e084d03c3ab540e0607498d371563c0341c6f043aff756c8f1b32c64","tests/fixtures/invalid/bool/starting-same-true.stderr":"2a1817a1e3a6558860eec1d802e1be8f2f2b54da9b2d9eaf1cddecd35d71a8d6","tests/fixtures/invalid/bool/wrong-case-false.stderr":"5eb58e82290b767febd475712f7de9ee712f094a30dcb627a757b305ab64d096","tests/fixtures/invalid/bool/wrong-case-true.stderr":"dc8e696e9137f737a232009e7e9f801aa9ebe4320a445259af74d83a6235c7b7","tests/fixtures/invalid/control/bare-cr.stderr":"568eff61d56bb362866973d9a7a488831b8b08d02f4808538a04b22ebe10bf09","tests/fixtures/invalid/control/bare-formfeed.stderr":"4532c2fdc7c4bab8fa6683cc4c46975c1dddf2f531459793dedfaab73e4ae347","tests/fixtures/invalid/control/bare-null.stderr":"fe799f446b55ba89609a52842b4eb63bfa725035c0006107c85c6a8f6e8db688","tests/fixtures/invalid/control/bare-vertical-tab.stderr":"b85c55e64c58b85343482dadcd5d833fa771a79e1d0f13a24f4185a4d0d826d5","tests/fixtures/invalid/control/comment-cr.stderr":"656e1b16fbc152545a9726a290a8ce84463a73d780ad13a32b65291f56cb7dc6","tests/fixtures/invalid/control/comment-del.stderr":"08f586fc1f6ea69e3718ab43fded3da139d5ae296cfe70bc27a7ffb4b2f106d5","tests/fixtures/invalid/control/comment-lf.stderr":"71725b218014e5ae260d5075f6bb90477e97c946e27a40c797710a190d586a58","tests/fixtures/invalid/control/comment-null.stderr":"39ca1697c9e13969314368c85401dbb141ee80f514ab4a359ea8e74880e33d28","tests/fixtures/invalid/control/comment-us.stderr":"1d8c3a908fb274503d357bdc428b82c97fd9f9b37681be09129a46454f31e0cd","tests/fixtures/invalid/control/control.stderr":"aa1ae71dbb29473161d8f82a163e6862f78c7c55d4831574e6994651fdccdb19","tests/fixtures/invalid/control/multi-del.stderr":"812c0742dab1b933689c925dd1cca16ed185d091acc51026e8fc6585c0401c00","tests/fixtures/invalid/control/multi-lf.stderr":"3d2ac666d19fc3d0fe676b4897557fe3735c43da64b4a71577c04445a1341a06","tests/fixtures/invalid/control/multi-null.stderr":"9fec8ad3ba45ddb96ad3b6a118b4fa648056e26a9128528b2c0a8fa3b01e741c","tests/fixtures/invalid/control/multi-us.stderr":"a4769a44b32457fbc791b15b442293f37c936d2394ca9aa87ad5c964dc7cbb35","tests/fixtures/invalid/control/rawmulti-del.stderr":"b2dd93070d5bb09e19ea6ca015cfa1ef279ac2cf5e7fb242d8b74318f5d8418c","tests/fixtures/invalid/control/rawmulti-lf.stderr":"7e1d64429ed08f831783bace226535852bcebb48aae05541590fb242491cd7e9","tests/fixtures/invalid/control/rawmulti-null.stderr":"84c04cc89a6bc716b6f7811142899014abdb0b49c4ea56bc163c19220b14c323","tests/fixtures/invalid/control/rawmulti-us.stderr":"4e4566a74bde0a055d2e5a0dde72d41208c2ed188175b11c9e46167dff231d3c","tests/fixtures/invalid/control/rawstring-del.stderr":"c49c702bda4ed350dec4fc43edecb16202f8e5f1f4b02b06b42b2109d775a9b5","tests/fixtures/invalid/control/rawstring-lf.stderr":"5b11decc012a95bde096088a285eaaad4b8984f6d683bd633640141b19135530","tests/fixtures/invalid/control/rawstring-null.stderr":"eafa2a63e9d12293b290405049457860a8fef70de56c4ba2f203e5f2c79a8634","tests/fixtures/invalid/control/rawstring-us.stderr":"b3d8e5dcb1c66b93f2543ea325a50decb62178a5f0bea59fe64b04d89472b25e","tests/fixtures/invalid/control/string-bs.stderr":"1b35fdd656fb29e3011e5f4302fd37d0354922a21e740eb947dac766cebf3200","tests/fixtures/invalid/control/string-del.stderr":"ec80f70e9aea38e11191e50e9dfd80415de5b0406608c935aae8b8dbed9a8a7f","tests/fixtures/invalid/control/string-lf.stderr":"f91e1e0035af8ff259ff98c79097f845d8be8886629a93da962daba1079cb382","tests/fixtures/invalid/control/string-null.stderr":"fe34d284c478853bad94235aac1f37ac3c591f97e12990847b5da0b6c99bd47d","tests/fixtures/invalid/control/string-us.stderr":"dce016319c9fa0981f03cfd8b2b1d52d2d847697ea88e037f5a0e28bb53d8830","tests/fixtures/invalid/datetime/hour-over.stderr":"bd2220bdbaa96caf3d2aaff640620e4856bffb722a0e5be61dcb5283ffd08056","tests/fixtures/invalid/datetime/mday-over.stderr":"de9d27d65c68dd09da10c229167ce881dfe0ebda457badfe24b7598ae80c47a6","tests/fixtures/invalid/datetime/mday-under.stderr":"18daf3ce2a6a972476ccabcf92690a488e4f3be804dab8458da2aebad22a2c8c","tests/fixtures/invalid/datetime/minute-over.stderr":"a29009d3f7a6b1d9afad2420f223d6a6e02df8149577547837f5eeec4075bb9a","tests/fixtures/invalid/datetime/month-over.stderr":"37a203b22c3b2510541e413ff347447f9f3319a896ee005b96f65bc0d68150f4","tests/fixtures/invalid/datetime/month-under.stderr":"24c554595ca9a999a1d8e1ef7dc28b443f2f0ad6e17337ee157fb18bdcf678c1","tests/fixtures/invalid/datetime/no-leads-with-milli.stderr":"a35c496884e921aa086c1404bc812ff74f2bfd347a3ecd96640942be5555afbb","tests/fixtures/invalid/datetime/no-leads.stderr":"2e20cb60a1ecee85b172d1402e4d8c425362e4db607706bd39494385dc6dc98e","tests/fixtures/invalid/datetime/no-secs.stderr":"65871ee020e645e737c363b22cf43c160b295871cd4ac97a37d3ea46f60e3250","tests/fixtures/invalid/datetime/no-t.stderr":"ff50b85f6bc0d49000ec6f1303fda9b44bf934c2ede61743363411bbf6ebecbb","tests/fixtures/invalid/datetime/second-over.stderr":"0ed555a874efa08b711b5227501208758d87a01ad8360cf76c3dc8761807fac4","tests/fixtures/invalid/datetime/time-no-leads-2.stderr":"f725d49ddb5af69b7285f071d68e3d8441d5e331adcfd8c025c1f3cbb68028a5","tests/fixtures/invalid/datetime/time-no-leads.stderr":"cf06f3847f3d14655a94d8cfd5a6984dc74115b1d3cdbee0662ef215738bbf65","tests/fixtures/invalid/datetime/trailing-t.stderr":"87a15cd62bbe7cba2b942fe424c045ce30a12fe439a1b49587a5cc037ffa6b09","tests/fixtures/invalid/encoding/bad-utf8-at-end.stderr":"518dc443f0404d486b40bbbd152870276016795b05f3cc8a1de64a0e08fcdda2","tests/fixtures/invalid/encoding/bad-utf8-in-comment.stderr":"e0f252d14c18ea072c098834997db8e5f68b807bb0fa6d3d34e4042a5ea6fbb7","tests/fixtures/invalid/encoding/bad-utf8-in-multiline-literal.stderr":"2328a89cd9043de10ee656f4ea0dd5e6491fd8c0484ac36099c23161dd7a2625","tests/fixtures/invalid/encoding/bad-utf8-in-multiline.stderr":"2328a89cd9043de10ee656f4ea0dd5e6491fd8c0484ac36099c23161dd7a2625","tests/fixtures/invalid/encoding/bad-utf8-in-string-literal.stderr":"eefb00fee073933fbdb95d24a9e7050c281d4719d0cb970c2c06a71a86f108b3","tests/fixtures/invalid/encoding/bad-utf8-in-string.stderr":"eefb00fee073933fbdb95d24a9e7050c281d4719d0cb970c2c06a71a86f108b3","tests/fixtures/invalid/encoding/bom-not-at-start-1.stderr":"bd4e557b8b4586cdb39a8fde46f0bb214954f9f8ef37be46e2cc19823f6d6919","tests/fixtures/invalid/encoding/bom-not-at-start-2.stderr":"27003a498cb355011782dc21f01e15457490b78c472bb9ddb54147413c8f597e","tests/fixtures/invalid/encoding/utf16-bom.stderr":"a8800edcb8f6184b712da53e74bb787c39eb891073575acbae1ad575f15043cc","tests/fixtures/invalid/encoding/utf16.stderr":"edb66c01034865f484ccf7921bfcec1efaa8599762cb9cd30c9c8103275bc4e6","tests/fixtures/invalid/float/double-point-1.stderr":"2917901dd186adc39cb5965faf388fa2babe577ef3bfcadd4919232868a727cf","tests/fixtures/invalid/float/double-point-2.stderr":"7eda489da0436d6f0f2268aa4005b422d215b4785af0c1696c8731908a563f17","tests/fixtures/invalid/float/exp-double-e-1.stderr":"e64082e328fcfbeff57e6801448c769b12bc8e879b77421b688b2e147e386713","tests/fixtures/invalid/float/exp-double-e-2.stderr":"5c45326ef7287ea16a9e08275222e281b5d61c9322f8764f6533707f9772e255","tests/fixtures/invalid/float/exp-double-us.stderr":"ebd30aa3f7cd3a0a5e79bbbde1beff209d24f4ab58eb5552c1baf0eb2194e97b","tests/fixtures/invalid/float/exp-leading-us.stderr":"19c8f676dd45a5db09bd5baba5c3e7b661e83099a340331ee6bb10defe679569","tests/fixtures/invalid/float/exp-point-1.stderr":"23e73e4e63db888546866967a1c0319a1db269f23ee9c277b298e9f2db88800e","tests/fixtures/invalid/float/exp-point-2.stderr":"633328e085fb04d6a79cdfb696f45a1836c3a8b6afafc4cd5e16d48465aa4613","tests/fixtures/invalid/float/exp-trailing-us.stderr":"d633c5a44a55dc2b6cac18f739cecb33526f31d85f72cada0ebf70c4cca56dcd","tests/fixtures/invalid/float/float.stderr":"cc664d16849deec2ae7ebee6a3f46923bd5959075e282315c4f60461cdb13a0f","tests/fixtures/invalid/float/inf-incomplete-1.stderr":"38cd906dfee7f13b8cbdb27f3406ab0499fae3ae16f3c77bc7fc48d009595d93","tests/fixtures/invalid/float/inf-incomplete-2.stderr":"97a9ae1ff194a95b5be2abaf2cd8179ada832cdd9fad349efa9951e7ab92e435","tests/fixtures/invalid/float/inf-incomplete-3.stderr":"034bc609343ecf1e659d6250f719e5f93512e8140228e44e57b538765e58a1f7","tests/fixtures/invalid/float/inf_underscore.stderr":"621326dde26e5364c7af1b562fb651f4184d9b5fc9bc45edc12f52b588d506bc","tests/fixtures/invalid/float/leading-point-neg.stderr":"d19e28ba2f11069800df4dd1951025aa7f75425f7258e8caf4bbf6abe0e84bc9","tests/fixtures/invalid/float/leading-point-plus.stderr":"10750e9acccb17f0682db30fb175d083d06c822a4863d3d6b8ddb6c75b7b22ec","tests/fixtures/invalid/float/leading-point.stderr":"2545b7a615528595f5d53a7338403c83a8587e70600b1501225446e5f456c805","tests/fixtures/invalid/float/leading-us.stderr":"dc958138922097b2e1e3865c7818604b2249268af4acbe5cafe0ce8c68a90a86","tests/fixtures/invalid/float/leading-zero-neg.stderr":"d1fad35fa8d18f93ebfdf681d3476f02600e5c39cc942ca9bc36181476cbbe53","tests/fixtures/invalid/float/leading-zero-plus.stderr":"ad8ba7a7c12cb4b296cc0d43915106732e6a6a713aea67034587d1fc0c8093df","tests/fixtures/invalid/float/leading-zero.stderr":"cc664d16849deec2ae7ebee6a3f46923bd5959075e282315c4f60461cdb13a0f","tests/fixtures/invalid/float/nan-incomplete-1.stderr":"f4bee0b1c639bf800fc4dda38276142e715cd85ab6cc5e93ae2112ea63d7de89","tests/fixtures/invalid/float/nan-incomplete-2.stderr":"dc908ec577d29083bfd709fc4bdc2fa641d7fb2ba77a5d7441215680a8839d69","tests/fixtures/invalid/float/nan-incomplete-3.stderr":"abab5a41e0f2f1bad2d2050d0c913dfd8c15e50530d53ef8de327f106f564e02","tests/fixtures/invalid/float/nan_underscore.stderr":"25b67a7d6c743f673be7b409c9990de5de8b52a1d97c32e6f4e62f33147f1872","tests/fixtures/invalid/float/trailing-point-min.stderr":"69ad03ae81990d580a6d63bdd5ab594de00c0a16694c8671704c6243b4578b38","tests/fixtures/invalid/float/trailing-point-plus.stderr":"fba0bbad890020fe943e9f23644e81bf0bb7d114230fe16182e866fddcfc108b","tests/fixtures/invalid/float/trailing-point.stderr":"2f12b368fd94304ab0126ebb5888c519475f9ca28e9ca702c477cf0085ba9216","tests/fixtures/invalid/float/trailing-us-exp.stderr":"2ad53ae4736ce5134921acf0c16bc5031627c0da3119edcdc4bd7eb300d40337","tests/fixtures/invalid/float/trailing-us.stderr":"506cb8051f1045ea1dc7f11865d58cbca0216502d273e1c10366c8be7cc9ab43","tests/fixtures/invalid/float/us-after-point.stderr":"fa9fb59f703b6770be3dc094c04eb2c4add8a7a7ab79d9fe508cfeee785404f1","tests/fixtures/invalid/float/us-before-point.stderr":"14e09a7a382e249e5143d1c81d6e4623408eb2d505e1e3f86c370a3a3bf6cd9e","tests/fixtures/invalid/inline-table/add.stderr":"bf95d34749254300f4179ed1314cc9cabd7c7b63fc2453fc7adbc7869b63be4a","tests/fixtures/invalid/inline-table/double-comma.stderr":"2132a1c4d97fab140089818f990284333e22ef91d20a9f65e11d4dd15b1a701a","tests/fixtures/invalid/inline-table/duplicate-key.stderr":"72bea73b20005f15ced977aae70a1b0f3bbe3e35598231aca9a2303d770efdc3","tests/fixtures/invalid/inline-table/empty.stderr":"604fef40337f04e5f37a52239d6509850aba95677a7a94ca8476a6c21b648a43","tests/fixtures/invalid/inline-table/linebreak-1.stderr":"45b0611d37c1ece88bf6c88b3528adc3d73e0cd3e3b24dcf07ab151023a6f488","tests/fixtures/invalid/inline-table/linebreak-2.stderr":"f7672965326b44adaf0cb4796a087fbe779a8b17fbb458090a33375d0c54e5b4","tests/fixtures/invalid/inline-table/linebreak-3.stderr":"e8c70f0c91b15e701567e93d8df1cd3bec593696af05ec1d95e8f9e00ab20fa6","tests/fixtures/invalid/inline-table/linebreak-4.stderr":"3d31147f9e1ff5f94384e4df1675dfff2da6f076cb0a729771615f05b990be91","tests/fixtures/invalid/inline-table/no-comma.stderr":"9f1c85e0df72c7e7e011c26a0d5dd9dea8b7a5e18c3ba9a53ff4a20a9429dce9","tests/fixtures/invalid/inline-table/overwrite.stderr":"812d1bc74d07750048a521e513a565676e606d4fa1a32d2ebda7af8fa064d3ab","tests/fixtures/invalid/inline-table/trailing-comma.stderr":"4791911dafd6602e2891d6ffc4d32ef8e9d0c1f8f6d37e84d440feb896d9cb88","tests/fixtures/invalid/integer/capital-bin.stderr":"fcfc8b0bddd36a641d3f5cc2ceee88554619fabf6874e11cdfdd147be8781881","tests/fixtures/invalid/integer/capital-hex.stderr":"c8e2d64f9659435a0387bb7e6447896eda253fef77e0214a4073fcffbac693a7","tests/fixtures/invalid/integer/capital-oct.stderr":"ec465fa25da212b0c9b6265ac8e9cd05c1fa07d614dafb3bc9b2ca74d6c2a7a7","tests/fixtures/invalid/integer/double-sign-nex.stderr":"8d57da526240c1cf73423b688442922ae291ff26e3c09f9c3b5b150e62e5cbaa","tests/fixtures/invalid/integer/double-sign-plus.stderr":"55896d9bd19637e124482966a12109a1a8351620ddc6f8d28553d70359f523f1","tests/fixtures/invalid/integer/double-us.stderr":"f14ed7bd3ad26b2203763fa953dd6e99212e50fb8e43a4eaeb115c1a7df4fc25","tests/fixtures/invalid/integer/incomplete-bin.stderr":"64168fc7ede87a10c12f82325fce644a7d9b9c3af55a313184175df7926845e3","tests/fixtures/invalid/integer/incomplete-hex.stderr":"ed2423540e288f4673bc68822a799bea04f571db5de56154e10360b03ab79553","tests/fixtures/invalid/integer/incomplete-oct.stderr":"9ed35e3078703a38996f20dc3e86477149564c8abd237c644bdf3a5ef26e3417","tests/fixtures/invalid/integer/integer.stderr":"ed5ef991b733b3d51700364da18bf58f1b7eb68053467afcbff22775b3b82788","tests/fixtures/invalid/integer/invalid-bin.stderr":"7248d47f2c7db309254a3a41af28bc1a6e96bfa95e0c8c94d607f65a1a30cee6","tests/fixtures/invalid/integer/invalid-hex.stderr":"3976255c6fe35a1e29f0fed7324eee8420ababd0f6f1f7702908c3df47c88846","tests/fixtures/invalid/integer/invalid-oct.stderr":"9f6776e33887cb446a5590d8fe4e51c36747c634cd5e4efaa84f807d3ce244e0","tests/fixtures/invalid/integer/leading-us-bin.stderr":"28edc918ac016cc9cb7b0b20fe2a5e1dc0175de0aa8105d7a6ca263815c6e4e7","tests/fixtures/invalid/integer/leading-us-hex.stderr":"2a1a5943399c8ba5849ba569411bfefc8323659c852bd714ca917231f6212ef0","tests/fixtures/invalid/integer/leading-us-oct.stderr":"aad69bdd80f94e907bda03558a1302e54d58d8911fe2b564e93cb0ec48403b09","tests/fixtures/invalid/integer/leading-us.stderr":"3a265cc11f1b0d43d4b532a47776486ec7c7ea7afe70813ab00c5a37cf87a9df","tests/fixtures/invalid/integer/leading-zero-1.stderr":"ed5ef991b733b3d51700364da18bf58f1b7eb68053467afcbff22775b3b82788","tests/fixtures/invalid/integer/leading-zero-2.stderr":"5c70e7874256512c0ef6bb364497d4e10154e994056f2feb7c5c729016522091","tests/fixtures/invalid/integer/leading-zero-3.stderr":"fb2730feda6f669a3b8c4332f01369e52ce1b942807f1bf3d9762b1fea04aeac","tests/fixtures/invalid/integer/leading-zero-sign-1.stderr":"c9d2d992eea36c4fe228eb74741bd8d0ede1e354cad132b79462e7b502b37f95","tests/fixtures/invalid/integer/leading-zero-sign-2.stderr":"4248329b339020cc2ea586f2775a0b4f4cbe2ae3f0f75b935263363b8be5eaf5","tests/fixtures/invalid/integer/leading-zero-sign-3.stderr":"3b414808727d3a446efdfca0033525e17536f9b54104d8a9cb9278b054d213df","tests/fixtures/invalid/integer/negative-bin.stderr":"74aae673b861bd46544e4835fe7075e20158dd69e27f75c790d48a6006476c73","tests/fixtures/invalid/integer/negative-hex.stderr":"799bd8120f4cf2c36e7f65a5f9aa43a3ec87dd95dd3bf68501059da9f21f8c9e","tests/fixtures/invalid/integer/negative-oct.stderr":"fb082674d0f5a8a231c91c2d34cf47fdeece4c8c5c8c7b23fb09fce95ed59a9f","tests/fixtures/invalid/integer/positive-bin.stderr":"54d8a33743737f374480cd1235bf3f7e0847d252ef7e2bb1d447529cbc0f6692","tests/fixtures/invalid/integer/positive-hex.stderr":"3b21b23cc3dd6b213a19256f4ffb4bb36172de2f739f90bbea78636f7a50524b","tests/fixtures/invalid/integer/positive-oct.stderr":"cc493d14bcb092f49b517fa5143e29c45020d491d94ac662f85b2af34805cf11","tests/fixtures/invalid/integer/text-after-integer.stderr":"07a13ad4841a452eff00947234a4ebac4d209ea0294162888db35668648bb55d","tests/fixtures/invalid/integer/trailing-us-bin.stderr":"62da06cf06527b9e9cbeba6c5299ce6001d40592e9d007c8350090977f4d1b58","tests/fixtures/invalid/integer/trailing-us-hex.stderr":"1b290eada58a7202b1a9251afd8e0e72a4caa8ad5c85036d1050e7de8141e94d","tests/fixtures/invalid/integer/trailing-us-oct.stderr":"34e6f86ffb0099e6e1ba67deb51e36af62dfce4e7299b94503a219339bf16447","tests/fixtures/invalid/integer/trailing-us.stderr":"3ab49ee921eb772f5aa4eaf0fb3619b1dcd9a9db3f4ebbd9bc505581a985e753","tests/fixtures/invalid/integer/us-after-bin.stderr":"a94a87ebab3536899ce7c0c785f020b3a236c60d24c0bd7494628ca310c40768","tests/fixtures/invalid/integer/us-after-hex.stderr":"9009b187f615f06e3392eabd8ffa58311ed1c2b1cd76f8c5bd99671242f2e026","tests/fixtures/invalid/integer/us-after-oct.stderr":"05af70a21980416fbd602337f9af22a1c600a294635d10ef1ca1b2138338e712","tests/fixtures/invalid/key/after-array.stderr":"487d957b20226ac36e27d6efb1e3d24147284c9a5e10a0188427a1c940d31ef0","tests/fixtures/invalid/key/after-table.stderr":"f70e84770817f096fcc1b6195c6b0a79d25210c6930ce412a89646040ee3d713","tests/fixtures/invalid/key/after-value.stderr":"00d4d2d3ccd61f64a92df0ca575aeafcd96e91d053d835ca855973339ba458cf","tests/fixtures/invalid/key/bare-invalid-character.stderr":"b1f64d54a43017e6cc09755fa7ba477901721d23f9271ec658fc9362f46631b3","tests/fixtures/invalid/key/dotted-redefine-table.stderr":"564febb355d1556df42f428a046ac6fdc5dad49b2b736be5824b0c13fcd1fae9","tests/fixtures/invalid/key/duplicate-keys.stderr":"7c9dfef2ef19b1487b7592a267ab5ba21c8b833dfa9ec1c3151e369c2fdba26e","tests/fixtures/invalid/key/duplicate.stderr":"764ef48bb06c9096c853b1156c8d29ba0065616939a5335146f5af88a424cea3","tests/fixtures/invalid/key/empty.stderr":"af6d3636ca73e5496c40d9c918c59b61fd86812db262649e5268094193873130","tests/fixtures/invalid/key/escape.stderr":"155aa9389f0eb28cac3b42974af7ea9e2eef8d96f084f08f9f75e960fc8ce8c7","tests/fixtures/invalid/key/hash.stderr":"85dd91b96aa4f81cc7922b02b411f25d9053bddd1e5b893c2a2ee9d0115a7cac","tests/fixtures/invalid/key/multiline.stderr":"d625f2caaf01d53d72d6f1c3df0952fe3ca8c5f3b081503cb02b9994c088b733","tests/fixtures/invalid/key/newline.stderr":"714aed0a140062f977ec85b9afa50f68448c67e806168e60b4f4554ab270b2b9","tests/fixtures/invalid/key/no-eol.stderr":"440ec927e94f0e520a0f256c865041f0478e1c82f3bb79323b7ddc36fc942edf","tests/fixtures/invalid/key/open-bracket.stderr":"3b36814373f51a8ea00a448d65bc514e8d99f5163b7dd8101df62bcd0a06e801","tests/fixtures/invalid/key/partial-quoted.stderr":"dc9059a014ed53071ed170b1e280923556dc09e0be2ae96cc8474e9da59fa378","tests/fixtures/invalid/key/quoted-unclosed-1.stderr":"6cdec8a7c5352a2f246273afaa923dfa81d4d2e68cca5b4f9a19193559b164c2","tests/fixtures/invalid/key/quoted-unclosed-2.stderr":"b4817e6f85a90fbb6adf049ba57c268f9888f1b42b3d62200c359606176170b1","tests/fixtures/invalid/key/single-open-bracket.stderr":"917c0203d1e45309fcff82ce33fdd2d989f630fb99290a40cb9e08a6f7ca0ef8","tests/fixtures/invalid/key/space.stderr":"3a5fa712d667890678873e3d4e4cabb084c67091c5ec6155355d5bd4229585dc","tests/fixtures/invalid/key/special-character.stderr":"a84c2f293c1e421a1c87050cb0211de80dbfe7a79939db0338fa35bf0c181ef2","tests/fixtures/invalid/key/start-bracket.stderr":"223d8a22bf34459cd9bcb993ae2a51ab3cc436674e3367e92f7d74e9f8710a45","tests/fixtures/invalid/key/start-dot.stderr":"f9366a1492ae24fd0721724b4039d2675e91219de564aff2826adefd83fac571","tests/fixtures/invalid/key/two-equals.stderr":"a0aae899cfa75df41104a4d3090a309fc7ebcd95bb5a944cf742f3d3fc9d4782","tests/fixtures/invalid/key/two-equals2.stderr":"861826b9456ab3a74f63f5c555e13d959a3991dfa6ce126ae5ed14d43f7dcee1","tests/fixtures/invalid/key/two-equals3.stderr":"71614864344e321ac5de238b7ef9d097c6d7f3ac3eee4118d96827b4b8bd6658","tests/fixtures/invalid/key/without-value-1.stderr":"16c2823a39a82c3c27e0959a691b7a95e3392d62195884697893d373b967b9c0","tests/fixtures/invalid/key/without-value-2.stderr":"d340f94f5d96f5730ab269db7ef27aca171d64e35af1181c474d75a7d11d6590","tests/fixtures/invalid/key/without-value-3.stderr":"3cf3072fe9206bfe6c682103d0414627a5a63db4c4a319cf37efeb5fe6b92007","tests/fixtures/invalid/key/without-value-4.stderr":"07132bec96e9a9a672bafdc3c448b7c596257245f8c3e2cae04641f9798644ec","tests/fixtures/invalid/spec/inline-table-2-0.stderr":"5ad1a938b1d1f0f3fdbd1871efdebfd30e136407ecdd9e2eff22150d00624b3f","tests/fixtures/invalid/spec/inline-table-3-0.stderr":"fcbc05e911b7db81bd918768fe98a51a7026fd476d616718cc417d2f08bcc1a1","tests/fixtures/invalid/spec/key-value-pair-1.stderr":"d5391142dfd56040840cf91b1e28e3c048229e3d9998534d41001cd6657f9bd6","tests/fixtures/invalid/spec/keys-2.stderr":"3c4ee6066fc75d2c1f1b325f618a01113694c318e330ff4f237e89127f332c87","tests/fixtures/invalid/spec/string-4-0.stderr":"910ee4b240159b828a7509c8dfb46507071a8d8636f3935a3914d6d91f315295","tests/fixtures/invalid/spec/string-7-0.stderr":"5128f0a930b3034e494a6bee4f384a587e9fd858b25f8cc529a488c94ee9670d","tests/fixtures/invalid/spec/table-9-0.stderr":"49dac70d337266f5c6b333fee468f279fed1bff62bfb4ec7436c8b6683ce0dd2","tests/fixtures/invalid/spec/table-9-1.stderr":"d9e071c70356c01b6537f876989ad2067e7773dd5eb24a298439d192dbad12d0","tests/fixtures/invalid/string/bad-byte-escape.stderr":"14f6ae446b3b8cb434267eba11c6ec5a1badef4f867169b173698cf9f1a29d95","tests/fixtures/invalid/string/bad-codepoint.stderr":"e5a9704b87fe85e447e817197ad4e59e27b33bd93e7c5ad3987561d119ce6ee4","tests/fixtures/invalid/string/bad-concat.stderr":"499219633467b9174471db40543ca188e2b906c470e511d2f701f5f5475d96be","tests/fixtures/invalid/string/bad-escape-1.stderr":"34a15ce7012217c62d31d5392038517c216f0cbfd5d75fb5f3c2bb07afd3f25c","tests/fixtures/invalid/string/bad-escape-2.stderr":"955aab40b16043c847d85d04e6adcd093c930dd8416d29c2ab5953c077eac6f4","tests/fixtures/invalid/string/bad-hex-esc-1.stderr":"aea935cf1e17743356e6fb1059afed2d0ee5262906594782e5537a025398038e","tests/fixtures/invalid/string/bad-hex-esc-2.stderr":"deac5217cf80acc759e1b40c43f5f56431b276dc2c896aae5490d57583105e06","tests/fixtures/invalid/string/bad-hex-esc-3.stderr":"94ecf886427e8fe5daf1d8f932bf1887f2533b10bc1f57cb6de03ea28fef466f","tests/fixtures/invalid/string/bad-hex-esc-4.stderr":"382b011dd4070554ee875fde06703d8332ef6ad36f3619f3536b0a4997ee2745","tests/fixtures/invalid/string/bad-hex-esc-5.stderr":"a8a039fae822eda68591da28ff2a117b5d85e99d066e9126ebbb6426a1cad52d","tests/fixtures/invalid/string/bad-hex-esc.stderr":"aea935cf1e17743356e6fb1059afed2d0ee5262906594782e5537a025398038e","tests/fixtures/invalid/string/bad-multiline.stderr":"141e5770190dd184bb1f64f6bb14fc017210bbd918ab5c8b7a3d80b86b21772b","tests/fixtures/invalid/string/bad-slash-escape.stderr":"d62f894ee166bddf84432507fb4ba56473c0a230fd88a3ccc2b199a72a34e613","tests/fixtures/invalid/string/bad-uni-esc-1.stderr":"d1d6e0c78b64f776a428aa7cb332b0ccd659d24950dd3e8f1d2a1450f61b37e5","tests/fixtures/invalid/string/bad-uni-esc-2.stderr":"d8ed938bafdeda05c083d79ed73f5043dabe0f5f1515c6857ae7a61db9026ebc","tests/fixtures/invalid/string/bad-uni-esc-3.stderr":"de1c29897549ae37988a38e1c370f9974fcbf7d4c4b3fd457d731999cfc05929","tests/fixtures/invalid/string/bad-uni-esc-4.stderr":"4e5a715e8dc212d073d399bb0ae9b49413396744282a195c34cb03e6f4fbd9eb","tests/fixtures/invalid/string/bad-uni-esc-5.stderr":"2419cd927d8e31ebf5025558e70bb1295d98bdb36c17f0e00620b9c4a7aadbf6","tests/fixtures/invalid/string/basic-byte-escapes.stderr":"b42fd0273c7438bf13ddea9552204bb9209cdcc8e4151311d2446185d2cd546a","tests/fixtures/invalid/string/basic-multiline-out-of-range-unicode-escape-1.stderr":"725cd4955987c3d6e736832281316d6c1a2446303e9a1dc78900cef4bb84ee64","tests/fixtures/invalid/string/basic-multiline-out-of-range-unicode-escape-2.stderr":"c6698fbdb95188d53bfdaa4a4f590d86a73aafcc321a5d9511ab43ce51be1c78","tests/fixtures/invalid/string/basic-multiline-quotes.stderr":"28177a49532f22aaffc9dc204592a2c5eca2fc20f8e208b7c7f589201e8b7de5","tests/fixtures/invalid/string/basic-multiline-unknown-escape.stderr":"a83406b30eb3ab2cebb0230d8d65d0b7583885138f2c070976ae61de2c8b17f3","tests/fixtures/invalid/string/basic-out-of-range-unicode-escape-1.stderr":"19af67599c6c2eef340c9fdb0ab2cc788928def50280af939247a1274447781f","tests/fixtures/invalid/string/basic-out-of-range-unicode-escape-2.stderr":"0e2e1a69358502ec17a07e4fc151b70e8a3b5123798cb38f98fe2d146515a84e","tests/fixtures/invalid/string/basic-unknown-escape.stderr":"1de467948fb18f61336350063701d9c5a6615054fe740a9be650f71f5ca4236b","tests/fixtures/invalid/string/literal-multiline-quotes-1.stderr":"249123229606aa8eedff1b5bdead5022daf470e47dbca639e32019d1d61dbcf9","tests/fixtures/invalid/string/literal-multiline-quotes-2.stderr":"d9784af1ff056a90bf531307749d53a5d24ffffbc0f4aada7fcee417a50d1615","tests/fixtures/invalid/string/missing-quotes.stderr":"462f24701d2c51d36b18d06b69be2f6eb36449b5f3ffbaa737fcbd2b2151ae4a","tests/fixtures/invalid/string/multiline-bad-escape-1.stderr":"18469c4d37d011b3f30ae17e3111b5e8a9526d593475e5d8d7a9b19461a40e8d","tests/fixtures/invalid/string/multiline-bad-escape-2.stderr":"d43896d3005c8470dc8149e2b74eb8825c6d9fedfe9f48125ad88a95c1dc3035","tests/fixtures/invalid/string/multiline-bad-escape-3.stderr":"92f732c6bcb922e25d2a001a389f93b596dd0e91109cbdcb651efa146309dc2a","tests/fixtures/invalid/string/multiline-escape-space.stderr":"94b451b6c03055186777a248cb216f95a1b2e29df25549f345d96bd0a4e63f1e","tests/fixtures/invalid/string/multiline-no-close-2.stderr":"e500e99a44305b1e148b211e963478cf1554f8c9536d3108390cf41d5b2ce069","tests/fixtures/invalid/string/multiline-no-close.stderr":"d5b9602d23b0cb023fbe3ae80d862fd60332475ba8863a1e977f17cb326a4548","tests/fixtures/invalid/string/multiline-quotes-1.stderr":"046956658c0a73e665e7a6a2044ff83c8efb8cdd8c2ab153c163eb1e61068c56","tests/fixtures/invalid/string/no-close.stderr":"3ad8aff0932d98592b808fc6f44fa68a854097f8025e92c11af1acb6de3d3cc7","tests/fixtures/invalid/string/text-after-string.stderr":"1c1e4677be8d3dba0e7933b3ed1cbb6e0bcf6f600cf9a989a7b09c9424a4d0a7","tests/fixtures/invalid/string/wrong-close.stderr":"441f4f1b73c11c8dbf2f73cf9a7766f17a9517b3b9142e86736ed43eaec07f18","tests/fixtures/invalid/table/append-with-dotted-keys-1.stderr":"a67f1f152005295e0a1bb3dcaaa755edd05f19ac5316b8ad2eb4d45797e0f770","tests/fixtures/invalid/table/append-with-dotted-keys-2.stderr":"72d9ea8a90b4d9e5319c2bf951bdde6a87a205612e82ed5a09cea2b706bfde7f","tests/fixtures/invalid/table/array-empty.stderr":"e8a41c60adf7756361920816b6c4f44125a813c869b71fae2c98473e4da1b231","tests/fixtures/invalid/table/array-implicit.stderr":"7797ce41aab0567fc9d40e277cc32c12e1f16ffc0e73857fdb3bbf754246305f","tests/fixtures/invalid/table/array-missing-bracket.stderr":"5f1e8703d59398f6595d21ed0abcc7dc3ce77943ad0f71eede9ad63ea2bcc7c1","tests/fixtures/invalid/table/duplicate-key-dotted-table.stderr":"ca58908463cbe2ec6b3de314237c178fee64245cc738c72a7b9e08bb3d02b2b0","tests/fixtures/invalid/table/duplicate-key-dotted-table2.stderr":"cb59f2ed324642de947f3cd9373ca111ec35104a5f33578f64c48084ce1a84f5","tests/fixtures/invalid/table/duplicate-key-table.stderr":"f4816522738b3e2ace87d1100a3d73e6a122d8dc67d05e0b35a1438e16a8952c","tests/fixtures/invalid/table/duplicate-table-array.stderr":"11d293e4b4f205fc98cd892f25a25f533cb922c963ecf095a932d2e9d550be4f","tests/fixtures/invalid/table/duplicate-table-array2.stderr":"fa9cd3b1212eed14ec56b66a16471ac2f7c0398d743982abb7c5cb4b5c7a5fe4","tests/fixtures/invalid/table/duplicate.stderr":"3e6d1b1a2f44d449e8cb0098e7c40ad1e755363b446f3821c399abfb26eb9939","tests/fixtures/invalid/table/empty-implicit-table.stderr":"cd3606ce97c5537d18146cd978403636a65fa703c83616da75b8cafa86e8fa24","tests/fixtures/invalid/table/empty.stderr":"4399e419abbcfbec93f5915e7fbdd11b6e462a4c066a29eacda159abfc588734","tests/fixtures/invalid/table/equals-sign.stderr":"472de6b908a03c99637b635a3a898ed956684ae422e1b4b135ec94986ea45f2d","tests/fixtures/invalid/table/llbrace.stderr":"db6bbee7ed15994398901c46ed4b40904897e71f5d972deb7904ccac49cd834e","tests/fixtures/invalid/table/nested-brackets-close.stderr":"e1dff60ea8f77dd1b8fae7d1d63c788c838c80560172d92377cc168f5cb5923a","tests/fixtures/invalid/table/nested-brackets-open.stderr":"bd58eb0630dc0c51ebc288258d360d707c8f43a5877ddc21e9420f8eb76a2f4c","tests/fixtures/invalid/table/quoted-no-close.stderr":"6bf7e2d30c735a55f595140af7c7f6be89b6faf868f4473ea39570fdb87d5823","tests/fixtures/invalid/table/redefine.stderr":"3e794bce5bb6ae9f603f50e3dc62d136701ec478078e8a8e99c94229778e24ca","tests/fixtures/invalid/table/rrbrace.stderr":"342a5ff362c8b4c1e85a6442029291bd33165a3b36552794fcd5269249bf36a1","tests/fixtures/invalid/table/text-after-table.stderr":"6dfaf1fc3199f0602fea52f7b1c65869eb2f8643b9e90dc1e718a183fb972485","tests/fixtures/invalid/table/whitespace.stderr":"fa48d4dc83f92e729dc25c6fc6a0c336014391b4bdb3392998f18141d2deb350","tests/fixtures/invalid/table/with-pound.stderr":"97dbd1ceb7f357bd98cc1caa9a602c638aaa5831237b7d63b18153acc64d3af4","tests/invalid.rs":"daa9034453fb7f10718020e36a07a19664eb852071995f17480c595cb44e2cdf","tests/testsuite/convert.rs":"9140d681dbb9370b975d5bc1cd4e9e640ac4023c6789edcae544e66657ad5fe9","tests/testsuite/datetime.rs":"105d95570d05e9ecbc30bfe7d081f9d63e2f36634e9124da012f467c6134549e","tests/testsuite/edit.rs":"7ff72670fe971ce9cd3e94a9254d1f54ebc792d8881b688d397cd9a996f2d051","tests/testsuite/invalid.rs":"31789643e3419ab922f8258e5a0421e1648b64aa5b96d3e1fb79bae36abf286e","tests/testsuite/main.rs":"a363749a7074ee95e3b7c556c0b0f59f5818445ca4762ec53693f451359b268a","tests/testsuite/parse.rs":"1c443e06cc5c019320658ac54254306a7ac9babe8c09283ec54162004043b553","tests/testsuite/stackoverflow.rs":"426d4e621bbafe62f8aba2e8c62e715929185d5eca4c5083b6427b601abc667a"},"package":"5e6a7712b49e1775fb9a7b998de6635b299237f48b404dde71704f2e0e7f37e5"}
\ No newline at end of file diff --git a/vendor/toml_edit/Cargo.lock b/vendor/toml_edit/Cargo.lock new file mode 100644 index 000000000..0e9478a36 --- /dev/null +++ b/vendor/toml_edit/Cargo.lock @@ -0,0 +1,749 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bstr" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f0778972c64420fdedc63f09919c8a88bda7b25135357fd25a5d9f3257e832" +dependencies = [ + "memchr", + "serde", +] + +[[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 = "chrono" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "clap" +version = "4.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76" +dependencies = [ + "bitflags", + "clap_derive", + "clap_lex", + "is-terminal", + "once_cell", + "strsim", + "termcolor", +] + +[[package]] +name = "clap_derive" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "concolor" +version = "0.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "318d6c16e73b3a900eb212ad6a82fc7d298c5ab8184c7a9998646455bc474a16" +dependencies = [ + "bitflags", + "concolor-query", + "is-terminal", +] + +[[package]] +name = "concolor-query" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82a90734b3d5dcf656e7624cca6bce9c3a90ee11f900e80141a7427ccfb3d317" + +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[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 = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "globset" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "856b5cb0902c2b6d65d5fd97dfa30f9b70c7538e770b98eab5ed52d8db923e01" + +[[package]] +name = "ignore" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492" +dependencies = [ + "globset", + "lazy_static", + "log", + "memchr", + "regex", + "same-file", + "thread_local", + "walkdir", + "winapi-util", +] + +[[package]] +name = "include_dir" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18762faeff7122e89e0857b02f7ce6fcc0d101d5e9ad2ad7846cc01d61b7f19e" +dependencies = [ + "include_dir_macros", +] + +[[package]] +name = "include_dir_macros" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b139284b5cf57ecfa712bcc66950bb635b31aff41c188e8a4cfc758eca374a3f" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "indexmap" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "is-terminal" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef" +dependencies = [ + "hermit-abi 0.3.0", + "io-lifetimes", + "rustix", + "windows-sys", +] + +[[package]] +name = "itoa" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" + +[[package]] +name = "kstring" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3066350882a1cd6d950d055997f379ac37fd39f81cd4d8ed186032eb3c5747" +dependencies = [ + "static_assertions", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.139" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" + +[[package]] +name = "libtest-mimic" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7b603516767d1ab23d0de09d023e62966c3322f7148297c35cf3d97aa8b37fa" +dependencies = [ + "clap", + "termcolor", + "threadpool", +] + +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "nom8" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8" +dependencies = [ + "memchr", +] + +[[package]] +name = "normalize-line-endings" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[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.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" + +[[package]] +name = "os_str_bytes" +version = "6.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" + +[[package]] +name = "rustix" +version = "0.36.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "ryu" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" + +[[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 = "serde" +version = "1.0.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7434af0dc1cbd59268aa98b4c22c131c0584d2232f6fb166efb993e2832e896a" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4" +dependencies = [ + "serde", +] + +[[package]] +name = "similar" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf" + +[[package]] +name = "snapbox" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34eced5a65e76d5a00047986a83c65f80dc666faa27b5138f331659e2ca6bcf5" +dependencies = [ + "concolor", + "ignore", + "libtest-mimic", + "normalize-line-endings", + "similar", + "snapbox-macros", + "yansi", +] + +[[package]] +name = "snapbox-macros" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "485e65c1203eb37244465e857d15a26d3a85a5410648ccb53b18bd44cb3a7336" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thread_local" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +dependencies = [ + "once_cell", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "toml-test" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488f0cf8da1d1dd4a756c6136fc3684a53df54c3f167e26b09678729b17a4d10" +dependencies = [ + "chrono", + "serde", + "serde_json", +] + +[[package]] +name = "toml-test-data" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f351b6d6005ee802b0d4a53ca1cdf05636f441df4d299e62cba57f1da52646" +dependencies = [ + "include_dir", +] + +[[package]] +name = "toml-test-harness" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e00fda5710922fe6b3005bf6a5050c303d6f9625249c37b7386e8818f4af675" +dependencies = [ + "ignore", + "libtest-mimic", + "toml-test", + "toml-test-data", +] + +[[package]] +name = "toml_datetime" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.3" +dependencies = [ + "indexmap", + "kstring", + "libtest-mimic", + "nom8", + "serde", + "serde_json", + "serde_spanned", + "snapbox", + "toml-test-data", + "toml-test-harness", + "toml_datetime", +] + +[[package]] +name = "unicode-ident" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + +[[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", +] + +[[package]] +name = "windows-targets" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" + +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" diff --git a/vendor/toml_edit/Cargo.toml b/vendor/toml_edit/Cargo.toml new file mode 100644 index 000000000..fdad3edd3 --- /dev/null +++ b/vendor/toml_edit/Cargo.toml @@ -0,0 +1,154 @@ +# 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.60.0" +name = "toml_edit" +version = "0.19.3" +authors = [ + "Andronik Ordian <write@reusable.software>", + "Ed Page <eopage@gmail.com>", +] +include = [ + "src/**/*", + "Cargo.toml", + "LICENSE*", + "README.md", + "examples/**/*", + "benches/**/*", + "tests/**/*", +] +description = "Yet another format-preserving TOML parser." +documentation = "https://docs.rs/toml_edit" +readme = "README.md" +keywords = [ + "encoding", + "toml", +] +categories = [ + "encoding", + "parser-implementations", + "parsing", + "config", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/ordian/toml_edit" + +[package.metadata.docs.rs] +rustdoc-args = [ + "--cfg", + "docsrs", +] +features = ["serde"] + +[package.metadata.release] +tag-name = "v{{version}}" + +[[package.metadata.release.pre-release-replacements]] +file = "CHANGELOG.md" +search = "Unreleased" +replace = "{{version}}" +min = 1 + +[[package.metadata.release.pre-release-replacements]] +file = "CHANGELOG.md" +search = '\.\.\.HEAD' +replace = "...{{tag_name}}" +exactly = 1 + +[[package.metadata.release.pre-release-replacements]] +file = "CHANGELOG.md" +search = "ReleaseDate" +replace = "{{date}}" +min = 1 + +[[package.metadata.release.pre-release-replacements]] +file = "CHANGELOG.md" +search = "<!-- next-header -->" +replace = """ +<!-- next-header --> +## [Unreleased] - ReleaseDate +""" +exactly = 1 + +[[package.metadata.release.pre-release-replacements]] +file = "CHANGELOG.md" +search = "<!-- next-url -->" +replace = """ +<!-- next-url --> +[Unreleased]: https://github.com/toml-rs/toml/compare/{{tag_name}}...HEAD""" +exactly = 1 + +[[example]] +name = "visit" +test = true + +[[test]] +name = "decoder_compliance" +harness = false + +[[test]] +name = "encoder_compliance" +harness = false + +[[test]] +name = "invalid" +harness = false + +[dependencies.indexmap] +version = "1.9.1" + +[dependencies.kstring] +version = "2.0.0" +features = ["max_inline"] +optional = true + +[dependencies.nom8] +version = "0.2.0" + +[dependencies.serde] +version = "1.0.145" +optional = true + +[dependencies.serde_spanned] +version = "0.6.1" +features = ["serde"] +optional = true + +[dependencies.toml_datetime] +version = "0.6.1" + +[dev-dependencies.libtest-mimic] +version = "0.6.0" + +[dev-dependencies.serde_json] +version = "1.0.91" + +[dev-dependencies.snapbox] +version = "0.4.4" +features = ["harness"] + +[dev-dependencies.toml-test-data] +version = "1.3.0" + +[dev-dependencies.toml-test-harness] +version = "0.4.3" + +[features] +default = [] +perf = ["dep:kstring"] +serde = [ + "dep:serde", + "toml_datetime/serde", + "dep:serde_spanned", +] +unbounded = [] diff --git a/vendor/toml_edit/LICENSE-APACHE b/vendor/toml_edit/LICENSE-APACHE new file mode 100644 index 000000000..16fe87b06 --- /dev/null +++ b/vendor/toml_edit/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/vendor/toml_edit/LICENSE-MIT b/vendor/toml_edit/LICENSE-MIT new file mode 100644 index 000000000..b9e61a2da --- /dev/null +++ b/vendor/toml_edit/LICENSE-MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Andronik Ordian + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/toml_edit/README.md b/vendor/toml_edit/README.md new file mode 100644 index 000000000..f1c74eeb0 --- /dev/null +++ b/vendor/toml_edit/README.md @@ -0,0 +1,59 @@ +# toml_edit + +[![Build Status](https://github.com/ordian/toml_edit/workflows/Continuous%20integration/badge.svg)](https://github.com/ordian/toml_edit/actions) +[![codecov](https://codecov.io/gh/ordian/toml_edit/branch/master/graph/badge.svg)](https://codecov.io/gh/ordian/toml_edit) +[![crates.io](https://img.shields.io/crates/v/toml_edit.svg)](https://crates.io/crates/toml_edit) +[![docs](https://docs.rs/toml_edit/badge.svg)](https://docs.rs/toml_edit) +[![Join the chat at https://gitter.im/toml_edit/Lobby](https://badges.gitter.im/a.svg)](https://gitter.im/toml_edit/Lobby) + + +This crate allows you to parse and modify toml +documents, while preserving comments, spaces *and +relative order* or items. + +`toml_edit` is primarily tailored for [cargo-edit](https://github.com/killercup/cargo-edit/) needs. + +## Example + +```rust +use toml_edit::{Document, value}; + +fn main() { + let toml = r#" +"hello" = 'toml!' # comment +['a'.b] + "#; + let mut doc = toml.parse::<Document>().expect("invalid doc"); + assert_eq!(doc.to_string(), toml); + // let's add a new key/value pair inside a.b: c = {d = "hello"} + doc["a"]["b"]["c"]["d"] = value("hello"); + // autoformat inline table a.b.c: { d = "hello" } + doc["a"]["b"]["c"].as_inline_table_mut().map(|t| t.fmt()); + let expected = r#" +"hello" = 'toml!' # comment +['a'.b] +c = { d = "hello" } + "#; + assert_eq!(doc.to_string(), expected); +} +``` + +## Limitations + +Things it does not preserve: + +* Scattered array of tables (tables are reordered by default, see [test]). +* Order of dotted keys, see [issue](https://github.com/ordian/toml_edit/issues/163). + +## License + +Licensed under either of + +- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://apache.org/licenses/LICENSE-2.0) +- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. + +[test]: https://github.com/ordian/toml_edit/blob/f09bd5d075fdb7d2ef8d9bb3270a34506c276753/tests/test_valid.rs#L84 diff --git a/vendor/toml_edit/examples/visit.rs b/vendor/toml_edit/examples/visit.rs new file mode 100644 index 000000000..cd7f851fe --- /dev/null +++ b/vendor/toml_edit/examples/visit.rs @@ -0,0 +1,284 @@ +//! Example for how to use `VisitMut` to iterate over a table. + +use std::collections::BTreeSet; +use toml_edit::visit::*; +use toml_edit::visit_mut::*; +use toml_edit::{Array, Document, InlineTable, Item, KeyMut, Table, Value}; + +/// This models the visit state for dependency keys in a `Cargo.toml`. +/// +/// Dependencies can be specified as: +/// +/// ```toml +/// [dependencies] +/// dep1 = "0.2" +/// +/// [build-dependencies] +/// dep2 = "0.3" +/// +/// [dev-dependencies] +/// dep3 = "0.4" +/// +/// [target.'cfg(windows)'.dependencies] +/// dep4 = "0.5" +/// +/// # and target build- and dev-dependencies +/// ``` +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +enum VisitState { + /// Represents the root of the table. + Root, + /// Represents "dependencies", "build-dependencies" or "dev-dependencies", or the target + /// forms of these. + Dependencies, + /// A table within dependencies. + SubDependencies, + /// Represents "target". + Target, + /// "target.[TARGET]". + TargetWithSpec, + /// Represents some other state. + Other, +} + +impl VisitState { + /// Figures out the next visit state, given the current state and the given key. + fn descend(self, key: &str) -> Self { + match (self, key) { + ( + VisitState::Root | VisitState::TargetWithSpec, + "dependencies" | "build-dependencies" | "dev-dependencies", + ) => VisitState::Dependencies, + (VisitState::Root, "target") => VisitState::Target, + (VisitState::Root | VisitState::TargetWithSpec, _) => VisitState::Other, + (VisitState::Target, _) => VisitState::TargetWithSpec, + (VisitState::Dependencies, _) => VisitState::SubDependencies, + (VisitState::SubDependencies, _) => VisitState::SubDependencies, + (VisitState::Other, _) => VisitState::Other, + } + } +} + +/// Collect the names of every dependency key. +#[derive(Debug)] +struct DependencyNameVisitor<'doc> { + state: VisitState, + names: BTreeSet<&'doc str>, +} + +impl<'doc> Visit<'doc> for DependencyNameVisitor<'doc> { + fn visit_table_like_kv(&mut self, key: &'doc str, node: &'doc Item) { + if self.state == VisitState::Dependencies { + self.names.insert(key); + } else { + // Since we're only interested in collecting the top-level keys right under + // [dependencies], don't recurse unconditionally. + + let old_state = self.state; + + // Figure out the next state given the key. + self.state = self.state.descend(key); + + // Recurse further into the document tree. + visit_table_like_kv(self, key, node); + + // Restore the old state after it's done. + self.state = old_state; + } + } +} + +/// Normalize all dependency tables into the format: +/// +/// ```toml +/// [dependencies] +/// dep = { version = "1.0", features = ["foo", "bar"], ... } +/// ``` +/// +/// leaving other tables untouched. +#[derive(Debug)] +struct NormalizeDependencyTablesVisitor { + state: VisitState, +} + +impl VisitMut for NormalizeDependencyTablesVisitor { + fn visit_table_mut(&mut self, node: &mut Table) { + visit_table_mut(self, node); + + // The conversion from regular tables into inline ones might leave some explicit parent + // tables hanging, so convert them to implicit. + if matches!(self.state, VisitState::Target | VisitState::TargetWithSpec) { + node.set_implicit(true); + } + } + + fn visit_table_like_kv_mut(&mut self, mut key: KeyMut<'_>, node: &mut Item) { + let old_state = self.state; + + // Figure out the next state given the key. + self.state = self.state.descend(key.get()); + + match self.state { + VisitState::Target | VisitState::TargetWithSpec | VisitState::Dependencies => { + // Top-level dependency row, or above: turn inline tables into regular ones. + if let Item::Value(Value::InlineTable(inline_table)) = node { + let inline_table = std::mem::replace(inline_table, InlineTable::new()); + let table = inline_table.into_table(); + key.fmt(); + *node = Item::Table(table); + } + } + VisitState::SubDependencies => { + // Individual dependency: turn regular tables into inline ones. + if let Item::Table(table) = node { + // Turn the table into an inline table. + let table = std::mem::replace(table, Table::new()); + let inline_table = table.into_inline_table(); + key.fmt(); + *node = Item::Value(Value::InlineTable(inline_table)); + } + } + _ => {} + } + + // Recurse further into the document tree. + visit_table_like_kv_mut(self, key, node); + + // Restore the old state after it's done. + self.state = old_state; + } + + fn visit_array_mut(&mut self, node: &mut Array) { + // Format any arrays within dependencies to be on the same line. + if matches!( + self.state, + VisitState::Dependencies | VisitState::SubDependencies + ) { + node.fmt(); + } + } +} + +/// This is the input provided to visit_mut_example. +static INPUT: &str = r#" +[package] +name = "my-package" + +[package.metadata.foo] +bar = 42 + +[dependencies] +atty = "0.2" +cargo-platform = { path = "crates/cargo-platform", version = "0.1.2" } + +[dependencies.pretty_env_logger] +version = "0.4" +optional = true + +[target.'cfg(windows)'.dependencies] +fwdansi = "1.1.0" + +[target.'cfg(windows)'.dependencies.winapi] +version = "0.3" +features = [ +"handleapi", +"jobapi", +] + +[target.'cfg(unix)'] +dev-dependencies = { miniz_oxide = "0.5" } + +[dev-dependencies.cargo-test-macro] +path = "crates/cargo-test-macro" + +[build-dependencies.flate2] +version = "0.4" +"#; + +/// This is the output produced by visit_mut_example. +#[cfg(test)] +static VISIT_MUT_OUTPUT: &str = r#" +[package] +name = "my-package" + +[package.metadata.foo] +bar = 42 + +[dependencies] +atty = "0.2" +cargo-platform = { path = "crates/cargo-platform", version = "0.1.2" } +pretty_env_logger = { version = "0.4", optional = true } + +[target.'cfg(windows)'.dependencies] +fwdansi = "1.1.0" +winapi = { version = "0.3", features = ["handleapi", "jobapi"] } + +[target.'cfg(unix)'.dev-dependencies] +miniz_oxide = "0.5" + +[dev-dependencies] +cargo-test-macro = { path = "crates/cargo-test-macro" } + +[build-dependencies] +flate2 = { version = "0.4" } +"#; + +fn visit_example(document: &Document) -> BTreeSet<&str> { + let mut visitor = DependencyNameVisitor { + state: VisitState::Root, + names: BTreeSet::new(), + }; + + visitor.visit_document(document); + + visitor.names +} + +fn visit_mut_example(document: &mut Document) { + let mut visitor = NormalizeDependencyTablesVisitor { + state: VisitState::Root, + }; + + visitor.visit_document_mut(document); +} + +fn main() { + let mut document: Document = INPUT.parse().expect("input is valid TOML"); + + println!("** visit example"); + println!("{:?}", visit_example(&document)); + + println!("** visit_mut example"); + visit_mut_example(&mut document); + println!("{}", document); +} + +#[cfg(test)] +#[test] +fn visit_correct() { + let document: Document = INPUT.parse().expect("input is valid TOML"); + + let names = visit_example(&document); + let expected = vec![ + "atty", + "cargo-platform", + "pretty_env_logger", + "fwdansi", + "winapi", + "miniz_oxide", + "cargo-test-macro", + "flate2", + ] + .into_iter() + .collect(); + assert_eq!(names, expected); +} + +#[cfg(test)] +#[test] +fn visit_mut_correct() { + let mut document: Document = INPUT.parse().expect("input is valid TOML"); + + visit_mut_example(&mut document); + assert_eq!(format!("{}", document), VISIT_MUT_OUTPUT); +} diff --git a/vendor/toml_edit/src/array.rs b/vendor/toml_edit/src/array.rs new file mode 100644 index 000000000..68cb4467a --- /dev/null +++ b/vendor/toml_edit/src/array.rs @@ -0,0 +1,389 @@ +use std::iter::FromIterator; +use std::mem; + +use crate::repr::Decor; +use crate::value::{DEFAULT_LEADING_VALUE_DECOR, DEFAULT_VALUE_DECOR}; +use crate::{Item, RawString, Value}; + +/// Type representing a TOML array, +/// payload of the `Value::Array` variant's value +#[derive(Debug, Default, Clone)] +pub struct Array { + // `trailing` represents whitespaces, newlines + // and comments in an empty array or after the trailing comma + trailing: RawString, + trailing_comma: bool, + // prefix before `[` and suffix after `]` + decor: Decor, + pub(crate) span: Option<std::ops::Range<usize>>, + // always Vec<Item::Value> + pub(crate) values: Vec<Item>, +} + +/// An owned iterator type over `Table`'s key/value pairs. +pub type ArrayIntoIter = Box<dyn Iterator<Item = Value>>; +/// An iterator type over `Array`'s values. +pub type ArrayIter<'a> = Box<dyn Iterator<Item = &'a Value> + 'a>; +/// An iterator type over `Array`'s values. +pub type ArrayIterMut<'a> = Box<dyn Iterator<Item = &'a mut Value> + 'a>; + +/// Constructors +/// +/// See also `FromIterator` +impl Array { + /// Create an empty `Array` + /// + /// # Examples + /// + /// ```rust + /// let mut arr = toml_edit::Array::new(); + /// ``` + pub fn new() -> Self { + Default::default() + } + + pub(crate) fn with_vec(values: Vec<Item>) -> Self { + Self { + values, + ..Default::default() + } + } +} + +/// Formatting +impl Array { + /// Auto formats the array. + pub fn fmt(&mut self) { + decorate_array(self); + } + + /// Set whether the array will use a trailing comma + pub fn set_trailing_comma(&mut self, yes: bool) { + self.trailing_comma = yes; + } + + /// Whether the array will use a trailing comma + pub fn trailing_comma(&self) -> bool { + self.trailing_comma + } + + /// Set whitespace after last element + pub fn set_trailing(&mut self, trailing: impl Into<RawString>) { + self.trailing = trailing.into(); + } + + /// Whitespace after last element + pub fn trailing(&self) -> &RawString { + &self.trailing + } + + /// Returns the surrounding whitespace + pub fn decor_mut(&mut self) -> &mut Decor { + &mut self.decor + } + + /// Returns the surrounding whitespace + pub fn decor(&self) -> &Decor { + &self.decor + } + + /// Returns the location within the original document + pub(crate) fn span(&self) -> Option<std::ops::Range<usize>> { + self.span.clone() + } + + pub(crate) fn despan(&mut self, input: &str) { + self.span = None; + self.decor.despan(input); + self.trailing.despan(input); + for value in &mut self.values { + value.despan(input); + } + } +} + +impl Array { + /// Returns an iterator over all values. + pub fn iter(&self) -> ArrayIter<'_> { + Box::new(self.values.iter().filter_map(Item::as_value)) + } + + /// Returns an iterator over all values. + pub fn iter_mut(&mut self) -> ArrayIterMut<'_> { + Box::new(self.values.iter_mut().filter_map(Item::as_value_mut)) + } + + /// Returns the length of the underlying Vec. + /// + /// In some rare cases, placeholder elements will exist. For a more accurate count, call + /// `a.iter().count()` + /// + /// # Examples + /// + /// ```rust + /// let mut arr = toml_edit::Array::new(); + /// arr.push(1); + /// arr.push("foo"); + /// assert_eq!(arr.len(), 2); + /// ``` + pub fn len(&self) -> usize { + self.values.len() + } + + /// Return true iff `self.len() == 0`. + /// + /// # Examples + /// + /// ```rust + /// let mut arr = toml_edit::Array::new(); + /// assert!(arr.is_empty()); + /// + /// arr.push(1); + /// arr.push("foo"); + /// assert!(! arr.is_empty()); + /// ``` + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Clears the array, removing all values. Keeps the allocated memory for reuse. + pub fn clear(&mut self) { + self.values.clear() + } + + /// Returns a reference to the value at the given index, or `None` if the index is out of + /// bounds. + pub fn get(&self, index: usize) -> Option<&Value> { + self.values.get(index).and_then(Item::as_value) + } + + /// Returns a reference to the value at the given index, or `None` if the index is out of + /// bounds. + pub fn get_mut(&mut self, index: usize) -> Option<&mut Value> { + self.values.get_mut(index).and_then(Item::as_value_mut) + } + + /// Appends a new value to the end of the array, applying default formatting to it. + /// + /// # Examples + /// + /// ```rust + /// let mut arr = toml_edit::Array::new(); + /// arr.push(1); + /// arr.push("foo"); + /// ``` + pub fn push<V: Into<Value>>(&mut self, v: V) { + self.value_op(v.into(), true, |items, value| { + items.push(Item::Value(value)) + }) + } + + /// Appends a new, already formatted value to the end of the array. + /// + /// # Examples + /// + /// ```rust + /// let formatted_value = "'literal'".parse::<toml_edit::Value>().unwrap(); + /// let mut arr = toml_edit::Array::new(); + /// arr.push_formatted(formatted_value); + /// ``` + pub fn push_formatted(&mut self, v: Value) { + self.values.push(Item::Value(v)); + } + + /// Inserts an element at the given position within the array, applying default formatting to + /// it and shifting all values after it to the right. + /// + /// # Panics + /// + /// Panics if `index > len`. + /// + /// # Examples + /// + /// ```rust + /// let mut arr = toml_edit::Array::new(); + /// arr.push(1); + /// arr.push("foo"); + /// + /// arr.insert(0, "start"); + /// ``` + pub fn insert<V: Into<Value>>(&mut self, index: usize, v: V) { + self.value_op(v.into(), true, |items, value| { + items.insert(index, Item::Value(value)) + }) + } + + /// Inserts an already formatted value at the given position within the array, shifting all + /// values after it to the right. + /// + /// # Panics + /// + /// Panics if `index > len`. + /// + /// # Examples + /// + /// ```rust + /// let mut arr = toml_edit::Array::new(); + /// arr.push(1); + /// arr.push("foo"); + /// + /// let formatted_value = "'start'".parse::<toml_edit::Value>().unwrap(); + /// arr.insert_formatted(0, formatted_value); + /// ``` + pub fn insert_formatted(&mut self, index: usize, v: Value) { + self.values.insert(index, Item::Value(v)) + } + + /// Replaces the element at the given position within the array, preserving existing formatting. + /// + /// # Panics + /// + /// Panics if `index >= len`. + /// + /// # Examples + /// + /// ```rust + /// let mut arr = toml_edit::Array::new(); + /// arr.push(1); + /// arr.push("foo"); + /// + /// arr.replace(0, "start"); + /// ``` + pub fn replace<V: Into<Value>>(&mut self, index: usize, v: V) -> Value { + // Read the existing value's decor and preserve it. + let existing_decor = self + .get(index) + .unwrap_or_else(|| panic!("index {} out of bounds (len = {})", index, self.len())) + .decor(); + let mut value = v.into(); + *value.decor_mut() = existing_decor.clone(); + self.replace_formatted(index, value) + } + + /// Replaces the element at the given position within the array with an already formatted value. + /// + /// # Panics + /// + /// Panics if `index >= len`. + /// + /// # Examples + /// + /// ```rust + /// let mut arr = toml_edit::Array::new(); + /// arr.push(1); + /// arr.push("foo"); + /// + /// let formatted_value = "'start'".parse::<toml_edit::Value>().unwrap(); + /// arr.replace_formatted(0, formatted_value); + /// ``` + pub fn replace_formatted(&mut self, index: usize, v: Value) -> Value { + match mem::replace(&mut self.values[index], Item::Value(v)) { + Item::Value(old_value) => old_value, + x => panic!("non-value item {:?} in an array", x), + } + } + + /// Removes the value at the given index. + /// + /// # Examples + /// + /// ```rust + /// let mut arr = toml_edit::Array::new(); + /// arr.push(1); + /// arr.push("foo"); + /// + /// arr.remove(0); + /// assert_eq!(arr.len(), 1); + /// ``` + pub fn remove(&mut self, index: usize) -> Value { + let removed = self.values.remove(index); + match removed { + Item::Value(v) => v, + x => panic!("non-value item {:?} in an array", x), + } + } + + fn value_op<T>( + &mut self, + v: Value, + decorate: bool, + op: impl FnOnce(&mut Vec<Item>, Value) -> T, + ) -> T { + let mut value = v; + if !self.is_empty() && decorate { + value.decorate(" ", ""); + } else if decorate { + value.decorate("", ""); + } + op(&mut self.values, value) + } +} + +impl std::fmt::Display for Array { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + crate::encode::Encode::encode(self, f, None, ("", "")) + } +} + +impl<V: Into<Value>> Extend<V> for Array { + fn extend<T: IntoIterator<Item = V>>(&mut self, iter: T) { + for value in iter { + self.push_formatted(value.into()); + } + } +} + +impl<V: Into<Value>> FromIterator<V> for Array { + fn from_iter<I>(iter: I) -> Self + where + I: IntoIterator<Item = V>, + { + let v = iter.into_iter().map(|a| Item::Value(a.into())); + Array { + values: v.collect(), + ..Default::default() + } + } +} + +impl IntoIterator for Array { + type Item = Value; + type IntoIter = ArrayIntoIter; + + fn into_iter(self) -> Self::IntoIter { + Box::new( + self.values + .into_iter() + .filter(|v| v.is_value()) + .map(|v| v.into_value().unwrap()), + ) + } +} + +impl<'s> IntoIterator for &'s Array { + type Item = &'s Value; + type IntoIter = ArrayIter<'s>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +fn decorate_array(array: &mut Array) { + for (i, value) in array + .values + .iter_mut() + .filter_map(Item::as_value_mut) + .enumerate() + { + // [value1, value2, value3] + if i == 0 { + value.decorate(DEFAULT_LEADING_VALUE_DECOR.0, DEFAULT_LEADING_VALUE_DECOR.1); + } else { + value.decorate(DEFAULT_VALUE_DECOR.0, DEFAULT_VALUE_DECOR.1); + } + } + // Since everything is now on the same line, remove trailing commas and whitespace. + array.set_trailing_comma(false); + array.set_trailing(""); +} diff --git a/vendor/toml_edit/src/array_of_tables.rs b/vendor/toml_edit/src/array_of_tables.rs new file mode 100644 index 000000000..461a716c2 --- /dev/null +++ b/vendor/toml_edit/src/array_of_tables.rs @@ -0,0 +1,152 @@ +use std::iter::FromIterator; + +use crate::{Array, Item, Table}; + +/// Type representing a TOML array of tables +#[derive(Clone, Debug, Default)] +pub struct ArrayOfTables { + // Always Vec<Item::Table>, just `Item` to make `Index` work + pub(crate) span: Option<std::ops::Range<usize>>, + pub(crate) values: Vec<Item>, +} + +/// Constructors +/// +/// See also `FromIterator` +impl ArrayOfTables { + /// Creates an empty array of tables. + pub fn new() -> Self { + Default::default() + } +} + +/// Formatting +impl ArrayOfTables { + /// Convert to an inline array + pub fn into_array(mut self) -> Array { + for value in self.values.iter_mut() { + value.make_value(); + } + let mut a = Array::with_vec(self.values); + a.fmt(); + a + } + + /// Returns the location within the original document + pub(crate) fn span(&self) -> Option<std::ops::Range<usize>> { + self.span.clone() + } + + pub(crate) fn despan(&mut self, input: &str) { + self.span = None; + for value in &mut self.values { + value.despan(input); + } + } +} + +impl ArrayOfTables { + /// Returns an iterator over tables. + pub fn iter(&self) -> ArrayOfTablesIter<'_> { + Box::new(self.values.iter().filter_map(Item::as_table)) + } + + /// Returns an iterator over tables. + pub fn iter_mut(&mut self) -> ArrayOfTablesIterMut<'_> { + Box::new(self.values.iter_mut().filter_map(Item::as_table_mut)) + } + + /// Returns the length of the underlying Vec. + /// To get the actual number of items use `a.iter().count()`. + pub fn len(&self) -> usize { + self.values.len() + } + + /// Returns true iff `self.len() == 0`. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Removes all the tables. + pub fn clear(&mut self) { + self.values.clear() + } + + /// Returns an optional reference to the table. + pub fn get(&self, index: usize) -> Option<&Table> { + self.values.get(index).and_then(Item::as_table) + } + + /// Returns an optional mutable reference to the table. + pub fn get_mut(&mut self, index: usize) -> Option<&mut Table> { + self.values.get_mut(index).and_then(Item::as_table_mut) + } + + /// Appends a table to the array. + pub fn push(&mut self, table: Table) { + self.values.push(Item::Table(table)); + } + + /// Removes a table with the given index. + pub fn remove(&mut self, index: usize) { + self.values.remove(index); + } +} + +/// An iterator type over `ArrayOfTables`'s values. +pub type ArrayOfTablesIter<'a> = Box<dyn Iterator<Item = &'a Table> + 'a>; +/// An iterator type over `ArrayOfTables`'s values. +pub type ArrayOfTablesIterMut<'a> = Box<dyn Iterator<Item = &'a mut Table> + 'a>; +/// An iterator type over `ArrayOfTables`'s values. +pub type ArrayOfTablesIntoIter = Box<dyn Iterator<Item = Table>>; + +impl Extend<Table> for ArrayOfTables { + fn extend<T: IntoIterator<Item = Table>>(&mut self, iter: T) { + for value in iter { + self.push(value); + } + } +} + +impl FromIterator<Table> for ArrayOfTables { + fn from_iter<I>(iter: I) -> Self + where + I: IntoIterator<Item = Table>, + { + let v = iter.into_iter().map(Item::Table); + ArrayOfTables { + values: v.collect(), + span: None, + } + } +} + +impl IntoIterator for ArrayOfTables { + type Item = Table; + type IntoIter = ArrayOfTablesIntoIter; + + fn into_iter(self) -> Self::IntoIter { + Box::new( + self.values + .into_iter() + .filter(|v| v.is_table()) + .map(|v| v.into_table().unwrap()), + ) + } +} + +impl<'s> IntoIterator for &'s ArrayOfTables { + type Item = &'s Table; + type IntoIter = ArrayOfTablesIter<'s>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +impl std::fmt::Display for ArrayOfTables { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // HACK: Without the header, we don't really have a proper way of printing this + self.clone().into_array().fmt(f) + } +} diff --git a/vendor/toml_edit/src/de/array.rs b/vendor/toml_edit/src/de/array.rs new file mode 100644 index 000000000..adc54016b --- /dev/null +++ b/vendor/toml_edit/src/de/array.rs @@ -0,0 +1,97 @@ +use crate::de::Error; + +pub(crate) struct ArrayDeserializer { + input: Vec<crate::Item>, + span: Option<std::ops::Range<usize>>, +} + +impl ArrayDeserializer { + pub(crate) fn new(input: Vec<crate::Item>, span: Option<std::ops::Range<usize>>) -> Self { + Self { input, span } + } +} + +// Note: this is wrapped by `ValueDeserializer` and any trait methods +// implemented here need to be wrapped there +impl<'de> serde::Deserializer<'de> for ArrayDeserializer { + type Error = Error; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: serde::de::Visitor<'de>, + { + visitor.visit_seq(ArraySeqAccess::new(self.input)) + } + + fn deserialize_struct<V>( + self, + name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Error> + where + V: serde::de::Visitor<'de>, + { + if serde_spanned::__unstable::is_spanned(name, fields) { + if let Some(span) = self.span.clone() { + return visitor.visit_map(super::SpannedDeserializer::new(self, span)); + } + } + + self.deserialize_any(visitor) + } + + serde::forward_to_deserialize_any! { + bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq + bytes byte_buf map option unit newtype_struct + ignored_any unit_struct tuple_struct tuple enum identifier + } +} + +impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for ArrayDeserializer { + type Deserializer = Self; + + fn into_deserializer(self) -> Self::Deserializer { + self + } +} + +impl crate::Array { + pub(crate) fn into_deserializer(self) -> ArrayDeserializer { + ArrayDeserializer::new(self.values, self.span) + } +} + +impl crate::ArrayOfTables { + pub(crate) fn into_deserializer(self) -> ArrayDeserializer { + ArrayDeserializer::new(self.values, self.span) + } +} + +pub(crate) struct ArraySeqAccess { + iter: std::vec::IntoIter<crate::Item>, +} + +impl ArraySeqAccess { + pub(crate) fn new(input: Vec<crate::Item>) -> Self { + Self { + iter: input.into_iter(), + } + } +} + +impl<'de> serde::de::SeqAccess<'de> for ArraySeqAccess { + type Error = Error; + + fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> + where + T: serde::de::DeserializeSeed<'de>, + { + match self.iter.next() { + Some(v) => seed + .deserialize(crate::de::ValueDeserializer::new(v)) + .map(Some), + None => Ok(None), + } + } +} diff --git a/vendor/toml_edit/src/de/datetime.rs b/vendor/toml_edit/src/de/datetime.rs new file mode 100644 index 000000000..14de28b3f --- /dev/null +++ b/vendor/toml_edit/src/de/datetime.rs @@ -0,0 +1,43 @@ +use serde::de::value::BorrowedStrDeserializer; +use serde::de::IntoDeserializer; + +use crate::de::Error; + +pub(crate) struct DatetimeDeserializer { + date: Option<crate::Datetime>, +} + +impl DatetimeDeserializer { + pub(crate) fn new(date: crate::Datetime) -> Self { + Self { date: Some(date) } + } +} + +impl<'de> serde::de::MapAccess<'de> for DatetimeDeserializer { + type Error = Error; + + fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error> + where + K: serde::de::DeserializeSeed<'de>, + { + if self.date.is_some() { + seed.deserialize(BorrowedStrDeserializer::new( + toml_datetime::__unstable::FIELD, + )) + .map(Some) + } else { + Ok(None) + } + } + + fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error> + where + V: serde::de::DeserializeSeed<'de>, + { + if let Some(date) = self.date.take() { + seed.deserialize(date.to_string().into_deserializer()) + } else { + panic!("next_value_seed called before next_key_seed") + } + } +} diff --git a/vendor/toml_edit/src/de/key.rs b/vendor/toml_edit/src/de/key.rs new file mode 100644 index 000000000..3da41df41 --- /dev/null +++ b/vendor/toml_edit/src/de/key.rs @@ -0,0 +1,140 @@ +use serde::de::IntoDeserializer; + +use super::Error; + +pub(crate) struct KeyDeserializer { + span: Option<std::ops::Range<usize>>, + key: crate::InternalString, +} + +impl KeyDeserializer { + pub(crate) fn new(key: crate::InternalString, span: Option<std::ops::Range<usize>>) -> Self { + KeyDeserializer { span, key } + } +} + +impl<'de> serde::de::IntoDeserializer<'de, Error> for KeyDeserializer { + type Deserializer = Self; + + fn into_deserializer(self) -> Self::Deserializer { + self + } +} + +impl<'de> serde::de::Deserializer<'de> for KeyDeserializer { + type Error = Error; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: serde::de::Visitor<'de>, + { + self.key.into_deserializer().deserialize_any(visitor) + } + + fn deserialize_enum<V>( + self, + name: &str, + variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: serde::de::Visitor<'de>, + { + let _ = name; + let _ = variants; + visitor.visit_enum(self) + } + + fn deserialize_struct<V>( + self, + name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Error> + where + V: serde::de::Visitor<'de>, + { + if serde_spanned::__unstable::is_spanned(name, fields) { + if let Some(span) = self.span.clone() { + return visitor.visit_map(super::SpannedDeserializer::new(self.key.as_str(), span)); + } + } + self.deserialize_any(visitor) + } + + serde::forward_to_deserialize_any! { + bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq + bytes byte_buf map option unit newtype_struct + ignored_any unit_struct tuple_struct tuple identifier + } +} + +impl<'de> serde::de::EnumAccess<'de> for KeyDeserializer { + type Error = super::Error; + type Variant = UnitOnly<Self::Error>; + + fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> + where + T: serde::de::DeserializeSeed<'de>, + { + seed.deserialize(self).map(unit_only) + } +} + +pub(crate) struct UnitOnly<E> { + marker: std::marker::PhantomData<E>, +} + +fn unit_only<T, E>(t: T) -> (T, UnitOnly<E>) { + ( + t, + UnitOnly { + marker: std::marker::PhantomData, + }, + ) +} + +impl<'de, E> serde::de::VariantAccess<'de> for UnitOnly<E> +where + E: serde::de::Error, +{ + type Error = E; + + fn unit_variant(self) -> Result<(), Self::Error> { + Ok(()) + } + + fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error> + where + T: serde::de::DeserializeSeed<'de>, + { + Err(serde::de::Error::invalid_type( + serde::de::Unexpected::UnitVariant, + &"newtype variant", + )) + } + + fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error> + where + V: serde::de::Visitor<'de>, + { + Err(serde::de::Error::invalid_type( + serde::de::Unexpected::UnitVariant, + &"tuple variant", + )) + } + + fn struct_variant<V>( + self, + _fields: &'static [&'static str], + _visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: serde::de::Visitor<'de>, + { + Err(serde::de::Error::invalid_type( + serde::de::Unexpected::UnitVariant, + &"struct variant", + )) + } +} diff --git a/vendor/toml_edit/src/de/mod.rs b/vendor/toml_edit/src/de/mod.rs new file mode 100644 index 000000000..09ea12096 --- /dev/null +++ b/vendor/toml_edit/src/de/mod.rs @@ -0,0 +1,289 @@ +//! Deserializing TOML into Rust structures. +//! +//! This module contains all the Serde support for deserializing TOML documents into Rust structures. + +use serde::de::DeserializeOwned; + +mod array; +mod datetime; +mod key; +mod spanned; +mod table; +mod table_enum; +mod value; + +use array::ArrayDeserializer; +use datetime::DatetimeDeserializer; +use key::KeyDeserializer; +use spanned::SpannedDeserializer; +use table::TableMapAccess; +use table_enum::TableEnumDeserializer; + +pub use value::ValueDeserializer; + +/// Errors that can occur when deserializing a type. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Error { + inner: crate::TomlError, +} + +impl Error { + pub(crate) fn custom<T>(msg: T, span: Option<std::ops::Range<usize>>) -> Self + where + T: std::fmt::Display, + { + Error { + inner: crate::TomlError::custom(msg.to_string(), span), + } + } + + /// Add key while unwinding + pub fn add_key(&mut self, key: String) { + self.inner.add_key(key) + } + + /// What went wrong + pub fn message(&self) -> &str { + self.inner.message() + } + + /// The start/end index into the original document where the error occurred + pub fn span(&self) -> Option<std::ops::Range<usize>> { + self.inner.span() + } + + pub(crate) fn set_span(&mut self, span: Option<std::ops::Range<usize>>) { + self.inner.set_span(span); + } +} + +impl serde::de::Error for Error { + fn custom<T>(msg: T) -> Self + where + T: std::fmt::Display, + { + Error::custom(msg, None) + } +} + +impl std::fmt::Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + self.inner.fmt(f) + } +} + +impl From<crate::TomlError> for Error { + fn from(e: crate::TomlError) -> Error { + Self { inner: e } + } +} + +impl From<Error> for crate::TomlError { + fn from(e: Error) -> crate::TomlError { + e.inner + } +} + +impl std::error::Error for Error {} + +/// Convert a value into `T`. +pub fn from_str<T>(s: &'_ str) -> Result<T, Error> +where + T: DeserializeOwned, +{ + let de = s.parse::<Deserializer>()?; + T::deserialize(de) +} + +/// Convert a value into `T`. +pub fn from_slice<T>(s: &'_ [u8]) -> Result<T, Error> +where + T: DeserializeOwned, +{ + let s = std::str::from_utf8(s).map_err(|e| Error::custom(e, None))?; + from_str(s) +} + +/// Convert a document into `T`. +pub fn from_document<T>(d: crate::Document) -> Result<T, Error> +where + T: DeserializeOwned, +{ + let deserializer = Deserializer::new(d); + T::deserialize(deserializer) +} + +/// Deserialization for TOML [documents][crate::Document]. +pub struct Deserializer { + input: crate::Document, +} + +impl Deserializer { + /// Deserialization implementation for TOML. + pub fn new(input: crate::Document) -> Self { + Self { input } + } +} + +impl std::str::FromStr for Deserializer { + type Err = Error; + + /// Parses a document from a &str + fn from_str(s: &str) -> Result<Self, Self::Err> { + let d = crate::parser::parse_document(s).map_err(Error::from)?; + Ok(Self::new(d)) + } +} + +// Note: this is wrapped by `toml::de::Deserializer` and any trait methods +// implemented here need to be wrapped there +impl<'de> serde::Deserializer<'de> for Deserializer { + type Error = Error; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: serde::de::Visitor<'de>, + { + let original = self.input.original; + self.input + .root + .into_deserializer() + .deserialize_any(visitor) + .map_err(|mut e: Self::Error| { + e.inner.set_original(original); + e + }) + } + + // `None` is interpreted as a missing field so be sure to implement `Some` + // as a present field. + fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: serde::de::Visitor<'de>, + { + let original = self.input.original; + self.input + .root + .into_deserializer() + .deserialize_option(visitor) + .map_err(|mut e: Self::Error| { + e.inner.set_original(original); + e + }) + } + + fn deserialize_newtype_struct<V>( + self, + name: &'static str, + visitor: V, + ) -> Result<V::Value, Error> + where + V: serde::de::Visitor<'de>, + { + let original = self.input.original; + self.input + .root + .into_deserializer() + .deserialize_newtype_struct(name, visitor) + .map_err(|mut e: Self::Error| { + e.inner.set_original(original); + e + }) + } + + fn deserialize_struct<V>( + self, + name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Error> + where + V: serde::de::Visitor<'de>, + { + let original = self.input.original; + self.input + .root + .into_deserializer() + .deserialize_struct(name, fields, visitor) + .map_err(|mut e: Self::Error| { + e.inner.set_original(original); + e + }) + } + + // Called when the type to deserialize is an enum, as opposed to a field in the type. + fn deserialize_enum<V>( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Error> + where + V: serde::de::Visitor<'de>, + { + let original = self.input.original; + self.input + .root + .into_deserializer() + .deserialize_enum(name, variants, visitor) + .map_err(|mut e: Self::Error| { + e.inner.set_original(original); + e + }) + } + + serde::forward_to_deserialize_any! { + bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq + bytes byte_buf map unit + ignored_any unit_struct tuple_struct tuple identifier + } +} + +impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for Deserializer { + type Deserializer = Deserializer; + + fn into_deserializer(self) -> Self::Deserializer { + self + } +} + +impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for crate::Document { + type Deserializer = Deserializer; + + fn into_deserializer(self) -> Self::Deserializer { + Deserializer::new(self) + } +} + +pub(crate) fn validate_struct_keys( + table: &crate::table::KeyValuePairs, + fields: &'static [&'static str], +) -> Result<(), Error> { + let extra_fields = table + .iter() + .filter_map(|(key, val)| { + if !fields.contains(&key.as_str()) { + Some(val.clone()) + } else { + None + } + }) + .collect::<Vec<_>>(); + + if extra_fields.is_empty() { + Ok(()) + } else { + Err(Error::custom( + format!( + "unexpected keys in table: {}, available keys: {}", + extra_fields + .iter() + .map(|k| k.key.get()) + .collect::<Vec<_>>() + .join(", "), + fields.join(", "), + ), + extra_fields[0].key.span(), + )) + } +} diff --git a/vendor/toml_edit/src/de/spanned.rs b/vendor/toml_edit/src/de/spanned.rs new file mode 100644 index 000000000..7ce58640a --- /dev/null +++ b/vendor/toml_edit/src/de/spanned.rs @@ -0,0 +1,70 @@ +use serde::de::value::BorrowedStrDeserializer; +use serde::de::IntoDeserializer as _; + +use super::Error; + +pub(crate) struct SpannedDeserializer<'de, T: serde::de::IntoDeserializer<'de, Error>> { + phantom_data: std::marker::PhantomData<&'de ()>, + start: Option<usize>, + end: Option<usize>, + value: Option<T>, +} + +impl<'de, T> SpannedDeserializer<'de, T> +where + T: serde::de::IntoDeserializer<'de, Error>, +{ + pub(crate) fn new(value: T, span: std::ops::Range<usize>) -> Self { + Self { + phantom_data: Default::default(), + start: Some(span.start), + end: Some(span.end), + value: Some(value), + } + } +} + +impl<'de, T> serde::de::MapAccess<'de> for SpannedDeserializer<'de, T> +where + T: serde::de::IntoDeserializer<'de, Error>, +{ + type Error = Error; + fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error> + where + K: serde::de::DeserializeSeed<'de>, + { + if self.start.is_some() { + seed.deserialize(BorrowedStrDeserializer::new( + serde_spanned::__unstable::START_FIELD, + )) + .map(Some) + } else if self.end.is_some() { + seed.deserialize(BorrowedStrDeserializer::new( + serde_spanned::__unstable::END_FIELD, + )) + .map(Some) + } else if self.value.is_some() { + seed.deserialize(BorrowedStrDeserializer::new( + serde_spanned::__unstable::VALUE_FIELD, + )) + .map(Some) + } else { + Ok(None) + } + } + + fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error> + where + V: serde::de::DeserializeSeed<'de>, + { + if let Some(start) = self.start.take() { + seed.deserialize(start.into_deserializer()) + } else if let Some(end) = self.end.take() { + seed.deserialize(end.into_deserializer()) + } else if let Some(value) = self.value.take() { + seed.deserialize(value.into_deserializer()) + } else { + panic!("next_value_seed called before next_key_seed") + } + } +} diff --git a/vendor/toml_edit/src/de/table.rs b/vendor/toml_edit/src/de/table.rs new file mode 100644 index 000000000..0b6183e09 --- /dev/null +++ b/vendor/toml_edit/src/de/table.rs @@ -0,0 +1,213 @@ +use serde::de::IntoDeserializer; + +use crate::de::Error; + +pub(crate) struct TableDeserializer { + span: Option<std::ops::Range<usize>>, + items: crate::table::KeyValuePairs, +} + +// Note: this is wrapped by `Deserializer` and `ValueDeserializer` and any trait methods +// implemented here need to be wrapped there +impl<'de> serde::Deserializer<'de> for TableDeserializer { + type Error = Error; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: serde::de::Visitor<'de>, + { + visitor.visit_map(crate::de::TableMapAccess::new(self)) + } + + // `None` is interpreted as a missing field so be sure to implement `Some` + // as a present field. + fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: serde::de::Visitor<'de>, + { + visitor.visit_some(self) + } + + fn deserialize_newtype_struct<V>( + self, + _name: &'static str, + visitor: V, + ) -> Result<V::Value, Error> + where + V: serde::de::Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + fn deserialize_struct<V>( + self, + name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Error> + where + V: serde::de::Visitor<'de>, + { + if serde_spanned::__unstable::is_spanned(name, fields) { + if let Some(span) = self.span.clone() { + return visitor.visit_map(super::SpannedDeserializer::new(self, span)); + } + } + + self.deserialize_any(visitor) + } + + // Called when the type to deserialize is an enum, as opposed to a field in the type. + fn deserialize_enum<V>( + self, + _name: &'static str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Error> + where + V: serde::de::Visitor<'de>, + { + if self.items.is_empty() { + Err(crate::de::Error::custom( + "wanted exactly 1 element, found 0 elements", + self.span, + )) + } else if self.items.len() != 1 { + Err(crate::de::Error::custom( + "wanted exactly 1 element, more than 1 element", + self.span, + )) + } else { + visitor.visit_enum(crate::de::TableMapAccess::new(self)) + } + } + + serde::forward_to_deserialize_any! { + bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq + bytes byte_buf map unit + ignored_any unit_struct tuple_struct tuple identifier + } +} + +impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for TableDeserializer { + type Deserializer = TableDeserializer; + + fn into_deserializer(self) -> Self::Deserializer { + self + } +} + +impl crate::Table { + pub(crate) fn into_deserializer(self) -> TableDeserializer { + TableDeserializer { + span: self.span(), + items: self.items, + } + } +} + +impl crate::InlineTable { + pub(crate) fn into_deserializer(self) -> TableDeserializer { + TableDeserializer { + span: self.span(), + items: self.items, + } + } +} + +pub(crate) struct TableMapAccess { + iter: indexmap::map::IntoIter<crate::InternalString, crate::table::TableKeyValue>, + span: Option<std::ops::Range<usize>>, + value: Option<(crate::InternalString, crate::Item)>, +} + +impl TableMapAccess { + pub(crate) fn new(input: TableDeserializer) -> Self { + Self { + iter: input.items.into_iter(), + span: input.span, + value: None, + } + } +} + +impl<'de> serde::de::MapAccess<'de> for TableMapAccess { + type Error = Error; + + fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error> + where + K: serde::de::DeserializeSeed<'de>, + { + match self.iter.next() { + Some((k, v)) => { + let ret = seed + .deserialize(super::KeyDeserializer::new(k, v.key.span())) + .map(Some) + .map_err(|mut e: Self::Error| { + if e.span().is_none() { + e.set_span(v.key.span()); + } + e + }); + self.value = Some((v.key.into(), v.value)); + ret + } + None => Ok(None), + } + } + + fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error> + where + V: serde::de::DeserializeSeed<'de>, + { + match self.value.take() { + Some((k, v)) => { + let span = v.span(); + seed.deserialize(crate::de::ValueDeserializer::new(v)) + .map_err(|mut e: Self::Error| { + if e.span().is_none() { + e.set_span(span); + } + e.add_key(k.as_str().to_owned()); + e + }) + } + None => { + panic!("no more values in next_value_seed, internal error in ValueDeserializer") + } + } + } +} + +impl<'de> serde::de::EnumAccess<'de> for TableMapAccess { + type Error = Error; + type Variant = super::TableEnumDeserializer; + + fn variant_seed<V>(mut self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> + where + V: serde::de::DeserializeSeed<'de>, + { + let (key, value) = match self.iter.next() { + Some(pair) => pair, + None => { + return Err(Error::custom( + "expected table with exactly 1 entry, found empty table", + self.span, + )); + } + }; + + let val = seed + .deserialize(key.into_deserializer()) + .map_err(|mut e: Self::Error| { + if e.span().is_none() { + e.set_span(value.key.span()); + } + e + })?; + + let variant = super::TableEnumDeserializer::new(value.value); + + Ok((val, variant)) + } +} diff --git a/vendor/toml_edit/src/de/table_enum.rs b/vendor/toml_edit/src/de/table_enum.rs new file mode 100644 index 000000000..197ad6ea7 --- /dev/null +++ b/vendor/toml_edit/src/de/table_enum.rs @@ -0,0 +1,160 @@ +use crate::de::Error; + +/// Deserializes table values into enum variants. +pub(crate) struct TableEnumDeserializer { + value: crate::Item, +} + +impl TableEnumDeserializer { + pub(crate) fn new(value: crate::Item) -> Self { + TableEnumDeserializer { value } + } +} + +impl<'de> serde::de::VariantAccess<'de> for TableEnumDeserializer { + type Error = Error; + + fn unit_variant(self) -> Result<(), Self::Error> { + match self.value { + crate::Item::Table(values) => { + if values.is_empty() { + Ok(()) + } else { + Err(Error::custom("expected empty table", values.span())) + } + } + crate::Item::Value(crate::Value::InlineTable(values)) => { + if values.is_empty() { + Ok(()) + } else { + Err(Error::custom("expected empty table", values.span())) + } + } + e => Err(Error::custom( + format!("expected table, found {}", e.type_name()), + e.span(), + )), + } + } + + fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error> + where + T: serde::de::DeserializeSeed<'de>, + { + seed.deserialize(super::ValueDeserializer::new(self.value)) + } + + fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error> + where + V: serde::de::Visitor<'de>, + { + match self.value { + crate::Item::Table(values) => { + let values_span = values.span(); + let tuple_values = values + .items + .into_iter() + .enumerate() + .map( + |(index, (_, value))| match value.key.get().parse::<usize>() { + Ok(key_index) if key_index == index => Ok(value.value), + Ok(_) | Err(_) => Err(Error::custom( + format!( + "expected table key `{}`, but was `{}`", + index, + value.key.get() + ), + value.key.span(), + )), + }, + ) + // Fold all values into a `Vec`, or return the first error. + .fold(Ok(Vec::with_capacity(len)), |result, value_result| { + result.and_then(move |mut tuple_values| match value_result { + Ok(value) => { + tuple_values.push(value); + Ok(tuple_values) + } + // `Result<de::Value, Self::Error>` to `Result<Vec<_>, Self::Error>` + Err(e) => Err(e), + }) + })?; + + if tuple_values.len() == len { + serde::de::Deserializer::deserialize_seq( + super::ArrayDeserializer::new(tuple_values, values_span), + visitor, + ) + } else { + Err(Error::custom( + format!("expected tuple with length {}", len), + values_span, + )) + } + } + crate::Item::Value(crate::Value::InlineTable(values)) => { + let values_span = values.span(); + let tuple_values = values + .items + .into_iter() + .enumerate() + .map( + |(index, (_, value))| match value.key.get().parse::<usize>() { + Ok(key_index) if key_index == index => Ok(value.value), + Ok(_) | Err(_) => Err(Error::custom( + format!( + "expected table key `{}`, but was `{}`", + index, + value.key.get() + ), + value.key.span(), + )), + }, + ) + // Fold all values into a `Vec`, or return the first error. + .fold(Ok(Vec::with_capacity(len)), |result, value_result| { + result.and_then(move |mut tuple_values| match value_result { + Ok(value) => { + tuple_values.push(value); + Ok(tuple_values) + } + // `Result<de::Value, Self::Error>` to `Result<Vec<_>, Self::Error>` + Err(e) => Err(e), + }) + })?; + + if tuple_values.len() == len { + serde::de::Deserializer::deserialize_seq( + super::ArrayDeserializer::new(tuple_values, values_span), + visitor, + ) + } else { + Err(Error::custom( + format!("expected tuple with length {}", len), + values_span, + )) + } + } + e => Err(Error::custom( + format!("expected table, found {}", e.type_name()), + e.span(), + )), + } + } + + fn struct_variant<V>( + self, + fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: serde::de::Visitor<'de>, + { + serde::de::Deserializer::deserialize_struct( + super::ValueDeserializer::new(self.value).with_struct_key_validation(), + "", // TODO: this should be the variant name + fields, + visitor, + ) + } +} diff --git a/vendor/toml_edit/src/de/value.rs b/vendor/toml_edit/src/de/value.rs new file mode 100644 index 000000000..5726feb9e --- /dev/null +++ b/vendor/toml_edit/src/de/value.rs @@ -0,0 +1,250 @@ +use serde::de::IntoDeserializer as _; + +use crate::de::DatetimeDeserializer; +use crate::de::Error; + +/// Deserialization implementation for TOML [values][crate::Value]. +/// +/// # Example +/// +/// ``` +/// use serde::Deserialize; +/// +/// #[derive(Deserialize)] +/// struct Config { +/// title: String, +/// owner: Owner, +/// } +/// +/// #[derive(Deserialize)] +/// struct Owner { +/// name: String, +/// } +/// +/// let value = r#"{ title = 'TOML Example', owner = { name = 'Lisa' } }"#; +/// let deserializer = value.parse::<toml_edit::de::ValueDeserializer>().unwrap(); +/// let config = Config::deserialize(deserializer).unwrap(); +/// +/// assert_eq!(config.title, "TOML Example"); +/// assert_eq!(config.owner.name, "Lisa"); +/// ``` +pub struct ValueDeserializer { + input: crate::Item, + validate_struct_keys: bool, +} + +impl ValueDeserializer { + pub(crate) fn new(input: crate::Item) -> Self { + Self { + input, + validate_struct_keys: false, + } + } + + pub(crate) fn with_struct_key_validation(mut self) -> Self { + self.validate_struct_keys = true; + self + } +} + +// Note: this is wrapped by `toml::de::ValueDeserializer` and any trait methods +// implemented here need to be wrapped there +impl<'de> serde::Deserializer<'de> for ValueDeserializer { + type Error = Error; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: serde::de::Visitor<'de>, + { + let span = self.input.span(); + match self.input { + crate::Item::None => visitor.visit_none(), + crate::Item::Value(crate::Value::String(v)) => visitor.visit_string(v.into_value()), + crate::Item::Value(crate::Value::Integer(v)) => visitor.visit_i64(v.into_value()), + crate::Item::Value(crate::Value::Float(v)) => visitor.visit_f64(v.into_value()), + crate::Item::Value(crate::Value::Boolean(v)) => visitor.visit_bool(v.into_value()), + crate::Item::Value(crate::Value::Datetime(v)) => { + visitor.visit_map(DatetimeDeserializer::new(v.into_value())) + } + crate::Item::Value(crate::Value::Array(v)) => { + v.into_deserializer().deserialize_any(visitor) + } + crate::Item::Value(crate::Value::InlineTable(v)) => { + v.into_deserializer().deserialize_any(visitor) + } + crate::Item::Table(v) => v.into_deserializer().deserialize_any(visitor), + crate::Item::ArrayOfTables(v) => v.into_deserializer().deserialize_any(visitor), + } + .map_err(|mut e: Self::Error| { + if e.span().is_none() { + e.set_span(span); + } + e + }) + } + + // `None` is interpreted as a missing field so be sure to implement `Some` + // as a present field. + fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: serde::de::Visitor<'de>, + { + let span = self.input.span(); + visitor.visit_some(self).map_err(|mut e: Self::Error| { + if e.span().is_none() { + e.set_span(span); + } + e + }) + } + + fn deserialize_newtype_struct<V>( + self, + _name: &'static str, + visitor: V, + ) -> Result<V::Value, Error> + where + V: serde::de::Visitor<'de>, + { + let span = self.input.span(); + visitor + .visit_newtype_struct(self) + .map_err(|mut e: Self::Error| { + if e.span().is_none() { + e.set_span(span); + } + e + }) + } + + fn deserialize_struct<V>( + self, + name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Error> + where + V: serde::de::Visitor<'de>, + { + if serde_spanned::__unstable::is_spanned(name, fields) { + if let Some(span) = self.input.span() { + return visitor.visit_map(super::SpannedDeserializer::new(self, span)); + } + } + + if name == toml_datetime::__unstable::NAME && fields == [toml_datetime::__unstable::FIELD] { + let span = self.input.span(); + if let crate::Item::Value(crate::Value::Datetime(d)) = self.input { + return visitor + .visit_map(DatetimeDeserializer::new(d.into_value())) + .map_err(|mut e: Self::Error| { + if e.span().is_none() { + e.set_span(span); + } + e + }); + } + } + + if self.validate_struct_keys { + let span = self.input.span(); + match &self.input { + crate::Item::Table(values) => super::validate_struct_keys(&values.items, fields), + crate::Item::Value(crate::Value::InlineTable(values)) => { + super::validate_struct_keys(&values.items, fields) + } + _ => Ok(()), + } + .map_err(|mut e: Self::Error| { + if e.span().is_none() { + e.set_span(span); + } + e + })? + } + + self.deserialize_any(visitor) + } + + // Called when the type to deserialize is an enum, as opposed to a field in the type. + fn deserialize_enum<V>( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Error> + where + V: serde::de::Visitor<'de>, + { + let span = self.input.span(); + match self.input { + crate::Item::Value(crate::Value::String(v)) => { + visitor.visit_enum(v.into_value().into_deserializer()) + } + crate::Item::Value(crate::Value::InlineTable(v)) => { + if v.is_empty() { + Err(crate::de::Error::custom( + "wanted exactly 1 element, found 0 elements", + v.span(), + )) + } else if v.len() != 1 { + Err(crate::de::Error::custom( + "wanted exactly 1 element, more than 1 element", + v.span(), + )) + } else { + v.into_deserializer() + .deserialize_enum(name, variants, visitor) + } + } + crate::Item::Table(v) => v + .into_deserializer() + .deserialize_enum(name, variants, visitor), + e => Err(crate::de::Error::custom("wanted string or table", e.span())), + } + .map_err(|mut e: Self::Error| { + if e.span().is_none() { + e.set_span(span); + } + e + }) + } + + serde::forward_to_deserialize_any! { + bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq + bytes byte_buf map unit + ignored_any unit_struct tuple_struct tuple identifier + } +} + +impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for ValueDeserializer { + type Deserializer = Self; + + fn into_deserializer(self) -> Self::Deserializer { + self + } +} + +impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for crate::Value { + type Deserializer = ValueDeserializer; + + fn into_deserializer(self) -> Self::Deserializer { + ValueDeserializer::new(crate::Item::Value(self)) + } +} + +impl crate::Item { + pub(crate) fn into_deserializer(self) -> ValueDeserializer { + ValueDeserializer::new(self) + } +} + +impl std::str::FromStr for ValueDeserializer { + type Err = Error; + + /// Parses a value from a &str + fn from_str(s: &str) -> Result<Self, Self::Err> { + let v = crate::parser::parse_value(s).map_err(Error::from)?; + Ok(v.into_deserializer()) + } +} diff --git a/vendor/toml_edit/src/document.rs b/vendor/toml_edit/src/document.rs new file mode 100644 index 000000000..67dd293dd --- /dev/null +++ b/vendor/toml_edit/src/document.rs @@ -0,0 +1,113 @@ +use std::str::FromStr; + +use crate::parser; +use crate::table::Iter; +use crate::{Item, RawString, Table}; + +/// Type representing a TOML document +#[derive(Debug, Clone)] +pub struct Document { + pub(crate) root: Item, + // Trailing comments and whitespaces + pub(crate) trailing: RawString, + pub(crate) original: Option<String>, + pub(crate) span: Option<std::ops::Range<usize>>, +} + +impl Document { + /// Creates an empty document + pub fn new() -> Self { + Default::default() + } + + /// Returns a reference to the root item. + pub fn as_item(&self) -> &Item { + &self.root + } + + /// Returns a mutable reference to the root item. + pub fn as_item_mut(&mut self) -> &mut Item { + &mut self.root + } + + /// Returns a reference to the root table. + pub fn as_table(&self) -> &Table { + self.root.as_table().expect("root should always be a table") + } + + /// Returns a mutable reference to the root table. + pub fn as_table_mut(&mut self) -> &mut Table { + self.root + .as_table_mut() + .expect("root should always be a table") + } + + /// Returns an iterator over the root table. + pub fn iter(&self) -> Iter<'_> { + self.as_table().iter() + } + + /// Set whitespace after last element + pub fn set_trailing(&mut self, trailing: impl Into<RawString>) { + self.trailing = trailing.into(); + } + + /// Whitespace after last element + pub fn trailing(&self) -> &RawString { + &self.trailing + } + + /// # Panics + /// + /// If run on on a `Document` not generated by the parser + pub(crate) fn despan(&mut self) { + self.span = None; + self.root.despan(self.original.as_deref().unwrap()); + self.trailing.despan(self.original.as_deref().unwrap()); + } +} + +impl Default for Document { + fn default() -> Self { + Self { + root: Item::Table(Table::with_pos(Some(0))), + trailing: Default::default(), + original: Default::default(), + span: Default::default(), + } + } +} + +impl FromStr for Document { + type Err = crate::TomlError; + + /// Parses a document from a &str + fn from_str(s: &str) -> Result<Self, Self::Err> { + let mut d = parser::parse_document(s)?; + d.despan(); + Ok(d) + } +} + +impl std::ops::Deref for Document { + type Target = Table; + + fn deref(&self) -> &Self::Target { + self.as_table() + } +} + +impl std::ops::DerefMut for Document { + fn deref_mut(&mut self) -> &mut Self::Target { + self.as_table_mut() + } +} + +impl From<Table> for Document { + fn from(root: Table) -> Self { + Self { + root: Item::Table(root), + ..Default::default() + } + } +} diff --git a/vendor/toml_edit/src/encode.rs b/vendor/toml_edit/src/encode.rs new file mode 100644 index 000000000..4747bd523 --- /dev/null +++ b/vendor/toml_edit/src/encode.rs @@ -0,0 +1,530 @@ +use std::borrow::Cow; +use std::fmt::{Display, Formatter, Result, Write}; + +use toml_datetime::*; + +use crate::document::Document; +use crate::inline_table::DEFAULT_INLINE_KEY_DECOR; +use crate::key::Key; +use crate::repr::{Formatted, Repr, ValueRepr}; +use crate::table::{DEFAULT_KEY_DECOR, DEFAULT_KEY_PATH_DECOR, DEFAULT_TABLE_DECOR}; +use crate::value::{ + DEFAULT_LEADING_VALUE_DECOR, DEFAULT_TRAILING_VALUE_DECOR, DEFAULT_VALUE_DECOR, +}; +use crate::{Array, InlineTable, Item, Table, Value}; + +pub(crate) trait Encode { + fn encode( + &self, + buf: &mut dyn Write, + input: Option<&str>, + default_decor: (&str, &str), + ) -> Result; +} + +impl Encode for Key { + fn encode( + &self, + buf: &mut dyn Write, + input: Option<&str>, + default_decor: (&str, &str), + ) -> Result { + let decor = self.decor(); + decor.prefix_encode(buf, input, default_decor.0)?; + + if let Some(input) = input { + let repr = self + .as_repr() + .map(Cow::Borrowed) + .unwrap_or_else(|| Cow::Owned(self.default_repr())); + repr.encode(buf, input)?; + } else { + let repr = self.display_repr(); + write!(buf, "{}", repr)?; + }; + + decor.suffix_encode(buf, input, default_decor.1)?; + Ok(()) + } +} + +impl<'k> Encode for &'k [&'k Key] { + fn encode( + &self, + buf: &mut dyn Write, + input: Option<&str>, + default_decor: (&str, &str), + ) -> Result { + for (i, key) in self.iter().enumerate() { + let first = i == 0; + let last = i + 1 == self.len(); + + let prefix = if first { + default_decor.0 + } else { + DEFAULT_KEY_PATH_DECOR.0 + }; + let suffix = if last { + default_decor.1 + } else { + DEFAULT_KEY_PATH_DECOR.1 + }; + + if !first { + write!(buf, ".")?; + } + key.encode(buf, input, (prefix, suffix))?; + } + Ok(()) + } +} + +impl<T> Encode for Formatted<T> +where + T: ValueRepr, +{ + fn encode( + &self, + buf: &mut dyn Write, + input: Option<&str>, + default_decor: (&str, &str), + ) -> Result { + let decor = self.decor(); + decor.prefix_encode(buf, input, default_decor.0)?; + + if let Some(input) = input { + let repr = self + .as_repr() + .map(Cow::Borrowed) + .unwrap_or_else(|| Cow::Owned(self.default_repr())); + repr.encode(buf, input)?; + } else { + let repr = self.display_repr(); + write!(buf, "{}", repr)?; + }; + + decor.suffix_encode(buf, input, default_decor.1)?; + Ok(()) + } +} + +impl Encode for Array { + fn encode( + &self, + buf: &mut dyn Write, + input: Option<&str>, + default_decor: (&str, &str), + ) -> Result { + let decor = self.decor(); + decor.prefix_encode(buf, input, default_decor.0)?; + write!(buf, "[")?; + + for (i, elem) in self.iter().enumerate() { + let inner_decor; + if i == 0 { + inner_decor = DEFAULT_LEADING_VALUE_DECOR; + } else { + inner_decor = DEFAULT_VALUE_DECOR; + write!(buf, ",")?; + } + elem.encode(buf, input, inner_decor)?; + } + if self.trailing_comma() && !self.is_empty() { + write!(buf, ",")?; + } + + self.trailing().encode_with_default(buf, input, "")?; + write!(buf, "]")?; + decor.suffix_encode(buf, input, default_decor.1)?; + + Ok(()) + } +} + +impl Encode for InlineTable { + fn encode( + &self, + buf: &mut dyn Write, + input: Option<&str>, + default_decor: (&str, &str), + ) -> Result { + let decor = self.decor(); + decor.prefix_encode(buf, input, default_decor.0)?; + write!(buf, "{{")?; + self.preamble().encode_with_default(buf, input, "")?; + + let children = self.get_values(); + let len = children.len(); + for (i, (key_path, value)) in children.into_iter().enumerate() { + if i != 0 { + write!(buf, ",")?; + } + let inner_decor = if i == len - 1 { + DEFAULT_TRAILING_VALUE_DECOR + } else { + DEFAULT_VALUE_DECOR + }; + key_path + .as_slice() + .encode(buf, input, DEFAULT_INLINE_KEY_DECOR)?; + write!(buf, "=")?; + value.encode(buf, input, inner_decor)?; + } + + write!(buf, "}}")?; + decor.suffix_encode(buf, input, default_decor.1)?; + + Ok(()) + } +} + +impl Encode for Value { + fn encode( + &self, + buf: &mut dyn Write, + input: Option<&str>, + default_decor: (&str, &str), + ) -> Result { + match self { + Value::String(repr) => repr.encode(buf, input, default_decor), + Value::Integer(repr) => repr.encode(buf, input, default_decor), + Value::Float(repr) => repr.encode(buf, input, default_decor), + Value::Boolean(repr) => repr.encode(buf, input, default_decor), + Value::Datetime(repr) => repr.encode(buf, input, default_decor), + Value::Array(array) => array.encode(buf, input, default_decor), + Value::InlineTable(table) => table.encode(buf, input, default_decor), + } + } +} + +impl Display for Document { + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + let mut path = Vec::new(); + let mut last_position = 0; + let mut tables = Vec::new(); + visit_nested_tables(self.as_table(), &mut path, false, &mut |t, p, is_array| { + if let Some(pos) = t.position() { + last_position = pos; + } + tables.push((last_position, t, p.clone(), is_array)); + Ok(()) + }) + .unwrap(); + + tables.sort_by_key(|&(id, _, _, _)| id); + let mut first_table = true; + for (_, table, path, is_array) in tables { + visit_table( + f, + self.original.as_deref(), + table, + &path, + is_array, + &mut first_table, + )?; + } + self.trailing() + .encode_with_default(f, self.original.as_deref(), "") + } +} + +fn visit_nested_tables<'t, F>( + table: &'t Table, + path: &mut Vec<&'t Key>, + is_array_of_tables: bool, + callback: &mut F, +) -> Result +where + F: FnMut(&'t Table, &Vec<&'t Key>, bool) -> Result, +{ + callback(table, path, is_array_of_tables)?; + + for kv in table.items.values() { + match kv.value { + Item::Table(ref t) if !t.is_dotted() => { + path.push(&kv.key); + visit_nested_tables(t, path, false, callback)?; + path.pop(); + } + Item::ArrayOfTables(ref a) => { + for t in a.iter() { + path.push(&kv.key); + visit_nested_tables(t, path, true, callback)?; + path.pop(); + } + } + _ => {} + } + } + Ok(()) +} + +fn visit_table( + buf: &mut dyn Write, + input: Option<&str>, + table: &Table, + path: &[&Key], + is_array_of_tables: bool, + first_table: &mut bool, +) -> Result { + let children = table.get_values(); + // We are intentionally hiding implicit tables without any tables nested under them (ie + // `table.is_empty()` which is in contrast to `table.get_values().is_empty()`). We are + // trusting the user that an empty implicit table is not semantically meaningful + // + // This allows a user to delete all tables under this implicit table and the implicit table + // will disappear. + // + // However, this means that users need to take care in deciding what tables get marked as + // implicit. + let is_visible_std_table = !(table.implicit && children.is_empty()); + + if path.is_empty() { + // don't print header for the root node + if !children.is_empty() { + *first_table = false; + } + } else if is_array_of_tables { + let default_decor = if *first_table { + *first_table = false; + ("", DEFAULT_TABLE_DECOR.1) + } else { + DEFAULT_TABLE_DECOR + }; + table.decor.prefix_encode(buf, input, default_decor.0)?; + write!(buf, "[[")?; + path.encode(buf, input, DEFAULT_KEY_PATH_DECOR)?; + write!(buf, "]]")?; + table.decor.suffix_encode(buf, input, default_decor.1)?; + writeln!(buf)?; + } else if is_visible_std_table { + let default_decor = if *first_table { + *first_table = false; + ("", DEFAULT_TABLE_DECOR.1) + } else { + DEFAULT_TABLE_DECOR + }; + table.decor.prefix_encode(buf, input, default_decor.0)?; + write!(buf, "[")?; + path.encode(buf, input, DEFAULT_KEY_PATH_DECOR)?; + write!(buf, "]")?; + table.decor.suffix_encode(buf, input, default_decor.1)?; + writeln!(buf)?; + } + // print table body + for (key_path, value) in children { + key_path.as_slice().encode(buf, input, DEFAULT_KEY_DECOR)?; + write!(buf, "=")?; + value.encode(buf, input, DEFAULT_VALUE_DECOR)?; + writeln!(buf)?; + } + Ok(()) +} + +impl ValueRepr for String { + fn to_repr(&self) -> Repr { + to_string_repr(self, None, None) + } +} + +pub(crate) fn to_string_repr( + value: &str, + style: Option<StringStyle>, + literal: Option<bool>, +) -> Repr { + let (style, literal) = match (style, literal) { + (Some(style), Some(literal)) => (style, literal), + (_, Some(literal)) => (infer_style(value).0, literal), + (Some(style), _) => (style, infer_style(value).1), + (_, _) => infer_style(value), + }; + + let mut output = String::with_capacity(value.len() * 2); + if literal { + output.push_str(style.literal_start()); + output.push_str(value); + output.push_str(style.literal_end()); + } else { + output.push_str(style.standard_start()); + for ch in value.chars() { + match ch { + '\u{8}' => output.push_str("\\b"), + '\u{9}' => output.push_str("\\t"), + '\u{a}' => match style { + StringStyle::NewlineTripple => output.push('\n'), + StringStyle::OnelineSingle => output.push_str("\\n"), + _ => unreachable!(), + }, + '\u{c}' => output.push_str("\\f"), + '\u{d}' => output.push_str("\\r"), + '\u{22}' => output.push_str("\\\""), + '\u{5c}' => output.push_str("\\\\"), + c if c <= '\u{1f}' || c == '\u{7f}' => { + write!(output, "\\u{:04X}", ch as u32).unwrap(); + } + ch => output.push(ch), + } + } + output.push_str(style.standard_end()); + } + + Repr::new_unchecked(output) +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub(crate) enum StringStyle { + NewlineTripple, + OnelineTripple, + OnelineSingle, +} + +impl StringStyle { + fn literal_start(self) -> &'static str { + match self { + Self::NewlineTripple => "'''\n", + Self::OnelineTripple => "'''", + Self::OnelineSingle => "'", + } + } + fn literal_end(self) -> &'static str { + match self { + Self::NewlineTripple => "'''", + Self::OnelineTripple => "'''", + Self::OnelineSingle => "'", + } + } + + fn standard_start(self) -> &'static str { + match self { + Self::NewlineTripple => "\"\"\"\n", + // note: OnelineTripple can happen if do_pretty wants to do + // '''it's one line''' + // but literal == false + Self::OnelineTripple | Self::OnelineSingle => "\"", + } + } + + fn standard_end(self) -> &'static str { + match self { + Self::NewlineTripple => "\"\"\"", + // note: OnelineTripple can happen if do_pretty wants to do + // '''it's one line''' + // but literal == false + Self::OnelineTripple | Self::OnelineSingle => "\"", + } + } +} + +fn infer_style(value: &str) -> (StringStyle, bool) { + // For doing pretty prints we store in a new String + // because there are too many cases where pretty cannot + // work. We need to determine: + // - if we are a "multi-line" pretty (if there are \n) + // - if ['''] appears if multi or ['] if single + // - if there are any invalid control characters + // + // Doing it any other way would require multiple passes + // to determine if a pretty string works or not. + let mut out = String::with_capacity(value.len() * 2); + let mut ty = StringStyle::OnelineSingle; + // found consecutive single quotes + let mut max_found_singles = 0; + let mut found_singles = 0; + let mut prefer_literal = false; + let mut can_be_pretty = true; + + for ch in value.chars() { + if can_be_pretty { + if ch == '\'' { + found_singles += 1; + if found_singles >= 3 { + can_be_pretty = false; + } + } else { + if found_singles > max_found_singles { + max_found_singles = found_singles; + } + found_singles = 0 + } + match ch { + '\t' => {} + '\\' => { + prefer_literal = true; + } + '\n' => ty = StringStyle::NewlineTripple, + // Escape codes are needed if any ascii control + // characters are present, including \b \f \r. + c if c <= '\u{1f}' || c == '\u{7f}' => can_be_pretty = false, + _ => {} + } + out.push(ch); + } else { + // the string cannot be represented as pretty, + // still check if it should be multiline + if ch == '\n' { + ty = StringStyle::NewlineTripple; + } + } + } + if found_singles > 0 && value.ends_with('\'') { + // We cannot escape the ending quote so we must use """ + can_be_pretty = false; + } + if !prefer_literal { + can_be_pretty = false; + } + if !can_be_pretty { + debug_assert!(ty != StringStyle::OnelineTripple); + return (ty, false); + } + if found_singles > max_found_singles { + max_found_singles = found_singles; + } + debug_assert!(max_found_singles < 3); + if ty == StringStyle::OnelineSingle && max_found_singles >= 1 { + // no newlines, but must use ''' because it has ' in it + ty = StringStyle::OnelineTripple; + } + (ty, true) +} + +impl ValueRepr for i64 { + fn to_repr(&self) -> Repr { + Repr::new_unchecked(self.to_string()) + } +} + +impl ValueRepr for f64 { + fn to_repr(&self) -> Repr { + to_f64_repr(*self) + } +} + +fn to_f64_repr(f: f64) -> Repr { + let repr = match (f.is_sign_negative(), f.is_nan(), f == 0.0) { + (true, true, _) => "-nan".to_owned(), + (false, true, _) => "nan".to_owned(), + (true, false, true) => "-0.0".to_owned(), + (false, false, true) => "0.0".to_owned(), + (_, false, false) => { + if f % 1.0 == 0.0 { + format!("{}.0", f) + } else { + format!("{}", f) + } + } + }; + Repr::new_unchecked(repr) +} + +impl ValueRepr for bool { + fn to_repr(&self) -> Repr { + Repr::new_unchecked(self.to_string()) + } +} + +impl ValueRepr for Datetime { + fn to_repr(&self) -> Repr { + Repr::new_unchecked(self.to_string()) + } +} diff --git a/vendor/toml_edit/src/index.rs b/vendor/toml_edit/src/index.rs new file mode 100644 index 000000000..276db7957 --- /dev/null +++ b/vendor/toml_edit/src/index.rs @@ -0,0 +1,156 @@ +use std::ops; + +use crate::document::Document; +use crate::key::Key; +use crate::table::TableKeyValue; +use crate::{value, InlineTable, InternalString, Item, Table, Value}; + +// copied from +// https://github.com/serde-rs/json/blob/master/src/value/index.rs + +pub trait Index: crate::private::Sealed { + #[doc(hidden)] + fn index<'v>(&self, val: &'v Item) -> Option<&'v Item>; + #[doc(hidden)] + fn index_mut<'v>(&self, val: &'v mut Item) -> Option<&'v mut Item>; +} + +impl Index for usize { + fn index<'v>(&self, v: &'v Item) -> Option<&'v Item> { + match *v { + Item::ArrayOfTables(ref aot) => aot.values.get(*self), + Item::Value(ref a) if a.is_array() => a.as_array().and_then(|a| a.values.get(*self)), + _ => None, + } + } + fn index_mut<'v>(&self, v: &'v mut Item) -> Option<&'v mut Item> { + match *v { + Item::ArrayOfTables(ref mut vec) => vec.values.get_mut(*self), + Item::Value(ref mut a) => a.as_array_mut().and_then(|a| a.values.get_mut(*self)), + _ => None, + } + } +} + +impl Index for str { + fn index<'v>(&self, v: &'v Item) -> Option<&'v Item> { + match *v { + Item::Table(ref t) => t.get(self), + Item::Value(ref v) => v + .as_inline_table() + .and_then(|t| t.items.get(self)) + .and_then(|kv| { + if !kv.value.is_none() { + Some(&kv.value) + } else { + None + } + }), + _ => None, + } + } + fn index_mut<'v>(&self, v: &'v mut Item) -> Option<&'v mut Item> { + if let Item::None = *v { + let mut t = InlineTable::default(); + t.items.insert( + InternalString::from(self), + TableKeyValue::new(Key::new(self), Item::None), + ); + *v = value(Value::InlineTable(t)); + } + match *v { + Item::Table(ref mut t) => Some(t.entry(self).or_insert(Item::None)), + Item::Value(ref mut v) => v.as_inline_table_mut().map(|t| { + &mut t + .items + .entry(InternalString::from(self)) + .or_insert_with(|| TableKeyValue::new(Key::new(self), Item::None)) + .value + }), + _ => None, + } + } +} + +impl Index for String { + fn index<'v>(&self, v: &'v Item) -> Option<&'v Item> { + self[..].index(v) + } + fn index_mut<'v>(&self, v: &'v mut Item) -> Option<&'v mut Item> { + self[..].index_mut(v) + } +} + +impl<'a, T: ?Sized> Index for &'a T +where + T: Index, +{ + fn index<'v>(&self, v: &'v Item) -> Option<&'v Item> { + (**self).index(v) + } + fn index_mut<'v>(&self, v: &'v mut Item) -> Option<&'v mut Item> { + (**self).index_mut(v) + } +} + +impl<I> ops::Index<I> for Item +where + I: Index, +{ + type Output = Item; + + fn index(&self, index: I) -> &Item { + index.index(self).expect("index not found") + } +} + +impl<I> ops::IndexMut<I> for Item +where + I: Index, +{ + fn index_mut(&mut self, index: I) -> &mut Item { + index.index_mut(self).expect("index not found") + } +} + +impl<'s> ops::Index<&'s str> for Table { + type Output = Item; + + fn index(&self, key: &'s str) -> &Item { + self.get(key).expect("index not found") + } +} + +impl<'s> ops::IndexMut<&'s str> for Table { + fn index_mut(&mut self, key: &'s str) -> &mut Item { + self.entry(key).or_insert(Item::None) + } +} + +impl<'s> ops::Index<&'s str> for InlineTable { + type Output = Value; + + fn index(&self, key: &'s str) -> &Value { + self.get(key).expect("index not found") + } +} + +impl<'s> ops::IndexMut<&'s str> for InlineTable { + fn index_mut(&mut self, key: &'s str) -> &mut Value { + self.get_mut(key).expect("index not found") + } +} + +impl<'s> ops::Index<&'s str> for Document { + type Output = Item; + + fn index(&self, key: &'s str) -> &Item { + self.root.index(key) + } +} + +impl<'s> ops::IndexMut<&'s str> for Document { + fn index_mut(&mut self, key: &'s str) -> &mut Item { + self.root.index_mut(key) + } +} diff --git a/vendor/toml_edit/src/inline_table.rs b/vendor/toml_edit/src/inline_table.rs new file mode 100644 index 000000000..9327818e6 --- /dev/null +++ b/vendor/toml_edit/src/inline_table.rs @@ -0,0 +1,661 @@ +use std::iter::FromIterator; + +use crate::key::Key; +use crate::repr::Decor; +use crate::table::{Iter, IterMut, KeyValuePairs, TableKeyValue, TableLike}; +use crate::{InternalString, Item, KeyMut, RawString, Table, Value}; + +/// Type representing a TOML inline table, +/// payload of the `Value::InlineTable` variant +#[derive(Debug, Default, Clone)] +pub struct InlineTable { + // `preamble` represents whitespaces in an empty table + preamble: RawString, + // prefix before `{` and suffix after `}` + decor: Decor, + pub(crate) span: Option<std::ops::Range<usize>>, + // whether this is a proxy for dotted keys + dotted: bool, + pub(crate) items: KeyValuePairs, +} + +/// Constructors +/// +/// See also `FromIterator` +impl InlineTable { + /// Creates an empty table. + pub fn new() -> Self { + Default::default() + } + + pub(crate) fn with_pairs(items: KeyValuePairs) -> Self { + Self { + items, + ..Default::default() + } + } + + /// Convert to a table + pub fn into_table(self) -> Table { + let mut t = Table::with_pairs(self.items); + t.fmt(); + t + } +} + +/// Formatting +impl InlineTable { + /// Get key/values for values that are visually children of this table + /// + /// For example, this will return dotted keys + pub fn get_values(&self) -> Vec<(Vec<&Key>, &Value)> { + let mut values = Vec::new(); + let root = Vec::new(); + self.append_values(&root, &mut values); + values + } + + pub(crate) fn append_values<'s, 'c>( + &'s self, + parent: &[&'s Key], + values: &'c mut Vec<(Vec<&'s Key>, &'s Value)>, + ) { + for value in self.items.values() { + let mut path = parent.to_vec(); + path.push(&value.key); + match &value.value { + Item::Value(Value::InlineTable(table)) if table.is_dotted() => { + table.append_values(&path, values); + } + Item::Value(value) => { + values.push((path, value)); + } + _ => {} + } + } + } + + /// Auto formats the table. + pub fn fmt(&mut self) { + decorate_inline_table(self); + } + + /// Sorts the key/value pairs by key. + pub fn sort_values(&mut self) { + // Assuming standard tables have their position set and this won't negatively impact them + self.items.sort_keys(); + for kv in self.items.values_mut() { + match &mut kv.value { + Item::Value(Value::InlineTable(table)) if table.is_dotted() => { + table.sort_values(); + } + _ => {} + } + } + } + + /// Sort Key/Value Pairs of the table using the using the comparison function `compare`. + /// + /// The comparison function receives two key and value pairs to compare (you can sort by keys or + /// values or their combination as needed). + pub fn sort_values_by<F>(&mut self, mut compare: F) + where + F: FnMut(&Key, &Value, &Key, &Value) -> std::cmp::Ordering, + { + self.sort_values_by_internal(&mut compare); + } + + fn sort_values_by_internal<F>(&mut self, compare: &mut F) + where + F: FnMut(&Key, &Value, &Key, &Value) -> std::cmp::Ordering, + { + let modified_cmp = |_: &InternalString, + val1: &TableKeyValue, + _: &InternalString, + val2: &TableKeyValue| + -> std::cmp::Ordering { + match (val1.value.as_value(), val2.value.as_value()) { + (Some(v1), Some(v2)) => compare(&val1.key, v1, &val2.key, v2), + (Some(_), None) => std::cmp::Ordering::Greater, + (None, Some(_)) => std::cmp::Ordering::Less, + (None, None) => std::cmp::Ordering::Equal, + } + }; + + self.items.sort_by(modified_cmp); + for kv in self.items.values_mut() { + match &mut kv.value { + Item::Value(Value::InlineTable(table)) if table.is_dotted() => { + table.sort_values_by_internal(compare); + } + _ => {} + } + } + } + + /// Change this table's dotted status + pub fn set_dotted(&mut self, yes: bool) { + self.dotted = yes; + } + + /// Check if this is a wrapper for dotted keys, rather than a standard table + pub fn is_dotted(&self) -> bool { + self.dotted + } + + /// Returns the surrounding whitespace + pub fn decor_mut(&mut self) -> &mut Decor { + &mut self.decor + } + + /// Returns the surrounding whitespace + pub fn decor(&self) -> &Decor { + &self.decor + } + + /// Returns the decor associated with a given key of the table. + pub fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor> { + self.items.get_mut(key).map(|kv| &mut kv.key.decor) + } + + /// Returns the decor associated with a given key of the table. + pub fn key_decor(&self, key: &str) -> Option<&Decor> { + self.items.get(key).map(|kv| &kv.key.decor) + } + + /// Set whitespace after before element + pub fn set_preamble(&mut self, preamble: impl Into<RawString>) { + self.preamble = preamble.into(); + } + + /// Whitespace after before element + pub fn preamble(&self) -> &RawString { + &self.preamble + } + + /// Returns the location within the original document + pub(crate) fn span(&self) -> Option<std::ops::Range<usize>> { + self.span.clone() + } + + pub(crate) fn despan(&mut self, input: &str) { + self.span = None; + self.decor.despan(input); + self.preamble.despan(input); + for kv in self.items.values_mut() { + kv.key.despan(input); + kv.value.despan(input); + } + } +} + +impl InlineTable { + /// Returns an iterator over key/value pairs. + pub fn iter(&self) -> InlineTableIter<'_> { + Box::new( + self.items + .iter() + .filter(|&(_, kv)| kv.value.is_value()) + .map(|(k, kv)| (&k[..], kv.value.as_value().unwrap())), + ) + } + + /// Returns an iterator over key/value pairs. + pub fn iter_mut(&mut self) -> InlineTableIterMut<'_> { + Box::new( + self.items + .iter_mut() + .filter(|(_, kv)| kv.value.is_value()) + .map(|(_, kv)| (kv.key.as_mut(), kv.value.as_value_mut().unwrap())), + ) + } + + /// Returns the number of key/value pairs. + pub fn len(&self) -> usize { + self.iter().count() + } + + /// Returns true iff the table is empty. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Clears the table, removing all key-value pairs. Keeps the allocated memory for reuse. + pub fn clear(&mut self) { + self.items.clear() + } + + /// Gets the given key's corresponding entry in the Table for in-place manipulation. + pub fn entry(&'_ mut self, key: impl Into<InternalString>) -> InlineEntry<'_> { + match self.items.entry(key.into()) { + indexmap::map::Entry::Occupied(mut entry) => { + // Ensure it is a `Value` to simplify `InlineOccupiedEntry`'s code. + let scratch = std::mem::take(&mut entry.get_mut().value); + let scratch = Item::Value( + scratch + .into_value() + // HACK: `Item::None` is a corner case of a corner case, let's just pick a + // "safe" value + .unwrap_or_else(|_| Value::InlineTable(Default::default())), + ); + entry.get_mut().value = scratch; + + InlineEntry::Occupied(InlineOccupiedEntry { entry }) + } + indexmap::map::Entry::Vacant(entry) => { + InlineEntry::Vacant(InlineVacantEntry { entry, key: None }) + } + } + } + + /// Gets the given key's corresponding entry in the Table for in-place manipulation. + pub fn entry_format<'a>(&'a mut self, key: &Key) -> InlineEntry<'a> { + // Accept a `&Key` to be consistent with `entry` + match self.items.entry(key.get().into()) { + indexmap::map::Entry::Occupied(mut entry) => { + // Ensure it is a `Value` to simplify `InlineOccupiedEntry`'s code. + let scratch = std::mem::take(&mut entry.get_mut().value); + let scratch = Item::Value( + scratch + .into_value() + // HACK: `Item::None` is a corner case of a corner case, let's just pick a + // "safe" value + .unwrap_or_else(|_| Value::InlineTable(Default::default())), + ); + entry.get_mut().value = scratch; + + InlineEntry::Occupied(InlineOccupiedEntry { entry }) + } + indexmap::map::Entry::Vacant(entry) => InlineEntry::Vacant(InlineVacantEntry { + entry, + key: Some(key.clone()), + }), + } + } + /// Return an optional reference to the value at the given the key. + pub fn get(&self, key: &str) -> Option<&Value> { + self.items.get(key).and_then(|kv| kv.value.as_value()) + } + + /// Return an optional mutable reference to the value at the given the key. + pub fn get_mut(&mut self, key: &str) -> Option<&mut Value> { + self.items + .get_mut(key) + .and_then(|kv| kv.value.as_value_mut()) + } + + /// Return references to the key-value pair stored for key, if it is present, else None. + pub fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> { + self.items.get(key).and_then(|kv| { + if !kv.value.is_none() { + Some((&kv.key, &kv.value)) + } else { + None + } + }) + } + + /// Return mutable references to the key-value pair stored for key, if it is present, else None. + pub fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> { + self.items.get_mut(key).and_then(|kv| { + if !kv.value.is_none() { + Some((kv.key.as_mut(), &mut kv.value)) + } else { + None + } + }) + } + + /// Returns true iff the table contains given key. + pub fn contains_key(&self, key: &str) -> bool { + if let Some(kv) = self.items.get(key) { + kv.value.is_value() + } else { + false + } + } + + /// Inserts a key/value pair if the table does not contain the key. + /// Returns a mutable reference to the corresponding value. + pub fn get_or_insert<V: Into<Value>>( + &mut self, + key: impl Into<InternalString>, + value: V, + ) -> &mut Value { + let key = key.into(); + self.items + .entry(key.clone()) + .or_insert(TableKeyValue::new(Key::new(key), Item::Value(value.into()))) + .value + .as_value_mut() + .expect("non-value type in inline table") + } + + /// Inserts a key-value pair into the map. + pub fn insert(&mut self, key: impl Into<InternalString>, value: Value) -> Option<Value> { + let key = key.into(); + let kv = TableKeyValue::new(Key::new(key.clone()), Item::Value(value)); + self.items + .insert(key, kv) + .and_then(|kv| kv.value.into_value().ok()) + } + + /// Inserts a key-value pair into the map. + pub fn insert_formatted(&mut self, key: &Key, value: Value) -> Option<Value> { + let kv = TableKeyValue::new(key.to_owned(), Item::Value(value)); + self.items + .insert(InternalString::from(key.get()), kv) + .filter(|kv| kv.value.is_value()) + .map(|kv| kv.value.into_value().unwrap()) + } + + /// Removes an item given the key. + pub fn remove(&mut self, key: &str) -> Option<Value> { + self.items + .shift_remove(key) + .and_then(|kv| kv.value.into_value().ok()) + } + + /// Removes a key from the map, returning the stored key and value if the key was previously in the map. + pub fn remove_entry(&mut self, key: &str) -> Option<(Key, Value)> { + self.items.shift_remove(key).and_then(|kv| { + let key = kv.key; + kv.value.into_value().ok().map(|value| (key, value)) + }) + } +} + +impl std::fmt::Display for InlineTable { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + crate::encode::Encode::encode(self, f, None, ("", "")) + } +} + +impl<K: Into<Key>, V: Into<Value>> Extend<(K, V)> for InlineTable { + fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) { + for (key, value) in iter { + let key = key.into(); + let value = Item::Value(value.into()); + let value = TableKeyValue::new(key, value); + self.items + .insert(InternalString::from(value.key.get()), value); + } + } +} + +impl<K: Into<Key>, V: Into<Value>> FromIterator<(K, V)> for InlineTable { + fn from_iter<I>(iter: I) -> Self + where + I: IntoIterator<Item = (K, V)>, + { + let mut table = InlineTable::new(); + table.extend(iter); + table + } +} + +impl IntoIterator for InlineTable { + type Item = (InternalString, Value); + type IntoIter = InlineTableIntoIter; + + fn into_iter(self) -> Self::IntoIter { + Box::new( + self.items + .into_iter() + .filter(|(_, kv)| kv.value.is_value()) + .map(|(k, kv)| (k, kv.value.into_value().unwrap())), + ) + } +} + +impl<'s> IntoIterator for &'s InlineTable { + type Item = (&'s str, &'s Value); + type IntoIter = InlineTableIter<'s>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +fn decorate_inline_table(table: &mut InlineTable) { + for (key_decor, value) in table + .items + .iter_mut() + .filter(|&(_, ref kv)| kv.value.is_value()) + .map(|(_, kv)| (&mut kv.key.decor, kv.value.as_value_mut().unwrap())) + { + key_decor.clear(); + value.decor_mut().clear(); + } +} + +/// An owned iterator type over key/value pairs of an inline table. +pub type InlineTableIntoIter = Box<dyn Iterator<Item = (InternalString, Value)>>; +/// An iterator type over key/value pairs of an inline table. +pub type InlineTableIter<'a> = Box<dyn Iterator<Item = (&'a str, &'a Value)> + 'a>; +/// A mutable iterator type over key/value pairs of an inline table. +pub type InlineTableIterMut<'a> = Box<dyn Iterator<Item = (KeyMut<'a>, &'a mut Value)> + 'a>; + +impl TableLike for InlineTable { + fn iter(&self) -> Iter<'_> { + Box::new(self.items.iter().map(|(key, kv)| (&key[..], &kv.value))) + } + fn iter_mut(&mut self) -> IterMut<'_> { + Box::new( + self.items + .iter_mut() + .map(|(_, kv)| (kv.key.as_mut(), &mut kv.value)), + ) + } + fn clear(&mut self) { + self.clear(); + } + fn entry<'a>(&'a mut self, key: &str) -> crate::Entry<'a> { + // Accept a `&str` rather than an owned type to keep `InternalString`, well, internal + match self.items.entry(key.into()) { + indexmap::map::Entry::Occupied(entry) => { + crate::Entry::Occupied(crate::OccupiedEntry { entry }) + } + indexmap::map::Entry::Vacant(entry) => { + crate::Entry::Vacant(crate::VacantEntry { entry, key: None }) + } + } + } + fn entry_format<'a>(&'a mut self, key: &Key) -> crate::Entry<'a> { + // Accept a `&Key` to be consistent with `entry` + match self.items.entry(key.get().into()) { + indexmap::map::Entry::Occupied(entry) => { + crate::Entry::Occupied(crate::OccupiedEntry { entry }) + } + indexmap::map::Entry::Vacant(entry) => crate::Entry::Vacant(crate::VacantEntry { + entry, + key: Some(key.to_owned()), + }), + } + } + fn get<'s>(&'s self, key: &str) -> Option<&'s Item> { + self.items.get(key).map(|kv| &kv.value) + } + fn get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item> { + self.items.get_mut(key).map(|kv| &mut kv.value) + } + fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> { + self.get_key_value(key) + } + fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> { + self.get_key_value_mut(key) + } + fn contains_key(&self, key: &str) -> bool { + self.contains_key(key) + } + fn insert(&mut self, key: &str, value: Item) -> Option<Item> { + self.insert(key, value.into_value().unwrap()) + .map(Item::Value) + } + fn remove(&mut self, key: &str) -> Option<Item> { + self.remove(key).map(Item::Value) + } + + fn get_values(&self) -> Vec<(Vec<&Key>, &Value)> { + self.get_values() + } + fn fmt(&mut self) { + self.fmt() + } + fn sort_values(&mut self) { + self.sort_values() + } + fn set_dotted(&mut self, yes: bool) { + self.set_dotted(yes) + } + fn is_dotted(&self) -> bool { + self.is_dotted() + } + + fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor> { + self.key_decor_mut(key) + } + fn key_decor(&self, key: &str) -> Option<&Decor> { + self.key_decor(key) + } +} + +// `{ key1 = value1, ... }` +pub(crate) const DEFAULT_INLINE_KEY_DECOR: (&str, &str) = (" ", " "); + +/// A view into a single location in a map, which may be vacant or occupied. +pub enum InlineEntry<'a> { + /// An occupied Entry. + Occupied(InlineOccupiedEntry<'a>), + /// A vacant Entry. + Vacant(InlineVacantEntry<'a>), +} + +impl<'a> InlineEntry<'a> { + /// Returns the entry key + /// + /// # Examples + /// + /// ``` + /// use toml_edit::Table; + /// + /// let mut map = Table::new(); + /// + /// assert_eq!("hello", map.entry("hello").key()); + /// ``` + pub fn key(&self) -> &str { + match self { + InlineEntry::Occupied(e) => e.key(), + InlineEntry::Vacant(e) => e.key(), + } + } + + /// Ensures a value is in the entry by inserting the default if empty, and returns + /// a mutable reference to the value in the entry. + pub fn or_insert(self, default: Value) -> &'a mut Value { + match self { + InlineEntry::Occupied(entry) => entry.into_mut(), + InlineEntry::Vacant(entry) => entry.insert(default), + } + } + + /// Ensures a value is in the entry by inserting the result of the default function if empty, + /// and returns a mutable reference to the value in the entry. + pub fn or_insert_with<F: FnOnce() -> Value>(self, default: F) -> &'a mut Value { + match self { + InlineEntry::Occupied(entry) => entry.into_mut(), + InlineEntry::Vacant(entry) => entry.insert(default()), + } + } +} + +/// A view into a single occupied location in a `IndexMap`. +pub struct InlineOccupiedEntry<'a> { + entry: indexmap::map::OccupiedEntry<'a, InternalString, TableKeyValue>, +} + +impl<'a> InlineOccupiedEntry<'a> { + /// Gets a reference to the entry key + /// + /// # Examples + /// + /// ``` + /// use toml_edit::Table; + /// + /// let mut map = Table::new(); + /// + /// assert_eq!("foo", map.entry("foo").key()); + /// ``` + pub fn key(&self) -> &str { + self.entry.key().as_str() + } + + /// Gets a mutable reference to the entry key + pub fn key_mut(&mut self) -> KeyMut<'_> { + self.entry.get_mut().key.as_mut() + } + + /// Gets a reference to the value in the entry. + pub fn get(&self) -> &Value { + self.entry.get().value.as_value().unwrap() + } + + /// Gets a mutable reference to the value in the entry. + pub fn get_mut(&mut self) -> &mut Value { + self.entry.get_mut().value.as_value_mut().unwrap() + } + + /// Converts the OccupiedEntry into a mutable reference to the value in the entry + /// with a lifetime bound to the map itself + pub fn into_mut(self) -> &'a mut Value { + self.entry.into_mut().value.as_value_mut().unwrap() + } + + /// Sets the value of the entry, and returns the entry's old value + pub fn insert(&mut self, value: Value) -> Value { + let mut value = Item::Value(value); + std::mem::swap(&mut value, &mut self.entry.get_mut().value); + value.into_value().unwrap() + } + + /// Takes the value out of the entry, and returns it + pub fn remove(self) -> Value { + self.entry.shift_remove().value.into_value().unwrap() + } +} + +/// A view into a single empty location in a `IndexMap`. +pub struct InlineVacantEntry<'a> { + entry: indexmap::map::VacantEntry<'a, InternalString, TableKeyValue>, + key: Option<Key>, +} + +impl<'a> InlineVacantEntry<'a> { + /// Gets a reference to the entry key + /// + /// # Examples + /// + /// ``` + /// use toml_edit::Table; + /// + /// let mut map = Table::new(); + /// + /// assert_eq!("foo", map.entry("foo").key()); + /// ``` + pub fn key(&self) -> &str { + self.entry.key().as_str() + } + + /// Sets the value of the entry with the VacantEntry's key, + /// and returns a mutable reference to it + pub fn insert(self, value: Value) -> &'a mut Value { + let entry = self.entry; + let key = self.key.unwrap_or_else(|| Key::new(entry.key().as_str())); + let value = Item::Value(value); + entry + .insert(TableKeyValue::new(key, value)) + .value + .as_value_mut() + .unwrap() + } +} diff --git a/vendor/toml_edit/src/internal_string.rs b/vendor/toml_edit/src/internal_string.rs new file mode 100644 index 000000000..d4347d25b --- /dev/null +++ b/vendor/toml_edit/src/internal_string.rs @@ -0,0 +1,183 @@ +use std::borrow::Borrow; +use std::str::FromStr; + +/// Opaque string storage internal to `toml_edit` +#[derive(Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct InternalString(Inner); + +#[cfg(feature = "kstring")] +type Inner = kstring::KString; +#[cfg(not(feature = "kstring"))] +type Inner = String; + +impl InternalString { + /// Create an empty string + pub fn new() -> Self { + InternalString(Inner::new()) + } + + /// Access the underlying string + #[inline] + pub fn as_str(&self) -> &str { + self.0.as_str() + } +} + +impl std::fmt::Debug for InternalString { + #[inline] + fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + self.0.fmt(formatter) + } +} + +impl std::ops::Deref for InternalString { + type Target = str; + + #[inline] + fn deref(&self) -> &str { + self.as_str() + } +} + +impl Borrow<str> for InternalString { + #[inline] + fn borrow(&self) -> &str { + self.as_str() + } +} + +impl AsRef<str> for InternalString { + #[inline] + fn as_ref(&self) -> &str { + self.as_str() + } +} + +impl From<&str> for InternalString { + #[inline] + fn from(s: &str) -> Self { + #[cfg(feature = "kstring")] + let inner = kstring::KString::from_ref(s); + #[cfg(not(feature = "kstring"))] + let inner = String::from(s); + + InternalString(inner) + } +} + +impl From<String> for InternalString { + #[inline] + fn from(s: String) -> Self { + #[allow(clippy::useless_conversion)] // handle any string type + InternalString(s.into()) + } +} + +impl From<&String> for InternalString { + #[inline] + fn from(s: &String) -> Self { + InternalString(s.into()) + } +} + +impl From<&InternalString> for InternalString { + #[inline] + fn from(s: &InternalString) -> Self { + s.clone() + } +} + +impl From<Box<str>> for InternalString { + #[inline] + fn from(s: Box<str>) -> Self { + InternalString(s.into()) + } +} + +impl FromStr for InternalString { + type Err = core::convert::Infallible; + #[inline] + fn from_str(s: &str) -> Result<Self, Self::Err> { + Ok(Self::from(s)) + } +} + +impl std::fmt::Display for InternalString { + #[inline] + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.as_str().fmt(f) + } +} + +#[cfg(feature = "serde")] +impl serde::Serialize for InternalString { + #[inline] + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: serde::Serializer, + { + serializer.serialize_str(self.as_str()) + } +} + +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for InternalString { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: serde::Deserializer<'de>, + { + deserializer.deserialize_string(StringVisitor) + } +} + +#[cfg(feature = "serde")] +struct StringVisitor; + +#[cfg(feature = "serde")] +impl<'de> serde::de::Visitor<'de> for StringVisitor { + type Value = InternalString; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("a string") + } + + fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> + where + E: serde::de::Error, + { + Ok(InternalString::from(v)) + } + + fn visit_string<E>(self, v: String) -> Result<Self::Value, E> + where + E: serde::de::Error, + { + Ok(InternalString::from(v)) + } + + fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> + where + E: serde::de::Error, + { + match std::str::from_utf8(v) { + Ok(s) => Ok(InternalString::from(s)), + Err(_) => Err(serde::de::Error::invalid_value( + serde::de::Unexpected::Bytes(v), + &self, + )), + } + } + + fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E> + where + E: serde::de::Error, + { + match String::from_utf8(v) { + Ok(s) => Ok(InternalString::from(s)), + Err(e) => Err(serde::de::Error::invalid_value( + serde::de::Unexpected::Bytes(&e.into_bytes()), + &self, + )), + } + } +} diff --git a/vendor/toml_edit/src/item.rs b/vendor/toml_edit/src/item.rs new file mode 100644 index 000000000..48a1a3566 --- /dev/null +++ b/vendor/toml_edit/src/item.rs @@ -0,0 +1,381 @@ +use std::str::FromStr; + +use toml_datetime::*; + +use crate::array_of_tables::ArrayOfTables; +use crate::table::TableLike; +use crate::{Array, InlineTable, Table, Value}; + +/// Type representing either a value, a table, an array of tables, or none. +#[derive(Debug, Clone)] +pub enum Item { + /// Type representing none. + None, + /// Type representing value. + Value(Value), + /// Type representing table. + Table(Table), + /// Type representing array of tables. + ArrayOfTables(ArrayOfTables), +} + +impl Item { + /// Sets `self` to the given item iff `self` is none and + /// returns a mutable reference to `self`. + pub fn or_insert(&mut self, item: Item) -> &mut Item { + if self.is_none() { + *self = item + } + self + } +} + +// TODO: This should be generated by macro or derive +/// Downcasting +impl Item { + /// Text description of value type + pub fn type_name(&self) -> &'static str { + match self { + Item::None => "none", + Item::Value(v) => v.type_name(), + Item::Table(..) => "table", + Item::ArrayOfTables(..) => "array of tables", + } + } + + /// Index into a TOML array or map. A string index can be used to access a + /// value in a map, and a usize index can be used to access an element of an + /// array. + /// + /// Returns `None` if: + /// - The type of `self` does not match the type of the + /// index, for example if the index is a string and `self` is an array or a + /// number. + /// - The given key does not exist in the map + /// or the given index is not within the bounds of the array. + pub fn get<I: crate::index::Index>(&self, index: I) -> Option<&Item> { + index.index(self) + } + + /// Mutably index into a TOML array or map. A string index can be used to + /// access a value in a map, and a usize index can be used to access an + /// element of an array. + /// + /// Returns `None` if: + /// - The type of `self` does not match the type of the + /// index, for example if the index is a string and `self` is an array or a + /// number. + /// - The given key does not exist in the map + /// or the given index is not within the bounds of the array. + pub fn get_mut<I: crate::index::Index>(&mut self, index: I) -> Option<&mut Item> { + index.index_mut(self) + } + + /// Casts `self` to value. + pub fn as_value(&self) -> Option<&Value> { + match *self { + Item::Value(ref v) => Some(v), + _ => None, + } + } + /// Casts `self` to table. + pub fn as_table(&self) -> Option<&Table> { + match *self { + Item::Table(ref t) => Some(t), + _ => None, + } + } + /// Casts `self` to array of tables. + pub fn as_array_of_tables(&self) -> Option<&ArrayOfTables> { + match *self { + Item::ArrayOfTables(ref a) => Some(a), + _ => None, + } + } + /// Casts `self` to mutable value. + pub fn as_value_mut(&mut self) -> Option<&mut Value> { + match *self { + Item::Value(ref mut v) => Some(v), + _ => None, + } + } + /// Casts `self` to mutable table. + pub fn as_table_mut(&mut self) -> Option<&mut Table> { + match *self { + Item::Table(ref mut t) => Some(t), + _ => None, + } + } + /// Casts `self` to mutable array of tables. + pub fn as_array_of_tables_mut(&mut self) -> Option<&mut ArrayOfTables> { + match *self { + Item::ArrayOfTables(ref mut a) => Some(a), + _ => None, + } + } + /// Casts `self` to value. + pub fn into_value(self) -> Result<Value, Self> { + match self { + Item::None => Err(self), + Item::Value(v) => Ok(v), + Item::Table(v) => { + let v = v.into_inline_table(); + Ok(Value::InlineTable(v)) + } + Item::ArrayOfTables(v) => { + let v = v.into_array(); + Ok(Value::Array(v)) + } + } + } + /// In-place convert to a value + pub fn make_value(&mut self) { + let other = std::mem::take(self); + let other = other.into_value().map(Item::Value).unwrap_or(Item::None); + *self = other; + } + /// Casts `self` to table. + pub fn into_table(self) -> Result<Table, Self> { + match self { + Item::Table(t) => Ok(t), + Item::Value(Value::InlineTable(t)) => Ok(t.into_table()), + _ => Err(self), + } + } + /// Casts `self` to array of tables. + pub fn into_array_of_tables(self) -> Result<ArrayOfTables, Self> { + match self { + Item::ArrayOfTables(a) => Ok(a), + Item::Value(Value::Array(a)) => { + if a.is_empty() { + Err(Item::Value(Value::Array(a))) + } else if a.iter().all(|v| v.is_inline_table()) { + let mut aot = ArrayOfTables::new(); + aot.values = a.values; + for value in aot.values.iter_mut() { + value.make_item(); + } + Ok(aot) + } else { + Err(Item::Value(Value::Array(a))) + } + } + _ => Err(self), + } + } + // Starting private because the name is unclear + pub(crate) fn make_item(&mut self) { + let other = std::mem::take(self); + let other = match other.into_table().map(crate::Item::Table) { + Ok(i) => i, + Err(i) => i, + }; + let other = match other.into_array_of_tables().map(crate::Item::ArrayOfTables) { + Ok(i) => i, + Err(i) => i, + }; + *self = other; + } + /// Returns true iff `self` is a value. + pub fn is_value(&self) -> bool { + self.as_value().is_some() + } + /// Returns true iff `self` is a table. + pub fn is_table(&self) -> bool { + self.as_table().is_some() + } + /// Returns true iff `self` is an array of tables. + pub fn is_array_of_tables(&self) -> bool { + self.as_array_of_tables().is_some() + } + /// Returns true iff `self` is `None`. + pub fn is_none(&self) -> bool { + matches!(*self, Item::None) + } + + // Duplicate Value downcasting API + + /// Casts `self` to integer. + pub fn as_integer(&self) -> Option<i64> { + self.as_value().and_then(Value::as_integer) + } + + /// Returns true iff `self` is an integer. + pub fn is_integer(&self) -> bool { + self.as_integer().is_some() + } + + /// Casts `self` to float. + pub fn as_float(&self) -> Option<f64> { + self.as_value().and_then(Value::as_float) + } + + /// Returns true iff `self` is a float. + pub fn is_float(&self) -> bool { + self.as_float().is_some() + } + + /// Casts `self` to boolean. + pub fn as_bool(&self) -> Option<bool> { + self.as_value().and_then(Value::as_bool) + } + + /// Returns true iff `self` is a boolean. + pub fn is_bool(&self) -> bool { + self.as_bool().is_some() + } + + /// Casts `self` to str. + pub fn as_str(&self) -> Option<&str> { + self.as_value().and_then(Value::as_str) + } + + /// Returns true iff `self` is a string. + pub fn is_str(&self) -> bool { + self.as_str().is_some() + } + + /// Casts `self` to date-time. + pub fn as_datetime(&self) -> Option<&Datetime> { + self.as_value().and_then(Value::as_datetime) + } + + /// Returns true iff `self` is a date-time. + pub fn is_datetime(&self) -> bool { + self.as_datetime().is_some() + } + + /// Casts `self` to array. + pub fn as_array(&self) -> Option<&Array> { + self.as_value().and_then(Value::as_array) + } + + /// Casts `self` to mutable array. + pub fn as_array_mut(&mut self) -> Option<&mut Array> { + self.as_value_mut().and_then(Value::as_array_mut) + } + + /// Returns true iff `self` is an array. + pub fn is_array(&self) -> bool { + self.as_array().is_some() + } + + /// Casts `self` to inline table. + pub fn as_inline_table(&self) -> Option<&InlineTable> { + self.as_value().and_then(Value::as_inline_table) + } + + /// Casts `self` to mutable inline table. + pub fn as_inline_table_mut(&mut self) -> Option<&mut InlineTable> { + self.as_value_mut().and_then(Value::as_inline_table_mut) + } + + /// Returns true iff `self` is an inline table. + pub fn is_inline_table(&self) -> bool { + self.as_inline_table().is_some() + } + + /// Casts `self` to either a table or an inline table. + pub fn as_table_like(&self) -> Option<&dyn TableLike> { + self.as_table() + .map(|t| t as &dyn TableLike) + .or_else(|| self.as_inline_table().map(|t| t as &dyn TableLike)) + } + + /// Casts `self` to either a table or an inline table. + pub fn as_table_like_mut(&mut self) -> Option<&mut dyn TableLike> { + match self { + Item::Table(t) => Some(t as &mut dyn TableLike), + Item::Value(Value::InlineTable(t)) => Some(t as &mut dyn TableLike), + _ => None, + } + } + + /// Returns true iff `self` is either a table, or an inline table. + pub fn is_table_like(&self) -> bool { + self.as_table_like().is_some() + } + + /// Returns the location within the original document + pub(crate) fn span(&self) -> Option<std::ops::Range<usize>> { + match self { + Item::None => None, + Item::Value(v) => v.span(), + Item::Table(v) => v.span(), + Item::ArrayOfTables(v) => v.span(), + } + } + + pub(crate) fn despan(&mut self, input: &str) { + match self { + Item::None => {} + Item::Value(v) => v.despan(input), + Item::Table(v) => v.despan(input), + Item::ArrayOfTables(v) => v.despan(input), + } + } +} + +impl Default for Item { + fn default() -> Self { + Item::None + } +} + +impl FromStr for Item { + type Err = crate::TomlError; + + /// Parses a value from a &str + fn from_str(s: &str) -> Result<Self, Self::Err> { + let value = s.parse::<Value>()?; + Ok(Item::Value(value)) + } +} + +impl std::fmt::Display for Item { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match &self { + Item::None => Ok(()), + Item::Value(v) => v.fmt(f), + Item::Table(v) => v.fmt(f), + Item::ArrayOfTables(v) => v.fmt(f), + } + } +} + +/// Returns a formatted value. +/// +/// Since formatting is part of a `Value`, the right hand side of the +/// assignment needs to be decorated with a space before the value. +/// The `value` function does just that. +/// +/// # Examples +/// ```rust +/// # use snapbox::assert_eq; +/// # use toml_edit::*; +/// let mut table = Table::default(); +/// let mut array = Array::default(); +/// array.push("hello"); +/// array.push("\\, world"); // \ is only allowed in a literal string +/// table["key1"] = value("value1"); +/// table["key2"] = value(42); +/// table["key3"] = value(array); +/// assert_eq(table.to_string(), +/// r#"key1 = "value1" +/// key2 = 42 +/// key3 = ["hello", '\, world'] +/// "#); +/// ``` +pub fn value<V: Into<Value>>(v: V) -> Item { + Item::Value(v.into()) +} + +/// Returns an empty table. +pub fn table() -> Item { + Item::Table(Table::new()) +} + +/// Returns an empty array of tables. +pub fn array() -> Item { + Item::ArrayOfTables(ArrayOfTables::new()) +} diff --git a/vendor/toml_edit/src/key.rs b/vendor/toml_edit/src/key.rs new file mode 100644 index 000000000..203445a7b --- /dev/null +++ b/vendor/toml_edit/src/key.rs @@ -0,0 +1,327 @@ +use std::borrow::Cow; +use std::str::FromStr; + +use crate::encode::{to_string_repr, StringStyle}; +use crate::parser; +use crate::parser::key::is_unquoted_char; +use crate::repr::{Decor, Repr}; +use crate::InternalString; + +/// Key as part of a Key/Value Pair or a table header. +/// +/// # Examples +/// +/// ```notrust +/// [dependencies."nom"] +/// version = "5.0" +/// 'literal key' = "nonsense" +/// "basic string key" = 42 +/// ``` +/// +/// There are 3 types of keys: +/// +/// 1. Bare keys (`version` and `dependencies`) +/// +/// 2. Basic quoted keys (`"basic string key"` and `"nom"`) +/// +/// 3. Literal quoted keys (`'literal key'`) +/// +/// For details see [toml spec](https://github.com/toml-lang/toml/#keyvalue-pair). +/// +/// To parse a key use `FromStr` trait implementation: `"string".parse::<Key>()`. +#[derive(Debug, Clone)] +pub struct Key { + key: InternalString, + pub(crate) repr: Option<Repr>, + pub(crate) decor: Decor, +} + +impl Key { + /// Create a new table key + pub fn new(key: impl Into<InternalString>) -> Self { + Self { + key: key.into(), + repr: None, + decor: Default::default(), + } + } + + /// Parse a TOML key expression + /// + /// Unlike `"".parse<Key>()`, this supports dotted keys. + pub fn parse(repr: &str) -> Result<Vec<Self>, crate::TomlError> { + Self::try_parse_path(repr) + } + + pub(crate) fn with_repr_unchecked(mut self, repr: Repr) -> Self { + self.repr = Some(repr); + self + } + + /// While creating the `Key`, add `Decor` to it + pub fn with_decor(mut self, decor: Decor) -> Self { + self.decor = decor; + self + } + + /// Access a mutable proxy for the `Key`. + pub fn as_mut(&mut self) -> KeyMut<'_> { + KeyMut { key: self } + } + + /// Returns the parsed key value. + pub fn get(&self) -> &str { + &self.key + } + + pub(crate) fn get_internal(&self) -> &InternalString { + &self.key + } + + /// Returns key raw representation, if available. + pub fn as_repr(&self) -> Option<&Repr> { + self.repr.as_ref() + } + + /// Returns the default raw representation. + pub fn default_repr(&self) -> Repr { + to_key_repr(&self.key) + } + + /// Returns a raw representation. + pub fn display_repr(&self) -> Cow<'_, str> { + self.as_repr() + .and_then(|r| r.as_raw().as_str()) + .map(Cow::Borrowed) + .unwrap_or_else(|| { + Cow::Owned(self.default_repr().as_raw().as_str().unwrap().to_owned()) + }) + } + + /// Returns the surrounding whitespace + pub fn decor_mut(&mut self) -> &mut Decor { + &mut self.decor + } + + /// Returns the surrounding whitespace + pub fn decor(&self) -> &Decor { + &self.decor + } + + /// Returns the location within the original document + #[cfg(feature = "serde")] + pub(crate) fn span(&self) -> Option<std::ops::Range<usize>> { + self.repr.as_ref().and_then(|r| r.span()) + } + + pub(crate) fn despan(&mut self, input: &str) { + self.decor.despan(input); + if let Some(repr) = &mut self.repr { + repr.despan(input) + } + } + + /// Auto formats the key. + pub fn fmt(&mut self) { + self.repr = Some(to_key_repr(&self.key)); + self.decor.clear(); + } + + fn try_parse_simple(s: &str) -> Result<Key, crate::TomlError> { + parser::parse_key(s) + } + + fn try_parse_path(s: &str) -> Result<Vec<Key>, crate::TomlError> { + parser::parse_key_path(s) + } +} + +impl std::ops::Deref for Key { + type Target = str; + + fn deref(&self) -> &Self::Target { + self.get() + } +} + +impl std::hash::Hash for Key { + fn hash<H: std::hash::Hasher>(&self, state: &mut H) { + self.get().hash(state); + } +} + +impl Ord for Key { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.get().cmp(other.get()) + } +} + +impl PartialOrd for Key { + fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { + Some(self.cmp(other)) + } +} + +impl Eq for Key {} + +impl PartialEq for Key { + #[inline] + fn eq(&self, other: &Key) -> bool { + PartialEq::eq(self.get(), other.get()) + } +} + +impl PartialEq<str> for Key { + #[inline] + fn eq(&self, other: &str) -> bool { + PartialEq::eq(self.get(), other) + } +} + +impl<'s> PartialEq<&'s str> for Key { + #[inline] + fn eq(&self, other: &&str) -> bool { + PartialEq::eq(self.get(), *other) + } +} + +impl PartialEq<String> for Key { + #[inline] + fn eq(&self, other: &String) -> bool { + PartialEq::eq(self.get(), other.as_str()) + } +} + +impl std::fmt::Display for Key { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + crate::encode::Encode::encode(self, f, None, ("", "")) + } +} + +impl FromStr for Key { + type Err = crate::TomlError; + + /// Tries to parse a key from a &str, + /// if fails, tries as basic quoted key (surrounds with "") + /// and then literal quoted key (surrounds with '') + fn from_str(s: &str) -> Result<Self, Self::Err> { + Key::try_parse_simple(s) + } +} + +fn to_key_repr(key: &str) -> Repr { + if key.as_bytes().iter().copied().all(is_unquoted_char) && !key.is_empty() { + Repr::new_unchecked(key) + } else { + to_string_repr(key, Some(StringStyle::OnelineSingle), Some(false)) + } +} + +impl<'b> From<&'b str> for Key { + fn from(s: &'b str) -> Self { + Key::new(s) + } +} + +impl<'b> From<&'b String> for Key { + fn from(s: &'b String) -> Self { + Key::new(s) + } +} + +impl From<String> for Key { + fn from(s: String) -> Self { + Key::new(s) + } +} + +impl From<InternalString> for Key { + fn from(s: InternalString) -> Self { + Key::new(s) + } +} + +#[doc(hidden)] +impl From<Key> for InternalString { + fn from(key: Key) -> InternalString { + key.key + } +} + +/// A mutable reference to a `Key` +#[derive(Debug, Eq, PartialEq, PartialOrd, Ord, Hash)] +pub struct KeyMut<'k> { + key: &'k mut Key, +} + +impl<'k> KeyMut<'k> { + /// Returns the parsed key value. + pub fn get(&self) -> &str { + self.key.get() + } + + /// Returns the raw representation, if available. + pub fn as_repr(&self) -> Option<&Repr> { + self.key.as_repr() + } + + /// Returns the default raw representation. + pub fn default_repr(&self) -> Repr { + self.key.default_repr() + } + + /// Returns a raw representation. + pub fn display_repr(&self) -> Cow<str> { + self.key.display_repr() + } + + /// Returns the surrounding whitespace + pub fn decor_mut(&mut self) -> &mut Decor { + self.key.decor_mut() + } + + /// Returns the surrounding whitespace + pub fn decor(&self) -> &Decor { + self.key.decor() + } + + /// Auto formats the key. + pub fn fmt(&mut self) { + self.key.fmt() + } +} + +impl<'k> std::ops::Deref for KeyMut<'k> { + type Target = str; + + fn deref(&self) -> &Self::Target { + self.get() + } +} + +impl<'s> PartialEq<str> for KeyMut<'s> { + #[inline] + fn eq(&self, other: &str) -> bool { + PartialEq::eq(self.get(), other) + } +} + +impl<'s> PartialEq<&'s str> for KeyMut<'s> { + #[inline] + fn eq(&self, other: &&str) -> bool { + PartialEq::eq(self.get(), *other) + } +} + +impl<'s> PartialEq<String> for KeyMut<'s> { + #[inline] + fn eq(&self, other: &String) -> bool { + PartialEq::eq(self.get(), other.as_str()) + } +} + +impl<'k> std::fmt::Display for KeyMut<'k> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(&self.key, f) + } +} diff --git a/vendor/toml_edit/src/lib.rs b/vendor/toml_edit/src/lib.rs new file mode 100644 index 000000000..80c0ddda2 --- /dev/null +++ b/vendor/toml_edit/src/lib.rs @@ -0,0 +1,124 @@ +#![deny(missing_docs)] +// https://github.com/Marwes/combine/issues/172 +#![recursion_limit = "256"] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] + +//! # `toml_edit` +//! +//! This crate allows you to parse and modify toml +//! documents, while preserving comments, spaces *and +//! relative order* or items. +//! +//! If you also need the ease of a more traditional API, see the [`toml`] crate. +//! +//! # Example +//! +//! ```rust +//! use toml_edit::{Document, value}; +//! +//! let toml = r#" +//! "hello" = 'toml!' # comment +//! ['a'.b] +//! "#; +//! let mut doc = toml.parse::<Document>().expect("invalid doc"); +//! assert_eq!(doc.to_string(), toml); +//! // let's add a new key/value pair inside a.b: c = {d = "hello"} +//! doc["a"]["b"]["c"]["d"] = value("hello"); +//! // autoformat inline table a.b.c: { d = "hello" } +//! doc["a"]["b"]["c"].as_inline_table_mut().map(|t| t.fmt()); +//! let expected = r#" +//! "hello" = 'toml!' # comment +//! ['a'.b] +//! c = { d = "hello" } +//! "#; +//! assert_eq!(doc.to_string(), expected); +//! ``` +//! +//! ## Controlling formatting +//! +//! By default, values are created with default formatting +//! ```rust +//! let mut doc = toml_edit::Document::new(); +//! doc["foo"] = toml_edit::value("bar"); +//! let expected = r#"foo = "bar" +//! "#; +//! assert_eq!(doc.to_string(), expected); +//! ``` +//! +//! You can choose a custom TOML representation by parsing the value. +//! ```rust +//! let mut doc = toml_edit::Document::new(); +//! doc["foo"] = "'bar'".parse::<toml_edit::Item>().unwrap(); +//! let expected = r#"foo = 'bar' +//! "#; +//! assert_eq!(doc.to_string(), expected); +//! ``` +//! +//! ## Limitations +//! +//! Things it does not preserve: +//! +//! * Scattered array of tables (tables are reordered by default, see [test]). +//! * Order of dotted keys, see [issue](https://github.com/ordian/toml_edit/issues/163). +//! +//! [`toml`]: https://docs.rs/toml/latest/toml/ +//! [test]: https://github.com/ordian/toml_edit/blob/f09bd5d075fdb7d2ef8d9bb3270a34506c276753/tests/test_valid.rs#L84 + +mod array; +mod array_of_tables; +mod document; +mod encode; +mod index; +mod inline_table; +mod internal_string; +mod item; +mod key; +mod parser; +mod raw_string; +mod repr; +mod table; +mod value; + +#[cfg(feature = "serde")] +pub mod de; +#[cfg(feature = "serde")] +pub mod ser; + +pub mod visit; +pub mod visit_mut; + +pub use crate::array::{Array, ArrayIntoIter, ArrayIter, ArrayIterMut}; +pub use crate::array_of_tables::{ + ArrayOfTables, ArrayOfTablesIntoIter, ArrayOfTablesIter, ArrayOfTablesIterMut, +}; +pub use crate::document::Document; +pub use crate::inline_table::{ + InlineEntry, InlineOccupiedEntry, InlineTable, InlineTableIntoIter, InlineTableIter, + InlineTableIterMut, InlineVacantEntry, +}; +pub use crate::internal_string::InternalString; +pub use crate::item::{array, table, value, Item}; +pub use crate::key::{Key, KeyMut}; +pub use crate::parser::TomlError; +pub use crate::raw_string::RawString; +pub use crate::repr::{Decor, Formatted, Repr}; +pub use crate::table::{ + Entry, IntoIter, Iter, IterMut, OccupiedEntry, Table, TableLike, VacantEntry, +}; +pub use crate::value::Value; +pub use toml_datetime::*; + +// Prevent users from some traits. +pub(crate) mod private { + pub trait Sealed {} + impl Sealed for usize {} + impl Sealed for str {} + impl Sealed for String {} + impl Sealed for i64 {} + impl Sealed for f64 {} + impl Sealed for bool {} + impl Sealed for crate::Datetime {} + impl<'a, T: ?Sized> Sealed for &'a T where T: Sealed {} + impl Sealed for crate::Table {} + impl Sealed for crate::InlineTable {} +} diff --git a/vendor/toml_edit/src/parser/array.rs b/vendor/toml_edit/src/parser/array.rs new file mode 100644 index 000000000..93d7873ec --- /dev/null +++ b/vendor/toml_edit/src/parser/array.rs @@ -0,0 +1,147 @@ +use nom8::combinator::cut; +use nom8::combinator::opt; +use nom8::multi::separated_list1; +use nom8::sequence::delimited; + +use crate::parser::trivia::ws_comment_newline; +use crate::parser::value::value; +use crate::{Array, Item, RawString, Value}; + +use crate::parser::prelude::*; + +// ;; Array + +// array = array-open array-values array-close +pub(crate) fn array( + check: RecursionCheck, +) -> impl FnMut(Input<'_>) -> IResult<Input<'_>, Array, ParserError<'_>> { + move |input| { + delimited( + ARRAY_OPEN, + cut(array_values(check)), + cut(ARRAY_CLOSE) + .context(Context::Expression("array")) + .context(Context::Expected(ParserValue::CharLiteral(']'))), + ) + .parse(input) + } +} + +// note: we're omitting ws and newlines here, because +// they should be part of the formatted values +// array-open = %x5B ws-newline ; [ +pub(crate) const ARRAY_OPEN: u8 = b'['; +// array-close = ws-newline %x5D ; ] +const ARRAY_CLOSE: u8 = b']'; +// array-sep = ws %x2C ws ; , Comma +const ARRAY_SEP: u8 = b','; + +// note: this rule is modified +// array-values = [ ( array-value array-sep array-values ) / +// array-value / ws-comment-newline ] +pub(crate) fn array_values( + check: RecursionCheck, +) -> impl FnMut(Input<'_>) -> IResult<Input<'_>, Array, ParserError<'_>> { + move |input| { + let check = check.recursing(input)?; + ( + opt(( + separated_list1(ARRAY_SEP, array_value(check)), + opt(ARRAY_SEP), + ) + .map(|(v, trailing): (Vec<Value>, Option<u8>)| { + ( + Array::with_vec(v.into_iter().map(Item::Value).collect()), + trailing.is_some(), + ) + })), + ws_comment_newline.span(), + ) + .map_res::<_, _, std::str::Utf8Error>(|(array, trailing)| { + let (mut array, comma) = array.unwrap_or_default(); + array.set_trailing_comma(comma); + array.set_trailing(RawString::with_span(trailing)); + Ok(array) + }) + .parse(input) + } +} + +pub(crate) fn array_value( + check: RecursionCheck, +) -> impl FnMut(Input<'_>) -> IResult<Input<'_>, Value, ParserError<'_>> { + move |input| { + ( + ws_comment_newline.span(), + value(check), + ws_comment_newline.span(), + ) + .map(|(ws1, v, ws2)| v.decorated(RawString::with_span(ws1), RawString::with_span(ws2))) + .parse(input) + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn arrays() { + let inputs = [ + r#"[]"#, + r#"[ ]"#, + r#"[ + 1, 2, 3 +]"#, + r#"[ + 1, + 2, # this is ok +]"#, + r#"[# comment +# comment2 + + + ]"#, + r#"[# comment +# comment2 + 1 + +#sd +, +# comment3 + + ]"#, + r#"[1]"#, + r#"[1,]"#, + r#"[ "all", 'strings', """are the same""", '''type''']"#, + r#"[ 100, -2,]"#, + r#"[1, 2, 3]"#, + r#"[1.1, 2.1, 3.1]"#, + r#"["a", "b", "c"]"#, + r#"[ [ 1, 2 ], [3, 4, 5] ]"#, + r#"[ [ 1, 2 ], ["a", "b", "c"] ]"#, + r#"[ { x = 1, a = "2" }, {a = "a",b = "b", c = "c"} ]"#, + ]; + for input in inputs { + dbg!(input); + let mut parsed = array(Default::default()).parse(new_input(input)).finish(); + if let Ok(parsed) = &mut parsed { + parsed.despan(input); + } + assert_eq!(parsed.map(|a| a.to_string()), Ok(input.to_owned())); + } + } + + #[test] + fn invalid_arrays() { + let invalid_inputs = [r#"["#, r#"[,]"#, r#"[,2]"#, r#"[1e165,,]"#]; + for input in invalid_inputs { + dbg!(input); + let mut parsed = array(Default::default()).parse(new_input(input)).finish(); + if let Ok(parsed) = &mut parsed { + parsed.despan(input); + } + assert!(parsed.is_err()); + } + } +} diff --git a/vendor/toml_edit/src/parser/datetime.rs b/vendor/toml_edit/src/parser/datetime.rs new file mode 100644 index 000000000..63a761655 --- /dev/null +++ b/vendor/toml_edit/src/parser/datetime.rs @@ -0,0 +1,430 @@ +use std::ops::RangeInclusive; + +use crate::parser::errors::CustomError; +use crate::parser::prelude::*; +use crate::parser::trivia::from_utf8_unchecked; + +use nom8::branch::alt; +use nom8::bytes::one_of; +use nom8::bytes::take_while_m_n; +use nom8::combinator::cut; +use nom8::combinator::opt; +use nom8::sequence::preceded; +use toml_datetime::*; + +// ;; Date and Time (as defined in RFC 3339) + +// date-time = offset-date-time / local-date-time / local-date / local-time +// offset-date-time = full-date time-delim full-time +// local-date-time = full-date time-delim partial-time +// local-date = full-date +// local-time = partial-time +// full-time = partial-time time-offset +pub(crate) fn date_time(input: Input<'_>) -> IResult<Input<'_>, Datetime, ParserError<'_>> { + alt(( + (full_date, opt((time_delim, partial_time, opt(time_offset)))) + .map(|(date, opt)| { + match opt { + // Offset Date-Time + Some((_, time, offset)) => Datetime { + date: Some(date), + time: Some(time), + offset, + }, + // Local Date + None => Datetime { + date: Some(date), + time: None, + offset: None, + }, + } + }) + .context(Context::Expression("date-time")), + partial_time + .map(|t| t.into()) + .context(Context::Expression("time")), + )) + .parse(input) +} + +// full-date = date-fullyear "-" date-month "-" date-mday +pub(crate) fn full_date(input: Input<'_>) -> IResult<Input<'_>, Date, ParserError<'_>> { + (date_fullyear, b'-', cut((date_month, b'-', date_mday))) + .map(|(year, _, (month, _, day))| Date { year, month, day }) + .parse(input) +} + +// partial-time = time-hour ":" time-minute ":" time-second [time-secfrac] +pub(crate) fn partial_time(input: Input<'_>) -> IResult<Input<'_>, Time, ParserError<'_>> { + ( + time_hour, + b':', + cut((time_minute, b':', time_second, opt(time_secfrac))), + ) + .map(|(hour, _, (minute, _, second, nanosecond))| Time { + hour, + minute, + second, + nanosecond: nanosecond.unwrap_or_default(), + }) + .parse(input) +} + +// time-offset = "Z" / time-numoffset +// time-numoffset = ( "+" / "-" ) time-hour ":" time-minute +pub(crate) fn time_offset(input: Input<'_>) -> IResult<Input<'_>, Offset, ParserError<'_>> { + alt(( + one_of((b'Z', b'z')).value(Offset::Z), + (one_of((b'+', b'-')), cut((time_hour, b':', time_minute))) + .map(|(sign, (hours, _, minutes))| { + let sign = match sign { + b'+' => 1, + b'-' => -1, + _ => unreachable!("Parser prevents this"), + }; + sign * (hours as i16 * 60 + minutes as i16) + }) + .verify(|minutes| ((-24 * 60)..=(24 * 60)).contains(minutes)) + .map(|minutes| Offset::Custom { minutes }), + )) + .context(Context::Expression("time offset")) + .parse(input) +} + +// date-fullyear = 4DIGIT +pub(crate) fn date_fullyear(input: Input<'_>) -> IResult<Input<'_>, u16, ParserError<'_>> { + unsigned_digits::<4, 4> + .map(|s: &str| s.parse::<u16>().expect("4DIGIT should match u8")) + .parse(input) +} + +// date-month = 2DIGIT ; 01-12 +pub(crate) fn date_month(input: Input<'_>) -> IResult<Input<'_>, u8, ParserError<'_>> { + unsigned_digits::<2, 2> + .map_res(|s: &str| { + let d = s.parse::<u8>().expect("2DIGIT should match u8"); + if (1..=12).contains(&d) { + Ok(d) + } else { + Err(CustomError::OutOfRange) + } + }) + .parse(input) +} + +// date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on month/year +pub(crate) fn date_mday(input: Input<'_>) -> IResult<Input<'_>, u8, ParserError<'_>> { + unsigned_digits::<2, 2> + .map_res(|s: &str| { + let d = s.parse::<u8>().expect("2DIGIT should match u8"); + if (1..=31).contains(&d) { + Ok(d) + } else { + Err(CustomError::OutOfRange) + } + }) + .parse(input) +} + +// time-delim = "T" / %x20 ; T, t, or space +pub(crate) fn time_delim(input: Input<'_>) -> IResult<Input<'_>, u8, ParserError<'_>> { + one_of(TIME_DELIM).parse(input) +} + +const TIME_DELIM: (u8, u8, u8) = (b'T', b't', b' '); + +// time-hour = 2DIGIT ; 00-23 +pub(crate) fn time_hour(input: Input<'_>) -> IResult<Input<'_>, u8, ParserError<'_>> { + unsigned_digits::<2, 2> + .map_res(|s: &str| { + let d = s.parse::<u8>().expect("2DIGIT should match u8"); + if (0..=23).contains(&d) { + Ok(d) + } else { + Err(CustomError::OutOfRange) + } + }) + .parse(input) +} + +// time-minute = 2DIGIT ; 00-59 +pub(crate) fn time_minute(input: Input<'_>) -> IResult<Input<'_>, u8, ParserError<'_>> { + unsigned_digits::<2, 2> + .map_res(|s: &str| { + let d = s.parse::<u8>().expect("2DIGIT should match u8"); + if (0..=59).contains(&d) { + Ok(d) + } else { + Err(CustomError::OutOfRange) + } + }) + .parse(input) +} + +// time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second rules +pub(crate) fn time_second(input: Input<'_>) -> IResult<Input<'_>, u8, ParserError<'_>> { + unsigned_digits::<2, 2> + .map_res(|s: &str| { + let d = s.parse::<u8>().expect("2DIGIT should match u8"); + if (0..=60).contains(&d) { + Ok(d) + } else { + Err(CustomError::OutOfRange) + } + }) + .parse(input) +} + +// time-secfrac = "." 1*DIGIT +pub(crate) fn time_secfrac(input: Input<'_>) -> IResult<Input<'_>, u32, ParserError<'_>> { + static SCALE: [u32; 10] = [ + 0, + 100_000_000, + 10_000_000, + 1_000_000, + 100_000, + 10_000, + 1_000, + 100, + 10, + 1, + ]; + const INF: usize = usize::MAX; + preceded(b'.', unsigned_digits::<1, INF>) + .map_res(|mut repr: &str| -> Result<u32, CustomError> { + let max_digits = SCALE.len() - 1; + if max_digits < repr.len() { + // Millisecond precision is required. Further precision of fractional seconds is + // implementation-specific. If the value contains greater precision than the + // implementation can support, the additional precision must be truncated, not rounded. + repr = &repr[0..max_digits]; + } + + let v = repr.parse::<u32>().map_err(|_| CustomError::OutOfRange)?; + let num_digits = repr.len(); + + // scale the number accordingly. + let scale = SCALE.get(num_digits).ok_or(CustomError::OutOfRange)?; + let v = v.checked_mul(*scale).ok_or(CustomError::OutOfRange)?; + Ok(v) + }) + .parse(input) +} + +pub(crate) fn unsigned_digits<const MIN: usize, const MAX: usize>( + input: Input<'_>, +) -> IResult<Input<'_>, &str, ParserError<'_>> { + take_while_m_n(MIN, MAX, DIGIT) + .map(|b: &[u8]| unsafe { from_utf8_unchecked(b, "`is_ascii_digit` filters out on-ASCII") }) + .parse(input) +} + +// DIGIT = %x30-39 ; 0-9 +const DIGIT: RangeInclusive<u8> = b'0'..=b'9'; + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn offset_date_time() { + let inputs = [ + ( + "1979-05-27T07:32:00Z", + Datetime { + date: Some(Date { + year: 1979, + month: 5, + day: 27, + }), + time: Some(Time { + hour: 7, + minute: 32, + second: 0, + nanosecond: 0, + }), + offset: Some(Offset::Z), + }, + ), + ( + "1979-05-27T00:32:00-07:00", + Datetime { + date: Some(Date { + year: 1979, + month: 5, + day: 27, + }), + time: Some(Time { + hour: 0, + minute: 32, + second: 0, + nanosecond: 0, + }), + offset: Some(Offset::Custom { minutes: -7 * 60 }), + }, + ), + ( + "1979-05-27T00:32:00-00:36", + Datetime { + date: Some(Date { + year: 1979, + month: 5, + day: 27, + }), + time: Some(Time { + hour: 0, + minute: 32, + second: 0, + nanosecond: 0, + }), + offset: Some(Offset::Custom { minutes: -36 }), + }, + ), + ( + "1979-05-27T00:32:00.999999", + Datetime { + date: Some(Date { + year: 1979, + month: 5, + day: 27, + }), + time: Some(Time { + hour: 0, + minute: 32, + second: 0, + nanosecond: 999999000, + }), + offset: None, + }, + ), + ]; + for (input, expected) in inputs { + dbg!(input); + let actual = date_time.parse(new_input(input)).finish().unwrap(); + assert_eq!(expected, actual); + } + } + + #[test] + fn local_date_time() { + let inputs = [ + ( + "1979-05-27T07:32:00", + Datetime { + date: Some(Date { + year: 1979, + month: 5, + day: 27, + }), + time: Some(Time { + hour: 7, + minute: 32, + second: 0, + nanosecond: 0, + }), + offset: None, + }, + ), + ( + "1979-05-27T00:32:00.999999", + Datetime { + date: Some(Date { + year: 1979, + month: 5, + day: 27, + }), + time: Some(Time { + hour: 0, + minute: 32, + second: 0, + nanosecond: 999999000, + }), + offset: None, + }, + ), + ]; + for (input, expected) in inputs { + dbg!(input); + let actual = date_time.parse(new_input(input)).finish().unwrap(); + assert_eq!(expected, actual); + } + } + + #[test] + fn local_date() { + let inputs = [ + ( + "1979-05-27", + Datetime { + date: Some(Date { + year: 1979, + month: 5, + day: 27, + }), + time: None, + offset: None, + }, + ), + ( + "2017-07-20", + Datetime { + date: Some(Date { + year: 2017, + month: 7, + day: 20, + }), + time: None, + offset: None, + }, + ), + ]; + for (input, expected) in inputs { + dbg!(input); + let actual = date_time.parse(new_input(input)).finish().unwrap(); + assert_eq!(expected, actual); + } + } + + #[test] + fn local_time() { + let inputs = [ + ( + "07:32:00", + Datetime { + date: None, + time: Some(Time { + hour: 7, + minute: 32, + second: 0, + nanosecond: 0, + }), + offset: None, + }, + ), + ( + "00:32:00.999999", + Datetime { + date: None, + time: Some(Time { + hour: 0, + minute: 32, + second: 0, + nanosecond: 999999000, + }), + offset: None, + }, + ), + ]; + for (input, expected) in inputs { + dbg!(input); + let actual = date_time.parse(new_input(input)).finish().unwrap(); + assert_eq!(expected, actual); + } + } + + #[test] + fn time_fraction_truncated() { + let input = "1987-07-05T17:45:00.123456789012345Z"; + date_time.parse(new_input(input)).finish().unwrap(); + } +} diff --git a/vendor/toml_edit/src/parser/document.rs b/vendor/toml_edit/src/parser/document.rs new file mode 100644 index 000000000..38e9e0eee --- /dev/null +++ b/vendor/toml_edit/src/parser/document.rs @@ -0,0 +1,147 @@ +use std::cell::RefCell; + +use nom8::bytes::any; +use nom8::bytes::one_of; +use nom8::combinator::cut; +use nom8::combinator::eof; +use nom8::combinator::opt; +use nom8::combinator::peek; +use nom8::error::FromExternalError; +use nom8::multi::many0_count; + +use crate::document::Document; +use crate::key::Key; +use crate::parser::inline_table::KEYVAL_SEP; +use crate::parser::key::key; +use crate::parser::prelude::*; +use crate::parser::state::ParseState; +use crate::parser::table::table; +use crate::parser::trivia::{comment, line_ending, line_trailing, newline, ws}; +use crate::parser::value::value; +use crate::table::TableKeyValue; +use crate::Item; +use crate::RawString; + +// ;; TOML + +// toml = expression *( newline expression ) + +// expression = ( ( ws comment ) / +// ( ws keyval ws [ comment ] ) / +// ( ws table ws [ comment ] ) / +// ws ) +pub(crate) fn document(input: Input<'_>) -> IResult<Input<'_>, Document, ParserError<'_>> { + let state = RefCell::new(ParseState::default()); + let state_ref = &state; + + let (i, _o) = ( + // Remove BOM if present + opt(b"\xEF\xBB\xBF"), + parse_ws(state_ref), + many0_count(( + dispatch! {peek(any); + crate::parser::trivia::COMMENT_START_SYMBOL => cut(parse_comment(state_ref)), + crate::parser::table::STD_TABLE_OPEN => cut(table(state_ref)), + crate::parser::trivia::LF | + crate::parser::trivia::CR => parse_newline(state_ref), + _ => cut(keyval(state_ref)), + }, + parse_ws(state_ref), + )), + eof, + ) + .parse(input)?; + state + .into_inner() + .into_document() + .map(|document| (i, document)) + .map_err(|err| { + nom8::Err::Error(ParserError::from_external_error( + i, + nom8::error::ErrorKind::MapRes, + err, + )) + }) +} + +pub(crate) fn parse_comment<'s, 'i>( + state: &'s RefCell<ParseState>, +) -> impl FnMut(Input<'i>) -> IResult<Input<'i>, (), ParserError<'_>> + 's { + move |i| { + (comment, line_ending) + .span() + .map(|span| { + state.borrow_mut().on_comment(span); + }) + .parse(i) + } +} + +pub(crate) fn parse_ws<'s, 'i>( + state: &'s RefCell<ParseState>, +) -> impl FnMut(Input<'i>) -> IResult<Input<'i>, (), ParserError<'i>> + 's { + move |i| { + ws.span() + .map(|span| state.borrow_mut().on_ws(span)) + .parse(i) + } +} + +pub(crate) fn parse_newline<'s, 'i>( + state: &'s RefCell<ParseState>, +) -> impl FnMut(Input<'i>) -> IResult<Input<'i>, (), ParserError<'i>> + 's { + move |i| { + newline + .span() + .map(|span| state.borrow_mut().on_ws(span)) + .parse(i) + } +} + +pub(crate) fn keyval<'s, 'i>( + state: &'s RefCell<ParseState>, +) -> impl FnMut(Input<'i>) -> IResult<Input<'i>, (), ParserError<'i>> + 's { + move |i| { + parse_keyval + .map_res(|(p, kv)| state.borrow_mut().on_keyval(p, kv)) + .parse(i) + } +} + +// keyval = key keyval-sep val +pub(crate) fn parse_keyval( + input: Input<'_>, +) -> IResult<Input<'_>, (Vec<Key>, TableKeyValue), ParserError<'_>> { + ( + key, + cut(( + one_of(KEYVAL_SEP) + .context(Context::Expected(ParserValue::CharLiteral('.'))) + .context(Context::Expected(ParserValue::CharLiteral('='))), + ( + ws.span(), + value(RecursionCheck::default()), + line_trailing + .context(Context::Expected(ParserValue::CharLiteral('\n'))) + .context(Context::Expected(ParserValue::CharLiteral('#'))), + ), + )), + ) + .map_res::<_, _, std::str::Utf8Error>(|(key, (_, v))| { + let mut path = key; + let key = path.pop().expect("grammar ensures at least 1"); + + let (pre, v, suf) = v; + let pre = RawString::with_span(pre); + let suf = RawString::with_span(suf); + let v = v.decorated(pre, suf); + Ok(( + path, + TableKeyValue { + key, + value: Item::Value(v), + }, + )) + }) + .parse(input) +} diff --git a/vendor/toml_edit/src/parser/errors.rs b/vendor/toml_edit/src/parser/errors.rs new file mode 100644 index 000000000..0baf6bdd4 --- /dev/null +++ b/vendor/toml_edit/src/parser/errors.rs @@ -0,0 +1,482 @@ +use std::error::Error as StdError; +use std::fmt::{Display, Formatter, Result}; + +use crate::parser::prelude::*; +use crate::Key; + +/// Type representing a TOML parse error +#[derive(Debug, Clone, Eq, PartialEq, Hash)] +pub struct TomlError { + message: String, + original: Option<String>, + keys: Vec<String>, + span: Option<std::ops::Range<usize>>, +} + +impl TomlError { + pub(crate) fn new(error: ParserError<'_>, original: Input<'_>) -> Self { + use nom8::input::IntoOutput; + use nom8::input::Offset; + + let offset = original.offset(&error.input); + let span = if offset == original.len() { + offset..offset + } else { + offset..(offset + 1) + }; + + let message = error.to_string(); + + Self { + message, + original: Some( + String::from_utf8(original.into_output().to_owned()) + .expect("original document was utf8"), + ), + keys: Vec::new(), + span: Some(span), + } + } + + #[cfg(feature = "serde")] + pub(crate) fn custom(message: String, span: Option<std::ops::Range<usize>>) -> Self { + Self { + message, + original: None, + keys: Vec::new(), + span, + } + } + + #[cfg(feature = "serde")] + pub(crate) fn add_key(&mut self, key: String) { + self.keys.insert(0, key); + } + + /// What went wrong + pub fn message(&self) -> &str { + &self.message + } + + /// The start/end index into the original document where the error occurred + pub fn span(&self) -> Option<std::ops::Range<usize>> { + self.span.clone() + } + + #[cfg(feature = "serde")] + pub(crate) fn set_span(&mut self, span: Option<std::ops::Range<usize>>) { + self.span = span; + } + + #[cfg(feature = "serde")] + pub(crate) fn set_original(&mut self, original: Option<String>) { + self.original = original; + } +} + +/// Displays a TOML parse error +/// +/// # Example +/// +/// TOML parse error at line 1, column 10 +/// | +/// 1 | 00:32:00.a999999 +/// | ^ +/// Unexpected `a` +/// Expected `digit` +/// While parsing a Time +/// While parsing a Date-Time +impl Display for TomlError { + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + let mut context = false; + if let (Some(original), Some(span)) = (&self.original, self.span()) { + context = true; + + let (line, column) = translate_position(original.as_bytes(), span.start); + let line_num = line + 1; + let col_num = column + 1; + let gutter = line_num.to_string().len(); + let content = original.split('\n').nth(line).expect("valid line number"); + + writeln!( + f, + "TOML parse error at line {}, column {}", + line_num, col_num + )?; + // | + for _ in 0..=gutter { + write!(f, " ")?; + } + writeln!(f, "|")?; + + // 1 | 00:32:00.a999999 + write!(f, "{} | ", line_num)?; + writeln!(f, "{}", content)?; + + // | ^ + for _ in 0..=gutter { + write!(f, " ")?; + } + write!(f, "|")?; + for _ in 0..=column { + write!(f, " ")?; + } + // The span will be empty at eof, so we need to make sure we always print at least + // one `^` + write!(f, "^")?; + for _ in (span.start + 1)..(span.end.min(span.start + content.len())) { + write!(f, "^")?; + } + writeln!(f)?; + } + writeln!(f, "{}", self.message)?; + if !context && !self.keys.is_empty() { + writeln!(f, "in `{}`", self.keys.join("."))?; + } + + Ok(()) + } +} + +impl StdError for TomlError { + fn description(&self) -> &'static str { + "TOML parse error" + } +} + +#[derive(Debug)] +pub(crate) struct ParserError<'b> { + input: Input<'b>, + context: Vec<Context>, + cause: Option<Box<dyn std::error::Error + Send + Sync + 'static>>, +} + +impl<'b> nom8::error::ParseError<Input<'b>> for ParserError<'b> { + fn from_error_kind(input: Input<'b>, _kind: nom8::error::ErrorKind) -> Self { + Self { + input, + context: Default::default(), + cause: Default::default(), + } + } + + fn append(_input: Input<'b>, _kind: nom8::error::ErrorKind, other: Self) -> Self { + other + } + + fn from_char(_input: Input<'b>, _: char) -> Self { + unimplemented!("this shouldn't be called with a binary parser") + } + + fn or(self, other: Self) -> Self { + other + } +} + +impl<'b> nom8::error::ParseError<&'b str> for ParserError<'b> { + fn from_error_kind(input: &'b str, _kind: nom8::error::ErrorKind) -> Self { + Self { + input: Input::new(input.as_bytes()), + context: Default::default(), + cause: Default::default(), + } + } + + fn append(_input: &'b str, _kind: nom8::error::ErrorKind, other: Self) -> Self { + other + } + + fn from_char(_input: &'b str, _: char) -> Self { + unimplemented!("this shouldn't be called with a binary parser") + } + + fn or(self, other: Self) -> Self { + other + } +} + +impl<'b> nom8::error::ContextError<Input<'b>, Context> for ParserError<'b> { + fn add_context(_input: Input<'b>, ctx: Context, mut other: Self) -> Self { + other.context.push(ctx); + other + } +} + +impl<'b, E: std::error::Error + Send + Sync + 'static> nom8::error::FromExternalError<Input<'b>, E> + for ParserError<'b> +{ + fn from_external_error(input: Input<'b>, _kind: nom8::error::ErrorKind, e: E) -> Self { + Self { + input, + context: Default::default(), + cause: Some(Box::new(e)), + } + } +} + +impl<'b, E: std::error::Error + Send + Sync + 'static> nom8::error::FromExternalError<&'b str, E> + for ParserError<'b> +{ + fn from_external_error(input: &'b str, _kind: nom8::error::ErrorKind, e: E) -> Self { + Self { + input: Input::new(input.as_bytes()), + context: Default::default(), + cause: Some(Box::new(e)), + } + } +} + +// For tests +impl<'b> std::cmp::PartialEq for ParserError<'b> { + fn eq(&self, other: &Self) -> bool { + self.input == other.input + && self.context == other.context + && self.cause.as_ref().map(ToString::to_string) + == other.cause.as_ref().map(ToString::to_string) + } +} + +impl<'a> std::fmt::Display for ParserError<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let expression = self.context.iter().find_map(|c| match c { + Context::Expression(c) => Some(c), + _ => None, + }); + let expected = self + .context + .iter() + .filter_map(|c| match c { + Context::Expected(c) => Some(c), + _ => None, + }) + .collect::<Vec<_>>(); + + let mut newline = false; + + if let Some(expression) = expression { + newline = true; + + write!(f, "invalid {}", expression)?; + } + + if !expected.is_empty() { + if newline { + writeln!(f)?; + } + newline = true; + + write!(f, "expected ")?; + for (i, expected) in expected.iter().enumerate() { + if i != 0 { + write!(f, ", ")?; + } + write!(f, "{}", expected)?; + } + } + if let Some(cause) = &self.cause { + if newline { + writeln!(f)?; + } + write!(f, "{}", cause)?; + } + + Ok(()) + } +} + +#[derive(Copy, Clone, Debug, PartialEq)] +pub(crate) enum Context { + Expression(&'static str), + Expected(ParserValue), +} + +#[derive(Copy, Clone, Debug, PartialEq)] +pub(crate) enum ParserValue { + CharLiteral(char), + StringLiteral(&'static str), + Description(&'static str), +} + +impl std::fmt::Display for ParserValue { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ParserValue::CharLiteral('\n') => "newline".fmt(f), + ParserValue::CharLiteral('`') => "'`'".fmt(f), + ParserValue::CharLiteral(c) if c.is_ascii_control() => { + write!(f, "`{}`", c.escape_debug()) + } + ParserValue::CharLiteral(c) => write!(f, "`{}`", c), + ParserValue::StringLiteral(c) => write!(f, "`{}`", c), + ParserValue::Description(c) => write!(f, "{}", c), + } + } +} + +fn translate_position(input: &[u8], index: usize) -> (usize, usize) { + if input.is_empty() { + return (0, index); + } + + let safe_index = index.min(input.len() - 1); + let column_offset = index - safe_index; + let index = safe_index; + + let nl = input[0..index] + .iter() + .rev() + .enumerate() + .find(|(_, b)| **b == b'\n') + .map(|(nl, _)| index - nl - 1); + let line_start = match nl { + Some(nl) => nl + 1, + None => 0, + }; + let line = input[0..line_start].iter().filter(|b| **b == b'\n').count(); + let line = line; + + let column = std::str::from_utf8(&input[line_start..=index]) + .map(|s| s.chars().count() - 1) + .unwrap_or_else(|_| index - line_start); + let column = column + column_offset; + + (line, column) +} + +#[cfg(test)] +mod test_translate_position { + use super::*; + + #[test] + fn empty() { + let input = b""; + let index = 0; + let position = translate_position(&input[..], index); + assert_eq!(position, (0, 0)); + } + + #[test] + fn start() { + let input = b"Hello"; + let index = 0; + let position = translate_position(&input[..], index); + assert_eq!(position, (0, 0)); + } + + #[test] + fn end() { + let input = b"Hello"; + let index = input.len() - 1; + let position = translate_position(&input[..], index); + assert_eq!(position, (0, input.len() - 1)); + } + + #[test] + fn after() { + let input = b"Hello"; + let index = input.len(); + let position = translate_position(&input[..], index); + assert_eq!(position, (0, input.len())); + } + + #[test] + fn first_line() { + let input = b"Hello\nWorld\n"; + let index = 2; + let position = translate_position(&input[..], index); + assert_eq!(position, (0, 2)); + } + + #[test] + fn end_of_line() { + let input = b"Hello\nWorld\n"; + let index = 5; + let position = translate_position(&input[..], index); + assert_eq!(position, (0, 5)); + } + + #[test] + fn start_of_second_line() { + let input = b"Hello\nWorld\n"; + let index = 6; + let position = translate_position(&input[..], index); + assert_eq!(position, (1, 0)); + } + + #[test] + fn second_line() { + let input = b"Hello\nWorld\n"; + let index = 8; + let position = translate_position(&input[..], index); + assert_eq!(position, (1, 2)); + } +} + +#[derive(Debug, Clone)] +pub(crate) enum CustomError { + DuplicateKey { + key: String, + table: Option<Vec<Key>>, + }, + DottedKeyExtendWrongType { + key: Vec<Key>, + actual: &'static str, + }, + OutOfRange, + #[cfg_attr(feature = "unbounded", allow(dead_code))] + RecursionLimitExceeded, +} + +impl CustomError { + pub(crate) fn duplicate_key(path: &[Key], i: usize) -> Self { + assert!(i < path.len()); + let key = &path[i]; + let repr = key.display_repr(); + Self::DuplicateKey { + key: repr.into(), + table: Some(path[..i].to_vec()), + } + } + + pub(crate) fn extend_wrong_type(path: &[Key], i: usize, actual: &'static str) -> Self { + assert!(i < path.len()); + Self::DottedKeyExtendWrongType { + key: path[..=i].to_vec(), + actual, + } + } +} + +impl StdError for CustomError { + fn description(&self) -> &'static str { + "TOML parse error" + } +} + +impl Display for CustomError { + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + match self { + CustomError::DuplicateKey { key, table } => { + if let Some(table) = table { + if table.is_empty() { + write!(f, "duplicate key `{}` in document root", key) + } else { + let path = table.iter().map(|k| k.get()).collect::<Vec<_>>().join("."); + write!(f, "duplicate key `{}` in table `{}`", key, path) + } + } else { + write!(f, "duplicate key `{}`", key) + } + } + CustomError::DottedKeyExtendWrongType { key, actual } => { + let path = key.iter().map(|k| k.get()).collect::<Vec<_>>().join("."); + write!( + f, + "dotted key `{}` attempted to extend non-table type ({})", + path, actual + ) + } + CustomError::OutOfRange => write!(f, "value is out of range"), + CustomError::RecursionLimitExceeded => write!(f, "recursion limit exceded"), + } + } +} diff --git a/vendor/toml_edit/src/parser/inline_table.rs b/vendor/toml_edit/src/parser/inline_table.rs new file mode 100644 index 000000000..e8d38f4a9 --- /dev/null +++ b/vendor/toml_edit/src/parser/inline_table.rs @@ -0,0 +1,186 @@ +use nom8::bytes::one_of; +use nom8::combinator::cut; +use nom8::multi::separated_list0; +use nom8::sequence::delimited; + +use crate::key::Key; +use crate::parser::errors::CustomError; +use crate::parser::key::key; +use crate::parser::prelude::*; +use crate::parser::trivia::ws; +use crate::parser::value::value; +use crate::table::TableKeyValue; +use crate::{InlineTable, InternalString, Item, RawString, Value}; + +use indexmap::map::Entry; + +// ;; Inline Table + +// inline-table = inline-table-open inline-table-keyvals inline-table-close +pub(crate) fn inline_table( + check: RecursionCheck, +) -> impl FnMut(Input<'_>) -> IResult<Input<'_>, InlineTable, ParserError<'_>> { + move |input| { + delimited( + INLINE_TABLE_OPEN, + cut(inline_table_keyvals(check).map_res(|(kv, p)| table_from_pairs(kv, p))), + cut(INLINE_TABLE_CLOSE) + .context(Context::Expression("inline table")) + .context(Context::Expected(ParserValue::CharLiteral('}'))), + ) + .parse(input) + } +} + +fn table_from_pairs( + v: Vec<(Vec<Key>, TableKeyValue)>, + preamble: RawString, +) -> Result<InlineTable, CustomError> { + let mut root = InlineTable::new(); + root.set_preamble(preamble); + // Assuming almost all pairs will be directly in `root` + root.items.reserve(v.len()); + + for (path, kv) in v { + let table = descend_path(&mut root, &path)?; + let key: InternalString = kv.key.get_internal().into(); + match table.items.entry(key) { + Entry::Vacant(o) => { + o.insert(kv); + } + Entry::Occupied(o) => { + return Err(CustomError::DuplicateKey { + key: o.key().as_str().into(), + table: None, + }); + } + } + } + Ok(root) +} + +fn descend_path<'a>( + mut table: &'a mut InlineTable, + path: &'a [Key], +) -> Result<&'a mut InlineTable, CustomError> { + for (i, key) in path.iter().enumerate() { + let entry = table.entry_format(key).or_insert_with(|| { + let mut new_table = InlineTable::new(); + new_table.set_dotted(true); + + Value::InlineTable(new_table) + }); + match *entry { + Value::InlineTable(ref mut sweet_child_of_mine) => { + table = sweet_child_of_mine; + } + ref v => { + return Err(CustomError::extend_wrong_type(path, i, v.type_name())); + } + } + } + Ok(table) +} + +// inline-table-open = %x7B ws ; { +pub(crate) const INLINE_TABLE_OPEN: u8 = b'{'; +// inline-table-close = ws %x7D ; } +const INLINE_TABLE_CLOSE: u8 = b'}'; +// inline-table-sep = ws %x2C ws ; , Comma +const INLINE_TABLE_SEP: u8 = b','; +// keyval-sep = ws %x3D ws ; = +pub(crate) const KEYVAL_SEP: u8 = b'='; + +// inline-table-keyvals = [ inline-table-keyvals-non-empty ] +// inline-table-keyvals-non-empty = +// ( key keyval-sep val inline-table-sep inline-table-keyvals-non-empty ) / +// ( key keyval-sep val ) + +fn inline_table_keyvals( + check: RecursionCheck, +) -> impl FnMut( + Input<'_>, +) -> IResult<Input<'_>, (Vec<(Vec<Key>, TableKeyValue)>, RawString), ParserError<'_>> { + move |input| { + let check = check.recursing(input)?; + ( + separated_list0(INLINE_TABLE_SEP, keyval(check)), + ws.span().map(RawString::with_span), + ) + .parse(input) + } +} + +fn keyval( + check: RecursionCheck, +) -> impl FnMut(Input<'_>) -> IResult<Input<'_>, (Vec<Key>, TableKeyValue), ParserError<'_>> { + move |input| { + ( + key, + cut(( + one_of(KEYVAL_SEP) + .context(Context::Expected(ParserValue::CharLiteral('.'))) + .context(Context::Expected(ParserValue::CharLiteral('='))), + (ws.span(), value(check), ws.span()), + )), + ) + .map(|(key, (_, v))| { + let mut path = key; + let key = path.pop().expect("grammar ensures at least 1"); + + let (pre, v, suf) = v; + let pre = RawString::with_span(pre); + let suf = RawString::with_span(suf); + let v = v.decorated(pre, suf); + ( + path, + TableKeyValue { + key, + value: Item::Value(v), + }, + ) + }) + .parse(input) + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn inline_tables() { + let inputs = [ + r#"{}"#, + r#"{ }"#, + r#"{a = 1e165}"#, + r#"{ hello = "world", a = 1}"#, + r#"{ hello.world = "a" }"#, + ]; + for input in inputs { + dbg!(input); + let mut parsed = inline_table(Default::default()) + .parse(new_input(input)) + .finish(); + if let Ok(parsed) = &mut parsed { + parsed.despan(input); + } + assert_eq!(parsed.map(|a| a.to_string()), Ok(input.to_owned())); + } + } + + #[test] + fn invalid_inline_tables() { + let invalid_inputs = [r#"{a = 1e165"#, r#"{ hello = "world", a = 2, hello = 1}"#]; + for input in invalid_inputs { + dbg!(input); + let mut parsed = inline_table(Default::default()) + .parse(new_input(input)) + .finish(); + if let Ok(parsed) = &mut parsed { + parsed.despan(input); + } + assert!(parsed.is_err()); + } + } +} diff --git a/vendor/toml_edit/src/parser/key.rs b/vendor/toml_edit/src/parser/key.rs new file mode 100644 index 000000000..82424916f --- /dev/null +++ b/vendor/toml_edit/src/parser/key.rs @@ -0,0 +1,104 @@ +use std::ops::RangeInclusive; + +use nom8::bytes::any; +use nom8::bytes::take_while1; +use nom8::combinator::peek; +use nom8::multi::separated_list1; + +use crate::key::Key; +use crate::parser::errors::CustomError; +use crate::parser::prelude::*; +use crate::parser::strings::{basic_string, literal_string}; +use crate::parser::trivia::{from_utf8_unchecked, ws}; +use crate::repr::{Decor, Repr}; +use crate::InternalString; +use crate::RawString; + +// key = simple-key / dotted-key +// dotted-key = simple-key 1*( dot-sep simple-key ) +pub(crate) fn key(input: Input<'_>) -> IResult<Input<'_>, Vec<Key>, ParserError<'_>> { + separated_list1( + DOT_SEP, + (ws.span(), simple_key, ws.span()).map(|(pre, (raw, key), suffix)| { + Key::new(key) + .with_repr_unchecked(Repr::new_unchecked(raw)) + .with_decor(Decor::new( + RawString::with_span(pre), + RawString::with_span(suffix), + )) + }), + ) + .context(Context::Expression("key")) + .map_res(|k| { + // Inserting the key will require recursion down the line + RecursionCheck::check_depth(k.len())?; + Ok::<_, CustomError>(k) + }) + .parse(input) +} + +// simple-key = quoted-key / unquoted-key +// quoted-key = basic-string / literal-string +pub(crate) fn simple_key( + input: Input<'_>, +) -> IResult<Input<'_>, (RawString, InternalString), ParserError<'_>> { + dispatch! {peek(any); + crate::parser::strings::QUOTATION_MARK => basic_string + .map(|s: std::borrow::Cow<'_, str>| s.as_ref().into()), + crate::parser::strings::APOSTROPHE => literal_string.map(|s: &str| s.into()), + _ => unquoted_key.map(|s: &str| s.into()), + } + .with_span() + .map(|(k, span)| { + let raw = RawString::with_span(span); + (raw, k) + }) + .parse(input) +} + +// unquoted-key = 1*( ALPHA / DIGIT / %x2D / %x5F ) ; A-Z / a-z / 0-9 / - / _ +fn unquoted_key(input: Input<'_>) -> IResult<Input<'_>, &str, ParserError<'_>> { + take_while1(UNQUOTED_CHAR) + .map(|b| unsafe { from_utf8_unchecked(b, "`is_unquoted_char` filters out on-ASCII") }) + .parse(input) +} + +pub(crate) fn is_unquoted_char(c: u8) -> bool { + use nom8::input::FindToken; + UNQUOTED_CHAR.find_token(c) +} + +const UNQUOTED_CHAR: ( + RangeInclusive<u8>, + RangeInclusive<u8>, + RangeInclusive<u8>, + u8, + u8, +) = (b'A'..=b'Z', b'a'..=b'z', b'0'..=b'9', b'-', b'_'); + +// dot-sep = ws %x2E ws ; . Period +const DOT_SEP: u8 = b'.'; + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn keys() { + let cases = [ + ("a", "a"), + (r#""hello\n ""#, "hello\n "), + (r#"'hello\n '"#, "hello\\n "), + ]; + + for (input, expected) in cases { + dbg!(input); + let parsed = simple_key.parse(new_input(input)).finish(); + assert_eq!( + parsed, + Ok((RawString::with_span(0..(input.len())), expected.into())), + "Parsing {input:?}" + ); + } + } +} diff --git a/vendor/toml_edit/src/parser/macros.rs b/vendor/toml_edit/src/parser/macros.rs new file mode 100644 index 000000000..591b2f7b1 --- /dev/null +++ b/vendor/toml_edit/src/parser/macros.rs @@ -0,0 +1,13 @@ +macro_rules! dispatch { + ($match_parser: expr; $( $pat:pat $(if $pred:expr)? => $expr: expr ),+ $(,)? ) => { + move |i| + { + let (i, initial) = $match_parser.parse(i)?; + match initial { + $( + $pat $(if $pred)? => $expr.parse(i), + )* + } + } + } +} diff --git a/vendor/toml_edit/src/parser/mod.rs b/vendor/toml_edit/src/parser/mod.rs new file mode 100644 index 000000000..2c7751ee0 --- /dev/null +++ b/vendor/toml_edit/src/parser/mod.rs @@ -0,0 +1,303 @@ +#![allow(clippy::type_complexity)] + +#[macro_use] +pub(crate) mod macros; + +pub(crate) mod array; +pub(crate) mod datetime; +pub(crate) mod document; +pub(crate) mod errors; +pub(crate) mod inline_table; +pub(crate) mod key; +pub(crate) mod numbers; +pub(crate) mod state; +pub(crate) mod strings; +pub(crate) mod table; +pub(crate) mod trivia; +pub(crate) mod value; + +pub use errors::TomlError; + +pub(crate) fn parse_document(raw: &str) -> Result<crate::Document, TomlError> { + use prelude::*; + + let b = new_input(raw); + let mut doc = document::document + .parse(b) + .finish() + .map_err(|e| TomlError::new(e, b))?; + doc.span = Some(0..(raw.len())); + doc.original = Some(raw.to_owned()); + Ok(doc) +} + +pub(crate) fn parse_key(raw: &str) -> Result<crate::Key, TomlError> { + use prelude::*; + + let b = new_input(raw); + let result = key::simple_key.parse(b).finish(); + match result { + Ok((raw, key)) => { + Ok(crate::Key::new(key).with_repr_unchecked(crate::Repr::new_unchecked(raw))) + } + Err(e) => Err(TomlError::new(e, b)), + } +} + +pub(crate) fn parse_key_path(raw: &str) -> Result<Vec<crate::Key>, TomlError> { + use prelude::*; + + let b = new_input(raw); + let result = key::key.parse(b).finish(); + match result { + Ok(mut keys) => { + for key in &mut keys { + key.despan(raw); + } + Ok(keys) + } + Err(e) => Err(TomlError::new(e, b)), + } +} + +pub(crate) fn parse_value(raw: &str) -> Result<crate::Value, TomlError> { + use prelude::*; + + let b = new_input(raw); + let parsed = value::value(RecursionCheck::default()).parse(b).finish(); + match parsed { + Ok(mut value) => { + // Only take the repr and not decor, as its probably not intended + value.decor_mut().clear(); + value.despan(raw); + Ok(value) + } + Err(e) => Err(TomlError::new(e, b)), + } +} + +pub(crate) mod prelude { + pub(crate) use super::errors::Context; + pub(crate) use super::errors::ParserError; + pub(crate) use super::errors::ParserValue; + pub(crate) use nom8::IResult; + pub(crate) use nom8::Parser as _; + + pub(crate) use nom8::FinishIResult as _; + + pub(crate) type Input<'b> = nom8::input::Located<&'b [u8]>; + + pub(crate) fn new_input(s: &str) -> Input<'_> { + nom8::input::Located::new(s.as_bytes()) + } + + pub(crate) fn ok_error<I, O, E>(res: IResult<I, O, E>) -> Result<Option<(I, O)>, nom8::Err<E>> { + match res { + Ok(ok) => Ok(Some(ok)), + Err(nom8::Err::Error(_)) => Ok(None), + Err(err) => Err(err), + } + } + + #[allow(dead_code)] + pub(crate) fn trace<I: std::fmt::Debug, O: std::fmt::Debug, E: std::fmt::Debug>( + context: impl std::fmt::Display, + mut parser: impl nom8::Parser<I, O, E>, + ) -> impl FnMut(I) -> IResult<I, O, E> { + static DEPTH: std::sync::atomic::AtomicUsize = std::sync::atomic::AtomicUsize::new(0); + move |input: I| { + let depth = DEPTH.fetch_add(1, std::sync::atomic::Ordering::SeqCst) * 2; + eprintln!("{:depth$}--> {} {:?}", "", context, input); + match parser.parse(input) { + Ok((i, o)) => { + DEPTH.fetch_sub(1, std::sync::atomic::Ordering::SeqCst); + eprintln!("{:depth$}<-- {} {:?}", "", context, i); + Ok((i, o)) + } + Err(err) => { + DEPTH.fetch_sub(1, std::sync::atomic::Ordering::SeqCst); + eprintln!("{:depth$}<-- {} {:?}", "", context, err); + Err(err) + } + } + } + } + + #[cfg(not(feature = "unbounded"))] + #[derive(Copy, Clone, Debug, Default)] + pub(crate) struct RecursionCheck { + current: usize, + } + + #[cfg(not(feature = "unbounded"))] + impl RecursionCheck { + pub(crate) fn check_depth(depth: usize) -> Result<(), super::errors::CustomError> { + if depth < 128 { + Ok(()) + } else { + Err(super::errors::CustomError::RecursionLimitExceeded) + } + } + + pub(crate) fn recursing( + mut self, + input: Input<'_>, + ) -> Result<Self, nom8::Err<ParserError<'_>>> { + self.current += 1; + if self.current < 128 { + Ok(self) + } else { + Err(nom8::Err::Error( + nom8::error::FromExternalError::from_external_error( + input, + nom8::error::ErrorKind::Eof, + super::errors::CustomError::RecursionLimitExceeded, + ), + )) + } + } + } + + #[cfg(feature = "unbounded")] + #[derive(Copy, Clone, Debug, Default)] + pub(crate) struct RecursionCheck {} + + #[cfg(feature = "unbounded")] + impl RecursionCheck { + pub(crate) fn check_depth(_depth: usize) -> Result<(), super::errors::CustomError> { + Ok(()) + } + + pub(crate) fn recursing( + self, + _input: Input<'_>, + ) -> Result<Self, nom8::Err<ParserError<'_>>> { + Ok(self) + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn documents() { + let documents = [ + "", + r#" +# This is a TOML document. + +title = "TOML Example" + + [owner] + name = "Tom Preston-Werner" + dob = 1979-05-27T07:32:00-08:00 # First class dates + + [database] + server = "192.168.1.1" + ports = [ 8001, 8001, 8002 ] + connection_max = 5000 + enabled = true + + [servers] + + # Indentation (tabs and/or spaces) is allowed but not required +[servers.alpha] + ip = "10.0.0.1" + dc = "eqdc10" + + [servers.beta] + ip = "10.0.0.2" + dc = "eqdc10" + + [clients] + data = [ ["gamma", "delta"], [1, 2] ] + + # Line breaks are OK when inside arrays +hosts = [ + "alpha", + "omega" +] + + 'some.wierd .stuff' = """ + like + that + # """ # this broke my sintax highlighting + " also. like " = ''' +that +''' + double = 2e39 # this number looks familiar +# trailing comment"#, + r#""#, + r#" "#, + r#" hello = 'darkness' # my old friend +"#, + r#"[parent . child] +key = "value" +"#, + r#"hello.world = "a" +"#, + r#"foo = 1979-05-27 # Comment +"#, + ]; + for input in documents { + dbg!(input); + let mut parsed = parse_document(input); + if let Ok(parsed) = &mut parsed { + parsed.despan(); + } + let doc = match parsed { + Ok(doc) => doc, + Err(err) => { + panic!( + "Parse error: {:?}\nFailed to parse:\n```\n{}\n```", + err, input + ) + } + }; + + snapbox::assert_eq(input, doc.to_string()); + } + } + + #[test] + fn documents_parse_only() { + let parse_only = ["\u{FEFF} +[package] +name = \"foo\" +version = \"0.0.1\" +authors = [] +"]; + for input in parse_only { + dbg!(input); + let mut parsed = parse_document(input); + if let Ok(parsed) = &mut parsed { + parsed.despan(); + } + match parsed { + Ok(_) => (), + Err(err) => { + panic!( + "Parse error: {:?}\nFailed to parse:\n```\n{}\n```", + err, input + ) + } + } + } + } + + #[test] + fn invalid_documents() { + let invalid_inputs = [r#" hello = 'darkness' # my old friend +$"#]; + for input in invalid_inputs { + dbg!(input); + let mut parsed = parse_document(input); + if let Ok(parsed) = &mut parsed { + parsed.despan(); + } + assert!(parsed.is_err(), "Input: {:?}", input); + } + } +} diff --git a/vendor/toml_edit/src/parser/numbers.rs b/vendor/toml_edit/src/parser/numbers.rs new file mode 100644 index 000000000..5a2a931f7 --- /dev/null +++ b/vendor/toml_edit/src/parser/numbers.rs @@ -0,0 +1,344 @@ +use std::ops::RangeInclusive; + +use nom8::branch::alt; +use nom8::bytes::one_of; +use nom8::bytes::tag; +use nom8::bytes::take; +use nom8::combinator::cut; +use nom8::combinator::opt; +use nom8::combinator::peek; +use nom8::combinator::rest; +use nom8::multi::many0_count; +use nom8::sequence::preceded; + +use crate::parser::prelude::*; +use crate::parser::trivia::from_utf8_unchecked; + +// ;; Boolean + +// boolean = true / false +#[allow(dead_code)] // directly define in `fn value` +pub(crate) fn boolean(input: Input<'_>) -> IResult<Input<'_>, bool, ParserError<'_>> { + alt((true_, false_)).parse(input) +} + +pub(crate) fn true_(input: Input<'_>) -> IResult<Input<'_>, bool, ParserError<'_>> { + (peek(TRUE[0]), cut(TRUE)).value(true).parse(input) +} +const TRUE: &[u8] = b"true"; + +pub(crate) fn false_(input: Input<'_>) -> IResult<Input<'_>, bool, ParserError<'_>> { + (peek(FALSE[0]), cut(FALSE)).value(false).parse(input) +} +const FALSE: &[u8] = b"false"; + +// ;; Integer + +// integer = dec-int / hex-int / oct-int / bin-int +pub(crate) fn integer(input: Input<'_>) -> IResult<Input<'_>, i64, ParserError<'_>> { + dispatch! {peek(opt::<_, &[u8], _, _>(take(2usize))); + Some(b"0x") => cut(hex_int.map_res(|s| i64::from_str_radix(&s.replace('_', ""), 16))), + Some(b"0o") => cut(oct_int.map_res(|s| i64::from_str_radix(&s.replace('_', ""), 8))), + Some(b"0b") => cut(bin_int.map_res(|s| i64::from_str_radix(&s.replace('_', ""), 2))), + _ => dec_int.and_then(cut(rest + .map_res(|s: &str| s.replace('_', "").parse()))) + } + .parse(input) +} + +// dec-int = [ minus / plus ] unsigned-dec-int +// unsigned-dec-int = DIGIT / digit1-9 1*( DIGIT / underscore DIGIT ) +pub(crate) fn dec_int(input: Input<'_>) -> IResult<Input<'_>, &str, ParserError<'_>> { + ( + opt(one_of((b'+', b'-'))), + alt(( + ( + one_of(DIGIT1_9), + many0_count(alt(( + digit.value(()), + ( + one_of(b'_'), + cut(digit).context(Context::Expected(ParserValue::Description("digit"))), + ) + .value(()), + ))), + ) + .value(()), + digit.value(()), + )), + ) + .recognize() + .map(|b: &[u8]| unsafe { from_utf8_unchecked(b, "`digit` and `_` filter out non-ASCII") }) + .context(Context::Expression("integer")) + .parse(input) +} +const DIGIT1_9: RangeInclusive<u8> = b'1'..=b'9'; + +// hex-prefix = %x30.78 ; 0x +// hex-int = hex-prefix HEXDIG *( HEXDIG / underscore HEXDIG ) +pub(crate) fn hex_int(input: Input<'_>) -> IResult<Input<'_>, &str, ParserError<'_>> { + preceded( + HEX_PREFIX, + cut(( + hexdig, + many0_count(alt(( + hexdig.value(()), + ( + one_of(b'_'), + cut(hexdig).context(Context::Expected(ParserValue::Description("digit"))), + ) + .value(()), + ))), + )) + .recognize(), + ) + .map(|b| unsafe { from_utf8_unchecked(b, "`hexdig` and `_` filter out non-ASCII") }) + .context(Context::Expression("hexadecimal integer")) + .parse(input) +} +const HEX_PREFIX: &[u8] = b"0x"; + +// oct-prefix = %x30.6F ; 0o +// oct-int = oct-prefix digit0-7 *( digit0-7 / underscore digit0-7 ) +pub(crate) fn oct_int(input: Input<'_>) -> IResult<Input<'_>, &str, ParserError<'_>> { + preceded( + OCT_PREFIX, + cut(( + one_of(DIGIT0_7), + many0_count(alt(( + one_of(DIGIT0_7).value(()), + ( + one_of(b'_'), + cut(one_of(DIGIT0_7)) + .context(Context::Expected(ParserValue::Description("digit"))), + ) + .value(()), + ))), + )) + .recognize(), + ) + .map(|b| unsafe { from_utf8_unchecked(b, "`DIGIT0_7` and `_` filter out non-ASCII") }) + .context(Context::Expression("octal integer")) + .parse(input) +} +const OCT_PREFIX: &[u8] = b"0o"; +const DIGIT0_7: RangeInclusive<u8> = b'0'..=b'7'; + +// bin-prefix = %x30.62 ; 0b +// bin-int = bin-prefix digit0-1 *( digit0-1 / underscore digit0-1 ) +pub(crate) fn bin_int(input: Input<'_>) -> IResult<Input<'_>, &str, ParserError<'_>> { + preceded( + BIN_PREFIX, + cut(( + one_of(DIGIT0_1), + many0_count(alt(( + one_of(DIGIT0_1).value(()), + ( + one_of(b'_'), + cut(one_of(DIGIT0_1)) + .context(Context::Expected(ParserValue::Description("digit"))), + ) + .value(()), + ))), + )) + .recognize(), + ) + .map(|b| unsafe { from_utf8_unchecked(b, "`DIGIT0_1` and `_` filter out non-ASCII") }) + .context(Context::Expression("binary integer")) + .parse(input) +} +const BIN_PREFIX: &[u8] = b"0b"; +const DIGIT0_1: RangeInclusive<u8> = b'0'..=b'1'; + +// ;; Float + +// float = float-int-part ( exp / frac [ exp ] ) +// float =/ special-float +// float-int-part = dec-int +pub(crate) fn float(input: Input<'_>) -> IResult<Input<'_>, f64, ParserError<'_>> { + alt(( + float_.and_then(cut(rest + .map_res(|s: &str| s.replace('_', "").parse()) + .verify(|f: &f64| *f != f64::INFINITY))), + special_float, + )) + .context(Context::Expression("floating-point number")) + .parse(input) +} + +pub(crate) fn float_(input: Input<'_>) -> IResult<Input<'_>, &str, ParserError<'_>> { + (dec_int, alt((exp, (frac, opt(exp)).map(|_| "")))) + .recognize() + .map(|b: &[u8]| unsafe { + from_utf8_unchecked( + b, + "`dec_int`, `one_of`, `exp`, and `frac` filter out non-ASCII", + ) + }) + .parse(input) +} + +// frac = decimal-point zero-prefixable-int +// decimal-point = %x2E ; . +pub(crate) fn frac(input: Input<'_>) -> IResult<Input<'_>, &str, ParserError<'_>> { + ( + b'.', + cut(zero_prefixable_int).context(Context::Expected(ParserValue::Description("digit"))), + ) + .recognize() + .map(|b: &[u8]| unsafe { + from_utf8_unchecked( + b, + "`.` and `parse_zero_prefixable_int` filter out non-ASCII", + ) + }) + .parse(input) +} + +// zero-prefixable-int = DIGIT *( DIGIT / underscore DIGIT ) +pub(crate) fn zero_prefixable_int(input: Input<'_>) -> IResult<Input<'_>, &str, ParserError<'_>> { + ( + digit, + many0_count(alt(( + digit.value(()), + ( + one_of(b'_'), + cut(digit).context(Context::Expected(ParserValue::Description("digit"))), + ) + .value(()), + ))), + ) + .recognize() + .map(|b: &[u8]| unsafe { from_utf8_unchecked(b, "`digit` and `_` filter out non-ASCII") }) + .parse(input) +} + +// exp = "e" float-exp-part +// float-exp-part = [ minus / plus ] zero-prefixable-int +pub(crate) fn exp(input: Input<'_>) -> IResult<Input<'_>, &str, ParserError<'_>> { + ( + one_of((b'e', b'E')), + opt(one_of([b'+', b'-'])), + cut(zero_prefixable_int), + ) + .recognize() + .map(|b: &[u8]| unsafe { + from_utf8_unchecked( + b, + "`one_of` and `parse_zero_prefixable_int` filter out non-ASCII", + ) + }) + .parse(input) +} + +// special-float = [ minus / plus ] ( inf / nan ) +pub(crate) fn special_float(input: Input<'_>) -> IResult<Input<'_>, f64, ParserError<'_>> { + (opt(one_of((b'+', b'-'))), alt((inf, nan))) + .map(|(s, f)| match s { + Some(b'+') | None => f, + Some(b'-') => -f, + _ => unreachable!("one_of should prevent this"), + }) + .parse(input) +} +// inf = %x69.6e.66 ; inf +pub(crate) fn inf(input: Input<'_>) -> IResult<Input<'_>, f64, ParserError<'_>> { + tag(INF).value(f64::INFINITY).parse(input) +} +const INF: &[u8] = b"inf"; +// nan = %x6e.61.6e ; nan +pub(crate) fn nan(input: Input<'_>) -> IResult<Input<'_>, f64, ParserError<'_>> { + tag(NAN).value(f64::NAN).parse(input) +} +const NAN: &[u8] = b"nan"; + +// DIGIT = %x30-39 ; 0-9 +pub(crate) fn digit(input: Input<'_>) -> IResult<Input<'_>, u8, ParserError<'_>> { + one_of(DIGIT).parse(input) +} +const DIGIT: RangeInclusive<u8> = b'0'..=b'9'; + +// HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" +pub(crate) fn hexdig(input: Input<'_>) -> IResult<Input<'_>, u8, ParserError<'_>> { + one_of(HEXDIG).parse(input) +} +pub(crate) const HEXDIG: (RangeInclusive<u8>, RangeInclusive<u8>, RangeInclusive<u8>) = + (DIGIT, b'A'..=b'F', b'a'..=b'f'); + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn integers() { + let cases = [ + ("+99", 99), + ("42", 42), + ("0", 0), + ("-17", -17), + ("1_000", 1_000), + ("5_349_221", 5_349_221), + ("1_2_3_4_5", 1_2_3_4_5), + ("0xF", 15), + ("0o0_755", 493), + ("0b1_0_1", 5), + (&std::i64::MIN.to_string()[..], std::i64::MIN), + (&std::i64::MAX.to_string()[..], std::i64::MAX), + ]; + for &(input, expected) in &cases { + dbg!(input); + let parsed = integer.parse(new_input(input)).finish(); + assert_eq!(parsed, Ok(expected), "Parsing {input:?}"); + } + + let overflow = "1000000000000000000000000000000000"; + let parsed = integer.parse(new_input(overflow)).finish(); + assert!(parsed.is_err()); + } + + #[track_caller] + fn assert_float_eq(actual: f64, expected: f64) { + if expected.is_nan() { + assert!(actual.is_nan()); + } else if expected.is_infinite() { + assert!(actual.is_infinite()); + assert_eq!(expected.is_sign_positive(), actual.is_sign_positive()); + } else { + dbg!(expected); + dbg!(actual); + assert!((expected - actual).abs() < std::f64::EPSILON); + } + } + + #[test] + fn floats() { + let cases = [ + ("+1.0", 1.0), + ("3.1419", 3.1419), + ("-0.01", -0.01), + ("5e+22", 5e+22), + ("1e6", 1e6), + ("-2E-2", -2E-2), + ("6.626e-34", 6.626e-34), + ("9_224_617.445_991_228_313", 9_224_617.445_991_227), + ("-1.7976931348623157e+308", std::f64::MIN), + ("1.7976931348623157e+308", std::f64::MAX), + ("nan", f64::NAN), + ("+nan", f64::NAN), + ("-nan", f64::NAN), + ("inf", f64::INFINITY), + ("+inf", f64::INFINITY), + ("-inf", f64::NEG_INFINITY), + // ("1e+400", std::f64::INFINITY), + ]; + for &(input, expected) in &cases { + dbg!(input); + let parsed = float.parse(new_input(input)).finish().unwrap(); + assert_float_eq(parsed, expected); + + let overflow = "9e99999"; + let parsed = float.parse(new_input(overflow)).finish(); + assert!(parsed.is_err(), "{:?}", parsed); + } + } +} diff --git a/vendor/toml_edit/src/parser/state.rs b/vendor/toml_edit/src/parser/state.rs new file mode 100644 index 000000000..efa884d2f --- /dev/null +++ b/vendor/toml_edit/src/parser/state.rs @@ -0,0 +1,323 @@ +use crate::key::Key; +use crate::parser::errors::CustomError; +use crate::repr::Decor; +use crate::table::TableKeyValue; +use crate::{ArrayOfTables, Document, InternalString, Item, RawString, Table}; + +pub(crate) struct ParseState { + document: Document, + trailing: Option<std::ops::Range<usize>>, + current_table_position: usize, + current_table: Table, + current_is_array: bool, + current_table_path: Vec<Key>, +} + +impl ParseState { + pub(crate) fn into_document(mut self) -> Result<Document, CustomError> { + self.finalize_table()?; + let trailing = self.trailing.map(RawString::with_span); + self.document.trailing = trailing.unwrap_or_default(); + Ok(self.document) + } + + pub(crate) fn on_ws(&mut self, span: std::ops::Range<usize>) { + if let Some(old) = self.trailing.take() { + self.trailing = Some(old.start..span.end); + } else { + self.trailing = Some(span); + } + } + + pub(crate) fn on_comment(&mut self, span: std::ops::Range<usize>) { + if let Some(old) = self.trailing.take() { + self.trailing = Some(old.start..span.end); + } else { + self.trailing = Some(span); + } + } + + pub(crate) fn on_keyval( + &mut self, + mut path: Vec<Key>, + mut kv: TableKeyValue, + ) -> Result<(), CustomError> { + { + let mut prefix = self.trailing.take(); + let first_key = if path.is_empty() { + &mut kv.key + } else { + &mut path[0] + }; + let prefix = match ( + prefix.take(), + first_key.decor.prefix().and_then(|d| d.span()), + ) { + (Some(p), Some(k)) => Some(p.start..k.end), + (Some(p), None) | (None, Some(p)) => Some(p), + (None, None) => None, + }; + first_key + .decor + .set_prefix(prefix.map(RawString::with_span).unwrap_or_default()); + } + + if let (Some(existing), Some(value)) = (self.current_table.span(), kv.value.span()) { + self.current_table.span = Some((existing.start)..(value.end)); + } + let table = &mut self.current_table; + let table = Self::descend_path(table, &path, true)?; + + // "Likewise, using dotted keys to redefine tables already defined in [table] form is not allowed" + let mixed_table_types = table.is_dotted() == path.is_empty(); + if mixed_table_types { + return Err(CustomError::DuplicateKey { + key: kv.key.get().into(), + table: None, + }); + } + + let key: InternalString = kv.key.get_internal().into(); + match table.items.entry(key) { + indexmap::map::Entry::Vacant(o) => { + o.insert(kv); + } + indexmap::map::Entry::Occupied(o) => { + // "Since tables cannot be defined more than once, redefining such tables using a [table] header is not allowed" + return Err(CustomError::DuplicateKey { + key: o.key().as_str().into(), + table: Some(self.current_table_path.clone()), + }); + } + } + + Ok(()) + } + + pub(crate) fn start_aray_table( + &mut self, + path: Vec<Key>, + decor: Decor, + span: std::ops::Range<usize>, + ) -> Result<(), CustomError> { + debug_assert!(!path.is_empty()); + debug_assert!(self.current_table.is_empty()); + debug_assert!(self.current_table_path.is_empty()); + + // Look up the table on start to ensure the duplicate_key error points to the right line + let root = self.document.as_table_mut(); + let parent_table = Self::descend_path(root, &path[..path.len() - 1], false)?; + let key = &path[path.len() - 1]; + let entry = parent_table + .entry_format(key) + .or_insert(Item::ArrayOfTables(ArrayOfTables::new())); + entry + .as_array_of_tables() + .ok_or_else(|| CustomError::duplicate_key(&path, path.len() - 1))?; + + self.current_table_position += 1; + self.current_table.decor = decor; + self.current_table.set_implicit(false); + self.current_table.set_dotted(false); + self.current_table.set_position(self.current_table_position); + self.current_table.span = Some(span); + self.current_is_array = true; + self.current_table_path = path; + + Ok(()) + } + + pub(crate) fn start_table( + &mut self, + path: Vec<Key>, + decor: Decor, + span: std::ops::Range<usize>, + ) -> Result<(), CustomError> { + debug_assert!(!path.is_empty()); + debug_assert!(self.current_table.is_empty()); + debug_assert!(self.current_table_path.is_empty()); + + // 1. Look up the table on start to ensure the duplicate_key error points to the right line + // 2. Ensure any child tables from an implicit table are preserved + let root = self.document.as_table_mut(); + let parent_table = Self::descend_path(root, &path[..path.len() - 1], false)?; + let key = &path[path.len() - 1]; + if let Some(entry) = parent_table.remove(key.get()) { + match entry { + Item::Table(t) if t.implicit && !t.is_dotted() => { + self.current_table = t; + } + // Since tables cannot be defined more than once, redefining such tables using a [table] header is not allowed. Likewise, using dotted keys to redefine tables already defined in [table] form is not allowed. + _ => return Err(CustomError::duplicate_key(&path, path.len() - 1)), + } + } + + self.current_table_position += 1; + self.current_table.decor = decor; + self.current_table.set_implicit(false); + self.current_table.set_dotted(false); + self.current_table.set_position(self.current_table_position); + self.current_table.span = Some(span); + self.current_is_array = false; + self.current_table_path = path; + + Ok(()) + } + + pub(crate) fn finalize_table(&mut self) -> Result<(), CustomError> { + let mut table = std::mem::take(&mut self.current_table); + let path = std::mem::take(&mut self.current_table_path); + + let root = self.document.as_table_mut(); + if path.is_empty() { + assert!(root.is_empty()); + std::mem::swap(&mut table, root); + } else if self.current_is_array { + let parent_table = Self::descend_path(root, &path[..path.len() - 1], false)?; + let key = &path[path.len() - 1]; + + let entry = parent_table + .entry_format(key) + .or_insert(Item::ArrayOfTables(ArrayOfTables::new())); + let array = entry + .as_array_of_tables_mut() + .ok_or_else(|| CustomError::duplicate_key(&path, path.len() - 1))?; + array.push(table); + let span = if let (Some(first), Some(last)) = ( + array.values.first().and_then(|t| t.span()), + array.values.last().and_then(|t| t.span()), + ) { + Some((first.start)..(last.end)) + } else { + None + }; + array.span = span; + } else { + let parent_table = Self::descend_path(root, &path[..path.len() - 1], false)?; + let key = &path[path.len() - 1]; + + let entry = parent_table.entry_format(key); + match entry { + crate::Entry::Occupied(entry) => { + match entry.into_mut() { + // if [a.b.c] header preceded [a.b] + Item::Table(ref mut t) if t.implicit => { + std::mem::swap(t, &mut table); + } + _ => return Err(CustomError::duplicate_key(&path, path.len() - 1)), + } + } + crate::Entry::Vacant(entry) => { + let item = Item::Table(table); + entry.insert(item); + } + } + } + + Ok(()) + } + + pub(crate) fn descend_path<'t, 'k>( + mut table: &'t mut Table, + path: &'k [Key], + dotted: bool, + ) -> Result<&'t mut Table, CustomError> { + for (i, key) in path.iter().enumerate() { + let entry = table.entry_format(key).or_insert_with(|| { + let mut new_table = Table::new(); + new_table.set_implicit(true); + new_table.set_dotted(dotted); + + Item::Table(new_table) + }); + match *entry { + Item::Value(ref v) => { + return Err(CustomError::extend_wrong_type(path, i, v.type_name())); + } + Item::ArrayOfTables(ref mut array) => { + debug_assert!(!array.is_empty()); + + let index = array.len() - 1; + let last_child = array.get_mut(index).unwrap(); + + table = last_child; + } + Item::Table(ref mut sweet_child_of_mine) => { + // Since tables cannot be defined more than once, redefining such tables using a + // [table] header is not allowed. Likewise, using dotted keys to redefine tables + // already defined in [table] form is not allowed. + if dotted && !sweet_child_of_mine.is_implicit() { + return Err(CustomError::DuplicateKey { + key: key.get().into(), + table: None, + }); + } + table = sweet_child_of_mine; + } + _ => unreachable!(), + } + } + Ok(table) + } + + pub(crate) fn on_std_header( + &mut self, + path: Vec<Key>, + trailing: std::ops::Range<usize>, + span: std::ops::Range<usize>, + ) -> Result<(), CustomError> { + debug_assert!(!path.is_empty()); + + self.finalize_table()?; + let leading = self + .trailing + .take() + .map(RawString::with_span) + .unwrap_or_default(); + self.start_table( + path, + Decor::new(leading, RawString::with_span(trailing)), + span, + )?; + + Ok(()) + } + + pub(crate) fn on_array_header( + &mut self, + path: Vec<Key>, + trailing: std::ops::Range<usize>, + span: std::ops::Range<usize>, + ) -> Result<(), CustomError> { + debug_assert!(!path.is_empty()); + + self.finalize_table()?; + let leading = self + .trailing + .take() + .map(RawString::with_span) + .unwrap_or_default(); + self.start_aray_table( + path, + Decor::new(leading, RawString::with_span(trailing)), + span, + )?; + + Ok(()) + } +} + +impl Default for ParseState { + fn default() -> Self { + let mut root = Table::new(); + root.span = Some(0..0); + Self { + document: Document::new(), + trailing: None, + current_table_position: 0, + current_table: root, + current_is_array: false, + current_table_path: Vec::new(), + } + } +} diff --git a/vendor/toml_edit/src/parser/strings.rs b/vendor/toml_edit/src/parser/strings.rs new file mode 100644 index 000000000..d31c43887 --- /dev/null +++ b/vendor/toml_edit/src/parser/strings.rs @@ -0,0 +1,456 @@ +use std::borrow::Cow; +use std::char; +use std::ops::RangeInclusive; + +use nom8::branch::alt; +use nom8::bytes::any; +use nom8::bytes::none_of; +use nom8::bytes::one_of; +use nom8::bytes::tag; +use nom8::bytes::take_while; +use nom8::bytes::take_while1; +use nom8::bytes::take_while_m_n; +use nom8::combinator::cut; +use nom8::combinator::fail; +use nom8::combinator::opt; +use nom8::combinator::peek; +use nom8::combinator::success; +use nom8::multi::many0_count; +use nom8::multi::many1_count; +use nom8::sequence::delimited; +use nom8::sequence::preceded; +use nom8::sequence::terminated; + +use crate::parser::errors::CustomError; +use crate::parser::numbers::HEXDIG; +use crate::parser::prelude::*; +use crate::parser::trivia::{from_utf8_unchecked, newline, ws, ws_newlines, NON_ASCII, WSCHAR}; + +// ;; String + +// string = ml-basic-string / basic-string / ml-literal-string / literal-string +pub(crate) fn string(input: Input<'_>) -> IResult<Input<'_>, Cow<'_, str>, ParserError<'_>> { + alt(( + ml_basic_string, + basic_string, + ml_literal_string, + literal_string.map(Cow::Borrowed), + )) + .parse(input) +} + +// ;; Basic String + +// basic-string = quotation-mark *basic-char quotation-mark +pub(crate) fn basic_string(input: Input<'_>) -> IResult<Input<'_>, Cow<'_, str>, ParserError<'_>> { + let (mut input, _) = one_of(QUOTATION_MARK).parse(input)?; + + let mut c = Cow::Borrowed(""); + if let Some((i, ci)) = ok_error(basic_chars.parse(input))? { + input = i; + c = ci; + } + while let Some((i, ci)) = ok_error(basic_chars.parse(input))? { + input = i; + c.to_mut().push_str(&ci); + } + + let (input, _) = cut(one_of(QUOTATION_MARK)) + .context(Context::Expression("basic string")) + .parse(input)?; + + Ok((input, c)) +} + +// quotation-mark = %x22 ; " +pub(crate) const QUOTATION_MARK: u8 = b'"'; + +// basic-char = basic-unescaped / escaped +fn basic_chars(input: Input<'_>) -> IResult<Input<'_>, Cow<'_, str>, ParserError<'_>> { + alt(( + // Deviate from the official grammar by batching the unescaped chars so we build a string a + // chunk at a time, rather than a `char` at a time. + take_while1(BASIC_UNESCAPED) + .map_res(std::str::from_utf8) + .map(Cow::Borrowed), + escaped.map(|c| Cow::Owned(String::from(c))), + )) + .parse(input) +} + +// basic-unescaped = wschar / %x21 / %x23-5B / %x5D-7E / non-ascii +pub(crate) const BASIC_UNESCAPED: ( + (u8, u8), + u8, + RangeInclusive<u8>, + RangeInclusive<u8>, + RangeInclusive<u8>, +) = (WSCHAR, 0x21, 0x23..=0x5B, 0x5D..=0x7E, NON_ASCII); + +// escaped = escape escape-seq-char +fn escaped(input: Input<'_>) -> IResult<Input<'_>, char, ParserError<'_>> { + preceded(ESCAPE, escape_seq_char).parse(input) +} + +// escape = %x5C ; \ +pub(crate) const ESCAPE: u8 = b'\\'; + +// escape-seq-char = %x22 ; " quotation mark U+0022 +// escape-seq-char =/ %x5C ; \ reverse solidus U+005C +// escape-seq-char =/ %x62 ; b backspace U+0008 +// escape-seq-char =/ %x66 ; f form feed U+000C +// escape-seq-char =/ %x6E ; n line feed U+000A +// escape-seq-char =/ %x72 ; r carriage return U+000D +// escape-seq-char =/ %x74 ; t tab U+0009 +// escape-seq-char =/ %x75 4HEXDIG ; uXXXX U+XXXX +// escape-seq-char =/ %x55 8HEXDIG ; UXXXXXXXX U+XXXXXXXX +fn escape_seq_char(input: Input<'_>) -> IResult<Input<'_>, char, ParserError<'_>> { + dispatch! {any; + b'b' => success('\u{8}'), + b'f' => success('\u{c}'), + b'n' => success('\n'), + b'r' => success('\r'), + b't' => success('\t'), + b'u' => cut(hexescape::<4>).context(Context::Expression("unicode 4-digit hex code")), + b'U' => cut(hexescape::<8>).context(Context::Expression("unicode 8-digit hex code")), + b'\\' => success('\\'), + b'"' => success('"'), + _ => { + cut(fail::<_, char, _>) + .context(Context::Expression("escape sequence")) + .context(Context::Expected(ParserValue::CharLiteral('b'))) + .context(Context::Expected(ParserValue::CharLiteral('f'))) + .context(Context::Expected(ParserValue::CharLiteral('n'))) + .context(Context::Expected(ParserValue::CharLiteral('r'))) + .context(Context::Expected(ParserValue::CharLiteral('t'))) + .context(Context::Expected(ParserValue::CharLiteral('u'))) + .context(Context::Expected(ParserValue::CharLiteral('U'))) + .context(Context::Expected(ParserValue::CharLiteral('\\'))) + .context(Context::Expected(ParserValue::CharLiteral('"'))) + } + } + .parse(input) +} + +pub(crate) fn hexescape<const N: usize>( + input: Input<'_>, +) -> IResult<Input<'_>, char, ParserError<'_>> { + take_while_m_n(0, N, HEXDIG) + .verify(|b: &[u8]| b.len() == N) + .map(|b: &[u8]| unsafe { from_utf8_unchecked(b, "`is_ascii_digit` filters out on-ASCII") }) + .map_opt(|s| u32::from_str_radix(s, 16).ok()) + .map_res(|h| char::from_u32(h).ok_or(CustomError::OutOfRange)) + .parse(input) +} + +// ;; Multiline Basic String + +// ml-basic-string = ml-basic-string-delim [ newline ] ml-basic-body +// ml-basic-string-delim +fn ml_basic_string(input: Input<'_>) -> IResult<Input<'_>, Cow<'_, str>, ParserError<'_>> { + delimited( + ML_BASIC_STRING_DELIM, + preceded(opt(newline), cut(ml_basic_body)), + cut(ML_BASIC_STRING_DELIM), + ) + .context(Context::Expression("multiline basic string")) + .parse(input) +} + +// ml-basic-string-delim = 3quotation-mark +pub(crate) const ML_BASIC_STRING_DELIM: &[u8] = b"\"\"\""; + +// ml-basic-body = *mlb-content *( mlb-quotes 1*mlb-content ) [ mlb-quotes ] +fn ml_basic_body(mut input: Input<'_>) -> IResult<Input<'_>, Cow<'_, str>, ParserError<'_>> { + let mut c = Cow::Borrowed(""); + if let Some((i, ci)) = ok_error(mlb_content.parse(input))? { + input = i; + c = ci; + } + while let Some((i, ci)) = ok_error(mlb_content.parse(input))? { + input = i; + c.to_mut().push_str(&ci); + } + + while let Some((i, qi)) = ok_error(mlb_quotes(none_of(b'\"').value(())).parse(input))? { + if let Some((i, ci)) = ok_error(mlb_content.parse(i))? { + input = i; + c.to_mut().push_str(qi); + c.to_mut().push_str(&ci); + while let Some((i, ci)) = ok_error(mlb_content.parse(input))? { + input = i; + c.to_mut().push_str(&ci); + } + } else { + break; + } + } + + if let Some((i, qi)) = ok_error(mlb_quotes(tag(ML_BASIC_STRING_DELIM).value(())).parse(input))? + { + input = i; + c.to_mut().push_str(qi); + } + + Ok((input, c)) +} + +// mlb-content = mlb-char / newline / mlb-escaped-nl +// mlb-char = mlb-unescaped / escaped +fn mlb_content(input: Input<'_>) -> IResult<Input<'_>, Cow<'_, str>, ParserError<'_>> { + alt(( + // Deviate from the official grammar by batching the unescaped chars so we build a string a + // chunk at a time, rather than a `char` at a time. + take_while1(MLB_UNESCAPED) + .map_res(std::str::from_utf8) + .map(Cow::Borrowed), + // Order changed fromg grammar so `escaped` can more easily `cut` on bad escape sequences + mlb_escaped_nl.map(|_| Cow::Borrowed("")), + escaped.map(|c| Cow::Owned(String::from(c))), + newline.map(|_| Cow::Borrowed("\n")), + )) + .parse(input) +} + +// mlb-quotes = 1*2quotation-mark +fn mlb_quotes<'i>( + mut term: impl nom8::Parser<Input<'i>, (), ParserError<'i>>, +) -> impl FnMut(Input<'i>) -> IResult<Input<'i>, &str, ParserError<'i>> { + move |input| { + let res = terminated(b"\"\"", peek(term.by_ref())) + .map(|b| unsafe { from_utf8_unchecked(b, "`bytes` out non-ASCII") }) + .parse(input); + + match res { + Err(nom8::Err::Error(_)) => terminated(b"\"", peek(term.by_ref())) + .map(|b| unsafe { from_utf8_unchecked(b, "`bytes` out non-ASCII") }) + .parse(input), + res => res, + } + } +} + +// mlb-unescaped = wschar / %x21 / %x23-5B / %x5D-7E / non-ascii +pub(crate) const MLB_UNESCAPED: ( + (u8, u8), + u8, + RangeInclusive<u8>, + RangeInclusive<u8>, + RangeInclusive<u8>, +) = (WSCHAR, 0x21, 0x23..=0x5B, 0x5D..=0x7E, NON_ASCII); + +// mlb-escaped-nl = escape ws newline *( wschar / newline +// When the last non-whitespace character on a line is a \, +// it will be trimmed along with all whitespace +// (including newlines) up to the next non-whitespace +// character or closing delimiter. +fn mlb_escaped_nl(input: Input<'_>) -> IResult<Input<'_>, (), ParserError<'_>> { + many1_count((ESCAPE, ws, ws_newlines)) + .value(()) + .parse(input) +} + +// ;; Literal String + +// literal-string = apostrophe *literal-char apostrophe +pub(crate) fn literal_string(input: Input<'_>) -> IResult<Input<'_>, &str, ParserError<'_>> { + delimited(APOSTROPHE, cut(take_while(LITERAL_CHAR)), cut(APOSTROPHE)) + .map_res(std::str::from_utf8) + .context(Context::Expression("literal string")) + .parse(input) +} + +// apostrophe = %x27 ; ' apostrophe +pub(crate) const APOSTROPHE: u8 = b'\''; + +// literal-char = %x09 / %x20-26 / %x28-7E / non-ascii +pub(crate) const LITERAL_CHAR: ( + u8, + RangeInclusive<u8>, + RangeInclusive<u8>, + RangeInclusive<u8>, +) = (0x9, 0x20..=0x26, 0x28..=0x7E, NON_ASCII); + +// ;; Multiline Literal String + +// ml-literal-string = ml-literal-string-delim [ newline ] ml-literal-body +// ml-literal-string-delim +fn ml_literal_string(input: Input<'_>) -> IResult<Input<'_>, Cow<'_, str>, ParserError<'_>> { + delimited( + (ML_LITERAL_STRING_DELIM, opt(newline)), + cut(ml_literal_body.map(|t| { + if t.contains("\r\n") { + Cow::Owned(t.replace("\r\n", "\n")) + } else { + Cow::Borrowed(t) + } + })), + cut(ML_LITERAL_STRING_DELIM), + ) + .context(Context::Expression("multiline literal string")) + .parse(input) +} + +// ml-literal-string-delim = 3apostrophe +pub(crate) const ML_LITERAL_STRING_DELIM: &[u8] = b"'''"; + +// ml-literal-body = *mll-content *( mll-quotes 1*mll-content ) [ mll-quotes ] +fn ml_literal_body(input: Input<'_>) -> IResult<Input<'_>, &str, ParserError<'_>> { + ( + many0_count(mll_content), + many0_count(( + mll_quotes(none_of(APOSTROPHE).value(())), + many1_count(mll_content), + )), + opt(mll_quotes(tag(ML_LITERAL_STRING_DELIM).value(()))), + ) + .recognize() + .map_res(std::str::from_utf8) + .parse(input) +} + +// mll-content = mll-char / newline +fn mll_content(input: Input<'_>) -> IResult<Input<'_>, u8, ParserError<'_>> { + alt((one_of(MLL_CHAR), newline)).parse(input) +} + +// mll-char = %x09 / %x20-26 / %x28-7E / non-ascii +const MLL_CHAR: ( + u8, + RangeInclusive<u8>, + RangeInclusive<u8>, + RangeInclusive<u8>, +) = (0x9, 0x20..=0x26, 0x28..=0x7E, NON_ASCII); + +// mll-quotes = 1*2apostrophe +fn mll_quotes<'i>( + mut term: impl nom8::Parser<Input<'i>, (), ParserError<'i>>, +) -> impl FnMut(Input<'i>) -> IResult<Input<'i>, &str, ParserError<'i>> { + move |input| { + let res = terminated(b"''", peek(term.by_ref())) + .map(|b| unsafe { from_utf8_unchecked(b, "`bytes` out non-ASCII") }) + .parse(input); + + match res { + Err(nom8::Err::Error(_)) => terminated(b"'", peek(term.by_ref())) + .map(|b| unsafe { from_utf8_unchecked(b, "`bytes` out non-ASCII") }) + .parse(input), + res => res, + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn basic_string() { + let input = + r#""I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF. \U0002070E""#; + let expected = "I\'m a string. \"You can quote me\". Name\tJosé\nLocation\tSF. \u{2070E}"; + let parsed = string.parse(new_input(input)).finish(); + assert_eq!(parsed.as_deref(), Ok(expected), "Parsing {input:?}"); + } + + #[test] + fn ml_basic_string() { + let cases = [ + ( + r#"""" +Roses are red +Violets are blue""""#, + r#"Roses are red +Violets are blue"#, + ), + (r#"""" \""" """"#, " \"\"\" "), + (r#"""" \\""""#, " \\"), + ]; + + for &(input, expected) in &cases { + let parsed = string.parse(new_input(input)).finish(); + assert_eq!(parsed.as_deref(), Ok(expected), "Parsing {input:?}"); + } + + let invalid_cases = [r#"""" """#, r#"""" \""""#]; + + for input in &invalid_cases { + let parsed = string.parse(new_input(input)).finish(); + assert!(parsed.is_err()); + } + } + + #[test] + fn ml_basic_string_escape_ws() { + let inputs = [ + r#"""" +The quick brown \ + + + fox jumps over \ + the lazy dog.""""#, + r#""""\ + The quick brown \ + fox jumps over \ + the lazy dog.\ + """"#, + ]; + for input in &inputs { + let expected = "The quick brown fox jumps over the lazy dog."; + let parsed = string.parse(new_input(input)).finish(); + assert_eq!(parsed.as_deref(), Ok(expected), "Parsing {input:?}"); + } + let empties = [ + r#""""\ + """"#, + r#"""" +\ + \ +""""#, + ]; + for input in &empties { + let expected = ""; + let parsed = string.parse(new_input(input)).finish(); + assert_eq!(parsed.as_deref(), Ok(expected), "Parsing {input:?}"); + } + } + + #[test] + fn literal_string() { + let inputs = [ + r#"'C:\Users\nodejs\templates'"#, + r#"'\\ServerX\admin$\system32\'"#, + r#"'Tom "Dubs" Preston-Werner'"#, + r#"'<\i\c*\s*>'"#, + ]; + + for input in &inputs { + let expected = &input[1..input.len() - 1]; + let parsed = string.parse(new_input(input)).finish(); + assert_eq!(parsed.as_deref(), Ok(expected), "Parsing {input:?}"); + } + } + + #[test] + fn ml_literal_string() { + let inputs = [ + r#"'''I [dw]on't need \d{2} apples'''"#, + r#"''''one_quote''''"#, + ]; + for input in &inputs { + let expected = &input[3..input.len() - 3]; + let parsed = string.parse(new_input(input)).finish(); + assert_eq!(parsed.as_deref(), Ok(expected), "Parsing {input:?}"); + } + + let input = r#"''' +The first newline is +trimmed in raw strings. + All other whitespace + is preserved. +'''"#; + let expected = &input[4..input.len() - 3]; + let parsed = string.parse(new_input(input)).finish(); + assert_eq!(parsed.as_deref(), Ok(expected), "Parsing {input:?}"); + } +} diff --git a/vendor/toml_edit/src/parser/table.rs b/vendor/toml_edit/src/parser/table.rs new file mode 100644 index 000000000..1c76ed19b --- /dev/null +++ b/vendor/toml_edit/src/parser/table.rs @@ -0,0 +1,89 @@ +use std::cell::RefCell; +#[allow(unused_imports)] +use std::ops::DerefMut; + +use nom8::bytes::take; +use nom8::combinator::cut; +use nom8::combinator::peek; +use nom8::sequence::delimited; + +// https://github.com/rust-lang/rust/issues/41358 +use crate::parser::key::key; +use crate::parser::prelude::*; +use crate::parser::state::ParseState; +use crate::parser::trivia::line_trailing; + +// std-table-open = %x5B ws ; [ Left square bracket +pub(crate) const STD_TABLE_OPEN: u8 = b'['; +// std-table-close = ws %x5D ; ] Right square bracket +const STD_TABLE_CLOSE: u8 = b']'; +// array-table-open = %x5B.5B ws ; [[ Double left square bracket +const ARRAY_TABLE_OPEN: &[u8] = b"[["; +// array-table-close = ws %x5D.5D ; ]] Double right quare bracket +const ARRAY_TABLE_CLOSE: &[u8] = b"]]"; + +// ;; Standard Table + +// std-table = std-table-open key *( table-key-sep key) std-table-close +pub(crate) fn std_table<'s, 'i>( + state: &'s RefCell<ParseState>, +) -> impl FnMut(Input<'i>) -> IResult<Input<'i>, (), ParserError<'i>> + 's { + move |i| { + ( + delimited( + STD_TABLE_OPEN, + cut(key), + cut(STD_TABLE_CLOSE) + .context(Context::Expected(ParserValue::CharLiteral('.'))) + .context(Context::Expected(ParserValue::StringLiteral("]"))), + ) + .with_span(), + cut(line_trailing) + .context(Context::Expected(ParserValue::CharLiteral('\n'))) + .context(Context::Expected(ParserValue::CharLiteral('#'))), + ) + .map_res(|((h, span), t)| state.borrow_mut().deref_mut().on_std_header(h, t, span)) + .parse(i) + } +} + +// ;; Array Table + +// array-table = array-table-open key *( table-key-sep key) array-table-close +pub(crate) fn array_table<'s, 'i>( + state: &'s RefCell<ParseState>, +) -> impl FnMut(Input<'i>) -> IResult<Input<'i>, (), ParserError<'i>> + 's { + move |i| { + ( + delimited( + ARRAY_TABLE_OPEN, + cut(key), + cut(ARRAY_TABLE_CLOSE) + .context(Context::Expected(ParserValue::CharLiteral('.'))) + .context(Context::Expected(ParserValue::StringLiteral("]]"))), + ) + .with_span(), + cut(line_trailing) + .context(Context::Expected(ParserValue::CharLiteral('\n'))) + .context(Context::Expected(ParserValue::CharLiteral('#'))), + ) + .map_res(|((h, span), t)| state.borrow_mut().deref_mut().on_array_header(h, t, span)) + .parse(i) + } +} + +// ;; Table + +// table = std-table / array-table +pub(crate) fn table<'s, 'i>( + state: &'s RefCell<ParseState>, +) -> impl FnMut(Input<'i>) -> IResult<Input<'i>, (), ParserError<'i>> + 's { + move |i| { + dispatch!(peek::<_, &[u8],_,_>(take(2usize)); + b"[[" => array_table(state), + _ => std_table(state), + ) + .context(Context::Expression("table header")) + .parse(i) + } +} diff --git a/vendor/toml_edit/src/parser/trivia.rs b/vendor/toml_edit/src/parser/trivia.rs new file mode 100644 index 000000000..981c7b23d --- /dev/null +++ b/vendor/toml_edit/src/parser/trivia.rs @@ -0,0 +1,150 @@ +use std::ops::RangeInclusive; + +use nom8::branch::alt; +use nom8::bytes::one_of; +use nom8::bytes::take_while; +use nom8::bytes::take_while1; +use nom8::combinator::eof; +use nom8::combinator::opt; +use nom8::multi::many0_count; +use nom8::multi::many1_count; +use nom8::prelude::*; +use nom8::sequence::terminated; + +use crate::parser::prelude::*; + +pub(crate) unsafe fn from_utf8_unchecked<'b>( + bytes: &'b [u8], + safety_justification: &'static str, +) -> &'b str { + if cfg!(debug_assertions) { + // Catch problems more quickly when testing + std::str::from_utf8(bytes).expect(safety_justification) + } else { + std::str::from_utf8_unchecked(bytes) + } +} + +// wschar = ( %x20 / ; Space +// %x09 ) ; Horizontal tab +pub(crate) const WSCHAR: (u8, u8) = (b' ', b'\t'); + +// ws = *wschar +pub(crate) fn ws(input: Input<'_>) -> IResult<Input<'_>, &str, ParserError<'_>> { + take_while(WSCHAR) + .map(|b| unsafe { from_utf8_unchecked(b, "`is_wschar` filters out on-ASCII") }) + .parse(input) +} + +// non-ascii = %x80-D7FF / %xE000-10FFFF +// - ASCII is 0xxxxxxx +// - First byte for UTF-8 is 11xxxxxx +// - Subsequent UTF-8 bytes are 10xxxxxx +pub(crate) const NON_ASCII: RangeInclusive<u8> = 0x80..=0xff; + +// non-eol = %x09 / %x20-7E / non-ascii +pub(crate) const NON_EOL: (u8, RangeInclusive<u8>, RangeInclusive<u8>) = + (0x09, 0x20..=0x7E, NON_ASCII); + +// comment-start-symbol = %x23 ; # +pub(crate) const COMMENT_START_SYMBOL: u8 = b'#'; + +// comment = comment-start-symbol *non-eol +pub(crate) fn comment(input: Input<'_>) -> IResult<Input<'_>, &[u8], ParserError<'_>> { + (COMMENT_START_SYMBOL, take_while(NON_EOL)) + .recognize() + .parse(input) +} + +// newline = ( %x0A / ; LF +// %x0D.0A ) ; CRLF +pub(crate) fn newline(input: Input<'_>) -> IResult<Input<'_>, u8, ParserError<'_>> { + alt(( + one_of(LF).value(b'\n'), + (one_of(CR), one_of(LF)).value(b'\n'), + )) + .parse(input) +} +pub(crate) const LF: u8 = b'\n'; +pub(crate) const CR: u8 = b'\r'; + +// ws-newline = *( wschar / newline ) +pub(crate) fn ws_newline(input: Input<'_>) -> IResult<Input<'_>, &str, ParserError<'_>> { + many0_count(alt((newline.value(&b"\n"[..]), take_while1(WSCHAR)))) + .recognize() + .map(|b| unsafe { + from_utf8_unchecked(b, "`is_wschar` and `newline` filters out on-ASCII") + }) + .parse(input) +} + +// ws-newlines = newline *( wschar / newline ) +pub(crate) fn ws_newlines(input: Input<'_>) -> IResult<Input<'_>, &str, ParserError<'_>> { + (newline, ws_newline) + .recognize() + .map(|b| unsafe { + from_utf8_unchecked(b, "`is_wschar` and `newline` filters out on-ASCII") + }) + .parse(input) +} + +// note: this rule is not present in the original grammar +// ws-comment-newline = *( ws-newline-nonempty / comment ) +pub(crate) fn ws_comment_newline(input: Input<'_>) -> IResult<Input<'_>, &[u8], ParserError<'_>> { + many0_count(alt(( + many1_count(alt((take_while1(WSCHAR), newline.value(&b"\n"[..])))).value(()), + comment.value(()), + ))) + .recognize() + .parse(input) +} + +// note: this rule is not present in the original grammar +// line-ending = newline / eof +pub(crate) fn line_ending(input: Input<'_>) -> IResult<Input<'_>, &str, ParserError<'_>> { + alt((newline.value("\n"), eof.value(""))).parse(input) +} + +// note: this rule is not present in the original grammar +// line-trailing = ws [comment] skip-line-ending +pub(crate) fn line_trailing( + input: Input<'_>, +) -> IResult<Input<'_>, std::ops::Range<usize>, ParserError<'_>> { + terminated((ws, opt(comment)).span(), line_ending).parse(input) +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn trivia() { + let inputs = [ + "", + r#" "#, + r#" +"#, + r#" +# comment + +# comment2 + + +"#, + r#" + "#, + r#"# comment +# comment2 + + + "#, + ]; + for input in inputs { + dbg!(input); + let parsed = ws_comment_newline.parse(new_input(input)).finish(); + assert!(parsed.is_ok(), "{:?}", parsed); + let parsed = parsed.unwrap(); + assert_eq!(parsed, input.as_bytes()); + } + } +} diff --git a/vendor/toml_edit/src/parser/value.rs b/vendor/toml_edit/src/parser/value.rs new file mode 100644 index 000000000..15ba4478e --- /dev/null +++ b/vendor/toml_edit/src/parser/value.rs @@ -0,0 +1,157 @@ +use nom8::branch::alt; +use nom8::bytes::any; +use nom8::combinator::fail; +use nom8::combinator::peek; + +use crate::parser::array::array; +use crate::parser::datetime::date_time; +use crate::parser::inline_table::inline_table; +use crate::parser::numbers::{float, integer}; +use crate::parser::prelude::*; +use crate::parser::strings::string; +use crate::repr::{Formatted, Repr}; +use crate::value as v; +use crate::RawString; +use crate::Value; + +// val = string / boolean / array / inline-table / date-time / float / integer +pub(crate) fn value( + check: RecursionCheck, +) -> impl FnMut(Input<'_>) -> IResult<Input<'_>, v::Value, ParserError<'_>> { + move |input| { + dispatch!{peek(any); + crate::parser::strings::QUOTATION_MARK | + crate::parser::strings::APOSTROPHE => string.map(|s| { + v::Value::String(Formatted::new( + s.into_owned() + )) + }), + crate::parser::array::ARRAY_OPEN => array(check).map(v::Value::Array), + crate::parser::inline_table::INLINE_TABLE_OPEN => inline_table(check).map(v::Value::InlineTable), + // Date/number starts + b'+' | b'-' | b'0'..=b'9' => { + // Uncommon enough not to be worth optimizing at this time + alt(( + date_time + .map(v::Value::from), + float + .map(v::Value::from), + integer + .map(v::Value::from), + )) + }, + // Report as if they were numbers because its most likely a typo + b'_' => { + integer + .map(v::Value::from) + .context(Context::Expected(ParserValue::Description("leading digit"))) + }, + // Report as if they were numbers because its most likely a typo + b'.' => { + float + .map(v::Value::from) + .context(Context::Expected(ParserValue::Description("leading digit"))) + }, + b't' => { + crate::parser::numbers::true_.map(v::Value::from) + .context(Context::Expression("string")) + .context(Context::Expected(ParserValue::CharLiteral('"'))) + .context(Context::Expected(ParserValue::CharLiteral('\''))) + }, + b'f' => { + crate::parser::numbers::false_.map(v::Value::from) + .context(Context::Expression("string")) + .context(Context::Expected(ParserValue::CharLiteral('"'))) + .context(Context::Expected(ParserValue::CharLiteral('\''))) + }, + b'i' => { + crate::parser::numbers::inf.map(v::Value::from) + .context(Context::Expression("string")) + .context(Context::Expected(ParserValue::CharLiteral('"'))) + .context(Context::Expected(ParserValue::CharLiteral('\''))) + }, + b'n' => { + crate::parser::numbers::nan.map(v::Value::from) + .context(Context::Expression("string")) + .context(Context::Expected(ParserValue::CharLiteral('"'))) + .context(Context::Expected(ParserValue::CharLiteral('\''))) + }, + _ => { + fail + .context(Context::Expression("string")) + .context(Context::Expected(ParserValue::CharLiteral('"'))) + .context(Context::Expected(ParserValue::CharLiteral('\''))) + }, + } + .with_span() + .map_res(|(value, span)| apply_raw(value, span)) + .parse(input) + } +} + +fn apply_raw(mut val: Value, span: std::ops::Range<usize>) -> Result<Value, std::str::Utf8Error> { + match val { + Value::String(ref mut f) => { + let raw = RawString::with_span(span); + f.set_repr_unchecked(Repr::new_unchecked(raw)); + } + Value::Integer(ref mut f) => { + let raw = RawString::with_span(span); + f.set_repr_unchecked(Repr::new_unchecked(raw)); + } + Value::Float(ref mut f) => { + let raw = RawString::with_span(span); + f.set_repr_unchecked(Repr::new_unchecked(raw)); + } + Value::Boolean(ref mut f) => { + let raw = RawString::with_span(span); + f.set_repr_unchecked(Repr::new_unchecked(raw)); + } + Value::Datetime(ref mut f) => { + let raw = RawString::with_span(span); + f.set_repr_unchecked(Repr::new_unchecked(raw)); + } + Value::Array(ref mut arr) => { + arr.span = Some(span); + } + Value::InlineTable(ref mut table) => { + table.span = Some(span); + } + }; + val.decorate("", ""); + Ok(val) +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn values() { + let inputs = [ + "1979-05-27T00:32:00.999999", + "-239", + "1e200", + "9_224_617.445_991_228_313", + r#"'''I [dw]on't need \d{2} apples'''"#, + r#"''' +The first newline is +trimmed in raw strings. + All other whitespace + is preserved. +'''"#, + r#""Jos\u00E9\n""#, + r#""\\\"\b/\f\n\r\t\u00E9\U000A0000""#, + r#"{ hello = "world", a = 1}"#, + r#"[ { x = 1, a = "2" }, {a = "a",b = "b", c = "c"} ]"#, + ]; + for input in inputs { + dbg!(input); + let mut parsed = value(Default::default()).parse(new_input(input)).finish(); + if let Ok(parsed) = &mut parsed { + parsed.despan(input); + } + assert_eq!(parsed.map(|a| a.to_string()), Ok(input.to_owned())); + } + } +} diff --git a/vendor/toml_edit/src/raw_string.rs b/vendor/toml_edit/src/raw_string.rs new file mode 100644 index 000000000..c5961f133 --- /dev/null +++ b/vendor/toml_edit/src/raw_string.rs @@ -0,0 +1,182 @@ +use crate::InternalString; + +/// Opaque string storage for raw TOML; internal to `toml_edit` +#[derive(PartialEq, Eq, Clone, Hash)] +pub struct RawString(RawStringInner); + +#[derive(PartialEq, Eq, Clone, Hash)] +enum RawStringInner { + Empty, + Explicit(InternalString), + Spanned(std::ops::Range<usize>), +} + +impl RawString { + pub(crate) fn with_span(span: std::ops::Range<usize>) -> Self { + if span.start == span.end { + RawString(RawStringInner::Empty) + } else { + RawString(RawStringInner::Spanned(span)) + } + } + + /// Access the underlying string + pub fn as_str(&self) -> Option<&str> { + match &self.0 { + RawStringInner::Empty => Some(""), + RawStringInner::Explicit(s) => Some(s.as_str()), + RawStringInner::Spanned(_) => None, + } + } + + pub(crate) fn to_str<'s>(&'s self, input: &'s str) -> &'s str { + match &self.0 { + RawStringInner::Empty => "", + RawStringInner::Explicit(s) => s.as_str(), + RawStringInner::Spanned(span) => input.get(span.clone()).unwrap_or_else(|| { + panic!("span {:?} should be in input:\n```\n{}\n```", span, input) + }), + } + } + + pub(crate) fn to_str_with_default<'s>( + &'s self, + input: Option<&'s str>, + default: &'s str, + ) -> &'s str { + match &self.0 { + RawStringInner::Empty => "", + RawStringInner::Explicit(s) => s.as_str(), + RawStringInner::Spanned(span) => { + if let Some(input) = input { + input.get(span.clone()).unwrap_or_else(|| { + panic!("span {:?} should be in input:\n```\n{}\n```", span, input) + }) + } else { + default + } + } + } + } + + /// Access the underlying span + pub(crate) fn span(&self) -> Option<std::ops::Range<usize>> { + match &self.0 { + RawStringInner::Empty => None, + RawStringInner::Explicit(_) => None, + RawStringInner::Spanned(span) => Some(span.clone()), + } + } + + pub(crate) fn despan(&mut self, input: &str) { + match &self.0 { + RawStringInner::Empty => {} + RawStringInner::Explicit(_) => {} + RawStringInner::Spanned(span) => { + *self = Self::from(input.get(span.clone()).unwrap_or_else(|| { + panic!("span {:?} should be in input:\n```\n{}\n```", span, input) + })) + } + } + } + + pub(crate) fn encode(&self, buf: &mut dyn std::fmt::Write, input: &str) -> std::fmt::Result { + let raw = self.to_str(input); + for part in raw.split('\r') { + write!(buf, "{}", part)?; + } + Ok(()) + } + + pub(crate) fn encode_with_default( + &self, + buf: &mut dyn std::fmt::Write, + input: Option<&str>, + default: &str, + ) -> std::fmt::Result { + let raw = self.to_str_with_default(input, default); + for part in raw.split('\r') { + write!(buf, "{}", part)?; + } + Ok(()) + } +} + +impl Default for RawString { + fn default() -> Self { + Self(RawStringInner::Empty) + } +} + +impl std::fmt::Debug for RawString { + #[inline] + fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + match &self.0 { + RawStringInner::Empty => write!(formatter, "empty"), + RawStringInner::Explicit(s) => write!(formatter, "{:?}", s), + RawStringInner::Spanned(s) => write!(formatter, "{:?}", s), + } + } +} + +impl From<&str> for RawString { + #[inline] + fn from(s: &str) -> Self { + if s.is_empty() { + Self(RawStringInner::Empty) + } else { + InternalString::from(s).into() + } + } +} + +impl From<String> for RawString { + #[inline] + fn from(s: String) -> Self { + if s.is_empty() { + Self(RawStringInner::Empty) + } else { + InternalString::from(s).into() + } + } +} + +impl From<&String> for RawString { + #[inline] + fn from(s: &String) -> Self { + if s.is_empty() { + Self(RawStringInner::Empty) + } else { + InternalString::from(s).into() + } + } +} + +impl From<InternalString> for RawString { + #[inline] + fn from(inner: InternalString) -> Self { + Self(RawStringInner::Explicit(inner)) + } +} + +impl From<&InternalString> for RawString { + #[inline] + fn from(s: &InternalString) -> Self { + if s.is_empty() { + Self(RawStringInner::Empty) + } else { + InternalString::from(s).into() + } + } +} + +impl From<Box<str>> for RawString { + #[inline] + fn from(s: Box<str>) -> Self { + if s.is_empty() { + Self(RawStringInner::Empty) + } else { + InternalString::from(s).into() + } + } +} diff --git a/vendor/toml_edit/src/repr.rs b/vendor/toml_edit/src/repr.rs new file mode 100644 index 000000000..d4ab6c231 --- /dev/null +++ b/vendor/toml_edit/src/repr.rs @@ -0,0 +1,253 @@ +use std::borrow::Cow; + +use crate::RawString; + +/// A value together with its `to_string` representation, +/// including surrounding it whitespaces and comments. +#[derive(Eq, PartialEq, Clone, Hash)] +pub struct Formatted<T> { + value: T, + repr: Option<Repr>, + decor: Decor, +} + +impl<T> Formatted<T> +where + T: ValueRepr, +{ + /// Default-formatted value + pub fn new(value: T) -> Self { + Self { + value, + repr: None, + decor: Default::default(), + } + } + + pub(crate) fn set_repr_unchecked(&mut self, repr: Repr) { + self.repr = Some(repr); + } + + /// The wrapped value + pub fn value(&self) -> &T { + &self.value + } + + /// The wrapped value + pub fn into_value(self) -> T { + self.value + } + + /// Returns the raw representation, if available. + pub fn as_repr(&self) -> Option<&Repr> { + self.repr.as_ref() + } + + /// Returns the default raw representation. + pub fn default_repr(&self) -> Repr { + self.value.to_repr() + } + + /// Returns a raw representation. + pub fn display_repr(&self) -> Cow<str> { + self.as_repr() + .and_then(|r| r.as_raw().as_str()) + .map(Cow::Borrowed) + .unwrap_or_else(|| { + Cow::Owned(self.default_repr().as_raw().as_str().unwrap().to_owned()) + }) + } + + /// Returns the location within the original document + pub(crate) fn span(&self) -> Option<std::ops::Range<usize>> { + self.repr.as_ref().and_then(|r| r.span()) + } + + pub(crate) fn despan(&mut self, input: &str) { + self.decor.despan(input); + if let Some(repr) = &mut self.repr { + repr.despan(input); + } + } + + /// Returns the surrounding whitespace + pub fn decor_mut(&mut self) -> &mut Decor { + &mut self.decor + } + + /// Returns the surrounding whitespace + pub fn decor(&self) -> &Decor { + &self.decor + } + + /// Auto formats the value. + pub fn fmt(&mut self) { + self.repr = Some(self.value.to_repr()); + } +} + +impl<T> std::fmt::Debug for Formatted<T> +where + T: std::fmt::Debug, +{ + #[inline] + fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + let mut d = formatter.debug_struct("Formatted"); + d.field("value", &self.value); + match &self.repr { + Some(r) => d.field("repr", r), + None => d.field("repr", &"default"), + }; + d.field("decor", &self.decor); + d.finish() + } +} + +impl<T> std::fmt::Display for Formatted<T> +where + T: ValueRepr, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + crate::encode::Encode::encode(self, f, None, ("", "")) + } +} + +pub trait ValueRepr: crate::private::Sealed { + /// The TOML representation of the value + fn to_repr(&self) -> Repr; +} + +/// TOML-encoded value +#[derive(Eq, PartialEq, Clone, Hash)] +pub struct Repr { + raw_value: RawString, +} + +impl Repr { + pub(crate) fn new_unchecked(raw: impl Into<RawString>) -> Self { + Repr { + raw_value: raw.into(), + } + } + + /// Access the underlying value + pub fn as_raw(&self) -> &RawString { + &self.raw_value + } + + /// Returns the location within the original document + pub(crate) fn span(&self) -> Option<std::ops::Range<usize>> { + self.raw_value.span() + } + + pub(crate) fn despan(&mut self, input: &str) { + self.raw_value.despan(input) + } + + pub(crate) fn encode(&self, buf: &mut dyn std::fmt::Write, input: &str) -> std::fmt::Result { + self.as_raw().encode(buf, input) + } +} + +impl std::fmt::Debug for Repr { + #[inline] + fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + self.raw_value.fmt(formatter) + } +} + +/// A prefix and suffix, +/// +/// Including comments, whitespaces and newlines. +#[derive(Eq, PartialEq, Clone, Default, Hash)] +pub struct Decor { + prefix: Option<RawString>, + suffix: Option<RawString>, +} + +impl Decor { + /// Creates a new decor from the given prefix and suffix. + pub fn new(prefix: impl Into<RawString>, suffix: impl Into<RawString>) -> Self { + Self { + prefix: Some(prefix.into()), + suffix: Some(suffix.into()), + } + } + + /// Go back to default decor + pub fn clear(&mut self) { + self.prefix = None; + self.suffix = None; + } + + /// Get the prefix. + pub fn prefix(&self) -> Option<&RawString> { + self.prefix.as_ref() + } + + pub(crate) fn prefix_encode( + &self, + buf: &mut dyn std::fmt::Write, + input: Option<&str>, + default: &str, + ) -> std::fmt::Result { + if let Some(prefix) = self.prefix() { + prefix.encode_with_default(buf, input, default) + } else { + write!(buf, "{}", default) + } + } + + /// Set the prefix. + pub fn set_prefix(&mut self, prefix: impl Into<RawString>) { + self.prefix = Some(prefix.into()); + } + + /// Get the suffix. + pub fn suffix(&self) -> Option<&RawString> { + self.suffix.as_ref() + } + + pub(crate) fn suffix_encode( + &self, + buf: &mut dyn std::fmt::Write, + input: Option<&str>, + default: &str, + ) -> std::fmt::Result { + if let Some(suffix) = self.suffix() { + suffix.encode_with_default(buf, input, default) + } else { + write!(buf, "{}", default) + } + } + + /// Set the suffix. + pub fn set_suffix(&mut self, suffix: impl Into<RawString>) { + self.suffix = Some(suffix.into()); + } + + pub(crate) fn despan(&mut self, input: &str) { + if let Some(prefix) = &mut self.prefix { + prefix.despan(input); + } + if let Some(suffix) = &mut self.suffix { + suffix.despan(input); + } + } +} + +impl std::fmt::Debug for Decor { + #[inline] + fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + let mut d = formatter.debug_struct("Decor"); + match &self.prefix { + Some(r) => d.field("prefix", r), + None => d.field("prefix", &"default"), + }; + match &self.suffix { + Some(r) => d.field("suffix", r), + None => d.field("suffix", &"default"), + }; + d.finish() + } +} diff --git a/vendor/toml_edit/src/ser/array.rs b/vendor/toml_edit/src/ser/array.rs new file mode 100644 index 000000000..80eba8ba7 --- /dev/null +++ b/vendor/toml_edit/src/ser/array.rs @@ -0,0 +1,84 @@ +use super::Error; + +#[doc(hidden)] +pub struct SerializeValueArray { + values: Vec<crate::Item>, +} + +impl SerializeValueArray { + pub(crate) fn new() -> Self { + Self { values: Vec::new() } + } + + pub(crate) fn with_capacity(len: usize) -> Self { + Self { + values: Vec::with_capacity(len), + } + } +} + +impl serde::ser::SerializeSeq for SerializeValueArray { + type Ok = crate::Value; + type Error = Error; + + fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error> + where + T: serde::ser::Serialize, + { + let value = value.serialize(super::ValueSerializer {})?; + self.values.push(crate::Item::Value(value)); + Ok(()) + } + + fn end(self) -> Result<Self::Ok, Self::Error> { + Ok(crate::Value::Array(crate::Array::with_vec(self.values))) + } +} + +impl serde::ser::SerializeTuple for SerializeValueArray { + type Ok = crate::Value; + type Error = Error; + + fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error> + where + T: serde::ser::Serialize, + { + serde::ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result<Self::Ok, Self::Error> { + serde::ser::SerializeSeq::end(self) + } +} + +impl serde::ser::SerializeTupleVariant for SerializeValueArray { + type Ok = crate::Value; + type Error = Error; + + fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error> + where + T: serde::ser::Serialize, + { + serde::ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result<Self::Ok, Self::Error> { + serde::ser::SerializeSeq::end(self) + } +} + +impl serde::ser::SerializeTupleStruct for SerializeValueArray { + type Ok = crate::Value; + type Error = Error; + + fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error> + where + T: serde::ser::Serialize, + { + serde::ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result<Self::Ok, Self::Error> { + serde::ser::SerializeSeq::end(self) + } +} diff --git a/vendor/toml_edit/src/ser/key.rs b/vendor/toml_edit/src/ser/key.rs new file mode 100644 index 000000000..d5e381bf7 --- /dev/null +++ b/vendor/toml_edit/src/ser/key.rs @@ -0,0 +1,173 @@ +use crate::InternalString; + +use super::Error; + +pub(crate) struct KeySerializer; + +impl serde::ser::Serializer for KeySerializer { + type Ok = InternalString; + type Error = Error; + type SerializeSeq = serde::ser::Impossible<InternalString, Error>; + type SerializeTuple = serde::ser::Impossible<InternalString, Error>; + type SerializeTupleStruct = serde::ser::Impossible<InternalString, Error>; + type SerializeTupleVariant = serde::ser::Impossible<InternalString, Error>; + type SerializeMap = serde::ser::Impossible<InternalString, Error>; + type SerializeStruct = serde::ser::Impossible<InternalString, Error>; + type SerializeStructVariant = serde::ser::Impossible<InternalString, Error>; + + fn serialize_bool(self, _v: bool) -> Result<InternalString, Self::Error> { + Err(Error::KeyNotString) + } + + fn serialize_i8(self, _v: i8) -> Result<InternalString, Self::Error> { + Err(Error::KeyNotString) + } + + fn serialize_i16(self, _v: i16) -> Result<InternalString, Self::Error> { + Err(Error::KeyNotString) + } + + fn serialize_i32(self, _v: i32) -> Result<InternalString, Self::Error> { + Err(Error::KeyNotString) + } + + fn serialize_i64(self, _v: i64) -> Result<InternalString, Self::Error> { + Err(Error::KeyNotString) + } + + fn serialize_u8(self, _v: u8) -> Result<InternalString, Self::Error> { + Err(Error::KeyNotString) + } + + fn serialize_u16(self, _v: u16) -> Result<InternalString, Self::Error> { + Err(Error::KeyNotString) + } + + fn serialize_u32(self, _v: u32) -> Result<InternalString, Self::Error> { + Err(Error::KeyNotString) + } + + fn serialize_u64(self, _v: u64) -> Result<InternalString, Self::Error> { + Err(Error::KeyNotString) + } + + fn serialize_f32(self, _v: f32) -> Result<InternalString, Self::Error> { + Err(Error::KeyNotString) + } + + fn serialize_f64(self, _v: f64) -> Result<InternalString, Self::Error> { + Err(Error::KeyNotString) + } + + fn serialize_char(self, _v: char) -> Result<InternalString, Self::Error> { + Err(Error::KeyNotString) + } + + fn serialize_str(self, value: &str) -> Result<InternalString, Self::Error> { + Ok(InternalString::from(value)) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result<InternalString, Self::Error> { + Err(Error::KeyNotString) + } + + fn serialize_none(self) -> Result<InternalString, Self::Error> { + Err(Error::KeyNotString) + } + + fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<InternalString, Self::Error> + where + T: serde::ser::Serialize, + { + Err(Error::KeyNotString) + } + + fn serialize_unit(self) -> Result<InternalString, Self::Error> { + Err(Error::KeyNotString) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result<InternalString, Self::Error> { + Err(Error::KeyNotString) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result<InternalString, Self::Error> { + Ok(variant.into()) + } + + fn serialize_newtype_struct<T: ?Sized>( + self, + _name: &'static str, + value: &T, + ) -> Result<InternalString, Self::Error> + where + T: serde::ser::Serialize, + { + value.serialize(self) + } + + fn serialize_newtype_variant<T: ?Sized>( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result<InternalString, Self::Error> + where + T: serde::ser::Serialize, + { + Err(Error::KeyNotString) + } + + fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> { + Err(Error::KeyNotString) + } + + fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> { + Err(Error::KeyNotString) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleStruct, Self::Error> { + Err(Error::KeyNotString) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleVariant, Self::Error> { + Err(Error::KeyNotString) + } + + fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> { + Err(Error::KeyNotString) + } + + fn serialize_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeStruct, Self::Error> { + Err(Error::KeyNotString) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeStructVariant, Self::Error> { + Err(Error::KeyNotString) + } +} diff --git a/vendor/toml_edit/src/ser/map.rs b/vendor/toml_edit/src/ser/map.rs new file mode 100644 index 000000000..d743e3d5d --- /dev/null +++ b/vendor/toml_edit/src/ser/map.rs @@ -0,0 +1,405 @@ +use super::{Error, KeySerializer}; + +#[doc(hidden)] +pub enum SerializeMap { + Datetime(SerializeDatetime), + Table(SerializeInlineTable), +} + +impl SerializeMap { + pub(crate) fn table() -> Self { + Self::Table(SerializeInlineTable::new()) + } + + pub(crate) fn table_with_capacity(len: usize) -> Self { + Self::Table(SerializeInlineTable::with_capacity(len)) + } + + pub(crate) fn datetime() -> Self { + Self::Datetime(SerializeDatetime::new()) + } +} + +impl serde::ser::SerializeMap for SerializeMap { + type Ok = crate::Value; + type Error = Error; + + fn serialize_key<T: ?Sized>(&mut self, input: &T) -> Result<(), Self::Error> + where + T: serde::ser::Serialize, + { + match self { + Self::Datetime(s) => s.serialize_key(input), + Self::Table(s) => s.serialize_key(input), + } + } + + fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> + where + T: serde::ser::Serialize, + { + match self { + Self::Datetime(s) => s.serialize_value(value), + Self::Table(s) => s.serialize_value(value), + } + } + + fn end(self) -> Result<Self::Ok, Self::Error> { + match self { + Self::Datetime(s) => s.end().map(|items| items.into()), + Self::Table(s) => s.end().map(|items| items.into()), + } + } +} + +impl serde::ser::SerializeStruct for SerializeMap { + type Ok = crate::Value; + type Error = Error; + + fn serialize_field<T: ?Sized>( + &mut self, + key: &'static str, + value: &T, + ) -> Result<(), Self::Error> + where + T: serde::ser::Serialize, + { + match self { + Self::Datetime(s) => s.serialize_field(key, value), + Self::Table(s) => s.serialize_field(key, value), + } + } + + fn end(self) -> Result<Self::Ok, Self::Error> { + match self { + Self::Datetime(s) => s.end().map(|items| items.into()), + Self::Table(s) => s.end().map(|items| items.into()), + } + } +} + +#[doc(hidden)] +pub struct SerializeDatetime { + value: Option<crate::Datetime>, +} + +impl SerializeDatetime { + pub(crate) fn new() -> Self { + Self { value: None } + } +} + +impl serde::ser::SerializeMap for SerializeDatetime { + type Ok = crate::Datetime; + type Error = Error; + + fn serialize_key<T: ?Sized>(&mut self, _input: &T) -> Result<(), Self::Error> + where + T: serde::ser::Serialize, + { + unreachable!("datetimes should only be serialized as structs, not maps") + } + + fn serialize_value<T: ?Sized>(&mut self, _value: &T) -> Result<(), Self::Error> + where + T: serde::ser::Serialize, + { + unreachable!("datetimes should only be serialized as structs, not maps") + } + + fn end(self) -> Result<Self::Ok, Self::Error> { + unreachable!("datetimes should only be serialized as structs, not maps") + } +} + +impl serde::ser::SerializeStruct for SerializeDatetime { + type Ok = crate::Datetime; + type Error = Error; + + fn serialize_field<T: ?Sized>( + &mut self, + key: &'static str, + value: &T, + ) -> Result<(), Self::Error> + where + T: serde::ser::Serialize, + { + if key == toml_datetime::__unstable::FIELD { + self.value = Some(value.serialize(DatetimeFieldSerializer::default())?); + } + + Ok(()) + } + + fn end(self) -> Result<Self::Ok, Self::Error> { + self.value.ok_or(Error::UnsupportedNone) + } +} + +#[doc(hidden)] +pub struct SerializeInlineTable { + items: crate::table::KeyValuePairs, + key: Option<crate::InternalString>, +} + +impl SerializeInlineTable { + pub(crate) fn new() -> Self { + Self { + items: Default::default(), + key: Default::default(), + } + } + + pub(crate) fn with_capacity(len: usize) -> Self { + let mut s = Self::new(); + s.items.reserve(len); + s + } +} + +impl serde::ser::SerializeMap for SerializeInlineTable { + type Ok = crate::InlineTable; + type Error = Error; + + fn serialize_key<T: ?Sized>(&mut self, input: &T) -> Result<(), Self::Error> + where + T: serde::ser::Serialize, + { + self.key = None; + self.key = Some(input.serialize(KeySerializer)?); + Ok(()) + } + + fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> + where + T: serde::ser::Serialize, + { + let res = value.serialize(super::ValueSerializer {}); + match res { + Ok(item) => { + let key = self.key.take().unwrap(); + let kv = crate::table::TableKeyValue::new( + crate::Key::new(&key), + crate::Item::Value(item), + ); + self.items.insert(key, kv); + } + Err(e) => { + if e != Error::UnsupportedNone { + return Err(e); + } + } + } + Ok(()) + } + + fn end(self) -> Result<Self::Ok, Self::Error> { + Ok(crate::InlineTable::with_pairs(self.items)) + } +} + +impl serde::ser::SerializeStruct for SerializeInlineTable { + type Ok = crate::InlineTable; + type Error = Error; + + fn serialize_field<T: ?Sized>( + &mut self, + key: &'static str, + value: &T, + ) -> Result<(), Self::Error> + where + T: serde::ser::Serialize, + { + let res = value.serialize(super::ValueSerializer {}); + match res { + Ok(item) => { + let kv = crate::table::TableKeyValue::new( + crate::Key::new(key), + crate::Item::Value(item), + ); + self.items.insert(crate::InternalString::from(key), kv); + } + Err(e) => { + if e != Error::UnsupportedNone { + return Err(e); + } + } + }; + Ok(()) + } + + fn end(self) -> Result<Self::Ok, Self::Error> { + Ok(crate::InlineTable::with_pairs(self.items)) + } +} + +#[derive(Default)] +struct DatetimeFieldSerializer {} + +impl serde::ser::Serializer for DatetimeFieldSerializer { + type Ok = toml_datetime::Datetime; + type Error = Error; + type SerializeSeq = serde::ser::Impossible<Self::Ok, Self::Error>; + type SerializeTuple = serde::ser::Impossible<Self::Ok, Self::Error>; + type SerializeTupleStruct = serde::ser::Impossible<Self::Ok, Self::Error>; + type SerializeTupleVariant = serde::ser::Impossible<Self::Ok, Self::Error>; + type SerializeMap = serde::ser::Impossible<Self::Ok, Self::Error>; + type SerializeStruct = serde::ser::Impossible<Self::Ok, Self::Error>; + type SerializeStructVariant = serde::ser::Impossible<Self::Ok, Self::Error>; + + fn serialize_bool(self, _value: bool) -> Result<Self::Ok, Self::Error> { + Err(Error::DateInvalid) + } + + fn serialize_i8(self, _value: i8) -> Result<Self::Ok, Self::Error> { + Err(Error::DateInvalid) + } + + fn serialize_i16(self, _value: i16) -> Result<Self::Ok, Self::Error> { + Err(Error::DateInvalid) + } + + fn serialize_i32(self, _value: i32) -> Result<Self::Ok, Self::Error> { + Err(Error::DateInvalid) + } + + fn serialize_i64(self, _value: i64) -> Result<Self::Ok, Self::Error> { + Err(Error::DateInvalid) + } + + fn serialize_u8(self, _value: u8) -> Result<Self::Ok, Self::Error> { + Err(Error::DateInvalid) + } + + fn serialize_u16(self, _value: u16) -> Result<Self::Ok, Self::Error> { + Err(Error::DateInvalid) + } + + fn serialize_u32(self, _value: u32) -> Result<Self::Ok, Self::Error> { + Err(Error::DateInvalid) + } + + fn serialize_u64(self, _value: u64) -> Result<Self::Ok, Self::Error> { + Err(Error::DateInvalid) + } + + fn serialize_f32(self, _value: f32) -> Result<Self::Ok, Self::Error> { + Err(Error::DateInvalid) + } + + fn serialize_f64(self, _value: f64) -> Result<Self::Ok, Self::Error> { + Err(Error::DateInvalid) + } + + fn serialize_char(self, _value: char) -> Result<Self::Ok, Self::Error> { + Err(Error::DateInvalid) + } + + fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> { + v.parse::<toml_datetime::Datetime>().map_err(Error::custom) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result<Self::Ok, Self::Error> { + Err(Error::DateInvalid) + } + + fn serialize_none(self) -> Result<Self::Ok, Self::Error> { + Err(Error::DateInvalid) + } + + fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<Self::Ok, Self::Error> + where + T: serde::ser::Serialize, + { + Err(Error::DateInvalid) + } + + fn serialize_unit(self) -> Result<Self::Ok, Self::Error> { + Err(Error::DateInvalid) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> { + Err(Error::DateInvalid) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + ) -> Result<Self::Ok, Self::Error> { + Err(Error::DateInvalid) + } + + fn serialize_newtype_struct<T: ?Sized>( + self, + _name: &'static str, + _value: &T, + ) -> Result<Self::Ok, Self::Error> + where + T: serde::ser::Serialize, + { + Err(Error::DateInvalid) + } + + fn serialize_newtype_variant<T: ?Sized>( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result<Self::Ok, Self::Error> + where + T: serde::ser::Serialize, + { + Err(Error::DateInvalid) + } + + fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> { + Err(Error::DateInvalid) + } + + fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> { + Err(Error::DateInvalid) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleStruct, Self::Error> { + Err(Error::DateInvalid) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleVariant, Self::Error> { + Err(Error::DateInvalid) + } + + fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> { + Err(Error::DateInvalid) + } + + fn serialize_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeStruct, Self::Error> { + Err(Error::DateInvalid) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeStructVariant, Self::Error> { + Err(Error::DateInvalid) + } +} diff --git a/vendor/toml_edit/src/ser/mod.rs b/vendor/toml_edit/src/ser/mod.rs new file mode 100644 index 000000000..2c310206b --- /dev/null +++ b/vendor/toml_edit/src/ser/mod.rs @@ -0,0 +1,165 @@ +//! Serializing Rust structures into TOML. +//! +//! This module contains all the Serde support for serializing Rust structures into TOML. + +mod array; +mod key; +mod map; +mod pretty; +mod value; + +pub(crate) use array::*; +pub(crate) use key::*; +pub(crate) use map::*; + +use crate::visit_mut::VisitMut; + +/// Errors that can occur when deserializing a type. +#[derive(Debug, Clone, PartialEq, Eq)] +#[non_exhaustive] +pub enum Error { + /// Type could not be serialized to TOML + UnsupportedType(Option<&'static str>), + /// Value was out of range for the given type + OutOfRange(Option<&'static str>), + /// `None` could not be serialized to TOML + UnsupportedNone, + /// Key was not convertable to `String` for serializing to TOML + KeyNotString, + /// A serialized date was invalid + DateInvalid, + /// Other serialization error + Custom(String), +} + +impl Error { + pub(crate) fn custom<T>(msg: T) -> Self + where + T: std::fmt::Display, + { + Error::Custom(msg.to_string()) + } +} + +impl serde::ser::Error for Error { + fn custom<T>(msg: T) -> Self + where + T: std::fmt::Display, + { + Self::custom(msg) + } +} + +impl std::fmt::Display for Error { + fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Self::UnsupportedType(Some(t)) => write!(formatter, "unsupported {t} type"), + Self::UnsupportedType(None) => write!(formatter, "unsupported rust type"), + Self::OutOfRange(Some(t)) => write!(formatter, "out-of-range value for {t} type"), + Self::OutOfRange(None) => write!(formatter, "out-of-range value"), + Self::UnsupportedNone => "unsupported None value".fmt(formatter), + Self::KeyNotString => "map key was not a string".fmt(formatter), + Self::DateInvalid => "a serialized date was invalid".fmt(formatter), + Self::Custom(s) => s.fmt(formatter), + } + } +} + +impl From<crate::TomlError> for Error { + fn from(e: crate::TomlError) -> Error { + Self::custom(e) + } +} + +impl From<Error> for crate::TomlError { + fn from(e: Error) -> crate::TomlError { + Self::custom(e.to_string(), None) + } +} + +impl std::error::Error for Error {} + +/// Serialize the given data structure as a TOML byte vector. +/// +/// Serialization can fail if `T`'s implementation of `Serialize` decides to +/// fail, if `T` contains a map with non-string keys, or if `T` attempts to +/// serialize an unsupported datatype such as an enum, tuple, or tuple struct. +pub fn to_vec<T: ?Sized>(value: &T) -> Result<Vec<u8>, Error> +where + T: serde::ser::Serialize, +{ + to_string(value).map(|e| e.into_bytes()) +} + +/// Serialize the given data structure as a String of TOML. +/// +/// Serialization can fail if `T`'s implementation of `Serialize` decides to +/// fail, if `T` contains a map with non-string keys, or if `T` attempts to +/// serialize an unsupported datatype such as an enum, tuple, or tuple struct. +/// +/// # Examples +/// +/// ``` +/// use serde::Serialize; +/// +/// #[derive(Serialize)] +/// struct Config { +/// database: Database, +/// } +/// +/// #[derive(Serialize)] +/// struct Database { +/// ip: String, +/// port: Vec<u16>, +/// connection_max: u32, +/// enabled: bool, +/// } +/// +/// let config = Config { +/// database: Database { +/// ip: "192.168.1.1".to_string(), +/// port: vec![8001, 8002, 8003], +/// connection_max: 5000, +/// enabled: false, +/// }, +/// }; +/// +/// let toml = toml_edit::ser::to_string(&config).unwrap(); +/// println!("{}", toml) +/// ``` +pub fn to_string<T: ?Sized>(value: &T) -> Result<String, Error> +where + T: serde::ser::Serialize, +{ + to_document(value).map(|e| e.to_string()) +} + +/// Serialize the given data structure as a "pretty" String of TOML. +/// +/// This is identical to `to_string` except the output string has a more +/// "pretty" output. See `ValueSerializer::pretty` for more details. +pub fn to_string_pretty<T: ?Sized>(value: &T) -> Result<String, Error> +where + T: serde::ser::Serialize, +{ + let mut document = to_document(value)?; + pretty::Pretty.visit_document_mut(&mut document); + Ok(document.to_string()) +} + +/// Serialize the given data structure into a TOML document. +/// +/// This would allow custom formatting to be applied, mixing with format preserving edits, etc. +pub fn to_document<T: ?Sized>(value: &T) -> Result<crate::Document, Error> +where + T: serde::ser::Serialize, +{ + let value = value.serialize(ValueSerializer::new())?; + let item = crate::Item::Value(value); + let root = item + .into_table() + .map_err(|_| Error::UnsupportedType(None))?; + Ok(root.into()) +} + +pub use value::ValueSerializer; diff --git a/vendor/toml_edit/src/ser/pretty.rs b/vendor/toml_edit/src/ser/pretty.rs new file mode 100644 index 000000000..2c22f6804 --- /dev/null +++ b/vendor/toml_edit/src/ser/pretty.rs @@ -0,0 +1,45 @@ +pub(crate) struct Pretty; + +impl crate::visit_mut::VisitMut for Pretty { + fn visit_document_mut(&mut self, node: &mut crate::Document) { + crate::visit_mut::visit_document_mut(self, node); + } + + fn visit_item_mut(&mut self, node: &mut crate::Item) { + node.make_item(); + + crate::visit_mut::visit_item_mut(self, node); + } + + fn visit_table_mut(&mut self, node: &mut crate::Table) { + node.decor_mut().clear(); + + // Empty tables could be semantically meaningful, so make sure they are not implicit + if !node.is_empty() { + node.set_implicit(true); + } + + crate::visit_mut::visit_table_mut(self, node); + } + + fn visit_value_mut(&mut self, node: &mut crate::Value) { + node.decor_mut().clear(); + + crate::visit_mut::visit_value_mut(self, node); + } + + fn visit_array_mut(&mut self, node: &mut crate::Array) { + crate::visit_mut::visit_array_mut(self, node); + + if (0..=1).contains(&node.len()) { + node.set_trailing(""); + node.set_trailing_comma(false); + } else { + for item in node.iter_mut() { + item.decor_mut().set_prefix("\n "); + } + node.set_trailing("\n"); + node.set_trailing_comma(true); + } + } +} diff --git a/vendor/toml_edit/src/ser/value.rs b/vendor/toml_edit/src/ser/value.rs new file mode 100644 index 000000000..cc7dfb773 --- /dev/null +++ b/vendor/toml_edit/src/ser/value.rs @@ -0,0 +1,240 @@ +use super::Error; + +/// Serialization for TOML [values][crate::Value]. +/// +/// This structure implements serialization support for TOML to serialize an +/// arbitrary type to TOML. Note that the TOML format does not support all +/// datatypes in Rust, such as enums, tuples, and tuple structs. These types +/// will generate an error when serialized. +/// +/// Currently a serializer always writes its output to an in-memory `String`, +/// which is passed in when creating the serializer itself. +/// +/// # Examples +/// +/// ``` +/// use serde::Serialize; +/// +/// #[derive(Serialize)] +/// struct Config { +/// database: Database, +/// } +/// +/// #[derive(Serialize)] +/// struct Database { +/// ip: String, +/// port: Vec<u16>, +/// connection_max: u32, +/// enabled: bool, +/// } +/// +/// let config = Config { +/// database: Database { +/// ip: "192.168.1.1".to_string(), +/// port: vec![8001, 8002, 8003], +/// connection_max: 5000, +/// enabled: false, +/// }, +/// }; +/// +/// let value = serde::Serialize::serialize( +/// &config, +/// toml_edit::ser::ValueSerializer::new() +/// ).unwrap(); +/// println!("{}", value) +/// ``` +#[derive(Default)] +#[non_exhaustive] +pub struct ValueSerializer {} + +impl ValueSerializer { + /// Creates a new serializer generate a TOML document. + pub fn new() -> Self { + Self {} + } +} + +impl serde::ser::Serializer for ValueSerializer { + type Ok = crate::Value; + type Error = Error; + type SerializeSeq = super::SerializeValueArray; + type SerializeTuple = super::SerializeValueArray; + type SerializeTupleStruct = super::SerializeValueArray; + type SerializeTupleVariant = super::SerializeValueArray; + type SerializeMap = super::SerializeMap; + type SerializeStruct = super::SerializeMap; + type SerializeStructVariant = serde::ser::Impossible<Self::Ok, Self::Error>; + + fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> { + Ok(v.into()) + } + + fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> { + self.serialize_i64(v as i64) + } + + fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> { + self.serialize_i64(v as i64) + } + + fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> { + self.serialize_i64(v as i64) + } + + fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> { + Ok(v.into()) + } + + fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> { + self.serialize_i64(v as i64) + } + + fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> { + self.serialize_i64(v as i64) + } + + fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> { + self.serialize_i64(v as i64) + } + + fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> { + let v: i64 = v + .try_into() + .map_err(|_err| Error::OutOfRange(Some("u64")))?; + self.serialize_i64(v) + } + + fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> { + self.serialize_f64(v as f64) + } + + fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> { + Ok(v.into()) + } + + fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> { + let mut buf = [0; 4]; + self.serialize_str(v.encode_utf8(&mut buf)) + } + + fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> { + Ok(v.into()) + } + + fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok, Self::Error> { + use serde::ser::Serialize; + value.serialize(self) + } + + fn serialize_none(self) -> Result<Self::Ok, Self::Error> { + Err(Error::UnsupportedNone) + } + + fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error> + where + T: serde::ser::Serialize, + { + value.serialize(self) + } + + fn serialize_unit(self) -> Result<Self::Ok, Self::Error> { + Err(Error::UnsupportedType(Some("unit"))) + } + + fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> { + Err(Error::UnsupportedType(Some(name))) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result<Self::Ok, Self::Error> { + self.serialize_str(variant) + } + + fn serialize_newtype_struct<T: ?Sized>( + self, + _name: &'static str, + value: &T, + ) -> Result<Self::Ok, Self::Error> + where + T: serde::ser::Serialize, + { + value.serialize(self) + } + + fn serialize_newtype_variant<T: ?Sized>( + self, + name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result<Self::Ok, Self::Error> + where + T: serde::ser::Serialize, + { + Err(Error::UnsupportedType(Some(name))) + } + + fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> { + let serializer = match len { + Some(len) => super::SerializeValueArray::with_capacity(len), + None => super::SerializeValueArray::new(), + }; + Ok(serializer) + } + + fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> { + self.serialize_seq(Some(len)) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + len: usize, + ) -> Result<Self::SerializeTupleStruct, Self::Error> { + self.serialize_seq(Some(len)) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + len: usize, + ) -> Result<Self::SerializeTupleVariant, Self::Error> { + self.serialize_seq(Some(len)) + } + + fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> { + let serializer = match len { + Some(len) => super::SerializeMap::table_with_capacity(len), + None => super::SerializeMap::table(), + }; + Ok(serializer) + } + + fn serialize_struct( + self, + name: &'static str, + len: usize, + ) -> Result<Self::SerializeStruct, Self::Error> { + if name == toml_datetime::__unstable::NAME { + Ok(super::SerializeMap::datetime()) + } else { + self.serialize_map(Some(len)) + } + } + + fn serialize_struct_variant( + self, + name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeStructVariant, Self::Error> { + Err(Error::UnsupportedType(Some(name))) + } +} diff --git a/vendor/toml_edit/src/table.rs b/vendor/toml_edit/src/table.rs new file mode 100644 index 000000000..f177028fa --- /dev/null +++ b/vendor/toml_edit/src/table.rs @@ -0,0 +1,743 @@ +use std::iter::FromIterator; + +use indexmap::map::IndexMap; + +use crate::key::Key; +use crate::repr::Decor; +use crate::value::DEFAULT_VALUE_DECOR; +use crate::{InlineTable, InternalString, Item, KeyMut, Value}; + +/// Type representing a TOML non-inline table +#[derive(Clone, Debug, Default)] +pub struct Table { + // Comments/spaces before and after the header + pub(crate) decor: Decor, + // Whether to hide an empty table + pub(crate) implicit: bool, + // Whether this is a proxy for dotted keys + pub(crate) dotted: bool, + // Used for putting tables back in their original order when serialising. + // + // `None` for user created tables (can be overridden with `set_position`) + doc_position: Option<usize>, + pub(crate) span: Option<std::ops::Range<usize>>, + pub(crate) items: KeyValuePairs, +} + +/// Constructors +/// +/// See also `FromIterator` +impl Table { + /// Creates an empty table. + pub fn new() -> Self { + Default::default() + } + + pub(crate) fn with_pos(doc_position: Option<usize>) -> Self { + Self { + doc_position, + ..Default::default() + } + } + + pub(crate) fn with_pairs(items: KeyValuePairs) -> Self { + Self { + items, + ..Default::default() + } + } + + /// Convert to an inline table + pub fn into_inline_table(mut self) -> InlineTable { + for (_, kv) in self.items.iter_mut() { + kv.value.make_value(); + } + let mut t = InlineTable::with_pairs(self.items); + t.fmt(); + t + } +} + +/// Formatting +impl Table { + /// Get key/values for values that are visually children of this table + /// + /// For example, this will return dotted keys + pub fn get_values(&self) -> Vec<(Vec<&Key>, &Value)> { + let mut values = Vec::new(); + let root = Vec::new(); + self.append_values(&root, &mut values); + values + } + + fn append_values<'s, 'c>( + &'s self, + parent: &[&'s Key], + values: &'c mut Vec<(Vec<&'s Key>, &'s Value)>, + ) { + for value in self.items.values() { + let mut path = parent.to_vec(); + path.push(&value.key); + match &value.value { + Item::Table(table) if table.is_dotted() => { + table.append_values(&path, values); + } + Item::Value(value) => { + if let Some(table) = value.as_inline_table() { + if table.is_dotted() { + table.append_values(&path, values); + } else { + values.push((path, value)); + } + } else { + values.push((path, value)); + } + } + _ => {} + } + } + } + + /// Auto formats the table. + pub fn fmt(&mut self) { + decorate_table(self); + } + + /// Sorts Key/Value Pairs of the table. + /// + /// Doesn't affect subtables or subarrays. + pub fn sort_values(&mut self) { + // Assuming standard tables have their doc_position set and this won't negatively impact them + self.items.sort_keys(); + for kv in self.items.values_mut() { + match &mut kv.value { + Item::Table(table) if table.is_dotted() => { + table.sort_values(); + } + _ => {} + } + } + } + + /// Sort Key/Value Pairs of the table using the using the comparison function `compare`. + /// + /// The comparison function receives two key and value pairs to compare (you can sort by keys or + /// values or their combination as needed). + pub fn sort_values_by<F>(&mut self, mut compare: F) + where + F: FnMut(&Key, &Item, &Key, &Item) -> std::cmp::Ordering, + { + self.sort_values_by_internal(&mut compare); + } + + fn sort_values_by_internal<F>(&mut self, compare: &mut F) + where + F: FnMut(&Key, &Item, &Key, &Item) -> std::cmp::Ordering, + { + let modified_cmp = |_: &InternalString, + val1: &TableKeyValue, + _: &InternalString, + val2: &TableKeyValue| + -> std::cmp::Ordering { + compare(&val1.key, &val1.value, &val2.key, &val2.value) + }; + + self.items.sort_by(modified_cmp); + + for kv in self.items.values_mut() { + match &mut kv.value { + Item::Table(table) if table.is_dotted() => { + table.sort_values_by_internal(compare); + } + _ => {} + } + } + } + + /// If a table has no key/value pairs and implicit, it will not be displayed. + /// + /// # Examples + /// + /// ```notrust + /// [target."x86_64/windows.json".dependencies] + /// ``` + /// + /// In the document above, tables `target` and `target."x86_64/windows.json"` are implicit. + /// + /// ``` + /// use toml_edit::Document; + /// let mut doc = "[a]\n[a.b]\n".parse::<Document>().expect("invalid toml"); + /// + /// doc["a"].as_table_mut().unwrap().set_implicit(true); + /// assert_eq!(doc.to_string(), "[a.b]\n"); + /// ``` + pub fn set_implicit(&mut self, implicit: bool) { + self.implicit = implicit; + } + + /// If a table has no key/value pairs and implicit, it will not be displayed. + pub fn is_implicit(&self) -> bool { + self.implicit + } + + /// Change this table's dotted status + pub fn set_dotted(&mut self, yes: bool) { + self.dotted = yes; + } + + /// Check if this is a wrapper for dotted keys, rather than a standard table + pub fn is_dotted(&self) -> bool { + self.dotted + } + + /// Sets the position of the `Table` within the `Document`. + pub fn set_position(&mut self, doc_position: usize) { + self.doc_position = Some(doc_position); + } + + /// The position of the `Table` within the `Document`. + /// + /// Returns `None` if the `Table` was created manually (i.e. not via parsing) + /// in which case its position is set automatically. This can be overridden with + /// [`Table::set_position`]. + pub fn position(&self) -> Option<usize> { + self.doc_position + } + + /// Returns the surrounding whitespace + pub fn decor_mut(&mut self) -> &mut Decor { + &mut self.decor + } + + /// Returns the decor associated with a given key of the table. + pub fn decor(&self) -> &Decor { + &self.decor + } + + /// Returns the decor associated with a given key of the table. + pub fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor> { + self.items.get_mut(key).map(|kv| &mut kv.key.decor) + } + + /// Returns the decor associated with a given key of the table. + pub fn key_decor(&self, key: &str) -> Option<&Decor> { + self.items.get(key).map(|kv| &kv.key.decor) + } + + /// Returns the location within the original document + pub(crate) fn span(&self) -> Option<std::ops::Range<usize>> { + self.span.clone() + } + + pub(crate) fn despan(&mut self, input: &str) { + self.span = None; + self.decor.despan(input); + for kv in self.items.values_mut() { + kv.key.despan(input); + kv.value.despan(input); + } + } +} + +impl Table { + /// Returns an iterator over all key/value pairs, including empty. + pub fn iter(&self) -> Iter<'_> { + Box::new( + self.items + .iter() + .filter(|(_, kv)| !kv.value.is_none()) + .map(|(key, kv)| (&key[..], &kv.value)), + ) + } + + /// Returns an mutable iterator over all key/value pairs, including empty. + pub fn iter_mut(&mut self) -> IterMut<'_> { + Box::new( + self.items + .iter_mut() + .filter(|(_, kv)| !kv.value.is_none()) + .map(|(_, kv)| (kv.key.as_mut(), &mut kv.value)), + ) + } + + /// Returns the number of non-empty items in the table. + pub fn len(&self) -> usize { + self.items.iter().filter(|i| !(i.1).value.is_none()).count() + } + + /// Returns true iff the table is empty. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Clears the table, removing all key-value pairs. Keeps the allocated memory for reuse. + pub fn clear(&mut self) { + self.items.clear() + } + + /// Gets the given key's corresponding entry in the Table for in-place manipulation. + pub fn entry<'a>(&'a mut self, key: &str) -> Entry<'a> { + // Accept a `&str` rather than an owned type to keep `InternalString`, well, internal + match self.items.entry(key.into()) { + indexmap::map::Entry::Occupied(entry) => Entry::Occupied(OccupiedEntry { entry }), + indexmap::map::Entry::Vacant(entry) => Entry::Vacant(VacantEntry { entry, key: None }), + } + } + + /// Gets the given key's corresponding entry in the Table for in-place manipulation. + pub fn entry_format<'a>(&'a mut self, key: &Key) -> Entry<'a> { + // Accept a `&Key` to be consistent with `entry` + match self.items.entry(key.get().into()) { + indexmap::map::Entry::Occupied(entry) => Entry::Occupied(OccupiedEntry { entry }), + indexmap::map::Entry::Vacant(entry) => Entry::Vacant(VacantEntry { + entry, + key: Some(key.to_owned()), + }), + } + } + + /// Returns an optional reference to an item given the key. + pub fn get<'a>(&'a self, key: &str) -> Option<&'a Item> { + self.items.get(key).and_then(|kv| { + if !kv.value.is_none() { + Some(&kv.value) + } else { + None + } + }) + } + + /// Returns an optional mutable reference to an item given the key. + pub fn get_mut<'a>(&'a mut self, key: &str) -> Option<&'a mut Item> { + self.items.get_mut(key).and_then(|kv| { + if !kv.value.is_none() { + Some(&mut kv.value) + } else { + None + } + }) + } + + /// Return references to the key-value pair stored for key, if it is present, else None. + pub fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> { + self.items.get(key).and_then(|kv| { + if !kv.value.is_none() { + Some((&kv.key, &kv.value)) + } else { + None + } + }) + } + + /// Return mutable references to the key-value pair stored for key, if it is present, else None. + pub fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> { + self.items.get_mut(key).and_then(|kv| { + if !kv.value.is_none() { + Some((kv.key.as_mut(), &mut kv.value)) + } else { + None + } + }) + } + + /// Returns true iff the table contains an item with the given key. + pub fn contains_key(&self, key: &str) -> bool { + if let Some(kv) = self.items.get(key) { + !kv.value.is_none() + } else { + false + } + } + + /// Returns true iff the table contains a table with the given key. + pub fn contains_table(&self, key: &str) -> bool { + if let Some(kv) = self.items.get(key) { + kv.value.is_table() + } else { + false + } + } + + /// Returns true iff the table contains a value with the given key. + pub fn contains_value(&self, key: &str) -> bool { + if let Some(kv) = self.items.get(key) { + kv.value.is_value() + } else { + false + } + } + + /// Returns true iff the table contains an array of tables with the given key. + pub fn contains_array_of_tables(&self, key: &str) -> bool { + if let Some(kv) = self.items.get(key) { + kv.value.is_array_of_tables() + } else { + false + } + } + + /// Inserts a key-value pair into the map. + pub fn insert(&mut self, key: &str, item: Item) -> Option<Item> { + let kv = TableKeyValue::new(Key::new(key), item); + self.items.insert(key.into(), kv).map(|kv| kv.value) + } + + /// Inserts a key-value pair into the map. + pub fn insert_formatted(&mut self, key: &Key, item: Item) -> Option<Item> { + let kv = TableKeyValue::new(key.to_owned(), item); + self.items.insert(key.get().into(), kv).map(|kv| kv.value) + } + + /// Removes an item given the key. + pub fn remove(&mut self, key: &str) -> Option<Item> { + self.items.shift_remove(key).map(|kv| kv.value) + } + + /// Removes a key from the map, returning the stored key and value if the key was previously in the map. + pub fn remove_entry(&mut self, key: &str) -> Option<(Key, Item)> { + self.items.shift_remove(key).map(|kv| (kv.key, kv.value)) + } +} + +impl std::fmt::Display for Table { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + use crate::encode::Encode; + let children = self.get_values(); + // print table body + for (key_path, value) in children { + key_path.as_slice().encode(f, None, DEFAULT_KEY_DECOR)?; + write!(f, "=")?; + value.encode(f, None, DEFAULT_VALUE_DECOR)?; + writeln!(f)?; + } + Ok(()) + } +} + +impl<K: Into<Key>, V: Into<Value>> Extend<(K, V)> for Table { + fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) { + for (key, value) in iter { + let key = key.into(); + let value = Item::Value(value.into()); + let value = TableKeyValue::new(key, value); + self.items.insert(value.key.get().into(), value); + } + } +} + +impl<K: Into<Key>, V: Into<Value>> FromIterator<(K, V)> for Table { + fn from_iter<I>(iter: I) -> Self + where + I: IntoIterator<Item = (K, V)>, + { + let mut table = Table::new(); + table.extend(iter); + table + } +} + +impl IntoIterator for Table { + type Item = (InternalString, Item); + type IntoIter = IntoIter; + + fn into_iter(self) -> Self::IntoIter { + Box::new(self.items.into_iter().map(|(k, kv)| (k, kv.value))) + } +} + +impl<'s> IntoIterator for &'s Table { + type Item = (&'s str, &'s Item); + type IntoIter = Iter<'s>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +pub(crate) type KeyValuePairs = IndexMap<InternalString, TableKeyValue>; + +fn decorate_table(table: &mut Table) { + for (key_decor, value) in table + .items + .iter_mut() + .filter(|&(_, ref kv)| kv.value.is_value()) + .map(|(_, kv)| (&mut kv.key.decor, kv.value.as_value_mut().unwrap())) + { + key_decor.clear(); + value.decor_mut().clear(); + } +} + +// `key1 = value1` +pub(crate) const DEFAULT_KEY_DECOR: (&str, &str) = ("", " "); +pub(crate) const DEFAULT_TABLE_DECOR: (&str, &str) = ("\n", ""); +pub(crate) const DEFAULT_KEY_PATH_DECOR: (&str, &str) = ("", ""); + +#[derive(Debug, Clone)] +pub(crate) struct TableKeyValue { + pub(crate) key: Key, + pub(crate) value: Item, +} + +impl TableKeyValue { + pub(crate) fn new(key: Key, value: Item) -> Self { + TableKeyValue { key, value } + } +} + +/// An owned iterator type over `Table`'s key/value pairs. +pub type IntoIter = Box<dyn Iterator<Item = (InternalString, Item)>>; +/// An iterator type over `Table`'s key/value pairs. +pub type Iter<'a> = Box<dyn Iterator<Item = (&'a str, &'a Item)> + 'a>; +/// A mutable iterator type over `Table`'s key/value pairs. +pub type IterMut<'a> = Box<dyn Iterator<Item = (KeyMut<'a>, &'a mut Item)> + 'a>; + +/// This trait represents either a `Table`, or an `InlineTable`. +pub trait TableLike: crate::private::Sealed { + /// Returns an iterator over key/value pairs. + fn iter(&self) -> Iter<'_>; + /// Returns an mutable iterator over all key/value pairs, including empty. + fn iter_mut(&mut self) -> IterMut<'_>; + /// Returns the number of nonempty items. + fn len(&self) -> usize { + self.iter().filter(|&(_, v)| !v.is_none()).count() + } + /// Returns true iff the table is empty. + fn is_empty(&self) -> bool { + self.len() == 0 + } + /// Clears the table, removing all key-value pairs. Keeps the allocated memory for reuse. + fn clear(&mut self); + /// Gets the given key's corresponding entry in the Table for in-place manipulation. + fn entry<'a>(&'a mut self, key: &str) -> Entry<'a>; + /// Gets the given key's corresponding entry in the Table for in-place manipulation. + fn entry_format<'a>(&'a mut self, key: &Key) -> Entry<'a>; + /// Returns an optional reference to an item given the key. + fn get<'s>(&'s self, key: &str) -> Option<&'s Item>; + /// Returns an optional mutable reference to an item given the key. + fn get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item>; + /// Return references to the key-value pair stored for key, if it is present, else None. + fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)>; + /// Return mutable references to the key-value pair stored for key, if it is present, else None. + fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)>; + /// Returns true iff the table contains an item with the given key. + fn contains_key(&self, key: &str) -> bool; + /// Inserts a key-value pair into the map. + fn insert(&mut self, key: &str, value: Item) -> Option<Item>; + /// Removes an item given the key. + fn remove(&mut self, key: &str) -> Option<Item>; + + /// Get key/values for values that are visually children of this table + /// + /// For example, this will return dotted keys + fn get_values(&self) -> Vec<(Vec<&Key>, &Value)>; + + /// Auto formats the table. + fn fmt(&mut self); + /// Sorts Key/Value Pairs of the table. + /// + /// Doesn't affect subtables or subarrays. + fn sort_values(&mut self); + /// Change this table's dotted status + fn set_dotted(&mut self, yes: bool); + /// Check if this is a wrapper for dotted keys, rather than a standard table + fn is_dotted(&self) -> bool; + + /// Returns the decor associated with a given key of the table. + fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor>; + /// Returns the decor associated with a given key of the table. + fn key_decor(&self, key: &str) -> Option<&Decor>; +} + +impl TableLike for Table { + fn iter(&self) -> Iter<'_> { + self.iter() + } + fn iter_mut(&mut self) -> IterMut<'_> { + self.iter_mut() + } + fn clear(&mut self) { + self.clear(); + } + fn entry<'a>(&'a mut self, key: &str) -> Entry<'a> { + self.entry(key) + } + fn entry_format<'a>(&'a mut self, key: &Key) -> Entry<'a> { + self.entry_format(key) + } + fn get<'s>(&'s self, key: &str) -> Option<&'s Item> { + self.get(key) + } + fn get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item> { + self.get_mut(key) + } + fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> { + self.get_key_value(key) + } + fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> { + self.get_key_value_mut(key) + } + fn contains_key(&self, key: &str) -> bool { + self.contains_key(key) + } + fn insert(&mut self, key: &str, value: Item) -> Option<Item> { + self.insert(key, value) + } + fn remove(&mut self, key: &str) -> Option<Item> { + self.remove(key) + } + + fn get_values(&self) -> Vec<(Vec<&Key>, &Value)> { + self.get_values() + } + fn fmt(&mut self) { + self.fmt() + } + fn sort_values(&mut self) { + self.sort_values() + } + fn is_dotted(&self) -> bool { + self.is_dotted() + } + fn set_dotted(&mut self, yes: bool) { + self.set_dotted(yes) + } + + fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor> { + self.key_decor_mut(key) + } + fn key_decor(&self, key: &str) -> Option<&Decor> { + self.key_decor(key) + } +} + +/// A view into a single location in a map, which may be vacant or occupied. +pub enum Entry<'a> { + /// An occupied Entry. + Occupied(OccupiedEntry<'a>), + /// A vacant Entry. + Vacant(VacantEntry<'a>), +} + +impl<'a> Entry<'a> { + /// Returns the entry key + /// + /// # Examples + /// + /// ``` + /// use toml_edit::Table; + /// + /// let mut map = Table::new(); + /// + /// assert_eq!("hello", map.entry("hello").key()); + /// ``` + pub fn key(&self) -> &str { + match self { + Entry::Occupied(e) => e.key(), + Entry::Vacant(e) => e.key(), + } + } + + /// Ensures a value is in the entry by inserting the default if empty, and returns + /// a mutable reference to the value in the entry. + pub fn or_insert(self, default: Item) -> &'a mut Item { + match self { + Entry::Occupied(entry) => entry.into_mut(), + Entry::Vacant(entry) => entry.insert(default), + } + } + + /// Ensures a value is in the entry by inserting the result of the default function if empty, + /// and returns a mutable reference to the value in the entry. + pub fn or_insert_with<F: FnOnce() -> Item>(self, default: F) -> &'a mut Item { + match self { + Entry::Occupied(entry) => entry.into_mut(), + Entry::Vacant(entry) => entry.insert(default()), + } + } +} + +/// A view into a single occupied location in a `IndexMap`. +pub struct OccupiedEntry<'a> { + pub(crate) entry: indexmap::map::OccupiedEntry<'a, InternalString, TableKeyValue>, +} + +impl<'a> OccupiedEntry<'a> { + /// Gets a reference to the entry key + /// + /// # Examples + /// + /// ``` + /// use toml_edit::Table; + /// + /// let mut map = Table::new(); + /// + /// assert_eq!("foo", map.entry("foo").key()); + /// ``` + pub fn key(&self) -> &str { + self.entry.key().as_str() + } + + /// Gets a mutable reference to the entry key + pub fn key_mut(&mut self) -> KeyMut<'_> { + self.entry.get_mut().key.as_mut() + } + + /// Gets a reference to the value in the entry. + pub fn get(&self) -> &Item { + &self.entry.get().value + } + + /// Gets a mutable reference to the value in the entry. + pub fn get_mut(&mut self) -> &mut Item { + &mut self.entry.get_mut().value + } + + /// Converts the OccupiedEntry into a mutable reference to the value in the entry + /// with a lifetime bound to the map itself + pub fn into_mut(self) -> &'a mut Item { + &mut self.entry.into_mut().value + } + + /// Sets the value of the entry, and returns the entry's old value + pub fn insert(&mut self, mut value: Item) -> Item { + std::mem::swap(&mut value, &mut self.entry.get_mut().value); + value + } + + /// Takes the value out of the entry, and returns it + pub fn remove(self) -> Item { + self.entry.shift_remove().value + } +} + +/// A view into a single empty location in a `IndexMap`. +pub struct VacantEntry<'a> { + pub(crate) entry: indexmap::map::VacantEntry<'a, InternalString, TableKeyValue>, + pub(crate) key: Option<Key>, +} + +impl<'a> VacantEntry<'a> { + /// Gets a reference to the entry key + /// + /// # Examples + /// + /// ``` + /// use toml_edit::Table; + /// + /// let mut map = Table::new(); + /// + /// assert_eq!("foo", map.entry("foo").key()); + /// ``` + pub fn key(&self) -> &str { + self.entry.key().as_str() + } + + /// Sets the value of the entry with the VacantEntry's key, + /// and returns a mutable reference to it + pub fn insert(self, value: Item) -> &'a mut Item { + let entry = self.entry; + let key = self.key.unwrap_or_else(|| Key::new(entry.key().as_str())); + &mut entry.insert(TableKeyValue::new(key, value)).value + } +} diff --git a/vendor/toml_edit/src/value.rs b/vendor/toml_edit/src/value.rs new file mode 100644 index 000000000..f10da9a4c --- /dev/null +++ b/vendor/toml_edit/src/value.rs @@ -0,0 +1,372 @@ +use std::iter::FromIterator; +use std::str::FromStr; + +use toml_datetime::*; + +use crate::key::Key; +use crate::parser; +use crate::repr::{Decor, Formatted}; +use crate::{Array, InlineTable, InternalString, RawString}; + +/// Representation of a TOML Value (as part of a Key/Value Pair). +#[derive(Debug, Clone)] +pub enum Value { + /// A string value. + String(Formatted<String>), + /// A 64-bit integer value. + Integer(Formatted<i64>), + /// A 64-bit float value. + Float(Formatted<f64>), + /// A boolean value. + Boolean(Formatted<bool>), + /// An RFC 3339 formatted date-time with offset. + Datetime(Formatted<Datetime>), + /// An inline array of values. + Array(Array), + /// An inline table of key/value pairs. + InlineTable(InlineTable), +} + +/// Downcasting +impl Value { + /// Text description of value type + pub fn type_name(&self) -> &'static str { + match self { + Value::String(..) => "string", + Value::Integer(..) => "integer", + Value::Float(..) => "float", + Value::Boolean(..) => "boolean", + Value::Datetime(..) => "datetime", + Value::Array(..) => "array", + Value::InlineTable(..) => "inline table", + } + } + + /// Casts `self` to str. + pub fn as_str(&self) -> Option<&str> { + match *self { + Value::String(ref value) => Some(value.value()), + _ => None, + } + } + + /// Returns true iff `self` is a string. + pub fn is_str(&self) -> bool { + self.as_str().is_some() + } + + /// Casts `self` to integer. + pub fn as_integer(&self) -> Option<i64> { + match *self { + Value::Integer(ref value) => Some(*value.value()), + _ => None, + } + } + + /// Returns true iff `self` is an integer. + pub fn is_integer(&self) -> bool { + self.as_integer().is_some() + } + + /// Casts `self` to float. + pub fn as_float(&self) -> Option<f64> { + match *self { + Value::Float(ref value) => Some(*value.value()), + _ => None, + } + } + + /// Returns true iff `self` is a float. + pub fn is_float(&self) -> bool { + self.as_float().is_some() + } + + /// Casts `self` to boolean. + pub fn as_bool(&self) -> Option<bool> { + match *self { + Value::Boolean(ref value) => Some(*value.value()), + _ => None, + } + } + + /// Returns true iff `self` is a boolean. + pub fn is_bool(&self) -> bool { + self.as_bool().is_some() + } + + /// Casts `self` to date-time. + pub fn as_datetime(&self) -> Option<&Datetime> { + match *self { + Value::Datetime(ref value) => Some(value.value()), + _ => None, + } + } + + /// Returns true iff `self` is a date-time. + pub fn is_datetime(&self) -> bool { + self.as_datetime().is_some() + } + + /// Casts `self` to array. + pub fn as_array(&self) -> Option<&Array> { + match *self { + Value::Array(ref value) => Some(value), + _ => None, + } + } + + /// Casts `self` to mutable array. + pub fn as_array_mut(&mut self) -> Option<&mut Array> { + match *self { + Value::Array(ref mut value) => Some(value), + _ => None, + } + } + + /// Returns true iff `self` is an array. + pub fn is_array(&self) -> bool { + self.as_array().is_some() + } + + /// Casts `self` to inline table. + pub fn as_inline_table(&self) -> Option<&InlineTable> { + match *self { + Value::InlineTable(ref value) => Some(value), + _ => None, + } + } + + /// Casts `self` to mutable inline table. + pub fn as_inline_table_mut(&mut self) -> Option<&mut InlineTable> { + match *self { + Value::InlineTable(ref mut value) => Some(value), + _ => None, + } + } + + /// Returns true iff `self` is an inline table. + pub fn is_inline_table(&self) -> bool { + self.as_inline_table().is_some() + } +} + +impl Value { + /// Get the decoration of the value. + /// # Example + /// ```rust + /// let v = toml_edit::Value::from(true); + /// assert_eq!(v.decor().suffix(), None); + ///``` + pub fn decor_mut(&mut self) -> &mut Decor { + match self { + Value::String(f) => f.decor_mut(), + Value::Integer(f) => f.decor_mut(), + Value::Float(f) => f.decor_mut(), + Value::Boolean(f) => f.decor_mut(), + Value::Datetime(f) => f.decor_mut(), + Value::Array(a) => a.decor_mut(), + Value::InlineTable(t) => t.decor_mut(), + } + } + + /// Get the decoration of the value. + /// # Example + /// ```rust + /// let v = toml_edit::Value::from(true); + /// assert_eq!(v.decor().suffix(), None); + ///``` + pub fn decor(&self) -> &Decor { + match *self { + Value::String(ref f) => f.decor(), + Value::Integer(ref f) => f.decor(), + Value::Float(ref f) => f.decor(), + Value::Boolean(ref f) => f.decor(), + Value::Datetime(ref f) => f.decor(), + Value::Array(ref a) => a.decor(), + Value::InlineTable(ref t) => t.decor(), + } + } + + /// Sets the prefix and the suffix for value. + /// # Example + /// ```rust + /// let mut v = toml_edit::Value::from(42); + /// assert_eq!(&v.to_string(), "42"); + /// let d = v.decorated(" ", " "); + /// assert_eq!(&d.to_string(), " 42 "); + /// ``` + pub fn decorated(mut self, prefix: impl Into<RawString>, suffix: impl Into<RawString>) -> Self { + self.decorate(prefix, suffix); + self + } + + pub(crate) fn decorate(&mut self, prefix: impl Into<RawString>, suffix: impl Into<RawString>) { + let decor = self.decor_mut(); + *decor = Decor::new(prefix, suffix); + } + + /// Returns the location within the original document + pub(crate) fn span(&self) -> Option<std::ops::Range<usize>> { + match self { + Value::String(f) => f.span(), + Value::Integer(f) => f.span(), + Value::Float(f) => f.span(), + Value::Boolean(f) => f.span(), + Value::Datetime(f) => f.span(), + Value::Array(a) => a.span(), + Value::InlineTable(t) => t.span(), + } + } + + pub(crate) fn despan(&mut self, input: &str) { + match self { + Value::String(f) => f.despan(input), + Value::Integer(f) => f.despan(input), + Value::Float(f) => f.despan(input), + Value::Boolean(f) => f.despan(input), + Value::Datetime(f) => f.despan(input), + Value::Array(a) => a.despan(input), + Value::InlineTable(t) => t.despan(input), + } + } +} + +impl FromStr for Value { + type Err = crate::TomlError; + + /// Parses a value from a &str + fn from_str(s: &str) -> Result<Self, Self::Err> { + parser::parse_value(s) + } +} + +impl<'b> From<&'b Value> for Value { + fn from(s: &'b Value) -> Self { + s.clone() + } +} + +impl<'b> From<&'b str> for Value { + fn from(s: &'b str) -> Self { + s.to_owned().into() + } +} + +impl<'b> From<&'b String> for Value { + fn from(s: &'b String) -> Self { + s.to_owned().into() + } +} + +impl From<String> for Value { + fn from(s: String) -> Self { + Value::String(Formatted::new(s)) + } +} + +impl<'b> From<&'b InternalString> for Value { + fn from(s: &'b InternalString) -> Self { + s.as_str().into() + } +} + +impl From<InternalString> for Value { + fn from(s: InternalString) -> Self { + s.as_str().into() + } +} + +impl From<i64> for Value { + fn from(i: i64) -> Self { + Value::Integer(Formatted::new(i)) + } +} + +impl From<f64> for Value { + fn from(f: f64) -> Self { + Value::Float(Formatted::new(f)) + } +} + +impl From<bool> for Value { + fn from(b: bool) -> Self { + Value::Boolean(Formatted::new(b)) + } +} + +impl From<Datetime> for Value { + fn from(d: Datetime) -> Self { + Value::Datetime(Formatted::new(d)) + } +} + +impl From<Date> for Value { + fn from(d: Date) -> Self { + let d: Datetime = d.into(); + d.into() + } +} + +impl From<Time> for Value { + fn from(d: Time) -> Self { + let d: Datetime = d.into(); + d.into() + } +} + +impl From<Array> for Value { + fn from(array: Array) -> Self { + Value::Array(array) + } +} + +impl From<InlineTable> for Value { + fn from(table: InlineTable) -> Self { + Value::InlineTable(table) + } +} + +impl<V: Into<Value>> FromIterator<V> for Value { + fn from_iter<I>(iter: I) -> Self + where + I: IntoIterator<Item = V>, + { + let array: Array = iter.into_iter().collect(); + Value::Array(array) + } +} + +impl<K: Into<Key>, V: Into<Value>> FromIterator<(K, V)> for Value { + fn from_iter<I>(iter: I) -> Self + where + I: IntoIterator<Item = (K, V)>, + { + let table: InlineTable = iter.into_iter().collect(); + Value::InlineTable(table) + } +} + +impl std::fmt::Display for Value { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + crate::encode::Encode::encode(self, f, None, ("", "")) + } +} + +// `key1 = value1` +pub(crate) const DEFAULT_VALUE_DECOR: (&str, &str) = (" ", ""); +// `{ key = value }` +pub(crate) const DEFAULT_TRAILING_VALUE_DECOR: (&str, &str) = (" ", " "); +// `[value1, value2]` +pub(crate) const DEFAULT_LEADING_VALUE_DECOR: (&str, &str) = ("", ""); + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn from_iter_formatting() { + let features = vec!["node".to_owned(), "mouth".to_owned()]; + let features: Value = features.iter().cloned().collect(); + assert_eq!(features.to_string(), r#"["node", "mouth"]"#); + } +} diff --git a/vendor/toml_edit/src/visit.rs b/vendor/toml_edit/src/visit.rs new file mode 100644 index 000000000..1bc640a88 --- /dev/null +++ b/vendor/toml_edit/src/visit.rs @@ -0,0 +1,236 @@ +#![allow(missing_docs)] + +//! Document tree traversal to walk a shared borrow of a document tree. +//! +//! Each method of the [`Visit`] trait is a hook that can be overridden +//! to customize the behavior when mutating the corresponding type of node. +//! By default, every method recursively visits the substructure of the +//! input by invoking the right visitor method of each of its fields. +//! +//! ``` +//! # use toml_edit::{Item, ArrayOfTables, Table, Value}; +//! +//! pub trait Visit<'doc> { +//! /* ... */ +//! +//! fn visit_item(&mut self, i: &'doc Item) { +//! visit_item(self, i); +//! } +//! +//! /* ... */ +//! # fn visit_value(&mut self, i: &'doc Value); +//! # fn visit_table(&mut self, i: &'doc Table); +//! # fn visit_array_of_tables(&mut self, i: &'doc ArrayOfTables); +//! } +//! +//! pub fn visit_item<'doc, V>(v: &mut V, node: &'doc Item) +//! where +//! V: Visit<'doc> + ?Sized, +//! { +//! match node { +//! Item::None => {} +//! Item::Value(value) => v.visit_value(value), +//! Item::Table(table) => v.visit_table(table), +//! Item::ArrayOfTables(array) => v.visit_array_of_tables(array), +//! } +//! } +//! ``` +//! +//! The API is modeled after [`syn::visit`](https://docs.rs/syn/1/syn/visit). +//! +//! # Examples +//! +//! This visitor stores every string in the document. +//! +//! ``` +//! # use toml_edit::*; +//! use toml_edit::visit::*; +//! +//! #[derive(Default)] +//! struct StringCollector<'doc> { +//! strings: Vec<&'doc str>, +//! } +//! +//! impl<'doc> Visit<'doc> for StringCollector<'doc> { +//! fn visit_string(&mut self, node: &'doc Formatted<String>) { +//! self.strings.push(node.value().as_str()); +//! } +//! } +//! +//! let input = r#" +//! laputa = "sky-castle" +//! the-force = { value = "surrounds-you" } +//! "#; +//! +//! let mut document: Document = input.parse().unwrap(); +//! let mut visitor = StringCollector::default(); +//! visitor.visit_document(&document); +//! +//! assert_eq!(visitor.strings, vec!["sky-castle", "surrounds-you"]); +//! ``` +//! +//! For a more complex example where the visitor has internal state, see `examples/visit.rs` +//! [on GitHub](https://github.com/ordian/toml_edit/blob/master/examples/visit.rs). + +use crate::{ + Array, ArrayOfTables, Datetime, Document, Formatted, InlineTable, Item, Table, TableLike, Value, +}; + +/// Document tree traversal to mutate an exclusive borrow of a document tree in-place. +/// +/// See the [module documentation](self) for details. +pub trait Visit<'doc> { + fn visit_document(&mut self, node: &'doc Document) { + visit_document(self, node); + } + + fn visit_item(&mut self, node: &'doc Item) { + visit_item(self, node); + } + + fn visit_table(&mut self, node: &'doc Table) { + visit_table(self, node); + } + + fn visit_inline_table(&mut self, node: &'doc InlineTable) { + visit_inline_table(self, node) + } + + fn visit_table_like(&mut self, node: &'doc dyn TableLike) { + visit_table_like(self, node); + } + + fn visit_table_like_kv(&mut self, key: &'doc str, node: &'doc Item) { + visit_table_like_kv(self, key, node); + } + + fn visit_array(&mut self, node: &'doc Array) { + visit_array(self, node); + } + + fn visit_array_of_tables(&mut self, node: &'doc ArrayOfTables) { + visit_array_of_tables(self, node); + } + + fn visit_value(&mut self, node: &'doc Value) { + visit_value(self, node); + } + + fn visit_boolean(&mut self, node: &'doc Formatted<bool>) { + visit_boolean(self, node) + } + + fn visit_datetime(&mut self, node: &'doc Formatted<Datetime>) { + visit_datetime(self, node); + } + + fn visit_float(&mut self, node: &'doc Formatted<f64>) { + visit_float(self, node) + } + + fn visit_integer(&mut self, node: &'doc Formatted<i64>) { + visit_integer(self, node) + } + + fn visit_string(&mut self, node: &'doc Formatted<String>) { + visit_string(self, node) + } +} + +pub fn visit_document<'doc, V>(v: &mut V, node: &'doc Document) +where + V: Visit<'doc> + ?Sized, +{ + v.visit_table(node.as_table()); +} + +pub fn visit_item<'doc, V>(v: &mut V, node: &'doc Item) +where + V: Visit<'doc> + ?Sized, +{ + match node { + Item::None => {} + Item::Value(value) => v.visit_value(value), + Item::Table(table) => v.visit_table(table), + Item::ArrayOfTables(array) => v.visit_array_of_tables(array), + } +} + +pub fn visit_table<'doc, V>(v: &mut V, node: &'doc Table) +where + V: Visit<'doc> + ?Sized, +{ + v.visit_table_like(node) +} + +pub fn visit_inline_table<'doc, V>(v: &mut V, node: &'doc InlineTable) +where + V: Visit<'doc> + ?Sized, +{ + v.visit_table_like(node) +} + +pub fn visit_table_like<'doc, V>(v: &mut V, node: &'doc dyn TableLike) +where + V: Visit<'doc> + ?Sized, +{ + for (key, item) in node.iter() { + v.visit_table_like_kv(key, item) + } +} + +pub fn visit_table_like_kv<'doc, V>(v: &mut V, _key: &'doc str, node: &'doc Item) +where + V: Visit<'doc> + ?Sized, +{ + v.visit_item(node) +} + +pub fn visit_array<'doc, V>(v: &mut V, node: &'doc Array) +where + V: Visit<'doc> + ?Sized, +{ + for value in node.iter() { + v.visit_value(value); + } +} + +pub fn visit_array_of_tables<'doc, V>(v: &mut V, node: &'doc ArrayOfTables) +where + V: Visit<'doc> + ?Sized, +{ + for table in node.iter() { + v.visit_table(table); + } +} + +pub fn visit_value<'doc, V>(v: &mut V, node: &'doc Value) +where + V: Visit<'doc> + ?Sized, +{ + match node { + Value::String(s) => v.visit_string(s), + Value::Integer(i) => v.visit_integer(i), + Value::Float(f) => v.visit_float(f), + Value::Boolean(b) => v.visit_boolean(b), + Value::Datetime(dt) => v.visit_datetime(dt), + Value::Array(array) => v.visit_array(array), + Value::InlineTable(table) => v.visit_inline_table(table), + } +} + +macro_rules! empty_visit { + ($name: ident, $t: ty) => { + fn $name<'doc, V>(_v: &mut V, _node: &'doc $t) + where + V: Visit<'doc> + ?Sized, + { + } + }; +} + +empty_visit!(visit_boolean, Formatted<bool>); +empty_visit!(visit_datetime, Formatted<Datetime>); +empty_visit!(visit_float, Formatted<f64>); +empty_visit!(visit_integer, Formatted<i64>); +empty_visit!(visit_string, Formatted<String>); diff --git a/vendor/toml_edit/src/visit_mut.rs b/vendor/toml_edit/src/visit_mut.rs new file mode 100644 index 000000000..2c2af9752 --- /dev/null +++ b/vendor/toml_edit/src/visit_mut.rs @@ -0,0 +1,252 @@ +#![allow(missing_docs)] + +//! Document tree traversal to mutate an exclusive borrow of a document tree in place. +//! +//! +//! Each method of the [`VisitMut`] trait is a hook that can be overridden +//! to customize the behavior when mutating the corresponding type of node. +//! By default, every method recursively visits the substructure of the +//! input by invoking the right visitor method of each of its fields. +//! +//! ``` +//! # use toml_edit::{Item, ArrayOfTables, Table, Value}; +//! +//! pub trait VisitMut { +//! /* ... */ +//! +//! fn visit_item_mut(&mut self, i: &mut Item) { +//! visit_item_mut(self, i); +//! } +//! +//! /* ... */ +//! # fn visit_value_mut(&mut self, i: &mut Value); +//! # fn visit_table_mut(&mut self, i: &mut Table); +//! # fn visit_array_of_tables_mut(&mut self, i: &mut ArrayOfTables); +//! } +//! +//! pub fn visit_item_mut<V>(v: &mut V, node: &mut Item) +//! where +//! V: VisitMut + ?Sized, +//! { +//! match node { +//! Item::None => {} +//! Item::Value(value) => v.visit_value_mut(value), +//! Item::Table(table) => v.visit_table_mut(table), +//! Item::ArrayOfTables(array) => v.visit_array_of_tables_mut(array), +//! } +//! } +//! ``` +//! +//! The API is modeled after [`syn::visit_mut`](https://docs.rs/syn/1/syn/visit_mut). +//! +//! # Examples +//! +//! This visitor replaces every floating point value with its decimal string representation, to +//! 2 decimal points. +//! +//! ``` +//! # use toml_edit::*; +//! use toml_edit::visit_mut::*; +//! +//! struct FloatToString; +//! +//! impl VisitMut for FloatToString { +//! fn visit_value_mut(&mut self, node: &mut Value) { +//! if let Value::Float(f) = node { +//! // Convert the float to a string. +//! let mut s = Formatted::new(format!("{:.2}", f.value())); +//! // Copy over the formatting. +//! std::mem::swap(s.decor_mut(), f.decor_mut()); +//! *node = Value::String(s); +//! } +//! // Most of the time, you will also need to call the default implementation to recurse +//! // further down the document tree. +//! visit_value_mut(self, node); +//! } +//! } +//! +//! let input = r#" +//! banana = 3.26 +//! table = { apple = 4.5 } +//! "#; +//! +//! let mut document: Document = input.parse().unwrap(); +//! let mut visitor = FloatToString; +//! visitor.visit_document_mut(&mut document); +//! +//! let output = r#" +//! banana = "3.26" +//! table = { apple = "4.50" } +//! "#; +//! +//! assert_eq!(format!("{}", document), output); +//! ``` +//! +//! For a more complex example where the visitor has internal state, see `examples/visit.rs` +//! [on GitHub](https://github.com/ordian/toml_edit/blob/master/examples/visit.rs). + +use crate::{ + Array, ArrayOfTables, Datetime, Document, Formatted, InlineTable, Item, KeyMut, Table, + TableLike, Value, +}; + +/// Document tree traversal to mutate an exclusive borrow of a document tree in-place. +/// +/// See the [module documentation](self) for details. +pub trait VisitMut { + fn visit_document_mut(&mut self, node: &mut Document) { + visit_document_mut(self, node); + } + + fn visit_item_mut(&mut self, node: &mut Item) { + visit_item_mut(self, node); + } + + fn visit_table_mut(&mut self, node: &mut Table) { + visit_table_mut(self, node); + } + + fn visit_inline_table_mut(&mut self, node: &mut InlineTable) { + visit_inline_table_mut(self, node) + } + + /// [`visit_table_mut`](Self::visit_table_mut) and + /// [`visit_inline_table_mut`](Self::visit_inline_table_mut) both recurse into this method. + fn visit_table_like_mut(&mut self, node: &mut dyn TableLike) { + visit_table_like_mut(self, node); + } + + fn visit_table_like_kv_mut(&mut self, key: KeyMut<'_>, node: &mut Item) { + visit_table_like_kv_mut(self, key, node); + } + + fn visit_array_mut(&mut self, node: &mut Array) { + visit_array_mut(self, node); + } + + fn visit_array_of_tables_mut(&mut self, node: &mut ArrayOfTables) { + visit_array_of_tables_mut(self, node); + } + + fn visit_value_mut(&mut self, node: &mut Value) { + visit_value_mut(self, node); + } + + fn visit_boolean_mut(&mut self, node: &mut Formatted<bool>) { + visit_boolean_mut(self, node) + } + + fn visit_datetime_mut(&mut self, node: &mut Formatted<Datetime>) { + visit_datetime_mut(self, node); + } + + fn visit_float_mut(&mut self, node: &mut Formatted<f64>) { + visit_float_mut(self, node) + } + + fn visit_integer_mut(&mut self, node: &mut Formatted<i64>) { + visit_integer_mut(self, node) + } + + fn visit_string_mut(&mut self, node: &mut Formatted<String>) { + visit_string_mut(self, node) + } +} + +pub fn visit_document_mut<V>(v: &mut V, node: &mut Document) +where + V: VisitMut + ?Sized, +{ + v.visit_table_mut(node.as_table_mut()); +} + +pub fn visit_item_mut<V>(v: &mut V, node: &mut Item) +where + V: VisitMut + ?Sized, +{ + match node { + Item::None => {} + Item::Value(value) => v.visit_value_mut(value), + Item::Table(table) => v.visit_table_mut(table), + Item::ArrayOfTables(array) => v.visit_array_of_tables_mut(array), + } +} + +pub fn visit_table_mut<V>(v: &mut V, node: &mut Table) +where + V: VisitMut + ?Sized, +{ + v.visit_table_like_mut(node); +} + +pub fn visit_inline_table_mut<V>(v: &mut V, node: &mut InlineTable) +where + V: VisitMut + ?Sized, +{ + v.visit_table_like_mut(node); +} + +pub fn visit_table_like_mut<V>(v: &mut V, node: &mut dyn TableLike) +where + V: VisitMut + ?Sized, +{ + for (key, item) in node.iter_mut() { + v.visit_table_like_kv_mut(key, item); + } +} + +pub fn visit_table_like_kv_mut<V>(v: &mut V, _key: KeyMut<'_>, node: &mut Item) +where + V: VisitMut + ?Sized, +{ + v.visit_item_mut(node) +} + +pub fn visit_array_mut<V>(v: &mut V, node: &mut Array) +where + V: VisitMut + ?Sized, +{ + for value in node.iter_mut() { + v.visit_value_mut(value); + } +} + +pub fn visit_array_of_tables_mut<V>(v: &mut V, node: &mut ArrayOfTables) +where + V: VisitMut + ?Sized, +{ + for table in node.iter_mut() { + v.visit_table_mut(table); + } +} + +pub fn visit_value_mut<V>(v: &mut V, node: &mut Value) +where + V: VisitMut + ?Sized, +{ + match node { + Value::String(s) => v.visit_string_mut(s), + Value::Integer(i) => v.visit_integer_mut(i), + Value::Float(f) => v.visit_float_mut(f), + Value::Boolean(b) => v.visit_boolean_mut(b), + Value::Datetime(dt) => v.visit_datetime_mut(dt), + Value::Array(array) => v.visit_array_mut(array), + Value::InlineTable(table) => v.visit_inline_table_mut(table), + } +} + +macro_rules! empty_visit_mut { + ($name: ident, $t: ty) => { + fn $name<V>(_v: &mut V, _node: &mut $t) + where + V: VisitMut + ?Sized, + { + } + }; +} + +empty_visit_mut!(visit_boolean_mut, Formatted<bool>); +empty_visit_mut!(visit_datetime_mut, Formatted<Datetime>); +empty_visit_mut!(visit_float_mut, Formatted<f64>); +empty_visit_mut!(visit_integer_mut, Formatted<i64>); +empty_visit_mut!(visit_string_mut, Formatted<String>); diff --git a/vendor/toml_edit/tests/decoder.rs b/vendor/toml_edit/tests/decoder.rs new file mode 100644 index 000000000..7306d4557 --- /dev/null +++ b/vendor/toml_edit/tests/decoder.rs @@ -0,0 +1,100 @@ +#[derive(Copy, Clone)] +pub struct Decoder; + +impl toml_test_harness::Decoder for Decoder { + fn name(&self) -> &str { + "toml_edit" + } + + fn decode(&self, data: &[u8]) -> Result<toml_test_harness::Decoded, toml_test_harness::Error> { + let data = std::str::from_utf8(data).map_err(toml_test_harness::Error::new)?; + let document = data + .parse::<toml_edit::Document>() + .map_err(toml_test_harness::Error::new)?; + document_to_decoded(&document) + } +} + +fn document_to_decoded( + value: &toml_edit::Document, +) -> Result<toml_test_harness::Decoded, toml_test_harness::Error> { + table_to_decoded(value) +} + +fn item_to_decoded( + value: &toml_edit::Item, +) -> Result<toml_test_harness::Decoded, toml_test_harness::Error> { + match value { + toml_edit::Item::None => unreachable!("No nones"), + toml_edit::Item::Value(v) => value_to_decoded(v), + toml_edit::Item::Table(v) => table_to_decoded(v), + toml_edit::Item::ArrayOfTables(v) => { + let v: Result<_, toml_test_harness::Error> = v.iter().map(table_to_decoded).collect(); + Ok(toml_test_harness::Decoded::Array(v?)) + } + } +} + +fn value_to_decoded( + value: &toml_edit::Value, +) -> Result<toml_test_harness::Decoded, toml_test_harness::Error> { + match value { + toml_edit::Value::Integer(v) => Ok(toml_test_harness::Decoded::Value( + toml_test_harness::DecodedValue::from(*v.value()), + )), + toml_edit::Value::String(v) => Ok(toml_test_harness::Decoded::Value( + toml_test_harness::DecodedValue::from(v.value()), + )), + toml_edit::Value::Float(v) => Ok(toml_test_harness::Decoded::Value( + toml_test_harness::DecodedValue::from(*v.value()), + )), + toml_edit::Value::Datetime(v) => { + let v = v.value(); + let value = v.to_string(); + let value = match (v.date.is_some(), v.time.is_some(), v.offset.is_some()) { + (true, true, true) => toml_test_harness::DecodedValue::Datetime(value), + (true, true, false) => toml_test_harness::DecodedValue::DatetimeLocal(value), + (true, false, false) => toml_test_harness::DecodedValue::DateLocal(value), + (false, true, false) => toml_test_harness::DecodedValue::TimeLocal(value), + _ => unreachable!("Unsupported case"), + }; + Ok(toml_test_harness::Decoded::Value(value)) + } + toml_edit::Value::Boolean(v) => Ok(toml_test_harness::Decoded::Value( + toml_test_harness::DecodedValue::from(*v.value()), + )), + toml_edit::Value::Array(v) => { + let v: Result<_, toml_test_harness::Error> = v.iter().map(value_to_decoded).collect(); + Ok(toml_test_harness::Decoded::Array(v?)) + } + toml_edit::Value::InlineTable(v) => inline_table_to_decoded(v), + } +} + +fn table_to_decoded( + value: &toml_edit::Table, +) -> Result<toml_test_harness::Decoded, toml_test_harness::Error> { + let table: Result<_, toml_test_harness::Error> = value + .iter() + .map(|(k, v)| { + let k = k.to_owned(); + let v = item_to_decoded(v)?; + Ok((k, v)) + }) + .collect(); + Ok(toml_test_harness::Decoded::Table(table?)) +} + +fn inline_table_to_decoded( + value: &toml_edit::InlineTable, +) -> Result<toml_test_harness::Decoded, toml_test_harness::Error> { + let table: Result<_, toml_test_harness::Error> = value + .iter() + .map(|(k, v)| { + let k = k.to_owned(); + let v = value_to_decoded(v)?; + Ok((k, v)) + }) + .collect(); + Ok(toml_test_harness::Decoded::Table(table?)) +} diff --git a/vendor/toml_edit/tests/decoder_compliance.rs b/vendor/toml_edit/tests/decoder_compliance.rs new file mode 100644 index 000000000..0f0b35015 --- /dev/null +++ b/vendor/toml_edit/tests/decoder_compliance.rs @@ -0,0 +1,17 @@ +mod decoder; + +fn main() { + let decoder = decoder::Decoder; + let mut harness = toml_test_harness::DecoderHarness::new(decoder); + harness + .ignore([ + "valid/spec/float-0.toml", // Test issue; `Decoder` turns `6.626e-34` into `0.0` + // Unreleased + "valid/string/escape-esc.toml", + "valid/string/hex-escape.toml", + "valid/datetime/no-seconds.toml", + "valid/inline-table/newline.toml", + ]) + .unwrap(); + harness.test(); +} diff --git a/vendor/toml_edit/tests/encoder.rs b/vendor/toml_edit/tests/encoder.rs new file mode 100644 index 000000000..808a20c42 --- /dev/null +++ b/vendor/toml_edit/tests/encoder.rs @@ -0,0 +1,111 @@ +#[derive(Copy, Clone)] +pub struct Encoder; + +impl toml_test_harness::Encoder for Encoder { + fn name(&self) -> &str { + "toml_edit" + } + + fn encode(&self, data: toml_test_harness::Decoded) -> Result<String, toml_test_harness::Error> { + let doc = decoded_to_document(&data)?; + Ok(doc.to_string()) + } +} + +fn decoded_to_document( + decoded: &toml_test_harness::Decoded, +) -> Result<toml_edit::Document, toml_test_harness::Error> { + let item = root_from_decoded(decoded)?; + let mut doc = toml_edit::Document::new(); + *doc = item; + Ok(doc) +} + +fn root_from_decoded( + decoded: &toml_test_harness::Decoded, +) -> Result<toml_edit::Table, toml_test_harness::Error> { + match decoded { + toml_test_harness::Decoded::Value(_) => { + Err(toml_test_harness::Error::new("Root cannot be a value")) + } + toml_test_harness::Decoded::Table(value) => value + .iter() + .map(|(k, v)| { + let k = k.as_str(); + let v = from_decoded(v)?; + Ok((k, v)) + }) + .collect(), + toml_test_harness::Decoded::Array(_) => { + Err(toml_test_harness::Error::new("Root cannot be an array")) + } + } +} + +fn from_decoded( + decoded: &toml_test_harness::Decoded, +) -> Result<toml_edit::Value, toml_test_harness::Error> { + let value = match decoded { + toml_test_harness::Decoded::Value(value) => from_decoded_value(value)?, + toml_test_harness::Decoded::Table(value) => { + toml_edit::Value::InlineTable(from_table(value)?) + } + toml_test_harness::Decoded::Array(value) => toml_edit::Value::Array(from_array(value)?), + }; + Ok(value) +} + +fn from_decoded_value( + decoded: &toml_test_harness::DecodedValue, +) -> Result<toml_edit::Value, toml_test_harness::Error> { + let value: toml_edit::Value = match decoded { + toml_test_harness::DecodedValue::String(value) => value.into(), + toml_test_harness::DecodedValue::Integer(value) => value + .parse::<i64>() + .map_err(toml_test_harness::Error::new)? + .into(), + toml_test_harness::DecodedValue::Float(value) => value + .parse::<f64>() + .map_err(toml_test_harness::Error::new)? + .into(), + toml_test_harness::DecodedValue::Bool(value) => value + .parse::<bool>() + .map_err(toml_test_harness::Error::new)? + .into(), + toml_test_harness::DecodedValue::Datetime(value) => value + .parse::<toml_edit::Datetime>() + .map_err(toml_test_harness::Error::new)? + .into(), + toml_test_harness::DecodedValue::DatetimeLocal(value) => value + .parse::<toml_edit::Datetime>() + .map_err(toml_test_harness::Error::new)? + .into(), + toml_test_harness::DecodedValue::DateLocal(value) => value + .parse::<toml_edit::Datetime>() + .map_err(toml_test_harness::Error::new)? + .into(), + toml_test_harness::DecodedValue::TimeLocal(value) => value + .parse::<toml_edit::Datetime>() + .map_err(toml_test_harness::Error::new)? + .into(), + }; + Ok(value) +} + +fn from_table( + decoded: &std::collections::HashMap<String, toml_test_harness::Decoded>, +) -> Result<toml_edit::InlineTable, toml_test_harness::Error> { + decoded + .iter() + .map(|(k, v)| { + let v = from_decoded(v)?; + Ok((k, v)) + }) + .collect() +} + +fn from_array( + decoded: &[toml_test_harness::Decoded], +) -> Result<toml_edit::Array, toml_test_harness::Error> { + decoded.iter().map(from_decoded).collect() +} diff --git a/vendor/toml_edit/tests/encoder_compliance.rs b/vendor/toml_edit/tests/encoder_compliance.rs new file mode 100644 index 000000000..ad65d75ce --- /dev/null +++ b/vendor/toml_edit/tests/encoder_compliance.rs @@ -0,0 +1,14 @@ +mod decoder; +mod encoder; + +fn main() { + let encoder = encoder::Encoder; + let decoder = decoder::Decoder; + let mut harness = toml_test_harness::EncoderHarness::new(encoder, decoder); + harness + .ignore([ + "valid/spec/float-0.toml", // Test issue; `Decoder` turns `6.626e-34` into `0.0` + ]) + .unwrap(); + harness.test(); +} diff --git a/vendor/toml_edit/tests/fixtures/invalid/array/double-comma-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/array/double-comma-1.stderr new file mode 100644 index 000000000..543e1b680 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/array/double-comma-1.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 12 + | +1 | array = [1,,2] + | ^ +invalid array +expected `]` diff --git a/vendor/toml_edit/tests/fixtures/invalid/array/double-comma-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/array/double-comma-2.stderr new file mode 100644 index 000000000..694d7ec40 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/array/double-comma-2.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 14 + | +1 | array = [1,2,,] + | ^ +invalid array +expected `]` diff --git a/vendor/toml_edit/tests/fixtures/invalid/array/extending-table.stderr b/vendor/toml_edit/tests/fixtures/invalid/array/extending-table.stderr new file mode 100644 index 000000000..6f92ff668 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/array/extending-table.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 5, column 1 + | +5 | [a.c] + | ^ +invalid table header +dotted key `a` attempted to extend non-table type (array) diff --git a/vendor/toml_edit/tests/fixtures/invalid/array/missing-separator.stderr b/vendor/toml_edit/tests/fixtures/invalid/array/missing-separator.stderr new file mode 100644 index 000000000..8e21f51fe --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/array/missing-separator.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 13 + | +1 | wrong = [ 1 2 3 ] + | ^ +invalid array +expected `]` diff --git a/vendor/toml_edit/tests/fixtures/invalid/array/no-close-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/array/no-close-2.stderr new file mode 100644 index 000000000..81ae5a968 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/array/no-close-2.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 11 + | +1 | x = [42 # + | ^ +invalid array +expected `]` diff --git a/vendor/toml_edit/tests/fixtures/invalid/array/no-close-table-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/array/no-close-table-2.stderr new file mode 100644 index 000000000..535943e2e --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/array/no-close-table-2.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 17 + | +1 | x = [{ key = 42 # + | ^ +invalid inline table +expected `}` diff --git a/vendor/toml_edit/tests/fixtures/invalid/array/no-close-table.stderr b/vendor/toml_edit/tests/fixtures/invalid/array/no-close-table.stderr new file mode 100644 index 000000000..b4c3c32d4 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/array/no-close-table.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 16 + | +1 | x = [{ key = 42 + | ^ +invalid inline table +expected `}` diff --git a/vendor/toml_edit/tests/fixtures/invalid/array/no-close.stderr b/vendor/toml_edit/tests/fixtures/invalid/array/no-close.stderr new file mode 100644 index 000000000..a4f0a88d3 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/array/no-close.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 24 + | +1 | long_array = [ 1, 2, 3 + | ^ +invalid array +expected `]` diff --git a/vendor/toml_edit/tests/fixtures/invalid/array/tables-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/array/tables-1.stderr new file mode 100644 index 000000000..771b4f6c9 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/array/tables-1.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 4, column 1 + | +4 | [[fruit]] # Not allowed + | ^ +invalid table header +duplicate key `fruit` in document root diff --git a/vendor/toml_edit/tests/fixtures/invalid/array/tables-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/array/tables-2.stderr new file mode 100644 index 000000000..1f88e6efd --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/array/tables-2.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 9, column 3 + | +9 | [fruit.variety] + | ^ +invalid table header +duplicate key `variety` in table `fruit` diff --git a/vendor/toml_edit/tests/fixtures/invalid/array/text-after-array-entries.stderr b/vendor/toml_edit/tests/fixtures/invalid/array/text-after-array-entries.stderr new file mode 100644 index 000000000..23b5ac27c --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/array/text-after-array-entries.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 2, column 46 + | +2 | "Is there life after an array separator?", No + | ^ +invalid array +expected `]` diff --git a/vendor/toml_edit/tests/fixtures/invalid/array/text-before-array-separator.stderr b/vendor/toml_edit/tests/fixtures/invalid/array/text-before-array-separator.stderr new file mode 100644 index 000000000..9d667990b --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/array/text-before-array-separator.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 2, column 46 + | +2 | "Is there life before an array separator?" No, + | ^ +invalid array +expected `]` diff --git a/vendor/toml_edit/tests/fixtures/invalid/array/text-in-array.stderr b/vendor/toml_edit/tests/fixtures/invalid/array/text-in-array.stderr new file mode 100644 index 000000000..580237357 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/array/text-in-array.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 3, column 3 + | +3 | I don't belong, + | ^ +invalid array +expected `]` diff --git a/vendor/toml_edit/tests/fixtures/invalid/bool/almost-false-with-extra.stderr b/vendor/toml_edit/tests/fixtures/invalid/bool/almost-false-with-extra.stderr new file mode 100644 index 000000000..cd6c1cd5f --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/bool/almost-false-with-extra.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 5 + | +1 | a = falsify + | ^ +invalid string +expected `"`, `'` diff --git a/vendor/toml_edit/tests/fixtures/invalid/bool/almost-false.stderr b/vendor/toml_edit/tests/fixtures/invalid/bool/almost-false.stderr new file mode 100644 index 000000000..550020b92 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/bool/almost-false.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 5 + | +1 | a = fals + | ^ +invalid string +expected `"`, `'` diff --git a/vendor/toml_edit/tests/fixtures/invalid/bool/almost-true-with-extra.stderr b/vendor/toml_edit/tests/fixtures/invalid/bool/almost-true-with-extra.stderr new file mode 100644 index 000000000..c75c553ee --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/bool/almost-true-with-extra.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 5 + | +1 | a = truthy + | ^ +invalid string +expected `"`, `'` diff --git a/vendor/toml_edit/tests/fixtures/invalid/bool/almost-true.stderr b/vendor/toml_edit/tests/fixtures/invalid/bool/almost-true.stderr new file mode 100644 index 000000000..0c97e0076 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/bool/almost-true.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 5 + | +1 | a = tru + | ^ +invalid string +expected `"`, `'` diff --git a/vendor/toml_edit/tests/fixtures/invalid/bool/just-f.stderr b/vendor/toml_edit/tests/fixtures/invalid/bool/just-f.stderr new file mode 100644 index 000000000..ed2b9f0e7 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/bool/just-f.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 5 + | +1 | a = f + | ^ +invalid string +expected `"`, `'` diff --git a/vendor/toml_edit/tests/fixtures/invalid/bool/just-t.stderr b/vendor/toml_edit/tests/fixtures/invalid/bool/just-t.stderr new file mode 100644 index 000000000..2c8b6a5bd --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/bool/just-t.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 5 + | +1 | a = t + | ^ +invalid string +expected `"`, `'` diff --git a/vendor/toml_edit/tests/fixtures/invalid/bool/mixed-case.stderr b/vendor/toml_edit/tests/fixtures/invalid/bool/mixed-case.stderr new file mode 100644 index 000000000..b7c6192dd --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/bool/mixed-case.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 9 + | +1 | valid = False + | ^ +invalid string +expected `"`, `'` diff --git a/vendor/toml_edit/tests/fixtures/invalid/bool/starting-same-false.stderr b/vendor/toml_edit/tests/fixtures/invalid/bool/starting-same-false.stderr new file mode 100644 index 000000000..b3320892c --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/bool/starting-same-false.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 10 + | +1 | a = falsey + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/bool/starting-same-true.stderr b/vendor/toml_edit/tests/fixtures/invalid/bool/starting-same-true.stderr new file mode 100644 index 000000000..6053103c9 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/bool/starting-same-true.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 9 + | +1 | a = truer + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/bool/wrong-case-false.stderr b/vendor/toml_edit/tests/fixtures/invalid/bool/wrong-case-false.stderr new file mode 100644 index 000000000..f67444c40 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/bool/wrong-case-false.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 5 + | +1 | b = FALSE + | ^ +invalid string +expected `"`, `'` diff --git a/vendor/toml_edit/tests/fixtures/invalid/bool/wrong-case-true.stderr b/vendor/toml_edit/tests/fixtures/invalid/bool/wrong-case-true.stderr new file mode 100644 index 000000000..82bb6194f --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/bool/wrong-case-true.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 5 + | +1 | a = TRUE + | ^ +invalid string +expected `"`, `'` diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/bare-cr.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/bare-cr.stderr new file mode 100644 index 000000000..f0062f6f2 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/bare-cr.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 2, column 1 + | +2 | + | ^ + diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/bare-formfeed.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/bare-formfeed.stderr new file mode 100644 index 000000000..313274a3e --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/bare-formfeed.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 17 + | +1 | bare-formfeed = + | ^ +invalid string +expected `"`, `'` diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/bare-null.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/bare-null.stderr Binary files differnew file mode 100644 index 000000000..cd5e936ac --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/bare-null.stderr diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/bare-vertical-tab.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/bare-vertical-tab.stderr new file mode 100644 index 000000000..c8e01ba04 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/bare-vertical-tab.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 21 + | +1 | bare-vertical-tab = + | ^ +invalid string +expected `"`, `'` diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/comment-cr.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/comment-cr.stderr new file mode 100644 index 000000000..fb262e547 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/comment-cr.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 45 + | +1 | comment-cr = "Carriage return in comment" # +a=1 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/comment-del.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/comment-del.stderr new file mode 100644 index 000000000..3d25d68dc --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/comment-del.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 24 + | +1 | comment-del = "0x7f" # + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/comment-lf.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/comment-lf.stderr new file mode 100644 index 000000000..1613710ed --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/comment-lf.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 25 + | +1 | comment-lf = "ctrl-P" # + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/comment-null.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/comment-null.stderr Binary files differnew file mode 100644 index 000000000..4955b9deb --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/comment-null.stderr diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/comment-us.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/comment-us.stderr new file mode 100644 index 000000000..b48d4f33c --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/comment-us.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 25 + | +1 | comment-us = "ctrl-_" # + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/control.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/control.stderr new file mode 100644 index 000000000..486aacf1b --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/control.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 9, column 22 + | +9 | string-null = "null\x00" + | ^ +invalid escape sequence +expected `b`, `f`, `n`, `r`, `t`, `u`, `U`, `\`, `"` diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/multi-del.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/multi-del.stderr new file mode 100644 index 000000000..62702da7b --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/multi-del.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 20 + | +1 | multi-del = """null""" + | ^ +invalid multiline basic string diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/multi-lf.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/multi-lf.stderr new file mode 100644 index 000000000..7b7a13889 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/multi-lf.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 19 + | +1 | multi-lf = """null""" + | ^ +invalid multiline basic string diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/multi-null.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/multi-null.stderr Binary files differnew file mode 100644 index 000000000..2d3c33534 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/multi-null.stderr diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/multi-us.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/multi-us.stderr new file mode 100644 index 000000000..cf8e73286 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/multi-us.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 19 + | +1 | multi-us = """null""" + | ^ +invalid multiline basic string diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/rawmulti-del.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/rawmulti-del.stderr new file mode 100644 index 000000000..3beeae099 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/rawmulti-del.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 23 + | +1 | rawmulti-del = '''null''' + | ^ +invalid multiline literal string diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/rawmulti-lf.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/rawmulti-lf.stderr new file mode 100644 index 000000000..40782a261 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/rawmulti-lf.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 22 + | +1 | rawmulti-lf = '''null''' + | ^ +invalid multiline literal string diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/rawmulti-null.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/rawmulti-null.stderr Binary files differnew file mode 100644 index 000000000..d583ce6f5 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/rawmulti-null.stderr diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/rawmulti-us.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/rawmulti-us.stderr new file mode 100644 index 000000000..d413d54f1 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/rawmulti-us.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 22 + | +1 | rawmulti-us = '''null''' + | ^ +invalid multiline literal string diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/rawstring-del.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/rawstring-del.stderr new file mode 100644 index 000000000..640ba463b --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/rawstring-del.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 22 + | +1 | rawstring-del = 'null' + | ^ +invalid literal string diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/rawstring-lf.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/rawstring-lf.stderr new file mode 100644 index 000000000..e6499b6b9 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/rawstring-lf.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 21 + | +1 | rawstring-lf = 'null' + | ^ +invalid literal string diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/rawstring-null.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/rawstring-null.stderr Binary files differnew file mode 100644 index 000000000..9227d090e --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/rawstring-null.stderr diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/rawstring-us.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/rawstring-us.stderr new file mode 100644 index 000000000..492cdf743 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/rawstring-us.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 21 + | +1 | rawstring-us = 'null' + | ^ +invalid literal string diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/string-bs.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/string-bs.stderr new file mode 100644 index 000000000..556ba1d7b --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/string-bs.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 23 + | +1 | string-bs = "backspace" + | ^ +invalid basic string diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/string-del.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/string-del.stderr new file mode 100644 index 000000000..85d7af397 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/string-del.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 19 + | +1 | string-del = "null" + | ^ +invalid basic string diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/string-lf.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/string-lf.stderr new file mode 100644 index 000000000..fbf0d1a3f --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/string-lf.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 18 + | +1 | string-lf = "null" + | ^ +invalid basic string diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/string-null.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/string-null.stderr Binary files differnew file mode 100644 index 000000000..e9fc0befa --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/string-null.stderr diff --git a/vendor/toml_edit/tests/fixtures/invalid/control/string-us.stderr b/vendor/toml_edit/tests/fixtures/invalid/control/string-us.stderr new file mode 100644 index 000000000..8278e570a --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/control/string-us.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 18 + | +1 | string-us = "null" + | ^ +invalid basic string diff --git a/vendor/toml_edit/tests/fixtures/invalid/datetime/hour-over.stderr b/vendor/toml_edit/tests/fixtures/invalid/datetime/hour-over.stderr new file mode 100644 index 000000000..0e6747da3 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/datetime/hour-over.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 2, column 15 + | +2 | d = 2006-01-01T24:00:00-00:00 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/datetime/mday-over.stderr b/vendor/toml_edit/tests/fixtures/invalid/datetime/mday-over.stderr new file mode 100644 index 000000000..edb976990 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/datetime/mday-over.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 3, column 13 + | +3 | d = 2006-01-32T00:00:00-00:00 + | ^ +invalid date-time +value is out of range diff --git a/vendor/toml_edit/tests/fixtures/invalid/datetime/mday-under.stderr b/vendor/toml_edit/tests/fixtures/invalid/datetime/mday-under.stderr new file mode 100644 index 000000000..6af20509d --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/datetime/mday-under.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 3, column 13 + | +3 | d = 2006-01-00T00:00:00-00:00 + | ^ +invalid date-time +value is out of range diff --git a/vendor/toml_edit/tests/fixtures/invalid/datetime/minute-over.stderr b/vendor/toml_edit/tests/fixtures/invalid/datetime/minute-over.stderr new file mode 100644 index 000000000..20f3b4bc6 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/datetime/minute-over.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 2, column 19 + | +2 | d = 2006-01-01T00:60:00-00:00 + | ^ +invalid date-time +value is out of range diff --git a/vendor/toml_edit/tests/fixtures/invalid/datetime/month-over.stderr b/vendor/toml_edit/tests/fixtures/invalid/datetime/month-over.stderr new file mode 100644 index 000000000..33334755b --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/datetime/month-over.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 2, column 10 + | +2 | d = 2006-13-01T00:00:00-00:00 + | ^ +invalid date-time +value is out of range diff --git a/vendor/toml_edit/tests/fixtures/invalid/datetime/month-under.stderr b/vendor/toml_edit/tests/fixtures/invalid/datetime/month-under.stderr new file mode 100644 index 000000000..5d0cd0645 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/datetime/month-under.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 2, column 10 + | +2 | d = 2007-00-01T00:00:00-00:00 + | ^ +invalid date-time +value is out of range diff --git a/vendor/toml_edit/tests/fixtures/invalid/datetime/no-leads-with-milli.stderr b/vendor/toml_edit/tests/fixtures/invalid/datetime/no-leads-with-milli.stderr new file mode 100644 index 000000000..df9190dcf --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/datetime/no-leads-with-milli.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 2, column 22 + | +2 | with-milli = 1987-07-5T17:45:00.12Z + | ^ +invalid date-time diff --git a/vendor/toml_edit/tests/fixtures/invalid/datetime/no-leads.stderr b/vendor/toml_edit/tests/fixtures/invalid/datetime/no-leads.stderr new file mode 100644 index 000000000..3e0ccf722 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/datetime/no-leads.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 2, column 17 + | +2 | no-leads = 1987-7-05T17:45:00Z + | ^ +invalid date-time diff --git a/vendor/toml_edit/tests/fixtures/invalid/datetime/no-secs.stderr b/vendor/toml_edit/tests/fixtures/invalid/datetime/no-secs.stderr new file mode 100644 index 000000000..078d0a001 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/datetime/no-secs.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 2, column 27 + | +2 | no-secs = 1987-07-05T17:45Z + | ^ +invalid date-time diff --git a/vendor/toml_edit/tests/fixtures/invalid/datetime/no-t.stderr b/vendor/toml_edit/tests/fixtures/invalid/datetime/no-t.stderr new file mode 100644 index 000000000..15e955463 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/datetime/no-t.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 2, column 18 + | +2 | no-t = 1987-07-0517:45:00Z + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/datetime/second-over.stderr b/vendor/toml_edit/tests/fixtures/invalid/datetime/second-over.stderr new file mode 100644 index 000000000..186a38dad --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/datetime/second-over.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 3, column 22 + | +3 | d = 2006-01-01T00:00:61-00:00 + | ^ +invalid date-time +value is out of range diff --git a/vendor/toml_edit/tests/fixtures/invalid/datetime/time-no-leads-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/datetime/time-no-leads-2.stderr new file mode 100644 index 000000000..fd77fb297 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/datetime/time-no-leads-2.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 2, column 11 + | +2 | d = 01:32:0 + | ^ +invalid time diff --git a/vendor/toml_edit/tests/fixtures/invalid/datetime/time-no-leads.stderr b/vendor/toml_edit/tests/fixtures/invalid/datetime/time-no-leads.stderr new file mode 100644 index 000000000..7a9890229 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/datetime/time-no-leads.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 2, column 6 + | +2 | d = 1:32:00 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/datetime/trailing-t.stderr b/vendor/toml_edit/tests/fixtures/invalid/datetime/trailing-t.stderr new file mode 100644 index 000000000..061ec2682 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/datetime/trailing-t.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 2, column 15 + | +2 | d = 2006-01-30T + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/encoding/bad-utf8-at-end.stderr b/vendor/toml_edit/tests/fixtures/invalid/encoding/bad-utf8-at-end.stderr new file mode 100644 index 000000000..7a11cf905 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/encoding/bad-utf8-at-end.stderr @@ -0,0 +1 @@ +incomplete utf-8 byte sequence from index 241
\ No newline at end of file diff --git a/vendor/toml_edit/tests/fixtures/invalid/encoding/bad-utf8-in-comment.stderr b/vendor/toml_edit/tests/fixtures/invalid/encoding/bad-utf8-in-comment.stderr new file mode 100644 index 000000000..72d1465ca --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/encoding/bad-utf8-in-comment.stderr @@ -0,0 +1 @@ +invalid utf-8 sequence of 1 bytes from index 2
\ No newline at end of file diff --git a/vendor/toml_edit/tests/fixtures/invalid/encoding/bad-utf8-in-multiline-literal.stderr b/vendor/toml_edit/tests/fixtures/invalid/encoding/bad-utf8-in-multiline-literal.stderr new file mode 100644 index 000000000..0c70f2864 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/encoding/bad-utf8-in-multiline-literal.stderr @@ -0,0 +1 @@ +invalid utf-8 sequence of 1 bytes from index 66
\ No newline at end of file diff --git a/vendor/toml_edit/tests/fixtures/invalid/encoding/bad-utf8-in-multiline.stderr b/vendor/toml_edit/tests/fixtures/invalid/encoding/bad-utf8-in-multiline.stderr new file mode 100644 index 000000000..0c70f2864 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/encoding/bad-utf8-in-multiline.stderr @@ -0,0 +1 @@ +invalid utf-8 sequence of 1 bytes from index 66
\ No newline at end of file diff --git a/vendor/toml_edit/tests/fixtures/invalid/encoding/bad-utf8-in-string-literal.stderr b/vendor/toml_edit/tests/fixtures/invalid/encoding/bad-utf8-in-string-literal.stderr new file mode 100644 index 000000000..9e1a687c6 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/encoding/bad-utf8-in-string-literal.stderr @@ -0,0 +1 @@ +invalid utf-8 sequence of 1 bytes from index 64
\ No newline at end of file diff --git a/vendor/toml_edit/tests/fixtures/invalid/encoding/bad-utf8-in-string.stderr b/vendor/toml_edit/tests/fixtures/invalid/encoding/bad-utf8-in-string.stderr new file mode 100644 index 000000000..9e1a687c6 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/encoding/bad-utf8-in-string.stderr @@ -0,0 +1 @@ +invalid utf-8 sequence of 1 bytes from index 64
\ No newline at end of file diff --git a/vendor/toml_edit/tests/fixtures/invalid/encoding/bom-not-at-start-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/encoding/bom-not-at-start-1.stderr new file mode 100644 index 000000000..8d9d90bfe --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/encoding/bom-not-at-start-1.stderr @@ -0,0 +1 @@ +invalid utf-8 sequence of 1 bytes from index 17
\ No newline at end of file diff --git a/vendor/toml_edit/tests/fixtures/invalid/encoding/bom-not-at-start-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/encoding/bom-not-at-start-2.stderr new file mode 100644 index 000000000..8fce4086e --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/encoding/bom-not-at-start-2.stderr @@ -0,0 +1 @@ +invalid utf-8 sequence of 1 bytes from index 18
\ No newline at end of file diff --git a/vendor/toml_edit/tests/fixtures/invalid/encoding/utf16-bom.stderr b/vendor/toml_edit/tests/fixtures/invalid/encoding/utf16-bom.stderr new file mode 100644 index 000000000..b1b9eedac --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/encoding/utf16-bom.stderr @@ -0,0 +1 @@ +invalid utf-8 sequence of 1 bytes from index 0
\ No newline at end of file diff --git a/vendor/toml_edit/tests/fixtures/invalid/encoding/utf16.stderr b/vendor/toml_edit/tests/fixtures/invalid/encoding/utf16.stderr Binary files differnew file mode 100644 index 000000000..688616546 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/encoding/utf16.stderr diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/double-point-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/double-point-1.stderr new file mode 100644 index 000000000..390520f7d --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/double-point-1.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 20 + | +1 | double-point-1 = 0..1 + | ^ +invalid floating-point number +expected digit diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/double-point-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/double-point-2.stderr new file mode 100644 index 000000000..a020a4846 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/double-point-2.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 21 + | +1 | double-point-2 = 0.1.2 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/exp-double-e-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/exp-double-e-1.stderr new file mode 100644 index 000000000..54118395c --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/exp-double-e-1.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 20 + | +1 | exp-double-e-1 = 1ee2 + | ^ +invalid floating-point number diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/exp-double-e-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/exp-double-e-2.stderr new file mode 100644 index 000000000..1b99d374d --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/exp-double-e-2.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 21 + | +1 | exp-double-e-2 = 1e2e3 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/exp-double-us.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/exp-double-us.stderr new file mode 100644 index 000000000..6a66e43d6 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/exp-double-us.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 19 + | +1 | exp-double-us = 1e__23 + | ^ +invalid floating-point number diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/exp-leading-us.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/exp-leading-us.stderr new file mode 100644 index 000000000..769668690 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/exp-leading-us.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 20 + | +1 | exp-leading-us = 1e_23 + | ^ +invalid floating-point number diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/exp-point-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/exp-point-1.stderr new file mode 100644 index 000000000..87f0a0b2e --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/exp-point-1.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 18 + | +1 | exp-point-1 = 1e2.3 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/exp-point-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/exp-point-2.stderr new file mode 100644 index 000000000..808905064 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/exp-point-2.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 17 + | +1 | exp-point-2 = 1.e2 + | ^ +invalid floating-point number +expected digit diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/exp-trailing-us.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/exp-trailing-us.stderr new file mode 100644 index 000000000..9a2818493 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/exp-trailing-us.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 21 + | +1 | exp-trailing-us = 1e_23_ + | ^ +invalid floating-point number diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/float.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/float.stderr new file mode 100644 index 000000000..627650f81 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/float.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 17 + | +1 | leading-zero = 03.14 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/inf-incomplete-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/inf-incomplete-1.stderr new file mode 100644 index 000000000..99fe59b32 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/inf-incomplete-1.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 20 + | +1 | inf-incomplete-1 = in + | ^ +invalid string +expected `"`, `'` diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/inf-incomplete-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/inf-incomplete-2.stderr new file mode 100644 index 000000000..38ef4cf4b --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/inf-incomplete-2.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 21 + | +1 | inf-incomplete-2 = +in + | ^ +invalid integer diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/inf-incomplete-3.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/inf-incomplete-3.stderr new file mode 100644 index 000000000..af66478ec --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/inf-incomplete-3.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 21 + | +1 | inf-incomplete-3 = -in + | ^ +invalid integer diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/inf_underscore.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/inf_underscore.stderr new file mode 100644 index 000000000..825484291 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/inf_underscore.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 18 + | +1 | inf_underscore = in_f + | ^ +invalid string +expected `"`, `'` diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/leading-point-neg.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/leading-point-neg.stderr new file mode 100644 index 000000000..c46efe103 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/leading-point-neg.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 22 + | +1 | leading-point-neg = -.12345 + | ^ +invalid integer diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/leading-point-plus.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/leading-point-plus.stderr new file mode 100644 index 000000000..a643a7eef --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/leading-point-plus.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 23 + | +1 | leading-point-plus = +.12345 + | ^ +invalid integer diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/leading-point.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/leading-point.stderr new file mode 100644 index 000000000..65e66b0cc --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/leading-point.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 17 + | +1 | leading-point = .12345 + | ^ +invalid floating-point number +expected leading digit diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/leading-us.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/leading-us.stderr new file mode 100644 index 000000000..e6d8e5235 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/leading-us.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 14 + | +1 | leading-us = _1.2 + | ^ +invalid integer +expected leading digit diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/leading-zero-neg.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/leading-zero-neg.stderr new file mode 100644 index 000000000..a60ec4da5 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/leading-zero-neg.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 22 + | +1 | leading-zero-neg = -03.14 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/leading-zero-plus.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/leading-zero-plus.stderr new file mode 100644 index 000000000..f7c612b16 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/leading-zero-plus.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 23 + | +1 | leading-zero-plus = +03.14 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/leading-zero.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/leading-zero.stderr new file mode 100644 index 000000000..627650f81 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/leading-zero.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 17 + | +1 | leading-zero = 03.14 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/nan-incomplete-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/nan-incomplete-1.stderr new file mode 100644 index 000000000..36faeb0be --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/nan-incomplete-1.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 20 + | +1 | nan-incomplete-1 = na + | ^ +invalid string +expected `"`, `'` diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/nan-incomplete-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/nan-incomplete-2.stderr new file mode 100644 index 000000000..38e01516c --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/nan-incomplete-2.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 21 + | +1 | nan-incomplete-2 = +na + | ^ +invalid integer diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/nan-incomplete-3.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/nan-incomplete-3.stderr new file mode 100644 index 000000000..e03ff4b92 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/nan-incomplete-3.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 21 + | +1 | nan-incomplete-3 = -na + | ^ +invalid integer diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/nan_underscore.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/nan_underscore.stderr new file mode 100644 index 000000000..f6dead338 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/nan_underscore.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 18 + | +1 | nan_underscore = na_n + | ^ +invalid string +expected `"`, `'` diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/trailing-point-min.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/trailing-point-min.stderr new file mode 100644 index 000000000..41f4ad9ce --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/trailing-point-min.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 25 + | +1 | trailing-point-min = -1. + | ^ +invalid floating-point number +expected digit diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/trailing-point-plus.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/trailing-point-plus.stderr new file mode 100644 index 000000000..9927935d0 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/trailing-point-plus.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 26 + | +1 | trailing-point-plus = +1. + | ^ +invalid floating-point number +expected digit diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/trailing-point.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/trailing-point.stderr new file mode 100644 index 000000000..bd345d251 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/trailing-point.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 20 + | +1 | trailing-point = 1. + | ^ +invalid floating-point number +expected digit diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/trailing-us-exp.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/trailing-us-exp.stderr new file mode 100644 index 000000000..811f951e3 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/trailing-us-exp.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 2, column 21 + | +2 | trailing-us-exp = 1_e2 + | ^ +invalid integer +expected digit diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/trailing-us.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/trailing-us.stderr new file mode 100644 index 000000000..aa4f28897 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/trailing-us.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 19 + | +1 | trailing-us = 1.2_ + | ^ +invalid floating-point number +expected digit, digit diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/us-after-point.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/us-after-point.stderr new file mode 100644 index 000000000..d93821dc5 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/us-after-point.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 20 + | +1 | us-after-point = 1._2 + | ^ +invalid floating-point number +expected digit diff --git a/vendor/toml_edit/tests/fixtures/invalid/float/us-before-point.stderr b/vendor/toml_edit/tests/fixtures/invalid/float/us-before-point.stderr new file mode 100644 index 000000000..109d8f71a --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/float/us-before-point.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 21 + | +1 | us-before-point = 1_.2 + | ^ +invalid integer +expected digit diff --git a/vendor/toml_edit/tests/fixtures/invalid/inline-table/add.stderr b/vendor/toml_edit/tests/fixtures/invalid/inline-table/add.stderr new file mode 100644 index 000000000..4108142dc --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/inline-table/add.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 3, column 1 + | +3 | [a.b] + | ^ +invalid table header +dotted key `a` attempted to extend non-table type (inline table) diff --git a/vendor/toml_edit/tests/fixtures/invalid/inline-table/double-comma.stderr b/vendor/toml_edit/tests/fixtures/invalid/inline-table/double-comma.stderr new file mode 100644 index 000000000..ab4772b5a --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/inline-table/double-comma.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 9 + | +1 | t = {x=3,,y=4} + | ^ +invalid inline table +expected `}` diff --git a/vendor/toml_edit/tests/fixtures/invalid/inline-table/duplicate-key.stderr b/vendor/toml_edit/tests/fixtures/invalid/inline-table/duplicate-key.stderr new file mode 100644 index 000000000..acee967ac --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/inline-table/duplicate-key.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 2, column 4 + | +2 | a={b=1, b=2} + | ^ +duplicate key `b` diff --git a/vendor/toml_edit/tests/fixtures/invalid/inline-table/empty.stderr b/vendor/toml_edit/tests/fixtures/invalid/inline-table/empty.stderr new file mode 100644 index 000000000..0fcfd34f6 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/inline-table/empty.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 6 + | +1 | t = {,} + | ^ +invalid inline table +expected `}` diff --git a/vendor/toml_edit/tests/fixtures/invalid/inline-table/linebreak-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/inline-table/linebreak-1.stderr new file mode 100644 index 000000000..ed67c3ac7 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/inline-table/linebreak-1.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 3, column 18 + | +3 | simple = { a = 1 + | ^ +invalid inline table +expected `}` diff --git a/vendor/toml_edit/tests/fixtures/invalid/inline-table/linebreak-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/inline-table/linebreak-2.stderr new file mode 100644 index 000000000..a81575846 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/inline-table/linebreak-2.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 9 + | +1 | t = {a=1, + | ^ +invalid inline table +expected `}` diff --git a/vendor/toml_edit/tests/fixtures/invalid/inline-table/linebreak-3.stderr b/vendor/toml_edit/tests/fixtures/invalid/inline-table/linebreak-3.stderr new file mode 100644 index 000000000..4aff61b76 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/inline-table/linebreak-3.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 9 + | +1 | t = {a=1 + | ^ +invalid inline table +expected `}` diff --git a/vendor/toml_edit/tests/fixtures/invalid/inline-table/linebreak-4.stderr b/vendor/toml_edit/tests/fixtures/invalid/inline-table/linebreak-4.stderr new file mode 100644 index 000000000..658456b86 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/inline-table/linebreak-4.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 14 + | +1 | json_like = { + | ^ +invalid inline table +expected `}` diff --git a/vendor/toml_edit/tests/fixtures/invalid/inline-table/no-comma.stderr b/vendor/toml_edit/tests/fixtures/invalid/inline-table/no-comma.stderr new file mode 100644 index 000000000..89552182f --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/inline-table/no-comma.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 12 + | +1 | t = {x = 3 y = 4} + | ^ +invalid inline table +expected `}` diff --git a/vendor/toml_edit/tests/fixtures/invalid/inline-table/overwrite.stderr b/vendor/toml_edit/tests/fixtures/invalid/inline-table/overwrite.stderr new file mode 100644 index 000000000..5c48ee223 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/inline-table/overwrite.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 3, column 1 + | +3 | a={} + | ^ +duplicate key `a` in document root diff --git a/vendor/toml_edit/tests/fixtures/invalid/inline-table/trailing-comma.stderr b/vendor/toml_edit/tests/fixtures/invalid/inline-table/trailing-comma.stderr new file mode 100644 index 000000000..b17fca503 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/inline-table/trailing-comma.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 3, column 18 + | +3 | abc = { abc = 123, } + | ^ +invalid inline table +expected `}` diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/capital-bin.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/capital-bin.stderr new file mode 100644 index 000000000..333ba92f8 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/capital-bin.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 16 + | +1 | capital-bin = 0B0 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/capital-hex.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/capital-hex.stderr new file mode 100644 index 000000000..ac064f9c4 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/capital-hex.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 16 + | +1 | capital-hex = 0X1 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/capital-oct.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/capital-oct.stderr new file mode 100644 index 000000000..774a8f2d6 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/capital-oct.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 16 + | +1 | capital-oct = 0O0 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/double-sign-nex.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/double-sign-nex.stderr new file mode 100644 index 000000000..542ba06bc --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/double-sign-nex.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 20 + | +1 | double-sign-nex = --99 + | ^ +invalid integer diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/double-sign-plus.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/double-sign-plus.stderr new file mode 100644 index 000000000..8f8bad0fd --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/double-sign-plus.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 21 + | +1 | double-sign-plus = ++99 + | ^ +invalid integer diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/double-us.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/double-us.stderr new file mode 100644 index 000000000..e229868b0 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/double-us.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 15 + | +1 | double-us = 1__23 + | ^ +invalid integer +expected digit diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/incomplete-bin.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/incomplete-bin.stderr new file mode 100644 index 000000000..13d7b46ff --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/incomplete-bin.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 20 + | +1 | incomplete-bin = 0b + | ^ +invalid binary integer diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/incomplete-hex.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/incomplete-hex.stderr new file mode 100644 index 000000000..ea5073a56 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/incomplete-hex.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 20 + | +1 | incomplete-hex = 0x + | ^ +invalid hexadecimal integer diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/incomplete-oct.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/incomplete-oct.stderr new file mode 100644 index 000000000..46d51c189 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/incomplete-oct.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 20 + | +1 | incomplete-oct = 0o + | ^ +invalid octal integer diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/integer.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/integer.stderr new file mode 100644 index 000000000..f058a2d9e --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/integer.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 19 + | +1 | leading-zero-1 = 01 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/invalid-bin.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/invalid-bin.stderr new file mode 100644 index 000000000..62c00fb28 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/invalid-bin.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 20 + | +1 | invalid-bin = 0b0012 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/invalid-hex.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/invalid-hex.stderr new file mode 100644 index 000000000..29b112b25 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/invalid-hex.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 20 + | +1 | invalid-hex = 0xaafz + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/invalid-oct.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/invalid-oct.stderr new file mode 100644 index 000000000..f3e1ada9b --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/invalid-oct.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 19 + | +1 | invalid-oct = 0o778 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/leading-us-bin.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/leading-us-bin.stderr new file mode 100644 index 000000000..c893e7547 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/leading-us-bin.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 18 + | +1 | leading-us-bin = _0o1 + | ^ +invalid integer +expected leading digit diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/leading-us-hex.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/leading-us-hex.stderr new file mode 100644 index 000000000..12eb8e6f5 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/leading-us-hex.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 18 + | +1 | leading-us-hex = _0o1 + | ^ +invalid integer +expected leading digit diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/leading-us-oct.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/leading-us-oct.stderr new file mode 100644 index 000000000..c670551a3 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/leading-us-oct.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 18 + | +1 | leading-us-oct = _0o1 + | ^ +invalid integer +expected leading digit diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/leading-us.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/leading-us.stderr new file mode 100644 index 000000000..f53275c0b --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/leading-us.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 14 + | +1 | leading-us = _123 + | ^ +invalid integer +expected leading digit diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/leading-zero-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/leading-zero-1.stderr new file mode 100644 index 000000000..f058a2d9e --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/leading-zero-1.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 19 + | +1 | leading-zero-1 = 01 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/leading-zero-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/leading-zero-2.stderr new file mode 100644 index 000000000..082381464 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/leading-zero-2.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 19 + | +1 | leading-zero-2 = 00 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/leading-zero-3.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/leading-zero-3.stderr new file mode 100644 index 000000000..7b0e481d0 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/leading-zero-3.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 19 + | +1 | leading-zero-3 = 0_0 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/leading-zero-sign-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/leading-zero-sign-1.stderr new file mode 100644 index 000000000..384c9d402 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/leading-zero-sign-1.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 25 + | +1 | leading-zero-sign-1 = -01 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/leading-zero-sign-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/leading-zero-sign-2.stderr new file mode 100644 index 000000000..795c3297f --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/leading-zero-sign-2.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 25 + | +1 | leading-zero-sign-2 = +01 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/leading-zero-sign-3.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/leading-zero-sign-3.stderr new file mode 100644 index 000000000..639aef5f1 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/leading-zero-sign-3.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 25 + | +1 | leading-zero-sign-3 = +0_1 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/negative-bin.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/negative-bin.stderr new file mode 100644 index 000000000..7122d38f8 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/negative-bin.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 18 + | +1 | negative-bin = -0b11010110 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/negative-hex.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/negative-hex.stderr new file mode 100644 index 000000000..0c7e58421 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/negative-hex.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 18 + | +1 | negative-hex = -0xff + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/negative-oct.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/negative-oct.stderr new file mode 100644 index 000000000..fcf31407d --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/negative-oct.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 18 + | +1 | negative-oct = -0o99 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/positive-bin.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/positive-bin.stderr new file mode 100644 index 000000000..bc5dc4ed3 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/positive-bin.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 18 + | +1 | positive-bin = +0b11010110 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/positive-hex.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/positive-hex.stderr new file mode 100644 index 000000000..f57111431 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/positive-hex.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 18 + | +1 | positive-hex = +0xff + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/positive-oct.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/positive-oct.stderr new file mode 100644 index 000000000..cc0946689 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/positive-oct.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 18 + | +1 | positive-oct = +0o99 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/text-after-integer.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/text-after-integer.stderr new file mode 100644 index 000000000..0405cb410 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/text-after-integer.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 13 + | +1 | answer = 42 the ultimate answer? + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/trailing-us-bin.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/trailing-us-bin.stderr new file mode 100644 index 000000000..7042a6e39 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/trailing-us-bin.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 23 + | +1 | trailing-us-bin = 0b1_ + | ^ +invalid binary integer +expected digit diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/trailing-us-hex.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/trailing-us-hex.stderr new file mode 100644 index 000000000..9526a9489 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/trailing-us-hex.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 23 + | +1 | trailing-us-hex = 0x1_ + | ^ +invalid hexadecimal integer +expected digit diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/trailing-us-oct.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/trailing-us-oct.stderr new file mode 100644 index 000000000..bb4330d0e --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/trailing-us-oct.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 23 + | +1 | trailing-us-oct = 0o1_ + | ^ +invalid octal integer +expected digit diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/trailing-us.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/trailing-us.stderr new file mode 100644 index 000000000..f8c901ef4 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/trailing-us.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 19 + | +1 | trailing-us = 123_ + | ^ +invalid integer +expected digit diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/us-after-bin.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/us-after-bin.stderr new file mode 100644 index 000000000..1620bc6bc --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/us-after-bin.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 18 + | +1 | us-after-bin = 0b_1 + | ^ +invalid binary integer diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/us-after-hex.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/us-after-hex.stderr new file mode 100644 index 000000000..e8283a070 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/us-after-hex.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 18 + | +1 | us-after-hex = 0x_1 + | ^ +invalid hexadecimal integer diff --git a/vendor/toml_edit/tests/fixtures/invalid/integer/us-after-oct.stderr b/vendor/toml_edit/tests/fixtures/invalid/integer/us-after-oct.stderr new file mode 100644 index 000000000..e6884d0c6 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/integer/us-after-oct.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 18 + | +1 | us-after-oct = 0o_1 + | ^ +invalid octal integer diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/after-array.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/after-array.stderr new file mode 100644 index 000000000..861f82d13 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/after-array.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 14 + | +1 | [[agencies]] owner = "S Cjelli" + | ^ +invalid table header +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/after-table.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/after-table.stderr new file mode 100644 index 000000000..499a43012 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/after-table.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 9 + | +1 | [error] this = "should not be here" + | ^ +invalid table header +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/after-value.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/after-value.stderr new file mode 100644 index 000000000..9852ec8d0 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/after-value.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 15 + | +1 | first = "Tom" last = "Preston-Werner" # INVALID + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/bare-invalid-character.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/bare-invalid-character.stderr new file mode 100644 index 000000000..0ba21fd81 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/bare-invalid-character.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 5 + | +1 | bare!key = 123 + | ^ +expected `.`, `=` diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/dotted-redefine-table.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/dotted-redefine-table.stderr new file mode 100644 index 000000000..3a2b8d5d9 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/dotted-redefine-table.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 4, column 1 + | +4 | a.b.c = 2 + | ^ +dotted key `a.b` attempted to extend non-table type (integer) diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/duplicate-keys.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/duplicate-keys.stderr new file mode 100644 index 000000000..74149f851 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/duplicate-keys.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 2, column 1 + | +2 | dupe = true + | ^ +duplicate key `dupe` in document root diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/duplicate.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/duplicate.stderr new file mode 100644 index 000000000..8c7d7b7ea --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/duplicate.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 3, column 1 + | +3 | name = "Pradyun" + | ^ +duplicate key `name` in document root diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/empty.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/empty.stderr new file mode 100644 index 000000000..b859159f8 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/empty.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 2 + | +1 | = 1 + | ^ +invalid key diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/escape.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/escape.stderr new file mode 100644 index 000000000..2a4ee3f72 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/escape.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 1 + | +1 | \u00c0 = "latin capital letter A with grave" + | ^ +invalid key diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/hash.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/hash.stderr new file mode 100644 index 000000000..15d8048ba --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/hash.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 2 + | +1 | a# = 1 + | ^ +expected `.`, `=` diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/multiline.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/multiline.stderr new file mode 100644 index 000000000..b4241ee9f --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/multiline.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 3 + | +1 | """long + | ^ +expected `.`, `=` diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/newline.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/newline.stderr new file mode 100644 index 000000000..141932e42 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/newline.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 8 + | +1 | barekey + | ^ +expected `.`, `=` diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/no-eol.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/no-eol.stderr new file mode 100644 index 000000000..fc3c01ebf --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/no-eol.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 7 + | +1 | a = 1 b = 2 + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/open-bracket.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/open-bracket.stderr new file mode 100644 index 000000000..eee8cba03 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/open-bracket.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 6 + | +1 | [abc = 1 + | ^ +invalid table header +expected `.`, `]` diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/partial-quoted.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/partial-quoted.stderr new file mode 100644 index 000000000..e0a7c32ba --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/partial-quoted.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 8 + | +1 | partial"quoted" = 5 + | ^ +expected `.`, `=` diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/quoted-unclosed-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/quoted-unclosed-1.stderr new file mode 100644 index 000000000..6f15232e8 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/quoted-unclosed-1.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 9 + | +1 | "key = x + | ^ +invalid basic string diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/quoted-unclosed-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/quoted-unclosed-2.stderr new file mode 100644 index 000000000..f3fdc7f02 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/quoted-unclosed-2.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 5 + | +1 | "key + | ^ +invalid basic string diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/single-open-bracket.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/single-open-bracket.stderr new file mode 100644 index 000000000..022f1fabc --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/single-open-bracket.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 2 + | +1 | [ + | ^ +invalid key diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/space.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/space.stderr new file mode 100644 index 000000000..cd3258b55 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/space.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 3 + | +1 | a b = 1 + | ^ +expected `.`, `=` diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/special-character.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/special-character.stderr new file mode 100644 index 000000000..7ada2f21b --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/special-character.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 1 + | +1 | μ = "greek small letter mu" + | ^ +invalid key diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/start-bracket.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/start-bracket.stderr new file mode 100644 index 000000000..43f937b25 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/start-bracket.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 2, column 6 + | +2 | [xyz = 5 + | ^ +invalid table header +expected `.`, `]` diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/start-dot.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/start-dot.stderr new file mode 100644 index 000000000..c71f0cf53 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/start-dot.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 1 + | +1 | .key = 1 + | ^ +invalid key diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/two-equals.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/two-equals.stderr new file mode 100644 index 000000000..2f92886e1 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/two-equals.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 6 + | +1 | key= = 1 + | ^ +invalid string +expected `"`, `'` diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/two-equals2.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/two-equals2.stderr new file mode 100644 index 000000000..f2adb1f33 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/two-equals2.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 3 + | +1 | a==1 + | ^ +invalid string +expected `"`, `'` diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/two-equals3.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/two-equals3.stderr new file mode 100644 index 000000000..dbee16973 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/two-equals3.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 3 + | +1 | a=b=1 + | ^ +invalid string +expected `"`, `'` diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/without-value-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/without-value-1.stderr new file mode 100644 index 000000000..2ddb1240a --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/without-value-1.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 4 + | +1 | key + | ^ +expected `.`, `=` diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/without-value-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/without-value-2.stderr new file mode 100644 index 000000000..a3f280f72 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/without-value-2.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 7 + | +1 | key = + | ^ +invalid string +expected `"`, `'` diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/without-value-3.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/without-value-3.stderr new file mode 100644 index 000000000..a6ca6ffd6 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/without-value-3.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 6 + | +1 | "key" + | ^ +expected `.`, `=` diff --git a/vendor/toml_edit/tests/fixtures/invalid/key/without-value-4.stderr b/vendor/toml_edit/tests/fixtures/invalid/key/without-value-4.stderr new file mode 100644 index 000000000..c14af0c30 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/key/without-value-4.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 9 + | +1 | "key" = + | ^ +invalid string +expected `"`, `'` diff --git a/vendor/toml_edit/tests/fixtures/invalid/spec/inline-table-2-0.stderr b/vendor/toml_edit/tests/fixtures/invalid/spec/inline-table-2-0.stderr new file mode 100644 index 000000000..7fed2698e --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/spec/inline-table-2-0.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 3, column 1 + | +3 | type.edible = false # INVALID + | ^ +dotted key `type` attempted to extend non-table type (inline table) diff --git a/vendor/toml_edit/tests/fixtures/invalid/spec/inline-table-3-0.stderr b/vendor/toml_edit/tests/fixtures/invalid/spec/inline-table-3-0.stderr new file mode 100644 index 000000000..45ba696b9 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/spec/inline-table-3-0.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 3, column 1 + | +3 | type = { edible = false } # INVALID + | ^ +duplicate key `type` in table `product` diff --git a/vendor/toml_edit/tests/fixtures/invalid/spec/key-value-pair-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/spec/key-value-pair-1.stderr new file mode 100644 index 000000000..ba765a823 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/spec/key-value-pair-1.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 7 + | +1 | key = # INVALID + | ^ +invalid string +expected `"`, `'` diff --git a/vendor/toml_edit/tests/fixtures/invalid/spec/keys-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/spec/keys-2.stderr new file mode 100644 index 000000000..bdbcce45b --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/spec/keys-2.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 1 + | +1 | = "no key name" # INVALID + | ^ +invalid key diff --git a/vendor/toml_edit/tests/fixtures/invalid/spec/string-4-0.stderr b/vendor/toml_edit/tests/fixtures/invalid/spec/string-4-0.stderr new file mode 100644 index 000000000..e82601dd7 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/spec/string-4-0.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 2, column 46 + | +2 | str5 = """Here are three quotation marks: """.""" # INVALID + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/spec/string-7-0.stderr b/vendor/toml_edit/tests/fixtures/invalid/spec/string-7-0.stderr new file mode 100644 index 000000000..7a928e190 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/spec/string-7-0.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 3, column 48 + | +3 | apos15 = '''Here are fifteen apostrophes: '''''''''''''''''' # INVALID + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/spec/table-9-0.stderr b/vendor/toml_edit/tests/fixtures/invalid/spec/table-9-0.stderr new file mode 100644 index 000000000..a2e1d4991 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/spec/table-9-0.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 5, column 1 + | +5 | [fruit.apple] # INVALID + | ^ +invalid table header +duplicate key `apple` in table `fruit` diff --git a/vendor/toml_edit/tests/fixtures/invalid/spec/table-9-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/spec/table-9-1.stderr new file mode 100644 index 000000000..78dea2144 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/spec/table-9-1.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 6, column 1 + | +6 | [fruit.apple.taste] # INVALID + | ^ +invalid table header +duplicate key `taste` in table `fruit.apple` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/bad-byte-escape.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/bad-byte-escape.stderr new file mode 100644 index 000000000..6d88863e2 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/bad-byte-escape.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 14 + | +1 | naughty = "\xAg" + | ^ +invalid escape sequence +expected `b`, `f`, `n`, `r`, `t`, `u`, `U`, `\`, `"` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/bad-codepoint.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/bad-codepoint.stderr new file mode 100644 index 000000000..4061c79cc --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/bad-codepoint.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 76 + | +1 | invalid-codepoint = "This string contains a non scalar unicode codepoint \uD801" + | ^ +invalid unicode 4-digit hex code +value is out of range diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/bad-concat.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/bad-concat.stderr new file mode 100644 index 000000000..a7346a40e --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/bad-concat.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 21 + | +1 | no_concat = "first" "second" + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/bad-escape-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/bad-escape-1.stderr new file mode 100644 index 000000000..02cb48310 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/bad-escape-1.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 43 + | +1 | invalid-escape = "This string has a bad \a escape character." + | ^ +invalid escape sequence +expected `b`, `f`, `n`, `r`, `t`, `u`, `U`, `\`, `"` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/bad-escape-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/bad-escape-2.stderr new file mode 100644 index 000000000..57f0acef5 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/bad-escape-2.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 43 + | +1 | invalid-escape = "This string has a bad \ escape character." + | ^ +invalid escape sequence +expected `b`, `f`, `n`, `r`, `t`, `u`, `U`, `\`, `"` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/bad-hex-esc-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/bad-hex-esc-1.stderr new file mode 100644 index 000000000..5d5577fa5 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/bad-hex-esc-1.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 20 + | +1 | bad-hex-esc-1 = "\x0g" + | ^ +invalid escape sequence +expected `b`, `f`, `n`, `r`, `t`, `u`, `U`, `\`, `"` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/bad-hex-esc-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/bad-hex-esc-2.stderr new file mode 100644 index 000000000..5a40ad444 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/bad-hex-esc-2.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 20 + | +1 | bad-hex-esc-2 = "\xG0" + | ^ +invalid escape sequence +expected `b`, `f`, `n`, `r`, `t`, `u`, `U`, `\`, `"` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/bad-hex-esc-3.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/bad-hex-esc-3.stderr new file mode 100644 index 000000000..70e1183fd --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/bad-hex-esc-3.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 20 + | +1 | bad-hex-esc-3 = "\x" + | ^ +invalid escape sequence +expected `b`, `f`, `n`, `r`, `t`, `u`, `U`, `\`, `"` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/bad-hex-esc-4.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/bad-hex-esc-4.stderr new file mode 100644 index 000000000..df028ee8b --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/bad-hex-esc-4.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 20 + | +1 | bad-hex-esc-4 = "\x 50" + | ^ +invalid escape sequence +expected `b`, `f`, `n`, `r`, `t`, `u`, `U`, `\`, `"` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/bad-hex-esc-5.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/bad-hex-esc-5.stderr new file mode 100644 index 000000000..4b5cd33d3 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/bad-hex-esc-5.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 20 + | +1 | bad-hex-esc-5 = "\x 50" + | ^ +invalid escape sequence +expected `b`, `f`, `n`, `r`, `t`, `u`, `U`, `\`, `"` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/bad-hex-esc.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/bad-hex-esc.stderr new file mode 100644 index 000000000..5d5577fa5 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/bad-hex-esc.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 20 + | +1 | bad-hex-esc-1 = "\x0g" + | ^ +invalid escape sequence +expected `b`, `f`, `n`, `r`, `t`, `u`, `U`, `\`, `"` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/bad-multiline.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/bad-multiline.stderr new file mode 100644 index 000000000..f88e0dd04 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/bad-multiline.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 20 + | +1 | multi = "first line + | ^ +invalid basic string diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/bad-slash-escape.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/bad-slash-escape.stderr new file mode 100644 index 000000000..19bd111b2 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/bad-slash-escape.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 43 + | +1 | invalid-escape = "This string has a bad \/ escape character." + | ^ +invalid escape sequence +expected `b`, `f`, `n`, `r`, `t`, `u`, `U`, `\`, `"` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/bad-uni-esc-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/bad-uni-esc-1.stderr new file mode 100644 index 000000000..a9e439bff --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/bad-uni-esc-1.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 13 + | +1 | str = "val\ue" + | ^ +invalid unicode 4-digit hex code diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/bad-uni-esc-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/bad-uni-esc-2.stderr new file mode 100644 index 000000000..87c8681b9 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/bad-uni-esc-2.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 13 + | +1 | str = "val\Ux" + | ^ +invalid unicode 8-digit hex code diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/bad-uni-esc-3.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/bad-uni-esc-3.stderr new file mode 100644 index 000000000..61f8dede0 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/bad-uni-esc-3.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 13 + | +1 | str = "val\U0000000" + | ^ +invalid unicode 8-digit hex code diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/bad-uni-esc-4.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/bad-uni-esc-4.stderr new file mode 100644 index 000000000..1a781d999 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/bad-uni-esc-4.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 13 + | +1 | str = "val\U0000" + | ^ +invalid unicode 8-digit hex code diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/bad-uni-esc-5.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/bad-uni-esc-5.stderr new file mode 100644 index 000000000..88773ca85 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/bad-uni-esc-5.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 13 + | +1 | str = "val\Ugggggggg" + | ^ +invalid unicode 8-digit hex code diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/basic-byte-escapes.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/basic-byte-escapes.stderr new file mode 100644 index 000000000..64f8d8654 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/basic-byte-escapes.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 13 + | +1 | answer = "\x33" + | ^ +invalid escape sequence +expected `b`, `f`, `n`, `r`, `t`, `u`, `U`, `\`, `"` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/basic-multiline-out-of-range-unicode-escape-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/basic-multiline-out-of-range-unicode-escape-1.stderr new file mode 100644 index 000000000..c4be6a6c8 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/basic-multiline-out-of-range-unicode-escape-1.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 10 + | +1 | a = """\UFFFFFFFF""" + | ^ +invalid unicode 8-digit hex code +value is out of range diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/basic-multiline-out-of-range-unicode-escape-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/basic-multiline-out-of-range-unicode-escape-2.stderr new file mode 100644 index 000000000..f034203f8 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/basic-multiline-out-of-range-unicode-escape-2.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 10 + | +1 | a = """\U00D80000""" + | ^ +invalid unicode 8-digit hex code +value is out of range diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/basic-multiline-quotes.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/basic-multiline-quotes.stderr new file mode 100644 index 000000000..7a1600898 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/basic-multiline-quotes.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 46 + | +1 | str5 = """Here are three quotation marks: """.""" + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/basic-multiline-unknown-escape.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/basic-multiline-unknown-escape.stderr new file mode 100644 index 000000000..d2462bf13 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/basic-multiline-unknown-escape.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 10 + | +1 | a = """\@""" + | ^ +invalid escape sequence +expected `b`, `f`, `n`, `r`, `t`, `u`, `U`, `\`, `"` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/basic-out-of-range-unicode-escape-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/basic-out-of-range-unicode-escape-1.stderr new file mode 100644 index 000000000..806e6e786 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/basic-out-of-range-unicode-escape-1.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 8 + | +1 | a = "\UFFFFFFFF" + | ^ +invalid unicode 8-digit hex code +value is out of range diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/basic-out-of-range-unicode-escape-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/basic-out-of-range-unicode-escape-2.stderr new file mode 100644 index 000000000..69396c669 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/basic-out-of-range-unicode-escape-2.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 8 + | +1 | a = "\U00D80000" + | ^ +invalid unicode 8-digit hex code +value is out of range diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/basic-unknown-escape.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/basic-unknown-escape.stderr new file mode 100644 index 000000000..a7fbb254e --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/basic-unknown-escape.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 8 + | +1 | a = "\@" + | ^ +invalid escape sequence +expected `b`, `f`, `n`, `r`, `t`, `u`, `U`, `\`, `"` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/literal-multiline-quotes-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/literal-multiline-quotes-1.stderr new file mode 100644 index 000000000..ed65b3342 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/literal-multiline-quotes-1.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 28 + | +1 | a = '''6 apostrophes: '''''' + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/literal-multiline-quotes-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/literal-multiline-quotes-2.stderr new file mode 100644 index 000000000..3fbb44acd --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/literal-multiline-quotes-2.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 29 + | +1 | a = '''15 apostrophes: '''''''''''''''''' + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/missing-quotes.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/missing-quotes.stderr new file mode 100644 index 000000000..3558aab56 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/missing-quotes.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 8 + | +1 | name = value + | ^ +invalid string +expected `"`, `'` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/multiline-bad-escape-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/multiline-bad-escape-1.stderr new file mode 100644 index 000000000..1a3b24baf --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/multiline-bad-escape-1.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 11 + | +1 | k = """t\a""" + | ^ +invalid escape sequence +expected `b`, `f`, `n`, `r`, `t`, `u`, `U`, `\`, `"` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/multiline-bad-escape-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/multiline-bad-escape-2.stderr new file mode 100644 index 000000000..db17685ce --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/multiline-bad-escape-2.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 2, column 11 + | +2 | k = """t\ t""" + | ^ +invalid escape sequence +expected `b`, `f`, `n`, `r`, `t`, `u`, `U`, `\`, `"` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/multiline-bad-escape-3.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/multiline-bad-escape-3.stderr new file mode 100644 index 000000000..646aa4d30 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/multiline-bad-escape-3.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 2, column 11 + | +2 | k = """t\ """ + | ^ +invalid escape sequence +expected `b`, `f`, `n`, `r`, `t`, `u`, `U`, `\`, `"` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/multiline-escape-space.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/multiline-escape-space.stderr new file mode 100644 index 000000000..4b3c32b98 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/multiline-escape-space.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 2, column 9 + | +2 | foo \ \n + | ^ +invalid escape sequence +expected `b`, `f`, `n`, `r`, `t`, `u`, `U`, `\`, `"` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/multiline-no-close-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/multiline-no-close-2.stderr new file mode 100644 index 000000000..be5420add --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/multiline-no-close-2.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 7 + | +1 | x=""" + | ^ +invalid multiline basic string diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/multiline-no-close.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/multiline-no-close.stderr new file mode 100644 index 000000000..99e967a46 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/multiline-no-close.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 2, column 20 + | +2 | this will fail + | ^ +invalid multiline basic string diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/multiline-quotes-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/multiline-quotes-1.stderr new file mode 100644 index 000000000..c3cf4c6e5 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/multiline-quotes-1.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 23 + | +1 | a = """6 quotes: """""" + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/no-close.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/no-close.stderr new file mode 100644 index 000000000..f23223d3f --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/no-close.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 42 + | +1 | no-ending-quote = "One time, at band camp + | ^ +invalid basic string diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/text-after-string.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/text-after-string.stderr new file mode 100644 index 000000000..f05e33b53 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/text-after-string.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 41 + | +1 | string = "Is there life after strings?" No. + | ^ +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/string/wrong-close.stderr b/vendor/toml_edit/tests/fixtures/invalid/string/wrong-close.stderr new file mode 100644 index 000000000..9a785e050 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/string/wrong-close.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 39 + | +1 | bad-ending-quote = "double and single' + | ^ +invalid basic string diff --git a/vendor/toml_edit/tests/fixtures/invalid/table/append-with-dotted-keys-1.stderr b/vendor/toml_edit/tests/fixtures/invalid/table/append-with-dotted-keys-1.stderr new file mode 100644 index 000000000..54ee50e1d --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/table/append-with-dotted-keys-1.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 17, column 3 + | +17 | b.c.t = "Using dotted keys to add to [a.b.c] after explicitly defining it above is not allowed" + | ^ +duplicate key `c` diff --git a/vendor/toml_edit/tests/fixtures/invalid/table/append-with-dotted-keys-2.stderr b/vendor/toml_edit/tests/fixtures/invalid/table/append-with-dotted-keys-2.stderr new file mode 100644 index 000000000..7c665f97b --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/table/append-with-dotted-keys-2.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 8, column 3 + | +8 | b.c.d.k.t = "Using dotted keys to add to [a.b.c.d] after explicitly defining it above is not allowed" + | ^ +duplicate key `d` diff --git a/vendor/toml_edit/tests/fixtures/invalid/table/array-empty.stderr b/vendor/toml_edit/tests/fixtures/invalid/table/array-empty.stderr new file mode 100644 index 000000000..ad2440ac8 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/table/array-empty.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 3 + | +1 | [[]] + | ^ +invalid key diff --git a/vendor/toml_edit/tests/fixtures/invalid/table/array-implicit.stderr b/vendor/toml_edit/tests/fixtures/invalid/table/array-implicit.stderr new file mode 100644 index 000000000..ed1ab7fea --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/table/array-implicit.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 13, column 1 + | +13 | [[albums]] + | ^ +invalid table header +duplicate key `albums` in document root diff --git a/vendor/toml_edit/tests/fixtures/invalid/table/array-missing-bracket.stderr b/vendor/toml_edit/tests/fixtures/invalid/table/array-missing-bracket.stderr new file mode 100644 index 000000000..ed370ef85 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/table/array-missing-bracket.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 9 + | +1 | [[albums] + | ^ +invalid table header +expected `.`, `]]` diff --git a/vendor/toml_edit/tests/fixtures/invalid/table/duplicate-key-dotted-table.stderr b/vendor/toml_edit/tests/fixtures/invalid/table/duplicate-key-dotted-table.stderr new file mode 100644 index 000000000..3cbc0a320 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/table/duplicate-key-dotted-table.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 4, column 1 + | +4 | [fruit.apple] # INVALID + | ^ +invalid table header +duplicate key `apple` in table `fruit` diff --git a/vendor/toml_edit/tests/fixtures/invalid/table/duplicate-key-dotted-table2.stderr b/vendor/toml_edit/tests/fixtures/invalid/table/duplicate-key-dotted-table2.stderr new file mode 100644 index 000000000..c5ab1eb51 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/table/duplicate-key-dotted-table2.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 4, column 1 + | +4 | [fruit.apple.taste] # INVALID + | ^ +invalid table header +duplicate key `taste` in table `fruit.apple` diff --git a/vendor/toml_edit/tests/fixtures/invalid/table/duplicate-key-table.stderr b/vendor/toml_edit/tests/fixtures/invalid/table/duplicate-key-table.stderr new file mode 100644 index 000000000..bc76d9ce0 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/table/duplicate-key-table.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 4, column 1 + | +4 | [fruit.type] + | ^ +invalid table header +duplicate key `type` in table `fruit` diff --git a/vendor/toml_edit/tests/fixtures/invalid/table/duplicate-table-array.stderr b/vendor/toml_edit/tests/fixtures/invalid/table/duplicate-table-array.stderr new file mode 100644 index 000000000..536fdc3ba --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/table/duplicate-table-array.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 2, column 1 + | +2 | [[tbl]] + | ^ +invalid table header +duplicate key `tbl` in document root diff --git a/vendor/toml_edit/tests/fixtures/invalid/table/duplicate-table-array2.stderr b/vendor/toml_edit/tests/fixtures/invalid/table/duplicate-table-array2.stderr new file mode 100644 index 000000000..81c27fba1 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/table/duplicate-table-array2.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 2, column 1 + | +2 | [tbl] + | ^ +invalid table header +duplicate key `tbl` in document root diff --git a/vendor/toml_edit/tests/fixtures/invalid/table/duplicate.stderr b/vendor/toml_edit/tests/fixtures/invalid/table/duplicate.stderr new file mode 100644 index 000000000..81bf4ed03 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/table/duplicate.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 4, column 1 + | +4 | [a] + | ^ +invalid table header +duplicate key `a` in document root diff --git a/vendor/toml_edit/tests/fixtures/invalid/table/empty-implicit-table.stderr b/vendor/toml_edit/tests/fixtures/invalid/table/empty-implicit-table.stderr new file mode 100644 index 000000000..a7f7444e5 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/table/empty-implicit-table.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 9 + | +1 | [naughty..naughty] + | ^ +invalid table header +expected `.`, `]` diff --git a/vendor/toml_edit/tests/fixtures/invalid/table/empty.stderr b/vendor/toml_edit/tests/fixtures/invalid/table/empty.stderr new file mode 100644 index 000000000..5dd0d56b5 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/table/empty.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 2 + | +1 | [] + | ^ +invalid key diff --git a/vendor/toml_edit/tests/fixtures/invalid/table/equals-sign.stderr b/vendor/toml_edit/tests/fixtures/invalid/table/equals-sign.stderr new file mode 100644 index 000000000..52451c949 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/table/equals-sign.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 6 + | +1 | [name=bad] + | ^ +invalid table header +expected `.`, `]` diff --git a/vendor/toml_edit/tests/fixtures/invalid/table/llbrace.stderr b/vendor/toml_edit/tests/fixtures/invalid/table/llbrace.stderr new file mode 100644 index 000000000..316590da6 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/table/llbrace.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 3 + | +1 | [ [table]] + | ^ +invalid key diff --git a/vendor/toml_edit/tests/fixtures/invalid/table/nested-brackets-close.stderr b/vendor/toml_edit/tests/fixtures/invalid/table/nested-brackets-close.stderr new file mode 100644 index 000000000..e74e178f4 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/table/nested-brackets-close.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 4 + | +1 | [a]b] + | ^ +invalid table header +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/table/nested-brackets-open.stderr b/vendor/toml_edit/tests/fixtures/invalid/table/nested-brackets-open.stderr new file mode 100644 index 000000000..094cf7cde --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/table/nested-brackets-open.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 3 + | +1 | [a[b] + | ^ +invalid table header +expected `.`, `]` diff --git a/vendor/toml_edit/tests/fixtures/invalid/table/quoted-no-close.stderr b/vendor/toml_edit/tests/fixtures/invalid/table/quoted-no-close.stderr new file mode 100644 index 000000000..2b05e95ae --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/table/quoted-no-close.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 21 + | +1 | ["where will it end] + | ^ +invalid basic string diff --git a/vendor/toml_edit/tests/fixtures/invalid/table/redefine.stderr b/vendor/toml_edit/tests/fixtures/invalid/table/redefine.stderr new file mode 100644 index 000000000..99c1f98a1 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/table/redefine.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 5, column 1 + | +5 | [a.b] + | ^ +invalid table header +duplicate key `b` in table `a` diff --git a/vendor/toml_edit/tests/fixtures/invalid/table/rrbrace.stderr b/vendor/toml_edit/tests/fixtures/invalid/table/rrbrace.stderr new file mode 100644 index 000000000..adcdf9043 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/table/rrbrace.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 8 + | +1 | [[table] ] + | ^ +invalid table header +expected `.`, `]]` diff --git a/vendor/toml_edit/tests/fixtures/invalid/table/text-after-table.stderr b/vendor/toml_edit/tests/fixtures/invalid/table/text-after-table.stderr new file mode 100644 index 000000000..e7d7c4eb5 --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/table/text-after-table.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 9 + | +1 | [error] this shouldn't be here + | ^ +invalid table header +expected newline, `#` diff --git a/vendor/toml_edit/tests/fixtures/invalid/table/whitespace.stderr b/vendor/toml_edit/tests/fixtures/invalid/table/whitespace.stderr new file mode 100644 index 000000000..aa149d2cb --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/table/whitespace.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 10 + | +1 | [invalid key] + | ^ +invalid table header +expected `.`, `]` diff --git a/vendor/toml_edit/tests/fixtures/invalid/table/with-pound.stderr b/vendor/toml_edit/tests/fixtures/invalid/table/with-pound.stderr new file mode 100644 index 000000000..f5531cc5d --- /dev/null +++ b/vendor/toml_edit/tests/fixtures/invalid/table/with-pound.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 5 + | +1 | [key#group] + | ^ +invalid table header +expected `.`, `]` diff --git a/vendor/toml_edit/tests/invalid.rs b/vendor/toml_edit/tests/invalid.rs new file mode 100644 index 000000000..9fff23582 --- /dev/null +++ b/vendor/toml_edit/tests/invalid.rs @@ -0,0 +1,26 @@ +use toml_edit::Document; + +fn main() { + let args = libtest_mimic::Arguments::from_args(); + let tests = toml_test_data::invalid() + .map(|case| { + libtest_mimic::Trial::test(case.name.display().to_string(), || { + let expect_path = + std::path::Path::new("tests/fixtures").join(case.name.with_extension("stderr")); + let err = match run_case(case.fixture) { + Ok(()) => "".to_owned(), + Err(err) => err, + }; + snapbox::assert_eq_path(expect_path, err); + Ok(()) + }) + }) + .collect(); + libtest_mimic::run(&args, tests).exit() +} + +fn run_case(input: &[u8]) -> Result<(), String> { + let raw = std::str::from_utf8(input).map_err(|e| e.to_string())?; + let _ = raw.parse::<Document>().map_err(|e| e.to_string())?; + Ok(()) +} diff --git a/vendor/toml_edit/tests/testsuite/convert.rs b/vendor/toml_edit/tests/testsuite/convert.rs new file mode 100644 index 000000000..98f93979e --- /dev/null +++ b/vendor/toml_edit/tests/testsuite/convert.rs @@ -0,0 +1,79 @@ +use snapbox::assert_eq; + +use toml_edit::{Document, Item, Value}; + +#[test] +fn table_into_inline() { + let toml = r#" +[table] +string = "value" +array = [1, 2, 3] +inline = { "1" = 1, "2" = 2 } + +[table.child] +other = "world" +"#; + let mut doc = toml.parse::<Document>().unwrap(); + + doc.get_mut("table").unwrap().make_value(); + + let actual = doc.to_string(); + // `table=` is because we didn't re-format the table key, only the value + let expected = r#"table= { string = "value", array = [1, 2, 3], inline = { "1" = 1, "2" = 2 }, child = { other = "world" } } +"#; + assert_eq(expected, actual); +} + +#[test] +fn inline_table_to_table() { + let toml = r#"table = { string = "value", array = [1, 2, 3], inline = { "1" = 1, "2" = 2 }, child = { other = "world" } } +"#; + let mut doc = toml.parse::<Document>().unwrap(); + + let t = doc.remove("table").unwrap(); + let t = match t { + Item::Value(Value::InlineTable(t)) => t, + _ => unreachable!("Unexpected {:?}", t), + }; + let t = t.into_table(); + doc.insert("table", Item::Table(t)); + + let actual = doc.to_string(); + let expected = r#"[table] +string = "value" +array = [1, 2, 3] +inline = { "1" = 1, "2" = 2 } +child = { other = "world" } +"#; + assert_eq(expected, actual); +} + +#[test] +fn array_of_tables_to_array() { + let toml = r#" +[[table]] +string = "value" +array = [1, 2, 3] +inline = { "1" = 1, "2" = 2 } + +[table.child] +other = "world" + +[[table]] +string = "value" +array = [1, 2, 3] +inline = { "1" = 1, "2" = 2 } + +[table.child] +other = "world" +"#; + let mut doc = toml.parse::<Document>().unwrap(); + + doc.get_mut("table").unwrap().make_value(); + + let actual = doc.to_string(); + // `table=` is because we didn't re-format the table key, only the value + let expected = r#"table= [{ string = "value", array = [1, 2, 3], inline = { "1" = 1, "2" = 2 }, child = { other = "world" } }, { string = "value", array = [1, 2, 3], inline = { "1" = 1, "2" = 2 }, child = { other = "world" } }] +"#; + assert_eq(expected, actual); +} diff --git a/vendor/toml_edit/tests/testsuite/datetime.rs b/vendor/toml_edit/tests/testsuite/datetime.rs new file mode 100644 index 000000000..541f8ea1d --- /dev/null +++ b/vendor/toml_edit/tests/testsuite/datetime.rs @@ -0,0 +1,256 @@ +macro_rules! bad { + ($toml:expr, $msg:expr) => { + match $toml.parse::<toml_edit::Document>() { + Ok(s) => panic!("parsed to: {:#?}", s), + Err(e) => snapbox::assert_eq($msg, e.to_string()), + } + }; +} + +#[test] +fn times() { + fn dogood(s: &str, serialized: &str) { + let to_parse = format!("foo = {}", s); + let document = to_parse.parse::<toml_edit::Document>().unwrap(); + assert_eq!( + document["foo"].as_datetime().unwrap().to_string(), + serialized + ); + } + fn good(s: &str) { + dogood(s, s); + dogood(&s.replace('T', " "), s); + dogood(&s.replace('T', "t"), s); + dogood(&s.replace('Z', "z"), s); + } + + good("1997-09-09T09:09:09Z"); + good("1997-09-09T09:09:09+09:09"); + good("1997-09-09T09:09:09-09:09"); + good("1997-09-09T09:09:09"); + good("1997-09-09"); + dogood("1997-09-09 ", "1997-09-09"); + dogood("1997-09-09 # comment", "1997-09-09"); + good("09:09:09"); + good("1997-09-09T09:09:09.09Z"); + good("1997-09-09T09:09:09.09+09:09"); + good("1997-09-09T09:09:09.09-09:09"); + good("1997-09-09T09:09:09.09"); + good("09:09:09.09"); +} + +#[test] +fn bad_times() { + bad!( + "foo = 199-09-09", + "\ +TOML parse error at line 1, column 10 + | +1 | foo = 199-09-09 + | ^ +expected newline, `#` +" + ); + bad!( + "foo = 199709-09", + "\ +TOML parse error at line 1, column 13 + | +1 | foo = 199709-09 + | ^ +expected newline, `#` +" + ); + bad!( + "foo = 1997-9-09", + "\ +TOML parse error at line 1, column 12 + | +1 | foo = 1997-9-09 + | ^ +invalid date-time +" + ); + bad!( + "foo = 1997-09-9", + "\ +TOML parse error at line 1, column 15 + | +1 | foo = 1997-09-9 + | ^ +invalid date-time +" + ); + bad!( + "foo = 1997-09-0909:09:09", + "\ +TOML parse error at line 1, column 17 + | +1 | foo = 1997-09-0909:09:09 + | ^ +expected newline, `#` +" + ); + bad!( + "foo = 1997-09-09T09:09:09.", + "\ +TOML parse error at line 1, column 26 + | +1 | foo = 1997-09-09T09:09:09. + | ^ +expected newline, `#` +" + ); + bad!( + "foo = T", + r#"TOML parse error at line 1, column 7 + | +1 | foo = T + | ^ +invalid string +expected `"`, `'` +"# + ); + bad!( + "foo = T.", + r#"TOML parse error at line 1, column 7 + | +1 | foo = T. + | ^ +invalid string +expected `"`, `'` +"# + ); + bad!( + "foo = TZ", + r#"TOML parse error at line 1, column 7 + | +1 | foo = TZ + | ^ +invalid string +expected `"`, `'` +"# + ); + bad!( + "foo = 1997-09-09T09:09:09.09+", + r#"TOML parse error at line 1, column 30 + | +1 | foo = 1997-09-09T09:09:09.09+ + | ^ +invalid time offset +"# + ); + bad!( + "foo = 1997-09-09T09:09:09.09+09", + r#"TOML parse error at line 1, column 32 + | +1 | foo = 1997-09-09T09:09:09.09+09 + | ^ +invalid time offset +"# + ); + bad!( + "foo = 1997-09-09T09:09:09.09+09:9", + r#"TOML parse error at line 1, column 33 + | +1 | foo = 1997-09-09T09:09:09.09+09:9 + | ^ +invalid time offset +"# + ); + bad!( + "foo = 1997-09-09T09:09:09.09+0909", + r#"TOML parse error at line 1, column 32 + | +1 | foo = 1997-09-09T09:09:09.09+0909 + | ^ +invalid time offset +"# + ); + bad!( + "foo = 1997-09-09T09:09:09.09-", + r#"TOML parse error at line 1, column 30 + | +1 | foo = 1997-09-09T09:09:09.09- + | ^ +invalid time offset +"# + ); + bad!( + "foo = 1997-09-09T09:09:09.09-09", + r#"TOML parse error at line 1, column 32 + | +1 | foo = 1997-09-09T09:09:09.09-09 + | ^ +invalid time offset +"# + ); + bad!( + "foo = 1997-09-09T09:09:09.09-09:9", + r#"TOML parse error at line 1, column 33 + | +1 | foo = 1997-09-09T09:09:09.09-09:9 + | ^ +invalid time offset +"# + ); + bad!( + "foo = 1997-09-09T09:09:09.09-0909", + r#"TOML parse error at line 1, column 32 + | +1 | foo = 1997-09-09T09:09:09.09-0909 + | ^ +invalid time offset +"# + ); + + bad!( + "foo = 1997-00-09T09:09:09.09Z", + r#"TOML parse error at line 1, column 12 + | +1 | foo = 1997-00-09T09:09:09.09Z + | ^ +invalid date-time +value is out of range +"# + ); + bad!( + "foo = 1997-09-00T09:09:09.09Z", + r#"TOML parse error at line 1, column 15 + | +1 | foo = 1997-09-00T09:09:09.09Z + | ^ +invalid date-time +value is out of range +"# + ); + bad!( + "foo = 1997-09-09T30:09:09.09Z", + r#"TOML parse error at line 1, column 17 + | +1 | foo = 1997-09-09T30:09:09.09Z + | ^ +expected newline, `#` +"# + ); + bad!( + "foo = 1997-09-09T12:69:09.09Z", + r#"TOML parse error at line 1, column 21 + | +1 | foo = 1997-09-09T12:69:09.09Z + | ^ +invalid date-time +value is out of range +"# + ); + bad!( + "foo = 1997-09-09T12:09:69.09Z", + r#"TOML parse error at line 1, column 24 + | +1 | foo = 1997-09-09T12:09:69.09Z + | ^ +invalid date-time +value is out of range +"# + ); +} diff --git a/vendor/toml_edit/tests/testsuite/edit.rs b/vendor/toml_edit/tests/testsuite/edit.rs new file mode 100644 index 000000000..28f73c1ac --- /dev/null +++ b/vendor/toml_edit/tests/testsuite/edit.rs @@ -0,0 +1,855 @@ +use std::fmt; +use std::iter::FromIterator; + +use snapbox::assert_eq; +use toml_edit::{array, table, value, Document, Item, Key, Table, Value}; + +macro_rules! parse_key { + ($s:expr) => {{ + let key = $s.parse::<Key>(); + assert!(key.is_ok()); + key.unwrap() + }}; +} + +macro_rules! as_table { + ($e:ident) => {{ + assert!($e.is_table()); + $e.as_table_mut().unwrap() + }}; +} + +// Copied from https://github.com/colin-kiegel/rust-pretty-assertions/issues/24 +/// Wrapper around string slice that makes debug output `{:?}` to print string same way as `{}`. +/// Used in different `assert*!` macros in combination with `pretty_assertions` crate to make +/// test failures to show nice diffs. +#[derive(PartialEq, Eq)] +struct PrettyString<'a>(pub &'a str); +/// Make diff to display string as multi-line string +impl<'a> fmt::Debug for PrettyString<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.0) + } +} + +struct Test { + doc: Document, +} + +fn given(input: &str) -> Test { + let doc = input.parse::<Document>(); + assert!(doc.is_ok()); + Test { doc: doc.unwrap() } +} + +impl Test { + fn running<F>(&mut self, func: F) -> &mut Self + where + F: Fn(&mut Table), + { + { + let root = self.doc.as_table_mut(); + func(root); + } + self + } + + #[track_caller] + fn produces_display(&self, expected: &str) -> &Self { + assert_eq(expected, self.doc.to_string()); + self + } +} + +// insertion + +#[test] +fn test_insert_leaf_table() { + given( + r#"[servers] + + [servers.alpha] + ip = "10.0.0.1" + dc = "eqdc10" + + [other.table]"#, + ) + .running(|root| { + root["servers"]["beta"] = table(); + root["servers"]["beta"]["ip"] = value("10.0.0.2"); + root["servers"]["beta"]["dc"] = value("eqdc10"); + }) + .produces_display( + r#"[servers] + + [servers.alpha] + ip = "10.0.0.1" + dc = "eqdc10" + +[servers.beta] +ip = "10.0.0.2" +dc = "eqdc10" + + [other.table] +"#, + ); +} + +#[test] +fn test_inserted_leaf_table_goes_after_last_sibling() { + given( + r#" + [package] + [dependencies] + [[example]] + [dependencies.opencl] + [dev-dependencies]"#, + ) + .running(|root| { + root["dependencies"]["newthing"] = table(); + }) + .produces_display( + r#" + [package] + [dependencies] + [[example]] + [dependencies.opencl] + +[dependencies.newthing] + [dev-dependencies] +"#, + ); +} + +#[test] +fn test_inserting_tables_from_different_parsed_docs() { + given("[a]") + .running(|root| { + let other = "[b]".parse::<Document>().unwrap(); + root["b"] = other["b"].clone(); + }) + .produces_display("[a]\n[b]\n"); +} +#[test] +fn test_insert_nonleaf_table() { + given( + r#" + [other.table]"#, + ) + .running(|root| { + root["servers"] = table(); + root["servers"]["alpha"] = table(); + root["servers"]["alpha"]["ip"] = value("10.0.0.1"); + root["servers"]["alpha"]["dc"] = value("eqdc10"); + }) + .produces_display( + r#" + [other.table] + +[servers] + +[servers.alpha] +ip = "10.0.0.1" +dc = "eqdc10" +"#, + ); +} + +#[test] +fn test_insert_array() { + given( + r#" + [package] + title = "withoutarray""#, + ) + .running(|root| { + root["bin"] = array(); + assert!(root["bin"].is_array_of_tables()); + let array = root["bin"].as_array_of_tables_mut().unwrap(); + { + let mut table = Table::new(); + table["hello"] = value("world"); + array.push(table); + } + array.push(Table::new()); + }) + .produces_display( + r#" + [package] + title = "withoutarray" + +[[bin]] +hello = "world" + +[[bin]] +"#, + ); +} + +#[test] +fn test_insert_values() { + given( + r#" + [tbl.son]"#, + ) + .running(|root| { + root["tbl"]["key1"] = value("value1"); + root["tbl"]["key2"] = value(42); + root["tbl"]["key3"] = value(8.1415926); + }) + .produces_display( + r#"[tbl] +key1 = "value1" +key2 = 42 +key3 = 8.1415926 + + [tbl.son] +"#, + ); +} + +// removal + +#[test] +fn test_remove_leaf_table() { + given( + r#" + [servers] + + # Indentation (tabs and/or spaces) is allowed but not required +[servers.alpha] + ip = "10.0.0.1" + dc = "eqdc10" + + [servers.beta] + ip = "10.0.0.2" + dc = "eqdc10""#, + ) + .running(|root| { + let servers = root.get_mut("servers").unwrap(); + let servers = as_table!(servers); + assert!(servers.remove("alpha").is_some()); + }) + .produces_display( + r#" + [servers] + + [servers.beta] + ip = "10.0.0.2" + dc = "eqdc10" +"#, + ); +} + +#[test] +fn test_remove_nonleaf_table() { + given( + r#" + title = "not relevant" + + # comment 1 + [a.b.c] # comment 1.1 + key1 = 1 # comment 1.2 + # comment 2 + [b] # comment 2.1 + key2 = 2 # comment 2.2 + + # comment 3 + [a] # comment 3.1 + key3 = 3 # comment 3.2 + [[a.'array']] + b = 1 + + [[a.b.c.trololololololo]] # ohohohohoho + c = 2 + key3 = 42 + + # comment on some other table + [some.other.table] + + + + + # comment 4 + [a.b] # comment 4.1 + key4 = 4 # comment 4.2 + key41 = 41 # comment 4.3 + + + "#, + ) + .running(|root| { + assert!(root.remove("a").is_some()); + }) + .produces_display( + r#" + title = "not relevant" + # comment 2 + [b] # comment 2.1 + key2 = 2 # comment 2.2 + + # comment on some other table + [some.other.table] + + + "#, + ); +} + +#[test] +fn test_remove_array_entry() { + given( + r#" + [package] + name = "hello" + version = "1.0.0" + + [[bin]] + name = "world" + path = "src/bin/world/main.rs" + + [dependencies] + nom = "4.0" # future is here + + [[bin]] + name = "delete me please" + path = "src/bin/dmp/main.rs""#, + ) + .running(|root| { + let dmp = root.get_mut("bin").unwrap(); + assert!(dmp.is_array_of_tables()); + let dmp = dmp.as_array_of_tables_mut().unwrap(); + assert_eq!(dmp.len(), 2); + dmp.remove(1); + assert_eq!(dmp.len(), 1); + }) + .produces_display( + r#" + [package] + name = "hello" + version = "1.0.0" + + [[bin]] + name = "world" + path = "src/bin/world/main.rs" + + [dependencies] + nom = "4.0" # future is here +"#, + ); +} + +#[test] +fn test_remove_array() { + given( + r#" + [package] + name = "hello" + version = "1.0.0" + + [[bin]] + name = "world" + path = "src/bin/world/main.rs" + + [dependencies] + nom = "4.0" # future is here + + [[bin]] + name = "delete me please" + path = "src/bin/dmp/main.rs""#, + ) + .running(|root| { + assert!(root.remove("bin").is_some()); + }) + .produces_display( + r#" + [package] + name = "hello" + version = "1.0.0" + + [dependencies] + nom = "4.0" # future is here +"#, + ); +} + +#[test] +fn test_remove_value() { + given( + r#" + name = "hello" + # delete this + version = "1.0.0" # please + documentation = "https://docs.rs/hello""#, + ) + .running(|root| { + let value = root.remove("version"); + assert!(value.is_some()); + let value = value.unwrap(); + assert!(value.is_value()); + let value = value.as_value().unwrap(); + assert!(value.is_str()); + let value = value.as_str().unwrap(); + assert_eq(value, "1.0.0"); + }) + .produces_display( + r#" + name = "hello" + documentation = "https://docs.rs/hello" +"#, + ); +} + +#[test] +fn test_remove_last_value_from_implicit() { + given( + r#" + [a] + b = 1"#, + ) + .running(|root| { + let a = root.get_mut("a").unwrap(); + assert!(a.is_table()); + let a = as_table!(a); + a.set_implicit(true); + let value = a.remove("b"); + assert!(value.is_some()); + let value = value.unwrap(); + assert!(value.is_value()); + let value = value.as_value().unwrap(); + assert_eq!(value.as_integer(), Some(1)); + }) + .produces_display(r#""#); +} + +// values + +#[test] +fn test_sort_values() { + given( + r#" + [a.z] + + [a] + # this comment is attached to b + b = 2 # as well as this + a = 1 + c = 3 + + [a.y]"#, + ) + .running(|root| { + let a = root.get_mut("a").unwrap(); + let a = as_table!(a); + a.sort_values(); + }) + .produces_display( + r#" + [a.z] + + [a] + a = 1 + # this comment is attached to b + b = 2 # as well as this + c = 3 + + [a.y] +"#, + ); +} + +#[test] +fn test_sort_values_by() { + given( + r#" + [a.z] + + [a] + # this comment is attached to b + b = 2 # as well as this + a = 1 + "c" = 3 + + [a.y]"#, + ) + .running(|root| { + let a = root.get_mut("a").unwrap(); + let a = as_table!(a); + // Sort by the representation, not the value. So "\"c\"" sorts before "a" because '"' sorts + // before 'a'. + a.sort_values_by(|k1, _, k2, _| k1.display_repr().cmp(&k2.display_repr())); + }) + .produces_display( + r#" + [a.z] + + [a] + "c" = 3 + a = 1 + # this comment is attached to b + b = 2 # as well as this + + [a.y] +"#, + ); +} + +#[test] +fn test_set_position() { + given( + r#" + [package] + [dependencies] + [dependencies.opencl] + [dev-dependencies]"#, + ) + .running(|root| { + for (header, table) in root.iter_mut() { + if header == "dependencies" { + let tab = as_table!(table); + tab.set_position(0); + let (_, segmented) = tab.iter_mut().next().unwrap(); + as_table!(segmented).set_position(5) + } + } + }) + .produces_display( + r#" [dependencies] + + [package] + [dev-dependencies] + [dependencies.opencl] +"#, + ); +} + +#[test] +fn test_multiple_zero_positions() { + given( + r#" + [package] + [dependencies] + [dependencies.opencl] + a="" + [dev-dependencies]"#, + ) + .running(|root| { + for (_, table) in root.iter_mut() { + as_table!(table).set_position(0) + } + }) + .produces_display( + r#" + [package] + [dependencies] + [dev-dependencies] + [dependencies.opencl] + a="" +"#, + ); +} + +#[test] +fn test_multiple_max_usize_positions() { + given( + r#" + [package] + [dependencies] + [dependencies.opencl] + a="" + [dev-dependencies]"#, + ) + .running(|root| { + for (_, table) in root.iter_mut() { + as_table!(table).set_position(usize::MAX) + } + }) + .produces_display( + r#" [dependencies.opencl] + a="" + + [package] + [dependencies] + [dev-dependencies] +"#, + ); +} + +macro_rules! as_array { + ($entry:ident) => {{ + assert!($entry.is_value()); + let a = $entry.as_value_mut().unwrap(); + assert!(a.is_array()); + a.as_array_mut().unwrap() + }}; +} + +#[test] +fn test_insert_replace_into_array() { + given( + r#" + a = [1,2,3] + b = []"#, + ) + .running(|root| { + { + let a = root.get_mut("a").unwrap(); + let a = as_array!(a); + assert_eq!(a.len(), 3); + assert!(a.get(2).is_some()); + a.push(4); + assert_eq!(a.len(), 4); + a.fmt(); + } + let b = root.get_mut("b").unwrap(); + let b = as_array!(b); + assert!(b.is_empty()); + b.push("hello"); + assert_eq!(b.len(), 1); + + b.push_formatted(Value::from("world").decorated("\n", "\n")); + b.push_formatted(Value::from("test").decorated("", "")); + + b.insert(1, "beep"); + b.insert_formatted(2, Value::from("boop").decorated(" ", " ")); + + // This should preserve formatting. + assert_eq!(b.replace(2, "zoink").as_str(), Some("boop")); + // This should replace formatting. + assert_eq!( + b.replace_formatted(4, Value::from("yikes").decorated(" ", "")) + .as_str(), + Some("test") + ); + dbg!(root); + }) + .produces_display( + r#" + a = [1, 2, 3, 4] + b = ["hello", "beep", "zoink" , +"world" +, "yikes"] +"#, + ); +} + +#[test] +fn test_remove_from_array() { + given( + r#" + a = [1, 2, 3, 4] + b = ["hello"]"#, + ) + .running(|root| { + { + let a = root.get_mut("a").unwrap(); + let a = as_array!(a); + assert_eq!(a.len(), 4); + assert!(a.remove(3).is_integer()); + assert_eq!(a.len(), 3); + } + let b = root.get_mut("b").unwrap(); + let b = as_array!(b); + assert_eq!(b.len(), 1); + assert!(b.remove(0).is_str()); + assert!(b.is_empty()); + }) + .produces_display( + r#" + a = [1, 2, 3] + b = [] +"#, + ); +} + +#[test] +fn test_format_array() { + given( + r#" + a = [ + 1, + "2", + 3.0, + ] + "#, + ) + .running(|root| { + for (_, v) in root.iter_mut() { + if let Item::Value(Value::Array(array)) = v { + array.fmt(); + } + } + }) + .produces_display( + r#" + a = [1, "2", 3.0] + "#, + ); +} + +macro_rules! as_inline_table { + ($entry:ident) => {{ + assert!($entry.is_value()); + let a = $entry.as_value_mut().unwrap(); + assert!(a.is_inline_table()); + a.as_inline_table_mut().unwrap() + }}; +} + +#[test] +fn test_insert_into_inline_table() { + given( + r#" + a = {a=2, c = 3} + b = {}"#, + ) + .running(|root| { + { + let a = root.get_mut("a").unwrap(); + let a = as_inline_table!(a); + assert_eq!(a.len(), 2); + assert!(a.contains_key("a") && a.get("c").is_some() && a.get_mut("c").is_some()); + a.get_or_insert("b", 42); + assert_eq!(a.len(), 3); + a.fmt(); + } + let b = root.get_mut("b").unwrap(); + let b = as_inline_table!(b); + assert!(b.is_empty()); + b.get_or_insert("hello", "world"); + assert_eq!(b.len(), 1); + b.fmt() + }) + .produces_display( + r#" + a = { a = 2, c = 3, b = 42 } + b = { hello = "world" } +"#, + ); +} + +#[test] +fn test_remove_from_inline_table() { + given( + r#" + a = {a=2, c = 3, b = 42} + b = {'hello' = "world"}"#, + ) + .running(|root| { + { + let a = root.get_mut("a").unwrap(); + let a = as_inline_table!(a); + assert_eq!(a.len(), 3); + assert!(a.remove("c").is_some()); + assert_eq!(a.len(), 2); + } + let b = root.get_mut("b").unwrap(); + let b = as_inline_table!(b); + assert_eq!(b.len(), 1); + assert!(b.remove("hello").is_some()); + assert!(b.is_empty()); + }) + .produces_display( + r#" + a = {a=2, b = 42} + b = {} +"#, + ); +} + +#[test] +fn test_as_table_like() { + given( + r#" + a = {a=2, c = 3, b = 42} + x = {} + [[bin]] + [b] + x = "y" + [empty]"#, + ) + .running(|root| { + let a = root["a"].as_table_like(); + assert!(a.is_some()); + let a = a.unwrap(); + assert_eq!(a.iter().count(), 3); + assert_eq!(a.len(), 3); + assert_eq!(a.get("a").and_then(Item::as_integer), Some(2)); + + let b = root["b"].as_table_like(); + assert!(b.is_some()); + let b = b.unwrap(); + assert_eq!(b.iter().count(), 1); + assert_eq!(b.len(), 1); + assert_eq!(b.get("x").and_then(Item::as_str), Some("y")); + + assert_eq!(root["x"].as_table_like().map(|t| t.iter().count()), Some(0)); + assert_eq!( + root["empty"].as_table_like().map(|t| t.is_empty()), + Some(true) + ); + + assert!(root["bin"].as_table_like().is_none()); + }); +} + +#[test] +fn test_inline_table_append() { + let mut a = Value::from_iter(vec![ + (parse_key!("a"), 1), + (parse_key!("b"), 2), + (parse_key!("c"), 3), + ]); + let a = a.as_inline_table_mut().unwrap(); + + let mut b = Value::from_iter(vec![ + (parse_key!("c"), 4), + (parse_key!("d"), 5), + (parse_key!("e"), 6), + ]); + let b = b.as_inline_table_mut().unwrap(); + + a.extend(b.iter()); + assert_eq!(a.len(), 5); + assert!(a.contains_key("e")); + assert_eq!(b.len(), 3); +} + +#[test] +fn test_insert_dotted_into_std_table() { + given("") + .running(|root| { + root["nixpkgs"] = table(); + + root["nixpkgs"]["src"] = table(); + root["nixpkgs"]["src"] + .as_table_like_mut() + .unwrap() + .set_dotted(true); + root["nixpkgs"]["src"]["git"] = value("https://github.com/nixos/nixpkgs"); + }) + .produces_display( + r#"[nixpkgs] +src.git = "https://github.com/nixos/nixpkgs" +"#, + ); +} + +#[test] +fn test_insert_dotted_into_implicit_table() { + given("") + .running(|root| { + root["nixpkgs"] = table(); + + root["nixpkgs"]["src"]["git"] = value("https://github.com/nixos/nixpkgs"); + root["nixpkgs"]["src"] + .as_table_like_mut() + .unwrap() + .set_dotted(true); + }) + .produces_display( + r#"[nixpkgs] +src.git = "https://github.com/nixos/nixpkgs" +"#, + ); +} diff --git a/vendor/toml_edit/tests/testsuite/invalid.rs b/vendor/toml_edit/tests/testsuite/invalid.rs new file mode 100644 index 000000000..cb13b4e7d --- /dev/null +++ b/vendor/toml_edit/tests/testsuite/invalid.rs @@ -0,0 +1,211 @@ +#[test] +fn incomplete_inline_table_issue_296() { + let err = "native = {".parse::<toml_edit::Document>().unwrap_err(); + snapbox::assert_eq( + r#"TOML parse error at line 1, column 11 + | +1 | native = { + | ^ +invalid inline table +expected `}` +"#, + err.to_string(), + ); +} + +#[test] +fn bare_value_disallowed_issue_293() { + let err = "value=zzz".parse::<toml_edit::Document>().unwrap_err(); + snapbox::assert_eq( + r#"TOML parse error at line 1, column 7 + | +1 | value=zzz + | ^ +invalid string +expected `"`, `'` +"#, + err.to_string(), + ); +} + +#[test] +fn bare_value_in_array_disallowed_issue_293() { + let err = "value=[zzz]".parse::<toml_edit::Document>().unwrap_err(); + snapbox::assert_eq( + r#"TOML parse error at line 1, column 8 + | +1 | value=[zzz] + | ^ +invalid array +expected `]` +"#, + err.to_string(), + ); +} + +#[test] +fn duplicate_table_after_dotted_key_issue_509() { + let err = " +[dependencies.foo] +version = \"0.16\" + +[dependencies] +libc = \"0.2\" + +[dependencies] +rand = \"0.3.14\" +" + .parse::<toml_edit::Document>() + .unwrap_err(); + snapbox::assert_eq( + r#"TOML parse error at line 8, column 1 + | +8 | [dependencies] + | ^ +invalid table header +duplicate key `dependencies` in document root +"#, + err.to_string(), + ); +} + +#[test] +fn bad() { + let toml_input = "a = 01"; + let expected_err = "\ +TOML parse error at line 1, column 6 + | +1 | a = 01 + | ^ +expected newline, `#` +"; + let err = toml_input.parse::<toml_edit::Document>().unwrap_err(); + snapbox::assert_eq(expected_err, err.to_string()); + + let toml_input = "a = 1__1"; + let expected_err = "\ +TOML parse error at line 1, column 7 + | +1 | a = 1__1 + | ^ +invalid integer +expected digit +"; + let err = toml_input.parse::<toml_edit::Document>().unwrap_err(); + snapbox::assert_eq(expected_err, err.to_string()); + + let toml_input = "a = 1_"; + let expected_err = "\ +TOML parse error at line 1, column 7 + | +1 | a = 1_ + | ^ +invalid integer +expected digit +"; + let err = toml_input.parse::<toml_edit::Document>().unwrap_err(); + snapbox::assert_eq(expected_err, err.to_string()); + + let toml_input = "''"; + let expected_err = "\ +TOML parse error at line 1, column 3 + | +1 | '' + | ^ +expected `.`, `=` +"; + let err = toml_input.parse::<toml_edit::Document>().unwrap_err(); + snapbox::assert_eq(expected_err, err.to_string()); + + let toml_input = "a = 9e99999"; + let expected_err = "\ +TOML parse error at line 1, column 5 + | +1 | a = 9e99999 + | ^ +invalid floating-point number +"; + let err = toml_input.parse::<toml_edit::Document>().unwrap_err(); + snapbox::assert_eq(expected_err, err.to_string()); + + let toml_input = "a = \"\u{7f}\""; + let expected_err = "\ +TOML parse error at line 1, column 6 + | +1 | a = \"\u{7f}\" + | ^ +invalid basic string +"; + let err = toml_input.parse::<toml_edit::Document>().unwrap_err(); + snapbox::assert_eq(expected_err, err.to_string()); + + let toml_input = "a = '\u{7f}'"; + let expected_err = "\ +TOML parse error at line 1, column 6 + | +1 | a = '\u{7f}' + | ^ +invalid literal string +"; + let err = toml_input.parse::<toml_edit::Document>().unwrap_err(); + snapbox::assert_eq(expected_err, err.to_string()); + + let toml_input = "a = -0x1"; + let expected_err = "\ +TOML parse error at line 1, column 7 + | +1 | a = -0x1 + | ^ +expected newline, `#` +"; + let err = toml_input.parse::<toml_edit::Document>().unwrap_err(); + snapbox::assert_eq(expected_err, err.to_string()); + + let toml_input = "a = 0x-1"; + let expected_err = "\ +TOML parse error at line 1, column 7 + | +1 | a = 0x-1 + | ^ +invalid hexadecimal integer +"; + let err = toml_input.parse::<toml_edit::Document>().unwrap_err(); + snapbox::assert_eq(expected_err, err.to_string()); + + // Dotted keys. + let toml_input = "a.b.c = 1 + a.b = 2 + "; + let expected_err = "\ +TOML parse error at line 2, column 10 + | +2 | a.b = 2 + | ^ +duplicate key `b` in document root +"; + let err = toml_input.parse::<toml_edit::Document>().unwrap_err(); + snapbox::assert_eq(expected_err, err.to_string()); + + let toml_input = "a = 1 + a.b = 2"; + let expected_err = "\ +TOML parse error at line 2, column 10 + | +2 | a.b = 2 + | ^ +dotted key `a` attempted to extend non-table type (integer) +"; + let err = toml_input.parse::<toml_edit::Document>().unwrap_err(); + snapbox::assert_eq(expected_err, err.to_string()); + + let toml_input = "a = {k1 = 1, k1.name = \"joe\"}"; + let expected_err = "\ +TOML parse error at line 1, column 6 + | +1 | a = {k1 = 1, k1.name = \"joe\"} + | ^ +dotted key `k1` attempted to extend non-table type (integer) +"; + let err = toml_input.parse::<toml_edit::Document>().unwrap_err(); + snapbox::assert_eq(expected_err, err.to_string()); +} diff --git a/vendor/toml_edit/tests/testsuite/main.rs b/vendor/toml_edit/tests/testsuite/main.rs new file mode 100644 index 000000000..1476c5da0 --- /dev/null +++ b/vendor/toml_edit/tests/testsuite/main.rs @@ -0,0 +1,8 @@ +#![recursion_limit = "256"] + +mod convert; +mod datetime; +mod edit; +mod invalid; +mod parse; +mod stackoverflow; diff --git a/vendor/toml_edit/tests/testsuite/parse.rs b/vendor/toml_edit/tests/testsuite/parse.rs new file mode 100644 index 000000000..ed3ca3037 --- /dev/null +++ b/vendor/toml_edit/tests/testsuite/parse.rs @@ -0,0 +1,1448 @@ +use snapbox::assert_eq; +use toml_edit::{Document, Key, Value}; + +macro_rules! parse { + ($s:expr, $ty:ty) => {{ + let v = $s.parse::<$ty>(); + assert!(v.is_ok(), "Failed with {}", v.unwrap_err()); + v.unwrap() + }}; +} + +macro_rules! parse_value { + ($s:expr) => { + parse!($s, Value) + }; +} + +macro_rules! test_key { + ($s:expr, $expected:expr) => {{ + let key = parse!($s, Key); + assert_eq!($expected, key.get(), ""); + }}; +} + +#[test] +fn test_key_from_str() { + test_key!("a", "a"); + test_key!(r#"'hello key'"#, "hello key"); + test_key!( + r#""Jos\u00E9\U000A0000\n\t\r\f\b\"""#, + "Jos\u{00E9}\u{A0000}\n\t\r\u{c}\u{8}\"" + ); + test_key!("\"\"", ""); + test_key!("\"'hello key'bla\"", "'hello key'bla"); + test_key!( + "'C:\\Users\\appveyor\\AppData\\Local\\Temp\\1\\cargo-edit-test.YizxPxxElXn9'", + "C:\\Users\\appveyor\\AppData\\Local\\Temp\\1\\cargo-edit-test.YizxPxxElXn9" + ); +} + +#[test] +fn test_value_from_str() { + assert!(parse_value!("1979-05-27T00:32:00.999999-07:00").is_datetime()); + assert!(parse_value!("1979-05-27T00:32:00.999999Z").is_datetime()); + assert!(parse_value!("1979-05-27T00:32:00.999999").is_datetime()); + assert!(parse_value!("1979-05-27T00:32:00").is_datetime()); + assert!(parse_value!("1979-05-27").is_datetime()); + assert!(parse_value!("00:32:00").is_datetime()); + assert!(parse_value!("-239").is_integer()); + assert!(parse_value!("1e200").is_float()); + assert!(parse_value!("9_224_617.445_991_228_313").is_float()); + assert!(parse_value!(r#""basic string\nJos\u00E9\n""#).is_str()); + assert!(parse_value!( + r#"""" +multiline basic string +""""# + ) + .is_str()); + assert!(parse_value!(r#"'literal string\ \'"#).is_str()); + assert!(parse_value!( + r#"'''multiline +literal \ \ +string'''"# + ) + .is_str()); + assert!(parse_value!(r#"{ hello = "world", a = 1}"#).is_inline_table()); + assert!( + parse_value!(r#"[ { x = 1, a = "2" }, {a = "a",b = "b", c = "c"} ]"#).is_array() + ); + let wp = "C:\\Users\\appveyor\\AppData\\Local\\Temp\\1\\cargo-edit-test.YizxPxxElXn9"; + let lwp = "'C:\\Users\\appveyor\\AppData\\Local\\Temp\\1\\cargo-edit-test.YizxPxxElXn9'"; + assert_eq!(Value::from(wp).as_str(), parse_value!(lwp).as_str()); + assert!(parse_value!(r#""\\\"\b\f\n\r\t\u00E9\U000A0000""#).is_str()); +} + +#[test] +fn test_key_unification() { + let toml = r#" +[a] +[a.'b'.c] +[a."b".c.e] +[a.b.c.d] +"#; + let expected = r#" +[a] +[a.'b'.c] +[a.'b'.c.e] +[a.'b'.c.d] +"#; + let doc = toml.parse::<Document>(); + assert!(doc.is_ok()); + let doc = doc.unwrap(); + + assert_eq(expected, doc.to_string()); +} + +macro_rules! bad { + ($toml:expr, $msg:expr) => { + match $toml.parse::<Document>() { + Ok(s) => panic!("parsed to: {:#?}", s), + Err(e) => snapbox::assert_eq($msg, e.to_string()), + } + }; +} + +#[test] +fn crlf() { + "\ + [project]\r\n\ + \r\n\ + name = \"splay\"\r\n\ + version = \"0.1.0\"\r\n\ + authors = [\"alex@crichton.co\"]\r\n\ + \r\n\ + [[lib]]\r\n\ + \r\n\ + path = \"lib.rs\"\r\n\ + name = \"splay\"\r\n\ + description = \"\"\"\ + A Rust implementation of a TAR file reader and writer. This library does not\r\n\ + currently handle compression, but it is abstract over all I/O readers and\r\n\ + writers. Additionally, great lengths are taken to ensure that the entire\r\n\ + contents are never required to be entirely resident in memory all at once.\r\n\ + \"\"\"\ + " + .parse::<Document>() + .unwrap(); +} + +#[test] +fn fun_with_strings() { + let table = r#" +bar = "\U00000000" +key1 = "One\nTwo" +key2 = """One\nTwo""" +key3 = """ +One +Two""" + +key4 = "The quick brown fox jumps over the lazy dog." +key5 = """ +The quick brown \ + + +fox jumps over \ +the lazy dog.""" +key6 = """\ + The quick brown \ + fox jumps over \ + the lazy dog.\ + """ +# What you see is what you get. +winpath = 'C:\Users\nodejs\templates' +winpath2 = '\\ServerX\admin$\system32\' +quoted = 'Tom "Dubs" Preston-Werner' +regex = '<\i\c*\s*>' + +regex2 = '''I [dw]on't need \d{2} apples''' +lines = ''' +The first newline is +trimmed in raw strings. +All other whitespace +is preserved. +''' +"# + .parse::<Document>() + .unwrap(); + assert_eq!(table["bar"].as_str(), Some("\0")); + assert_eq!(table["key1"].as_str(), Some("One\nTwo")); + assert_eq!(table["key2"].as_str(), Some("One\nTwo")); + assert_eq!(table["key3"].as_str(), Some("One\nTwo")); + + let msg = "The quick brown fox jumps over the lazy dog."; + assert_eq!(table["key4"].as_str(), Some(msg)); + assert_eq!(table["key5"].as_str(), Some(msg)); + assert_eq!(table["key6"].as_str(), Some(msg)); + + assert_eq!( + table["winpath"].as_str(), + Some(r"C:\Users\nodejs\templates") + ); + assert_eq!( + table["winpath2"].as_str(), + Some(r"\\ServerX\admin$\system32\") + ); + assert_eq!( + table["quoted"].as_str(), + Some(r#"Tom "Dubs" Preston-Werner"#) + ); + assert_eq!(table["regex"].as_str(), Some(r"<\i\c*\s*>")); + assert_eq!( + table["regex2"].as_str(), + Some(r"I [dw]on't need \d{2} apples") + ); + assert_eq!( + table["lines"].as_str(), + Some( + "The first newline is\n\ + trimmed in raw strings.\n\ + All other whitespace\n\ + is preserved.\n" + ) + ); +} + +#[test] +fn tables_in_arrays() { + let table = r#" +[[foo]] +#… +[foo.bar] +#… + +[[foo]] # ... +#… +[foo.bar] +#... +"# + .parse::<Document>() + .unwrap(); + table["foo"][0]["bar"].as_table().unwrap(); + table["foo"][1]["bar"].as_table().unwrap(); +} + +#[test] +fn empty_table() { + let table = r#" +[foo]"# + .parse::<Document>() + .unwrap(); + table["foo"].as_table().unwrap(); +} + +#[test] +fn fruit() { + let table = r#" +[[fruit]] +name = "apple" + +[fruit.physical] +color = "red" +shape = "round" + +[[fruit.variety]] +name = "red delicious" + +[[fruit.variety]] +name = "granny smith" + +[[fruit]] +name = "banana" + +[[fruit.variety]] +name = "plantain" +"# + .parse::<Document>() + .unwrap(); + assert_eq!(table["fruit"][0]["name"].as_str(), Some("apple")); + assert_eq!(table["fruit"][0]["physical"]["color"].as_str(), Some("red")); + assert_eq!( + table["fruit"][0]["physical"]["shape"].as_str(), + Some("round") + ); + assert_eq!( + table["fruit"][0]["variety"][0]["name"].as_str(), + Some("red delicious") + ); + assert_eq!( + table["fruit"][0]["variety"][1]["name"].as_str(), + Some("granny smith") + ); + assert_eq!(table["fruit"][1]["name"].as_str(), Some("banana")); + assert_eq!( + table["fruit"][1]["variety"][0]["name"].as_str(), + Some("plantain") + ); +} + +#[test] +fn stray_cr() { + bad!( + "\r", + "\ +TOML parse error at line 1, column 1 + | +1 | \r + | ^ + +" + ); + bad!( + "a = [ \r ]", + "\ +TOML parse error at line 1, column 7 + | +1 | a = [ \r + ] + | ^ +invalid array +expected `]` +" + ); + bad!( + "a = \"\"\"\r\"\"\"", + "\ +TOML parse error at line 1, column 8 + | +1 | a = \"\"\"\r +\"\"\" + | ^ +invalid multiline basic string +" + ); + bad!( + "a = \"\"\"\\ \r \"\"\"", + "\ +TOML parse error at line 1, column 10 + | +1 | a = \"\"\"\\ \r + \"\"\" + | ^ +invalid escape sequence +expected `b`, `f`, `n`, `r`, `t`, `u`, `U`, `\\`, `\"` +" + ); + bad!( + "a = '''\r'''", + "\ +TOML parse error at line 1, column 8 + | +1 | a = '''\r +''' + | ^ +invalid multiline literal string +" + ); + bad!( + "a = '\r'", + "\ +TOML parse error at line 1, column 6 + | +1 | a = '\r +' + | ^ +invalid literal string +" + ); + bad!( + "a = \"\r\"", + "\ +TOML parse error at line 1, column 6 + | +1 | a = \"\r +\" + | ^ +invalid basic string +" + ); +} + +#[test] +fn blank_literal_string() { + let table = "foo = ''".parse::<Document>().unwrap(); + assert_eq!(table["foo"].as_str(), Some("")); +} + +#[test] +fn many_blank() { + let table = "foo = \"\"\"\n\n\n\"\"\"".parse::<Document>().unwrap(); + assert_eq!(table["foo"].as_str(), Some("\n\n")); +} + +#[test] +fn literal_eats_crlf() { + let table = " + foo = \"\"\"\\\r\n\"\"\" + bar = \"\"\"\\\r\n \r\n \r\n a\"\"\" + " + .parse::<Document>() + .unwrap(); + assert_eq!(table["foo"].as_str(), Some("")); + assert_eq!(table["bar"].as_str(), Some("a")); +} + +#[test] +fn string_no_newline() { + bad!( + "a = \"\n\"", + "\ +TOML parse error at line 1, column 6 + | +1 | a = \" + | ^ +invalid basic string +" + ); + bad!( + "a = '\n'", + "\ +TOML parse error at line 1, column 6 + | +1 | a = ' + | ^ +invalid literal string +" + ); +} + +#[test] +fn bad_leading_zeros() { + bad!( + "a = 00", + "\ +TOML parse error at line 1, column 6 + | +1 | a = 00 + | ^ +expected newline, `#` +" + ); + bad!( + "a = -00", + "\ +TOML parse error at line 1, column 7 + | +1 | a = -00 + | ^ +expected newline, `#` +" + ); + bad!( + "a = +00", + "\ +TOML parse error at line 1, column 7 + | +1 | a = +00 + | ^ +expected newline, `#` +" + ); + bad!( + "a = 00.0", + "\ +TOML parse error at line 1, column 6 + | +1 | a = 00.0 + | ^ +expected newline, `#` +" + ); + bad!( + "a = -00.0", + "\ +TOML parse error at line 1, column 7 + | +1 | a = -00.0 + | ^ +expected newline, `#` +" + ); + bad!( + "a = +00.0", + "\ +TOML parse error at line 1, column 7 + | +1 | a = +00.0 + | ^ +expected newline, `#` +" + ); + bad!( + "a = 9223372036854775808", + "\ +TOML parse error at line 1, column 5 + | +1 | a = 9223372036854775808 + | ^ +number too large to fit in target type +" + ); + bad!( + "a = -9223372036854775809", + "\ +TOML parse error at line 1, column 5 + | +1 | a = -9223372036854775809 + | ^ +number too small to fit in target type +" + ); +} + +#[test] +fn bad_floats() { + bad!( + "a = 0.", + "\ +TOML parse error at line 1, column 7 + | +1 | a = 0. + | ^ +invalid floating-point number +expected digit +" + ); + bad!( + "a = 0.e", + "\ +TOML parse error at line 1, column 7 + | +1 | a = 0.e + | ^ +invalid floating-point number +expected digit +" + ); + bad!( + "a = 0.E", + "\ +TOML parse error at line 1, column 7 + | +1 | a = 0.E + | ^ +invalid floating-point number +expected digit +" + ); + bad!( + "a = 0.0E", + "\ +TOML parse error at line 1, column 9 + | +1 | a = 0.0E + | ^ +invalid floating-point number +" + ); + bad!( + "a = 0.0e", + "\ +TOML parse error at line 1, column 9 + | +1 | a = 0.0e + | ^ +invalid floating-point number +" + ); + bad!( + "a = 0.0e-", + "\ +TOML parse error at line 1, column 10 + | +1 | a = 0.0e- + | ^ +invalid floating-point number +" + ); + bad!( + "a = 0.0e+", + "\ +TOML parse error at line 1, column 10 + | +1 | a = 0.0e+ + | ^ +invalid floating-point number +" + ); +} + +#[test] +fn floats() { + macro_rules! t { + ($actual:expr, $expected:expr) => {{ + let f = format!("foo = {}", $actual); + println!("{}", f); + let a = f.parse::<Document>().unwrap(); + assert_eq!(a["foo"].as_float().unwrap(), $expected); + }}; + } + + t!("1.0", 1.0); + t!("1.0e0", 1.0); + t!("1.0e+0", 1.0); + t!("1.0e-0", 1.0); + t!("1E-0", 1.0); + t!("1.001e-0", 1.001); + t!("2e10", 2e10); + t!("2e+10", 2e10); + t!("2e-10", 2e-10); + t!("2_0.0", 20.0); + t!("2_0.0_0e1_0", 20.0e10); + t!("2_0.1_0e1_0", 20.1e10); +} + +#[test] +fn bare_key_names() { + let a = " + foo = 3 + foo_3 = 3 + foo_-2--3--r23f--4-f2-4 = 3 + _ = 3 + - = 3 + 8 = 8 + \"a\" = 3 + \"!\" = 3 + \"a^b\" = 3 + \"\\\"\" = 3 + \"character encoding\" = \"value\" + 'ʎǝʞ' = \"value\" + " + .parse::<Document>() + .unwrap(); + let _ = &a["foo"]; + let _ = &a["-"]; + let _ = &a["_"]; + let _ = &a["8"]; + let _ = &a["foo_3"]; + let _ = &a["foo_-2--3--r23f--4-f2-4"]; + let _ = &a["a"]; + let _ = &a["!"]; + let _ = &a["\""]; + let _ = &a["character encoding"]; + let _ = &a["ʎǝʞ"]; +} + +#[test] +fn bad_keys() { + bad!( + "key\n=3", + "\ +TOML parse error at line 1, column 4 + | +1 | key + | ^ +expected `.`, `=` +" + ); + bad!( + "key=\n3", + "\ +TOML parse error at line 1, column 5 + | +1 | key= + | ^ +invalid string +expected `\"`, `'` +" + ); + bad!( + "key|=3", + "\ +TOML parse error at line 1, column 4 + | +1 | key|=3 + | ^ +expected `.`, `=` +" + ); + bad!( + "=3", + "\ +TOML parse error at line 1, column 1 + | +1 | =3 + | ^ +invalid key +" + ); + bad!( + "\"\"|=3", + "\ +TOML parse error at line 1, column 3 + | +1 | \"\"|=3 + | ^ +expected `.`, `=` +" + ); + bad!( + "\"\n\"|=3", + "\ +TOML parse error at line 1, column 2 + | +1 | \" + | ^ +invalid basic string +" + ); + bad!( + "\"\r\"|=3", + "\ +TOML parse error at line 1, column 2 + | +1 | \"\r\"|=3 + | ^ +invalid basic string +" + ); + bad!( + "''''''=3", + "\ +TOML parse error at line 1, column 3 + | +1 | ''''''=3 + | ^ +expected `.`, `=` +" + ); + bad!( + "\"\"\"\"\"\"=3", + "\ +TOML parse error at line 1, column 3 + | +1 | \"\"\"\"\"\"=3 + | ^ +expected `.`, `=` +" + ); + bad!( + "'''key'''=3", + "\ +TOML parse error at line 1, column 3 + | +1 | '''key'''=3 + | ^ +expected `.`, `=` +" + ); + bad!( + "\"\"\"key\"\"\"=3", + "\ +TOML parse error at line 1, column 3 + | +1 | \"\"\"key\"\"\"=3 + | ^ +expected `.`, `=` +" + ); +} + +#[test] +fn bad_table_names() { + bad!( + "[]", + "\ +TOML parse error at line 1, column 2 + | +1 | [] + | ^ +invalid key +" + ); + bad!( + "[.]", + "\ +TOML parse error at line 1, column 2 + | +1 | [.] + | ^ +invalid key +" + ); + bad!( + "[a.]", + "\ +TOML parse error at line 1, column 3 + | +1 | [a.] + | ^ +invalid table header +expected `.`, `]` +" + ); + bad!( + "[!]", + "\ +TOML parse error at line 1, column 2 + | +1 | [!] + | ^ +invalid key +" + ); + bad!( + "[\"\n\"]", + "\ +TOML parse error at line 1, column 3 + | +1 | [\" + | ^ +invalid basic string +" + ); + bad!( + "[a.b]\n[a.\"b\"]", + "\ +TOML parse error at line 2, column 1 + | +2 | [a.\"b\"] + | ^ +invalid table header +duplicate key `b` in table `a` +" + ); + bad!( + "[']", + "\ +TOML parse error at line 1, column 4 + | +1 | ['] + | ^ +invalid literal string +" + ); + bad!( + "[''']", + "\ +TOML parse error at line 1, column 4 + | +1 | ['''] + | ^ +invalid table header +expected `.`, `]` +" + ); + bad!( + "['''''']", + "\ +TOML parse error at line 1, column 4 + | +1 | [''''''] + | ^ +invalid table header +expected `.`, `]` +" + ); + bad!( + "['''foo''']", + "\ +TOML parse error at line 1, column 4 + | +1 | ['''foo'''] + | ^ +invalid table header +expected `.`, `]` +" + ); + bad!( + "[\"\"\"bar\"\"\"]", + "\ +TOML parse error at line 1, column 4 + | +1 | [\"\"\"bar\"\"\"] + | ^ +invalid table header +expected `.`, `]` +" + ); + bad!( + "['\n']", + "\ +TOML parse error at line 1, column 3 + | +1 | [' + | ^ +invalid literal string +" + ); + bad!( + "['\r\n']", + "\ +TOML parse error at line 1, column 3 + | +1 | [' + | ^ +invalid literal string +" + ); +} + +#[test] +fn table_names() { + let a = " + [a.\"b\"] + [\"f f\"] + [\"f.f\"] + [\"\\\"\"] + ['a.a'] + ['\"\"'] + " + .parse::<Document>() + .unwrap(); + println!("{:?}", a); + let _ = &a["a"]["b"]; + let _ = &a["f f"]; + let _ = &a["f.f"]; + let _ = &a["\""]; + let _ = &a["\"\""]; +} + +#[test] +fn invalid_bare_numeral() { + bad!( + "4", + "\ +TOML parse error at line 1, column 2 + | +1 | 4 + | ^ +expected `.`, `=` +" + ); +} + +#[test] +fn inline_tables() { + "a = {}".parse::<Document>().unwrap(); + "a = {b=1}".parse::<Document>().unwrap(); + "a = { b = 1 }".parse::<Document>().unwrap(); + "a = {a=1,b=2}".parse::<Document>().unwrap(); + "a = {a=1,b=2,c={}}".parse::<Document>().unwrap(); + + bad!( + "a = {a=1,}", + "\ +TOML parse error at line 1, column 9 + | +1 | a = {a=1,} + | ^ +invalid inline table +expected `}` +" + ); + bad!( + "a = {,}", + "\ +TOML parse error at line 1, column 6 + | +1 | a = {,} + | ^ +invalid inline table +expected `}` +" + ); + bad!( + "a = {a=1,a=1}", + "\ +TOML parse error at line 1, column 6 + | +1 | a = {a=1,a=1} + | ^ +duplicate key `a` +" + ); + bad!( + "a = {\n}", + "\ +TOML parse error at line 1, column 6 + | +1 | a = { + | ^ +invalid inline table +expected `}` +" + ); + bad!( + "a = {", + "\ +TOML parse error at line 1, column 6 + | +1 | a = { + | ^ +invalid inline table +expected `}` +" + ); + + "a = {a=[\n]}".parse::<Document>().unwrap(); + "a = {\"a\"=[\n]}".parse::<Document>().unwrap(); + "a = [\n{},\n{},\n]".parse::<Document>().unwrap(); +} + +#[test] +fn number_underscores() { + macro_rules! t { + ($actual:expr, $expected:expr) => {{ + let f = format!("foo = {}", $actual); + let table = f.parse::<Document>().unwrap(); + assert_eq!(table["foo"].as_integer().unwrap(), $expected); + }}; + } + + t!("1_0", 10); + t!("1_0_0", 100); + t!("1_000", 1000); + t!("+1_000", 1000); + t!("-1_000", -1000); +} + +#[test] +fn bad_underscores() { + bad!( + "foo = 0_", + "\ +TOML parse error at line 1, column 8 + | +1 | foo = 0_ + | ^ +expected newline, `#` +" + ); + bad!( + "foo = 0__0", + "\ +TOML parse error at line 1, column 8 + | +1 | foo = 0__0 + | ^ +expected newline, `#` +" + ); + bad!( + "foo = __0", + "\ +TOML parse error at line 1, column 7 + | +1 | foo = __0 + | ^ +invalid integer +expected leading digit +" + ); + bad!( + "foo = 1_0_", + "\ +TOML parse error at line 1, column 11 + | +1 | foo = 1_0_ + | ^ +invalid integer +expected digit +" + ); +} + +#[test] +fn bad_unicode_codepoint() { + bad!( + "foo = \"\\uD800\"", + "\ +TOML parse error at line 1, column 10 + | +1 | foo = \"\\uD800\" + | ^ +invalid unicode 4-digit hex code +value is out of range +" + ); +} + +#[test] +fn bad_strings() { + bad!( + "foo = \"\\uxx\"", + "\ +TOML parse error at line 1, column 10 + | +1 | foo = \"\\uxx\" + | ^ +invalid unicode 4-digit hex code +" + ); + bad!( + "foo = \"\\u\"", + "\ +TOML parse error at line 1, column 10 + | +1 | foo = \"\\u\" + | ^ +invalid unicode 4-digit hex code +" + ); + bad!( + "foo = \"\\", + "\ +TOML parse error at line 1, column 8 + | +1 | foo = \"\\ + | ^ +invalid basic string +" + ); + bad!( + "foo = '", + "\ +TOML parse error at line 1, column 8 + | +1 | foo = ' + | ^ +invalid literal string +" + ); +} + +#[test] +fn empty_string() { + assert_eq!( + "foo = \"\"".parse::<Document>().unwrap()["foo"] + .as_str() + .unwrap(), + "" + ); +} + +#[test] +fn booleans() { + let table = "foo = true".parse::<Document>().unwrap(); + assert_eq!(table["foo"].as_bool(), Some(true)); + + let table = "foo = false".parse::<Document>().unwrap(); + assert_eq!(table["foo"].as_bool(), Some(false)); + + bad!( + "foo = true2", + "\ +TOML parse error at line 1, column 11 + | +1 | foo = true2 + | ^ +expected newline, `#` +" + ); + bad!( + "foo = false2", + "\ +TOML parse error at line 1, column 12 + | +1 | foo = false2 + | ^ +expected newline, `#` +" + ); + bad!( + "foo = t1", + "\ +TOML parse error at line 1, column 7 + | +1 | foo = t1 + | ^ +invalid string +expected `\"`, `'` +" + ); + bad!( + "foo = f2", + "\ +TOML parse error at line 1, column 7 + | +1 | foo = f2 + | ^ +invalid string +expected `\"`, `'` +" + ); +} + +#[test] +fn bad_nesting() { + bad!( + " + a = [2] + [[a]] + b = 5 + ", + "\ +TOML parse error at line 3, column 9 + | +3 | [[a]] + | ^ +invalid table header +duplicate key `a` in document root +" + ); + bad!( + " + a = 1 + [a.b] + ", + "\ +TOML parse error at line 3, column 9 + | +3 | [a.b] + | ^ +invalid table header +dotted key `a` attempted to extend non-table type (integer) +" + ); + bad!( + " + a = [] + [a.b] + ", + "\ +TOML parse error at line 3, column 9 + | +3 | [a.b] + | ^ +invalid table header +dotted key `a` attempted to extend non-table type (array) +" + ); + bad!( + " + a = [] + [[a.b]] + ", + "\ +TOML parse error at line 3, column 9 + | +3 | [[a.b]] + | ^ +invalid table header +dotted key `a` attempted to extend non-table type (array) +" + ); + bad!( + " + [a] + b = { c = 2, d = {} } + [a.b] + c = 2 + ", + "\ +TOML parse error at line 4, column 9 + | +4 | [a.b] + | ^ +invalid table header +duplicate key `b` in table `a` +" + ); +} + +#[test] +fn bad_table_redefine() { + bad!( + " + [a] + foo=\"bar\" + [a.b] + foo=\"bar\" + [a] + ", + "\ +TOML parse error at line 6, column 9 + | +6 | [a] + | ^ +invalid table header +duplicate key `a` in document root +" + ); + bad!( + " + [a] + foo=\"bar\" + b = { foo = \"bar\" } + [a] + ", + "\ +TOML parse error at line 5, column 9 + | +5 | [a] + | ^ +invalid table header +duplicate key `a` in document root +" + ); + bad!( + " + [a] + b = {} + [a.b] + ", + "\ +TOML parse error at line 4, column 9 + | +4 | [a.b] + | ^ +invalid table header +duplicate key `b` in table `a` +" + ); + + bad!( + " + [a] + b = {} + [a] + ", + "\ +TOML parse error at line 4, column 9 + | +4 | [a] + | ^ +invalid table header +duplicate key `a` in document root +" + ); +} + +#[test] +fn datetimes() { + macro_rules! t { + ($actual:expr) => {{ + let f = format!("foo = {}", $actual); + let toml = f.parse::<Document>().expect(&format!("failed: {}", f)); + assert_eq!(toml["foo"].as_datetime().unwrap().to_string(), $actual); + }}; + } + + t!("2016-09-09T09:09:09Z"); + t!("2016-09-09T09:09:09.1Z"); + t!("2016-09-09T09:09:09.2+10:00"); + t!("2016-09-09T09:09:09.123456789-02:00"); + bad!( + "foo = 2016-09-09T09:09:09.Z", + "\ +TOML parse error at line 1, column 26 + | +1 | foo = 2016-09-09T09:09:09.Z + | ^ +expected newline, `#` +" + ); + bad!( + "foo = 2016-9-09T09:09:09Z", + "\ +TOML parse error at line 1, column 12 + | +1 | foo = 2016-9-09T09:09:09Z + | ^ +invalid date-time +" + ); + bad!( + "foo = 2016-09-09T09:09:09+2:00", + "\ +TOML parse error at line 1, column 27 + | +1 | foo = 2016-09-09T09:09:09+2:00 + | ^ +invalid time offset +" + ); + bad!( + "foo = 2016-09-09T09:09:09-2:00", + "\ +TOML parse error at line 1, column 27 + | +1 | foo = 2016-09-09T09:09:09-2:00 + | ^ +invalid time offset +" + ); + bad!( + "foo = 2016-09-09T09:09:09Z-2:00", + "\ +TOML parse error at line 1, column 27 + | +1 | foo = 2016-09-09T09:09:09Z-2:00 + | ^ +expected newline, `#` +" + ); +} + +#[test] +fn require_newline_after_value() { + bad!( + "0=0r=false", + "\ +TOML parse error at line 1, column 4 + | +1 | 0=0r=false + | ^ +expected newline, `#` +" + ); + bad!( + r#" +0=""o=""m=""r=""00="0"q="""0"""e="""0""" +"#, + r#"TOML parse error at line 2, column 5 + | +2 | 0=""o=""m=""r=""00="0"q="""0"""e="""0""" + | ^ +expected newline, `#` +"# + ); + bad!( + r#" +[[0000l0]] +0="0"[[0000l0]] +0="0"[[0000l0]] +0="0"l="0" +"#, + r#"TOML parse error at line 3, column 6 + | +3 | 0="0"[[0000l0]] + | ^ +expected newline, `#` +"# + ); + bad!( + r#" +0=[0]00=[0,0,0]t=["0","0","0"]s=[1000-00-00T00:00:00Z,2000-00-00T00:00:00Z] +"#, + r#"TOML parse error at line 2, column 6 + | +2 | 0=[0]00=[0,0,0]t=["0","0","0"]s=[1000-00-00T00:00:00Z,2000-00-00T00:00:00Z] + | ^ +expected newline, `#` +"# + ); + bad!( + r#" +0=0r0=0r=false +"#, + r#"TOML parse error at line 2, column 4 + | +2 | 0=0r0=0r=false + | ^ +expected newline, `#` +"# + ); + bad!( + r#" +0=0r0=0r=falsefal=false +"#, + r#"TOML parse error at line 2, column 4 + | +2 | 0=0r0=0r=falsefal=false + | ^ +expected newline, `#` +"# + ); +} diff --git a/vendor/toml_edit/tests/testsuite/stackoverflow.rs b/vendor/toml_edit/tests/testsuite/stackoverflow.rs new file mode 100644 index 000000000..de4c72262 --- /dev/null +++ b/vendor/toml_edit/tests/testsuite/stackoverflow.rs @@ -0,0 +1,54 @@ +#[test] +#[cfg(not(feature = "unbounded"))] +fn array_recursion_limit() { + let depths = [(1, true), (20, true), (300, false)]; + for (depth, is_ok) in depths { + let input = format!("x={}{}", &"[".repeat(depth), &"]".repeat(depth)); + let document = input.parse::<toml_edit::Document>(); + assert_eq!(document.is_ok(), is_ok, "depth: {}", depth); + } +} + +#[test] +#[cfg(not(feature = "unbounded"))] +fn inline_table_recursion_limit() { + let depths = [(1, true), (20, true), (300, false)]; + for (depth, is_ok) in depths { + let input = format!("x={}true{}", &"{ x = ".repeat(depth), &"}".repeat(depth)); + let document = input.parse::<toml_edit::Document>(); + assert_eq!(document.is_ok(), is_ok, "depth: {}", depth); + } +} + +#[test] +#[cfg(not(feature = "unbounded"))] +fn table_key_recursion_limit() { + let depths = [(1, true), (20, true), (300, false)]; + for (depth, is_ok) in depths { + let input = format!("[x{}]", &".x".repeat(depth)); + let document = input.parse::<toml_edit::Document>(); + assert_eq!(document.is_ok(), is_ok, "depth: {}", depth); + } +} + +#[test] +#[cfg(not(feature = "unbounded"))] +fn dotted_key_recursion_limit() { + let depths = [(1, true), (20, true), (300, false)]; + for (depth, is_ok) in depths { + let input = format!("x{} = true", &".x".repeat(depth)); + let document = input.parse::<toml_edit::Document>(); + assert_eq!(document.is_ok(), is_ok, "depth: {}", depth); + } +} + +#[test] +#[cfg(not(feature = "unbounded"))] +fn inline_dotted_key_recursion_limit() { + let depths = [(1, true), (20, true), (300, false)]; + for (depth, is_ok) in depths { + let input = format!("x = {{ x{} = true }}", &".x".repeat(depth)); + let document = input.parse::<toml_edit::Document>(); + assert_eq!(document.is_ok(), is_ok, "depth: {}", depth); + } +} |