mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-22 21:48:02 +00:00
Compare commits
641 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8932c852a5 | |||
| 9f3dd3c7c4 | |||
| dd9b415ff9 | |||
| 3bb4a5a4f6 | |||
| 6164627bea | |||
| 51aaf496d4 | |||
| bc66aeb0d3 | |||
| 7e7044d457 | |||
| 5498dc0550 | |||
| ff04e8be9b | |||
| 69240c17c5 | |||
| 237434f19c | |||
| 1833914346 | |||
| ab848060f2 | |||
| 7e39623f72 | |||
| 157dc44c51 | |||
| 80d01a3a79 | |||
| 343c060fc1 | |||
| 21c1ab6c50 | |||
| 594ab7745d | |||
| 8cf0ba7fe2 | |||
| 34b52c0b83 | |||
| ec7ddc93cd | |||
| 55a7cedd73 | |||
| 7af97c66b8 | |||
| 1f57084365 | |||
| 56bd369422 | |||
| ff259ec66b | |||
| 6c54aafeb9 | |||
| 5d41404e67 | |||
| 1eccb3c350 | |||
| 77ae1c3bf7 | |||
| b85e28166c | |||
| 0508cb50fc | |||
| 84fdc7df69 | |||
| ab1ca04b2e | |||
| fb2fe409c8 | |||
| 549fac7235 | |||
| c375d8b19b | |||
| 6cf507f808 | |||
| c3c1641c06 | |||
| 1fcda0ebdb | |||
| 8f16ac0a94 | |||
| 737f78c315 | |||
| 4a97386cb9 | |||
| 5b32217877 | |||
| 5b140361a3 | |||
| 678351eac7 | |||
| 999c261d11 | |||
| efbe574209 | |||
| 33b2677384 | |||
| 01ded9f405 | |||
| fc827ecec2 | |||
| 5c785eee58 | |||
| 819db93a3d | |||
| a6690ea2fe | |||
| 65e1a50749 | |||
| 87d41b59fd | |||
| 3f120fb355 | |||
| 2b92c80cc1 | |||
| c1c0ede452 | |||
| 4a66c5f33d | |||
| 714c8a5586 | |||
| dc0c0dcba1 | |||
| 54102ee7d0 | |||
| 14accf7518 | |||
| 55fdbea20b | |||
| 75d8902371 | |||
| 9451ea8df1 | |||
| c1ce03b3dd | |||
| a587eb8953 | |||
| 990f7eb6c1 | |||
| 082e18f9a1 | |||
| f309485787 | |||
| e2f85681fe | |||
| 8b840c3030 | |||
| 9c39115f82 | |||
| 89342af71e | |||
| 3c5e2d11f6 | |||
| 3805c037a8 | |||
| 7045fee260 | |||
| 9d81532e41 | |||
| 5e47432ef0 | |||
| e0fc46783d | |||
| ca772a14f9 | |||
| 7b840897a9 | |||
| 967795414b | |||
| 985725f820 | |||
| 0c303d85d7 | |||
| f68e9e901e | |||
| 1094e2d334 | |||
| d9c338ec4a | |||
| 699bf3a75d | |||
| dd29825217 | |||
| 6366f17da7 | |||
| 1120e5af4a | |||
| 1093f7e232 | |||
| 2ea132b8c4 | |||
| 2ebc771b88 | |||
| c17c4eef18 | |||
| 7aa4950504 | |||
| 47015a2727 | |||
| dc4c31eb50 | |||
| b53ebef438 | |||
| 6c3bf7a2fc | |||
| ce0844b9ec | |||
| e9270e59f0 | |||
| 72060b779a | |||
| 1bb23ad9d1 | |||
| 9be4c9654a | |||
| 4114e90bac | |||
| 8bb07b0743 | |||
| ba8c1d63c8 | |||
| 857a805993 | |||
| 5a8dcac2ed | |||
| 697b082e90 | |||
| d91075c8d5 | |||
| 4118cec731 | |||
| c261015325 | |||
| 6b5e5a83d0 | |||
| bc6b2b1dee | |||
| beb21cb640 | |||
| 7cfebbcd72 | |||
| b60c03ec3f | |||
| 3257851192 | |||
| 9a84622c56 | |||
| de8ac1c0be | |||
| 3d6c4149b1 | |||
| 29cdf888c0 | |||
| 2ba97394fb | |||
| 6699b0bc40 | |||
| b054ea4105 | |||
| e5efb6ad93 | |||
| 1f423580a5 | |||
| 033114a4ae | |||
| 7cec99c7fd | |||
| 6c5bf701be | |||
| 6e800ff826 | |||
| 68bda7a004 | |||
| dfeaf77bb2 | |||
| b0cc213e57 | |||
| 74ca06662e | |||
| 38edb473de | |||
| 1c03647656 | |||
| aeee73fe92 | |||
| 1a3ef39040 | |||
| deaf600af7 | |||
| 48556a4c7f | |||
| d88a4748f7 | |||
| ffed19243d | |||
| bb7f94df84 | |||
| ff0f467e25 | |||
| d1975f3661 | |||
| b91713e824 | |||
| 6ea446fb4b | |||
| 85c6904a93 | |||
| 2fd5212204 | |||
| 7d1bc1f0fc | |||
| cdc2fa1b9f | |||
| ac4001e590 | |||
| fbcb2230bb | |||
| 86c88bea12 | |||
| 82d0fe00fd | |||
| e61261e002 | |||
| 9fd56cd41c | |||
| e81f54fbc8 | |||
| c67017d466 | |||
| f6e7366b46 | |||
| 1f9f72bc48 | |||
| e24dbc418d | |||
| 18e5b03fd1 | |||
| 5aa163f27e | |||
| 3728d3c67a | |||
| 3f48ed36cc | |||
| b6a2d07f26 | |||
| 84ad76b2e5 | |||
| e6b6602a42 | |||
| 999b94d6ae | |||
| fa6712d2bf | |||
| 012ea8eb84 | |||
| 9add5812e2 | |||
| 5fd52100b6 | |||
| 6670a309ca | |||
| b7bad3a165 | |||
| 4e002ece07 | |||
| eaccae2c46 | |||
| 990a502c39 | |||
| 661206d885 | |||
| 51d4563ed1 | |||
| 7db0982e58 | |||
| ed04824f10 | |||
| 88ee470a1c | |||
| a5ecbdb4f4 | |||
| bd588db067 | |||
| 8f09aeacdd | |||
| 0b5c56b0db | |||
| 85de92e6f7 | |||
| c858a1fa77 | |||
| d02eb22557 | |||
| 034fe25d5b | |||
| 0a230e8598 | |||
| b20214d4a0 | |||
| 34f4b68f77 | |||
| 60e08f9545 | |||
| ba46f45dc5 | |||
| 44b9567e21 | |||
| b276849ce1 | |||
| 398fba9b1e | |||
| cd6697b0e4 | |||
| c162d51866 | |||
| 78a9dbc57e | |||
| 391d3ababf | |||
| 99d9151ce9 | |||
| 4c89cf89fd | |||
| b0c99ed761 | |||
| dd1f4b483e | |||
| 91bfa8f947 | |||
| 8847800ce2 | |||
| 3c9fa1ccdf | |||
| 3c29a8857f | |||
| a5da27e16d | |||
| e797431268 | |||
| 4a335f8933 | |||
| 84721920fd | |||
| 192c7819ee | |||
| ede40bdfaa | |||
| e3d871ff7b | |||
| 5cbc8439ea | |||
| 0e1c4093c8 | |||
| 0d5b6c180c | |||
| 97c350a95e | |||
| 920a77ad61 | |||
| a227a87865 | |||
| 7a7a182ab6 | |||
| 9e1f573f88 | |||
| 094f63b86a | |||
| 42fa79455e | |||
| 104ad9a7dd | |||
| 23c14e5f33 | |||
| e80571751d | |||
| 0737474640 | |||
| 34de1e00c8 | |||
| f6eb34a830 | |||
| 8084258a3e | |||
| fc3f104c4a | |||
| 4bec9ffd0f | |||
| e6d2322e68 | |||
| 2b504099e4 | |||
| db3074a40f | |||
| 2e821eab4b | |||
| be7d0e7eb2 | |||
| b539cb45d7 | |||
| a5490e20e1 | |||
| 45c45e87bf | |||
| 2e76f7013f | |||
| d35de19120 | |||
| e5b3507145 | |||
| 7ea7c2ceb9 | |||
| 2b5b15967e | |||
| 2ef60b62ac | |||
| e6f086d85e | |||
| bf76f50294 | |||
| ba07075590 | |||
| 26186bddd1 | |||
| 53b9871b17 | |||
| f8787c3ca8 | |||
| 3022064f84 | |||
| 9e140a2071 | |||
| 24e6acbfae | |||
| 29c5a50935 | |||
| c619b2a7c4 | |||
| 764ebd9b17 | |||
| 010444dfa4 | |||
| 9c6f0c3a0e | |||
| a9f8ea0a1e | |||
| 04faac962a | |||
| 7e5701ad2b | |||
| 1cd10a7d09 | |||
| d5e6436b28 | |||
| 8ff11dc234 | |||
| 6b3777b617 | |||
| 7350b58f5c | |||
| 7351e0e55a | |||
| b3ff7e43ef | |||
| a50e1c20e9 | |||
| 6980727d74 | |||
| bb1dedf04d | |||
| f3520e526b | |||
| e8fd2c85c3 | |||
| 97962d51e2 | |||
| 95b1a5d3d9 | |||
| 0856a2c101 | |||
| 9f331cc257 | |||
| ef16c815f6 | |||
| c45a809d5c | |||
| f7d06cae4c | |||
| 31fe82a215 | |||
| ef6ed1d1be | |||
| 9d1251548b | |||
| c20730ee39 | |||
| afd51ef0f4 | |||
| 3167f98689 | |||
| 078b171c1b | |||
| da8d6f678e | |||
| 548eb8f667 | |||
| 1fe39043ee | |||
| c2114491ca | |||
| 9f47c47cad | |||
| d6b39fd2c1 | |||
| 4d6d0ae539 | |||
| dda070f45c | |||
| b97a183e82 | |||
| 9433004307 | |||
| 9476838264 | |||
| 172edc4cf4 | |||
| 3c97e1b9a9 | |||
| a81968af3c | |||
| ea2789df0f | |||
| b7cfe33101 | |||
| 1b8ebf6b64 | |||
| 35ad468780 | |||
| 850a29beb1 | |||
| 16bf9871cd | |||
| 6182eceed1 | |||
| 99bc52f685 | |||
| 726ff5ed31 | |||
| f63acb52dc | |||
| 36a66873cc | |||
| 63809e69c7 | |||
| f44402e224 | |||
| 099fa25b86 | |||
| c120c4518b | |||
| 115c1b4830 | |||
| 23db3a41e7 | |||
| e2ff603587 | |||
| 19a11237b8 | |||
| 732544aed6 | |||
| 65dfa607c8 | |||
| 59104bbc24 | |||
| 38ad09aeb7 | |||
| 02631cef42 | |||
| f369707dc5 | |||
| e16e924c21 | |||
| 8b52ddd5b9 | |||
| 112f2040ea | |||
| cd836eb3ca | |||
| 2b4355724e | |||
| 5534bf4df1 | |||
| 60522937af | |||
| 29be721f79 | |||
| 0c4ffad9ec | |||
| 03addbae55 | |||
| 0bab6be124 | |||
| b6def5300a | |||
| 1b35c9e27e | |||
| d1564525ad | |||
| 645f672a55 | |||
| a135199ab1 | |||
| 2a9971a69d | |||
| e2ada0efef | |||
| 69653a762d | |||
| c33fb95127 | |||
| ec6ca6bf73 | |||
| 078e88b223 | |||
| 1894cb703f | |||
| 27c283ab53 | |||
| 142955b109 | |||
| a61cd0f236 | |||
| cb1632e957 | |||
| dbf1f9ab8f | |||
| 137ab48aff | |||
| fc43def8a3 | |||
| 2a351016ed | |||
| dfa321a1dd | |||
| 895eb2ba6c | |||
| cd365de70c | |||
| 7f799f3948 | |||
| 234fbfd7e3 | |||
| b9909cef3d | |||
| d540e72fc7 | |||
| 13d0899776 | |||
| 4fefa7a01d | |||
| 90486607a1 | |||
| 0b303c766c | |||
| c371563bfc | |||
| d17d8eb3ee | |||
| bcaebdb2b7 | |||
| 43a9f59c18 | |||
| ff70409215 | |||
| 97a98a7031 | |||
| 533fb9cc44 | |||
| 59b99d2d60 | |||
| c796daed7c | |||
| 6e2c385fa5 | |||
| 9a0e4e0176 | |||
| 640f8e0e82 | |||
| 4eb580790d | |||
| a2c83d754b | |||
| 6f946b20ec | |||
| 4dda90502a | |||
| dc6dbba47c | |||
| 2ceabad360 | |||
| a00aee1495 | |||
| 4e31c9984d | |||
| b8772a1e40 | |||
| 42990d8264 | |||
| cf31418555 | |||
| 5db72b8ad9 | |||
| fe8f8bcf7b | |||
| d4d737de8d | |||
| 52f6e96ee8 | |||
| 44fa7b0f6b | |||
| bda561df4e | |||
| 8955420baf | |||
| 21ee256911 | |||
| 4aba6fae78 | |||
| fe06bc2f88 | |||
| 8dfb4cd02f | |||
| d1ade37827 | |||
| 9de49241fb | |||
| b24d50160a | |||
| e46463e69f | |||
| a3157c9572 | |||
| 0d4722680a | |||
| 7ab12597bb | |||
| b86a46c83c | |||
| 187a0a3ec0 | |||
| 111c18dec3 | |||
| 7a2b137912 | |||
| 791b9fbe81 | |||
| 0fdc0257aa | |||
| b6a77c4413 | |||
| 33438850a6 | |||
| fcbb3d3783 | |||
| acc8640c1e | |||
| c083cfd65e | |||
| 4cea81f93f | |||
| 2d36be753a | |||
| 738d29eaa9 | |||
| b536fb67a4 | |||
| b10c23a950 | |||
| 85a5cf7cb1 | |||
| 192f5cd647 | |||
| 7dceee64fe | |||
| 8ad6ae71c6 | |||
| 3ea85a28cf | |||
| 273ecdb786 | |||
| de40eb7306 | |||
| b9c44073ce | |||
| d6e5947ad2 | |||
| 668651ee01 | |||
| fb1cacc10e | |||
| 735e56c26f | |||
| 97de3dccbb | |||
| 690467cbe2 | |||
| 71efd8ffda | |||
| 9bb196ae6e | |||
| ce75418e40 | |||
| 78c7f09e28 | |||
| e7269ac84e | |||
| 34866e20a8 | |||
| 3ae2bee272 | |||
| d0fb958e99 | |||
| b941c63a53 | |||
| cf70c3fb05 | |||
| f249e72162 | |||
| 92e0b62c6b | |||
| cf32a5b204 | |||
| 7b0e06c825 | |||
| 3158bf9093 | |||
| 01fade764c | |||
| 210c2419be | |||
| da05163d51 | |||
| f3e2bb5104 | |||
| 7a4c1086b5 | |||
| e89feb9635 | |||
| 5f72766c27 | |||
| 85ae57040d | |||
| d55a4a279f | |||
| bee9299693 | |||
| 9529fcec96 | |||
| bcec168e23 | |||
| 102a332616 | |||
| a280942f02 | |||
| 637dba5c2a | |||
| 24f292d081 | |||
| fa5c99e48a | |||
| 48f1a2c9b2 | |||
| 50ebbd63c6 | |||
| 4e5f63ff45 | |||
| de709e72a8 | |||
| 56d3c8f071 | |||
| ce89adecc1 | |||
| bc7a85063d | |||
| 0574f1e020 | |||
| f9fdd60e2e | |||
| 1c1eecabc0 | |||
| abd3fd004e | |||
| 15ee353488 | |||
| e75efbfd31 | |||
| 1c97a7ecb3 | |||
| fccd3e9fba | |||
| 4cb13b33e0 | |||
| 629802f2ab | |||
| afb1754528 | |||
| dbd67c6c89 | |||
| ed01bdb9dd | |||
| b54821d8ab | |||
| 89c6a79b6e | |||
| cd0412bddc | |||
| e42262f0f5 | |||
| 0a3eeab273 | |||
| e4e110e28f | |||
| 0726623389 | |||
| fd9d334d01 | |||
| 840eb14121 | |||
| 8fef196ee4 | |||
| 9c756f1ec0 | |||
| 4c29eea790 | |||
| 6dd2b4607f | |||
| 1e9ae88f53 | |||
| 5cc3902ab9 | |||
| c8e09e2d6d | |||
| e2a2ba116c | |||
| 0a9d24a218 | |||
| c222183669 | |||
| 140f9beee7 | |||
| 28ce892617 | |||
| 1e6d3ff99b | |||
| fba1b92cbf | |||
| ce1686379d | |||
| 79a20e9e33 | |||
| e9cd73f78e | |||
| 0be7f36d51 | |||
| 4c6cb6e359 | |||
| 82bde8d166 | |||
| 465392b618 | |||
| f3c6b9f05a | |||
| 2f1945eaf2 | |||
| b4d8a55b2a | |||
| 0e6ce8fa50 | |||
| a295c38ba3 | |||
| 295730ba1e | |||
| ac0d8f61c5 | |||
| b811588fa0 | |||
| 5fcdf0ff2b | |||
| 650b723da3 | |||
| 97920be33a | |||
| 58bbaa9e80 | |||
| 94f152730c | |||
| 535e3d4372 | |||
| 2ea43c8986 | |||
| 71fe2a5534 | |||
| f3ffcfd61e | |||
| bf27b28554 | |||
| 344602d27e | |||
| 64c483cf80 | |||
| 19091aacc7 | |||
| ef9028d798 | |||
| 1668cd19d3 | |||
| 134f268cee | |||
| c473633676 | |||
| 6a3a82007c | |||
| 1d6ef76cfb | |||
| c8e3959435 | |||
| 796f412a1e | |||
| fa854a2108 | |||
| 3a097ff2d2 | |||
| 8463bfc1e5 | |||
| 7a72b4c624 | |||
| 670c179417 | |||
| 1b1d868837 | |||
| d9704d02bb | |||
| 1349548367 | |||
| 18b1604fc8 | |||
| 0def7da5a8 | |||
| 4bb45c8252 | |||
| bb99b31eb0 | |||
| 84397183f3 | |||
| aeae265777 | |||
| a9c5df5da1 | |||
| 96576c4de9 | |||
| 9ec68e5829 | |||
| face857d5e | |||
| 85a1cc9b4f | |||
| 630501b93d | |||
| 8bbc2995ca | |||
| 7d3872df57 | |||
| 1ed228b92b | |||
| b605cd1bb9 | |||
| fea4e8e5b6 | |||
| 1df8b5785b | |||
| 981a75d7c9 | |||
| 11cc7014b3 | |||
| 0b667c88fa | |||
| 054ab1adaf | |||
| f1f8386f2e | |||
| ba8c3970b0 | |||
| 2f36b26a5c | |||
| 9b4edb3a1d | |||
| b8adc5ffa2 | |||
| bd90cafda7 | |||
| 6d43a08a1d | |||
| e71b8598ae | |||
| 95d0f437e3 | |||
| c95ee3968a | |||
| c22dd4ada5 | |||
| 727a40fc5a | |||
| ce84a5f1d3 | |||
| e6fda1c410 | |||
| 294dccc5be | |||
| da346a8878 | |||
| c5ccb995ad | |||
| 05ab569a80 | |||
| ab3f4971f0 | |||
| 47e238aa13 | |||
| e49b6c708b | |||
| eb7250792b | |||
| 7e5066b878 | |||
| 889e17816f | |||
| b1b9702daf | |||
| 32728d2f1d | |||
| 807a097387 | |||
| 794ee15386 | |||
| 2359417804 | |||
| 7950f3cdc5 | |||
| b87f8f35ee | |||
| 9e53405f43 | |||
| c6c1d8fa86 | |||
| 8aa5c2b45d | |||
| 414fd694c0 | |||
| 7e82809592 | |||
| 0dae5db30e | |||
| 5c24f0f0f3 | |||
| c2591e9b39 | |||
| 8ce0dee6da | |||
| 16daba8ea9 | |||
| 8b4074ee77 | |||
| 85fbd8793a | |||
| 65705e2091 | |||
| 385a385c62 |
@@ -1,7 +0,0 @@
|
||||
---
|
||||
name: Help or discussion
|
||||
about: This is the right place
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
schedule: [cron: "40 1 * * *"]
|
||||
|
||||
env:
|
||||
RUSTFLAGS: -Dwarnings
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test suite
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: dtolnay/rust-toolchain@nightly
|
||||
- run: cd test_suite && cargo test --features unstable
|
||||
|
||||
windows:
|
||||
name: Test suite (windows)
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: dtolnay/rust-toolchain@nightly
|
||||
- run: cd test_suite && cargo test --features unstable -- --skip ui --exact
|
||||
|
||||
stable:
|
||||
name: Rust ${{matrix.rust}}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
rust: [stable, beta]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: dtolnay/rust-toolchain@master
|
||||
with:
|
||||
toolchain: ${{matrix.rust}}
|
||||
- run: cd serde && cargo build --features rc
|
||||
- run: cd serde && cargo build --no-default-features
|
||||
- run: cd serde_test && cargo build
|
||||
- run: cd serde_test && cargo test --features serde/derive,serde/rc
|
||||
|
||||
nightly:
|
||||
name: Rust nightly ${{matrix.os == 'windows' && '(windows)' || ''}}
|
||||
runs-on: ${{matrix.os}}-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu, windows]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: dtolnay/rust-toolchain@nightly
|
||||
- run: cd serde && cargo build
|
||||
- run: cd serde && cargo build --no-default-features
|
||||
- run: cd serde && cargo build --no-default-features --features alloc
|
||||
- run: cd serde && cargo build --no-default-features --features rc,alloc
|
||||
- run: cd serde && cargo test --features derive,rc,unstable
|
||||
- run: cd test_suite/no_std && cargo build
|
||||
if: matrix.os != 'windows'
|
||||
|
||||
msrv:
|
||||
name: Rust 1.13.0
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: dtolnay/rust-toolchain@1.13.0
|
||||
- name: Get timestamp for cache
|
||||
id: date
|
||||
run: echo ::set-output name=yearmo::$(date +%Y%m)
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.cargo/registry/index
|
||||
key: cargo-registry-index-${{steps.date.outputs.yearmo}}
|
||||
- run: cd serde && cargo build --features rc
|
||||
- run: cd serde && cargo build --no-default-features
|
||||
- run: cd serde_test && cargo build
|
||||
|
||||
build:
|
||||
name: Rust ${{matrix.rust}}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
rust: [1.19.0, 1.20.0, 1.21.0, 1.25.0, 1.26.0, 1.34.0]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: dtolnay/rust-toolchain@master
|
||||
with:
|
||||
toolchain: ${{matrix.rust}}
|
||||
- run: cd serde && cargo build --no-default-features
|
||||
- run: cd serde && cargo build
|
||||
|
||||
more:
|
||||
name: Rust ${{matrix.rust}}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
rust: [1.27.0, 1.28.0]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: dtolnay/rust-toolchain@master
|
||||
with:
|
||||
toolchain: ${{matrix.rust}}
|
||||
# Work around failing to parse manifest because editions are unstable.
|
||||
- run: sed -i /test_suite/d Cargo.toml
|
||||
- run: cd serde && cargo build --no-default-features
|
||||
- run: cd serde && cargo build
|
||||
|
||||
derive:
|
||||
name: Rust 1.31.0
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: dtolnay/rust-toolchain@1.31.0
|
||||
- run: cd serde && cargo check --no-default-features
|
||||
- run: cd serde && cargo check
|
||||
- run: cd serde_derive && cargo check
|
||||
|
||||
alloc:
|
||||
name: Rust 1.36.0
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: dtolnay/rust-toolchain@1.36.0
|
||||
- run: cd serde && cargo build --no-default-features --features alloc
|
||||
|
||||
emscripten:
|
||||
name: Emscripten
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: dtolnay/rust-toolchain@nightly
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 9
|
||||
- name: Install cargo-web
|
||||
run: |
|
||||
CARGO_WEB_RELEASE=$(curl -L -s -H Accept:application/json https://github.com/koute/cargo-web/releases/latest)
|
||||
CARGO_WEB_VERSION=$(echo "${CARGO_WEB_RELEASE}" | jq -r .tag_name)
|
||||
CARGO_WEB_URL="https://github.com/koute/cargo-web/releases/download/${CARGO_WEB_VERSION}/cargo-web-x86_64-unknown-linux-gnu.gz"
|
||||
mkdir -p ~/.cargo/bin
|
||||
curl -L "${CARGO_WEB_URL}" | gzip -d > ~/.cargo/bin/cargo-web
|
||||
chmod +x ~/.cargo/bin/cargo-web
|
||||
- run: cd test_suite && cargo web test --target=asmjs-unknown-emscripten --nodejs
|
||||
continue-on-error: true
|
||||
- run: cd test_suite && cargo web test --target=wasm32-unknown-emscripten --nodejs
|
||||
continue-on-error: true
|
||||
|
||||
clippy:
|
||||
name: Clippy
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name != 'pull_request'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: dtolnay/rust-toolchain@clippy
|
||||
- run: cd serde && cargo clippy --features rc,unstable -- -Dclippy::all -Dclippy::pedantic
|
||||
- run: cd serde_derive && cargo clippy -- -Dclippy::all -Dclippy::pedantic
|
||||
- run: cd serde_derive_internals && cargo clippy -- -Dclippy::all -Dclippy::pedantic
|
||||
- run: cd serde_test && cargo clippy -- -Dclippy::all -Dclippy::pedantic
|
||||
- run: cd test_suite && cargo clippy --tests --features unstable -- -Dclippy::all -Dclippy::pedantic
|
||||
- run: cd test_suite/no_std && cargo clippy -- -Dclippy::all -Dclippy::pedantic
|
||||
-95
@@ -1,95 +0,0 @@
|
||||
language: rust
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- rust: stable
|
||||
script:
|
||||
- cd "${TRAVIS_BUILD_DIR}/serde"
|
||||
- cargo build --features rc
|
||||
- cargo build --no-default-features
|
||||
- cd "${TRAVIS_BUILD_DIR}/serde_test"
|
||||
- cargo build
|
||||
- cargo test
|
||||
|
||||
- rust: beta
|
||||
script:
|
||||
- cd "${TRAVIS_BUILD_DIR}/serde"
|
||||
- cargo build --features rc
|
||||
- cd "${TRAVIS_BUILD_DIR}/test_suite"
|
||||
- cargo test
|
||||
|
||||
- rust: nightly
|
||||
script:
|
||||
- cd "${TRAVIS_BUILD_DIR}/serde"
|
||||
- cargo build
|
||||
- cargo build --no-default-features
|
||||
- cargo build --no-default-features --features alloc
|
||||
- cargo build --no-default-features --features rc,alloc
|
||||
- cargo test --features rc,unstable
|
||||
- cd "${TRAVIS_BUILD_DIR}/test_suite/deps"
|
||||
- cargo build
|
||||
- cd "${TRAVIS_BUILD_DIR}/test_suite"
|
||||
- cargo test --features unstable
|
||||
- cd "${TRAVIS_BUILD_DIR}/test_suite/no_std"
|
||||
- cargo build
|
||||
|
||||
- rust: 1.13.0
|
||||
script:
|
||||
- cd "${TRAVIS_BUILD_DIR}/serde"
|
||||
- cargo build --features rc
|
||||
- cargo build --no-default-features
|
||||
- cd "${TRAVIS_BUILD_DIR}/serde_test"
|
||||
- cargo build
|
||||
|
||||
- rust: 1.15.0
|
||||
script:
|
||||
- cd "${TRAVIS_BUILD_DIR}/serde_derive"
|
||||
- cargo build
|
||||
|
||||
- rust: 1.20.0
|
||||
- rust: 1.21.0
|
||||
- rust: 1.25.0
|
||||
- rust: 1.26.0
|
||||
|
||||
- rust: nightly
|
||||
name: Clippy
|
||||
script:
|
||||
- rustup component add clippy-preview || travis_terminate 0
|
||||
- cargo clippy -- -Dclippy
|
||||
- cd "${TRAVIS_BUILD_DIR}/serde"
|
||||
- cargo clippy --features rc,unstable -- -Dclippy
|
||||
- cd "${TRAVIS_BUILD_DIR}/serde_derive"
|
||||
- cargo clippy -- -Dclippy
|
||||
- cd "${TRAVIS_BUILD_DIR}/serde_test"
|
||||
- cargo clippy -- -Dclippy
|
||||
- cd "${TRAVIS_BUILD_DIR}/test_suite"
|
||||
- cargo clippy --features unstable -- -Dclippy
|
||||
- cd "${TRAVIS_BUILD_DIR}/test_suite/no_std"
|
||||
- cargo clippy -- -Dclippy
|
||||
|
||||
- rust: nightly
|
||||
name: Emscripten
|
||||
script:
|
||||
- CARGO_WEB_RELEASE=$(curl -L -s -H Accept:application/json https://github.com/koute/cargo-web/releases/latest)
|
||||
- CARGO_WEB_VERSION=$(echo "${CARGO_WEB_RELEASE}" | jq -r .tag_name)
|
||||
- CARGO_WEB_URL="https://github.com/koute/cargo-web/releases/download/${CARGO_WEB_VERSION}/cargo-web-x86_64-unknown-linux-gnu.gz"
|
||||
|
||||
- nvm install 9
|
||||
- mkdir -p ~/.cargo/bin
|
||||
- curl -L "${CARGO_WEB_URL}" | gzip -d > ~/.cargo/bin/cargo-web
|
||||
- chmod +x ~/.cargo/bin/cargo-web
|
||||
|
||||
- cd "${TRAVIS_BUILD_DIR}/test_suite"
|
||||
- cargo web test --target=asmjs-unknown-emscripten --nodejs
|
||||
- cargo web test --target=wasm32-unknown-emscripten --nodejs
|
||||
|
||||
allow_failures:
|
||||
- rust: nightly
|
||||
name: Clippy
|
||||
- rust: nightly
|
||||
name: Emscripten
|
||||
|
||||
script:
|
||||
- cd "${TRAVIS_BUILD_DIR}/serde"
|
||||
- cargo build --no-default-features
|
||||
- cargo build
|
||||
+5
-16
@@ -4,11 +4,6 @@ Serde welcomes contribution from everyone in the form of suggestions, bug
|
||||
reports, pull requests, and feedback. This document gives some guidance if you
|
||||
are thinking of helping us.
|
||||
|
||||
Please reach out here in a GitHub issue or in the #serde IRC channel on
|
||||
[`irc.mozilla.org`] if we can do anything to help you contribute.
|
||||
|
||||
[`irc.mozilla.org`]: https://wiki.mozilla.org/IRC
|
||||
|
||||
## Submitting bug reports and feature requests
|
||||
|
||||
Serde development is spread across lots of repositories, but this serde-rs/serde
|
||||
@@ -36,25 +31,19 @@ tests for you.
|
||||
|
||||
```sh
|
||||
# Test all the example code in Serde documentation
|
||||
cargo test
|
||||
```
|
||||
|
||||
##### In the [`test_suite/deps`] directory
|
||||
|
||||
```sh
|
||||
# This is a prerequisite for running the full test suite
|
||||
cargo clean && cargo update && cargo build
|
||||
cargo test --features derive
|
||||
```
|
||||
|
||||
##### In the [`test_suite`] directory
|
||||
|
||||
```sh
|
||||
# Run the full test suite, including tests of unstable functionality
|
||||
cargo test --features unstable
|
||||
cargo +nightly test --features unstable
|
||||
```
|
||||
|
||||
Note that this test suite currently only supports running on a nightly compiler.
|
||||
|
||||
[`serde`]: https://github.com/serde-rs/serde/tree/master/serde
|
||||
[`test_suite/deps`]: https://github.com/serde-rs/serde/tree/master/test_suite/deps
|
||||
[`test_suite`]: https://github.com/serde-rs/serde/tree/master/test_suite
|
||||
|
||||
## Conduct
|
||||
@@ -63,4 +52,4 @@ In all Serde-related forums, we follow the [Rust Code of Conduct]. For
|
||||
escalation or moderation issues please contact Erick (erick.tryzelaar@gmail.com)
|
||||
instead of the Rust moderation team.
|
||||
|
||||
[Rust Code of Conduct]: https://www.rust-lang.org/conduct.html
|
||||
[Rust Code of Conduct]: https://www.rust-lang.org/policies/code-of-conduct
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
# Serde   [![Build Status]][travis] [![Latest Version]][crates.io] [![Rustc Version 1.13+]][rustc]
|
||||
# Serde   [![Build Status]][actions] [![Latest Version]][crates.io] [![serde: rustc 1.13+]][Rust 1.13] [![serde_derive: rustc 1.31+]][Rust 1.31]
|
||||
|
||||
[Build Status]: https://api.travis-ci.org/serde-rs/serde.svg?branch=master
|
||||
[travis]: https://travis-ci.org/serde-rs/serde
|
||||
[Build Status]: https://img.shields.io/github/workflow/status/serde-rs/serde/CI/master
|
||||
[actions]: https://github.com/serde-rs/serde/actions?query=branch%3Amaster
|
||||
[Latest Version]: https://img.shields.io/crates/v/serde.svg
|
||||
[crates.io]: https://crates.io/crates/serde
|
||||
[Rustc Version 1.13+]: https://img.shields.io/badge/rustc-1.13+-lightgray.svg
|
||||
[rustc]: https://blog.rust-lang.org/2016/11/10/Rust-1.13.html
|
||||
[serde: rustc 1.13+]: https://img.shields.io/badge/serde-rustc_1.13+-lightgray.svg
|
||||
[serde_derive: rustc 1.31+]: https://img.shields.io/badge/serde_derive-rustc_1.31+-lightgray.svg
|
||||
[Rust 1.13]: https://blog.rust-lang.org/2016/11/10/Rust-1.13.html
|
||||
[Rust 1.31]: https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html
|
||||
|
||||
**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.**
|
||||
|
||||
@@ -25,19 +27,17 @@ You may be looking for:
|
||||
<details>
|
||||
<summary>
|
||||
Click to show Cargo.toml.
|
||||
<a href="https://play.rust-lang.org/?gist=9003c5b88c1f4989941925d7190c6eec" target="_blank">Run this code in the playground.</a>
|
||||
<a href="https://play.rust-lang.org/?edition=2018&gist=72755f28f99afc95e01d63174b28c1f5" target="_blank">Run this code in the playground.</a>
|
||||
</summary>
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
|
||||
# The core APIs, including the Serialize and Deserialize traits. Always
|
||||
# required when using Serde.
|
||||
serde = "1.0"
|
||||
|
||||
# Support for #[derive(Serialize, Deserialize)]. Required if you want Serde
|
||||
# to work for structs and enums defined in your crate.
|
||||
serde_derive = "1.0"
|
||||
# required when using Serde. The "derive" feature is only required when
|
||||
# using #[derive(Serialize, Deserialize)] to make Serde work with structs
|
||||
# and enums defined in your crate.
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
# Each data format lives in its own crate; the sample code below uses JSON
|
||||
# but you may be using a different one.
|
||||
@@ -48,11 +48,7 @@ serde_json = "1.0"
|
||||
<p></p>
|
||||
|
||||
```rust
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
extern crate serde;
|
||||
extern crate serde_json;
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
struct Point {
|
||||
@@ -79,27 +75,40 @@ fn main() {
|
||||
|
||||
## Getting help
|
||||
|
||||
Serde developers live in the #serde channel on [`irc.mozilla.org`][irc]. The
|
||||
\#rust channel is also a good resource with generally faster response time but
|
||||
less specific knowledge about Serde. If IRC is not your thing or you don't get a
|
||||
good response, we are happy to respond to [GitHub issues][issues] as well.
|
||||
Serde is one of the most widely used Rust libraries so any place that Rustaceans
|
||||
congregate will be able to help you out. For chat, consider trying the
|
||||
[#rust-questions] or [#rust-beginners] channels of the unofficial community
|
||||
Discord (invite: <https://discord.gg/rust-lang-community>), the [#rust-usage] or
|
||||
[#beginners] channels of the official Rust Project Discord (invite:
|
||||
<https://discord.gg/rust-lang>), or the [#general][zulip] stream in Zulip. For
|
||||
asynchronous, consider the [\[rust\] tag on StackOverflow][stackoverflow], the
|
||||
[/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust
|
||||
[Discourse forum][discourse]. It's acceptable to file a support issue in this
|
||||
repo but they tend not to get as many eyes as any of the above and may get
|
||||
closed without a response after some time.
|
||||
|
||||
[irc]: https://wiki.mozilla.org/IRC
|
||||
[issues]: https://github.com/serde-rs/serde/issues/new/choose
|
||||
[#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513
|
||||
[#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281
|
||||
[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848
|
||||
[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612
|
||||
[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general
|
||||
[stackoverflow]: https://stackoverflow.com/questions/tagged/rust
|
||||
[/r/rust]: https://www.reddit.com/r/rust
|
||||
[discourse]: https://users.rust-lang.org
|
||||
|
||||
## License
|
||||
<br>
|
||||
|
||||
Serde is licensed under either of
|
||||
#### License
|
||||
|
||||
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
||||
http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* MIT license ([LICENSE-MIT](LICENSE-MIT) or
|
||||
http://opensource.org/licenses/MIT)
|
||||
<sup>
|
||||
Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
|
||||
2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
|
||||
</sup>
|
||||
|
||||
at your option.
|
||||
|
||||
### Contribution
|
||||
<br>
|
||||
|
||||
<sub>
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted
|
||||
for inclusion in Serde by you, as defined in the Apache-2.0 license, shall be
|
||||
dual licensed as above, without any additional terms or conditions.
|
||||
</sub>
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
environment:
|
||||
matrix:
|
||||
- APPVEYOR_RUST_CHANNEL: stable
|
||||
- APPVEYOR_RUST_CHANNEL: nightly
|
||||
|
||||
install:
|
||||
# Install rust, x86_64-pc-windows-msvc host
|
||||
- curl -sSf -o rustup-init.exe https://win.rustup.rs/
|
||||
- rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain %APPVEYOR_RUST_CHANNEL%
|
||||
- set PATH=C:\msys64\usr\bin;%PATH%;C:\Users\appveyor\.cargo\bin
|
||||
- rustc -vV
|
||||
- cargo -vV
|
||||
|
||||
build: false
|
||||
|
||||
for:
|
||||
- matrix:
|
||||
only:
|
||||
- APPVEYOR_RUST_CHANNEL: stable
|
||||
test_script:
|
||||
- cd %APPVEYOR_BUILD_FOLDER%\serde
|
||||
- cargo build --features rc
|
||||
- cargo build --no-default-features
|
||||
- cd %APPVEYOR_BUILD_FOLDER%\serde_test
|
||||
- cargo build
|
||||
- cargo test
|
||||
|
||||
- matrix:
|
||||
only:
|
||||
- APPVEYOR_RUST_CHANNEL: nightly
|
||||
test_script:
|
||||
- cd %APPVEYOR_BUILD_FOLDER%\serde
|
||||
- cargo build
|
||||
- cargo build --no-default-features
|
||||
- cargo build --no-default-features --features alloc
|
||||
- cargo build --no-default-features --features rc,alloc
|
||||
- cargo test --features rc,unstable
|
||||
- cd %APPVEYOR_BUILD_FOLDER%\test_suite\deps
|
||||
- cargo build
|
||||
- cd %APPVEYOR_BUILD_FOLDER%\test_suite
|
||||
- cargo test --features unstable
|
||||
+20
-11
@@ -16,11 +16,7 @@ You may be looking for:
|
||||
## Serde in action
|
||||
|
||||
```rust
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
extern crate serde;
|
||||
extern crate serde_json;
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
struct Point {
|
||||
@@ -47,10 +43,23 @@ fn main() {
|
||||
|
||||
## Getting help
|
||||
|
||||
Serde developers live in the #serde channel on [`irc.mozilla.org`][irc]. The
|
||||
\#rust channel is also a good resource with generally faster response time but
|
||||
less specific knowledge about Serde. If IRC is not your thing or you don't get a
|
||||
good response, we are happy to respond to [GitHub issues][issues] as well.
|
||||
Serde is one of the most widely used Rust libraries so any place that Rustaceans
|
||||
congregate will be able to help you out. For chat, consider trying the
|
||||
[#rust-questions] or [#rust-beginners] channels of the unofficial community
|
||||
Discord (invite: <https://discord.gg/rust-lang-community>, the [#rust-usage] or
|
||||
[#beginners] channels of the official Rust Project Discord (invite:
|
||||
<https://discord.gg/rust-lang>), or the [#general][zulip] stream in Zulip. For
|
||||
asynchronous, consider the [\[rust\] tag on StackOverflow][stackoverflow], the
|
||||
[/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust
|
||||
[Discourse forum][discourse]. It's acceptable to file a support issue in this
|
||||
repo but they tend not to get as many eyes as any of the above and may get
|
||||
closed without a response after some time.
|
||||
|
||||
[irc]: https://wiki.mozilla.org/IRC
|
||||
[issues]: https://github.com/serde-rs/serde/issues/new/choose
|
||||
[#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513
|
||||
[#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281
|
||||
[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848
|
||||
[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612
|
||||
[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general
|
||||
[stackoverflow]: https://stackoverflow.com/questions/tagged/rust
|
||||
[/r/rust]: https://www.reddit.com/r/rust
|
||||
[discourse]: https://users.rust-lang.org
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
error_on_line_overflow = false
|
||||
+13
-37
@@ -1,8 +1,9 @@
|
||||
[package]
|
||||
name = "serde"
|
||||
version = "1.0.81" # remember to update html_root_url
|
||||
version = "1.0.135" # remember to update html_root_url and serde_derive dependency
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
rust-version = "1.15"
|
||||
license = "MIT OR Apache-2.0"
|
||||
description = "A generic serialization/deserialization framework"
|
||||
homepage = "https://serde.rs"
|
||||
repository = "https://github.com/serde-rs/serde"
|
||||
@@ -10,49 +11,28 @@ documentation = "https://docs.serde.rs/serde/"
|
||||
keywords = ["serde", "serialization", "no_std"]
|
||||
categories = ["encoding"]
|
||||
readme = "crates-io.md"
|
||||
include = ["Cargo.toml", "build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
include = ["build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
build = "build.rs"
|
||||
|
||||
[badges]
|
||||
travis-ci = { repository = "serde-rs/serde" }
|
||||
appveyor = { repository = "serde-rs/serde" }
|
||||
|
||||
[dependencies]
|
||||
serde_derive = { version = "1.0", optional = true, path = "../serde_derive" }
|
||||
serde_derive = { version = "=1.0.135", optional = true, path = "../serde_derive" }
|
||||
|
||||
[dev-dependencies]
|
||||
serde_derive = { version = "1.0", path = "../serde_derive" }
|
||||
|
||||
[package.metadata.playground]
|
||||
features = ["derive", "rc"]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
||||
|
||||
### FEATURES #################################################################
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
|
||||
# Re-export the derive(Serialize, Deserialize) macros. This is intended for
|
||||
# library crates that provide optional Serde impls behind a Cargo cfg of their
|
||||
# own.
|
||||
#
|
||||
# Mainly this is a workaround for limitations associated with
|
||||
# rust-lang/cargo#1286 in which a library crate cannot use one "serde" cfg in
|
||||
# Cargo to enable dependencies on both serde and serde_derive crates.
|
||||
#
|
||||
# The recommended way to provide optional Serde support that requires derive is
|
||||
# as follows. In particular, please do not name your library's Serde feature
|
||||
# anything other than "serde".
|
||||
#
|
||||
# [dependencies]
|
||||
# serde = { version = "1.0", optional = true, features = ["derive"] }
|
||||
#
|
||||
# Within the library, these optional Serde derives would be written like this.
|
||||
#
|
||||
# #[cfg(feature = "serde")]
|
||||
# #[macro_use]
|
||||
# extern crate serde;
|
||||
#
|
||||
# #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
# struct ...
|
||||
#
|
||||
# Provide derive(Serialize, Deserialize) macros.
|
||||
derive = ["serde_derive"]
|
||||
|
||||
# Provide impls for common standard library types like Vec<T> and HashMap<K, V>.
|
||||
@@ -68,11 +48,7 @@ unstable = []
|
||||
# Provide impls for types in the Rust core allocation and collections library
|
||||
# including String, Box<T>, Vec<T>, and Cow<T>. This is a subset of std but may
|
||||
# be enabled without depending on all of std.
|
||||
#
|
||||
# Requires a dependency on the unstable core allocation library:
|
||||
#
|
||||
# https://doc.rust-lang.org/alloc/
|
||||
alloc = ["unstable"]
|
||||
alloc = []
|
||||
|
||||
# Opt into impls for Rc<T> and Arc<T>. Serializing and deserializing these types
|
||||
# does not preserve identity and may result in multiple copies of the same data.
|
||||
|
||||
+71
-16
@@ -14,44 +14,99 @@ fn main() {
|
||||
let target = env::var("TARGET").unwrap();
|
||||
let emscripten = target == "asmjs-unknown-emscripten" || target == "wasm32-unknown-emscripten";
|
||||
|
||||
// CString::into_boxed_c_str stabilized in Rust 1.20:
|
||||
// std::collections::Bound was stabilized in Rust 1.17
|
||||
// but it was moved to core::ops later in Rust 1.26:
|
||||
// https://doc.rust-lang.org/core/ops/enum.Bound.html
|
||||
if minor < 26 {
|
||||
println!("cargo:rustc-cfg=no_ops_bound");
|
||||
if minor < 17 {
|
||||
println!("cargo:rustc-cfg=no_collections_bound");
|
||||
}
|
||||
}
|
||||
|
||||
// core::cmp::Reverse stabilized in Rust 1.19:
|
||||
// https://doc.rust-lang.org/stable/core/cmp/struct.Reverse.html
|
||||
if minor < 19 {
|
||||
println!("cargo:rustc-cfg=no_core_reverse");
|
||||
}
|
||||
|
||||
// CString::into_boxed_c_str and PathBuf::into_boxed_path stabilized in Rust 1.20:
|
||||
// https://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_boxed_c_str
|
||||
if minor >= 20 {
|
||||
println!("cargo:rustc-cfg=de_boxed_c_str");
|
||||
// https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.into_boxed_path
|
||||
if minor < 20 {
|
||||
println!("cargo:rustc-cfg=no_de_boxed_c_str");
|
||||
println!("cargo:rustc-cfg=no_de_boxed_path");
|
||||
}
|
||||
|
||||
// From<Box<T>> for Rc<T> / Arc<T> stabilized in Rust 1.21:
|
||||
// https://doc.rust-lang.org/std/rc/struct.Rc.html#impl-From<Box<T>>
|
||||
// https://doc.rust-lang.org/std/sync/struct.Arc.html#impl-From<Box<T>>
|
||||
if minor >= 21 {
|
||||
println!("cargo:rustc-cfg=de_rc_dst");
|
||||
if minor < 21 {
|
||||
println!("cargo:rustc-cfg=no_de_rc_dst");
|
||||
}
|
||||
|
||||
// Duration available in core since Rust 1.25:
|
||||
// https://blog.rust-lang.org/2018/03/29/Rust-1.25.html#library-stabilizations
|
||||
if minor >= 25 {
|
||||
println!("cargo:rustc-cfg=core_duration");
|
||||
if minor < 25 {
|
||||
println!("cargo:rustc-cfg=no_core_duration");
|
||||
}
|
||||
|
||||
// 128-bit integers stabilized in Rust 1.26:
|
||||
// https://blog.rust-lang.org/2018/05/10/Rust-1.26.html
|
||||
//
|
||||
// Disabled on Emscripten targets as Emscripten doesn't
|
||||
// currently support integers larger than 64 bits.
|
||||
if minor >= 26 && !emscripten {
|
||||
println!("cargo:rustc-cfg=integer128");
|
||||
// Disabled on Emscripten targets before Rust 1.40 since
|
||||
// Emscripten did not support 128-bit integers until Rust 1.40
|
||||
// (https://github.com/rust-lang/rust/pull/65251)
|
||||
if minor < 26 || emscripten && minor < 40 {
|
||||
println!("cargo:rustc-cfg=no_integer128");
|
||||
}
|
||||
|
||||
// Inclusive ranges methods stabilized in Rust 1.27:
|
||||
// https://github.com/rust-lang/rust/pull/50758
|
||||
if minor >= 27 {
|
||||
println!("cargo:rustc-cfg=range_inclusive");
|
||||
// Also Iterator::try_for_each:
|
||||
// https://blog.rust-lang.org/2018/06/21/Rust-1.27.html#library-stabilizations
|
||||
if minor < 27 {
|
||||
println!("cargo:rustc-cfg=no_range_inclusive");
|
||||
println!("cargo:rustc-cfg=no_iterator_try_fold");
|
||||
}
|
||||
|
||||
// Non-zero integers stabilized in Rust 1.28:
|
||||
// https://github.com/rust-lang/rust/pull/50808
|
||||
if minor >= 28 {
|
||||
println!("cargo:rustc-cfg=num_nonzero");
|
||||
// https://blog.rust-lang.org/2018/08/02/Rust-1.28.html#library-stabilizations
|
||||
if minor < 28 {
|
||||
println!("cargo:rustc-cfg=no_num_nonzero");
|
||||
}
|
||||
|
||||
// Current minimum supported version of serde_derive crate is Rust 1.31.
|
||||
if minor < 31 {
|
||||
println!("cargo:rustc-cfg=no_serde_derive");
|
||||
}
|
||||
|
||||
// TryFrom, Atomic types, non-zero signed integers, and SystemTime::checked_add
|
||||
// stabilized in Rust 1.34:
|
||||
// https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#tryfrom-and-tryinto
|
||||
// https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#library-stabilizations
|
||||
if minor < 34 {
|
||||
println!("cargo:rustc-cfg=no_core_try_from");
|
||||
println!("cargo:rustc-cfg=no_num_nonzero_signed");
|
||||
println!("cargo:rustc-cfg=no_systemtime_checked_add");
|
||||
}
|
||||
|
||||
// Whitelist of archs that support std::sync::atomic module. Ideally we
|
||||
// would use #[cfg(target_has_atomic = "...")] but it is not stable yet.
|
||||
// Instead this is based on rustc's compiler/rustc_target/src/spec/*.rs.
|
||||
let has_atomic64 = target.starts_with("x86_64")
|
||||
|| target.starts_with("i686")
|
||||
|| target.starts_with("aarch64")
|
||||
|| target.starts_with("powerpc64")
|
||||
|| target.starts_with("sparc64")
|
||||
|| target.starts_with("mips64el")
|
||||
|| target.starts_with("riscv64");
|
||||
let has_atomic32 = has_atomic64 || emscripten;
|
||||
if minor < 34 || !has_atomic64 {
|
||||
println!("cargo:rustc-cfg=no_std_atomic64");
|
||||
}
|
||||
if minor < 34 || !has_atomic32 {
|
||||
println!("cargo:rustc-cfg=no_std_atomic");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,260 +0,0 @@
|
||||
use lib::*;
|
||||
|
||||
macro_rules! int_to_int {
|
||||
($dst:ident, $n:ident) => {
|
||||
if $dst::min_value() as i64 <= $n as i64 && $n as i64 <= $dst::max_value() as i64 {
|
||||
Some($n as $dst)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! int_to_uint {
|
||||
($dst:ident, $n:ident) => {
|
||||
if 0 <= $n && $n as u64 <= $dst::max_value() as u64 {
|
||||
Some($n as $dst)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! uint_to {
|
||||
($dst:ident, $n:ident) => {
|
||||
if $n as u64 <= $dst::max_value() as u64 {
|
||||
Some($n as $dst)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub trait FromPrimitive: Sized {
|
||||
fn from_i8(n: i8) -> Option<Self>;
|
||||
fn from_i16(n: i16) -> Option<Self>;
|
||||
fn from_i32(n: i32) -> Option<Self>;
|
||||
fn from_i64(n: i64) -> Option<Self>;
|
||||
fn from_u8(n: u8) -> Option<Self>;
|
||||
fn from_u16(n: u16) -> Option<Self>;
|
||||
fn from_u32(n: u32) -> Option<Self>;
|
||||
fn from_u64(n: u64) -> Option<Self>;
|
||||
}
|
||||
|
||||
macro_rules! impl_from_primitive_for_int {
|
||||
($t:ident) => {
|
||||
impl FromPrimitive for $t {
|
||||
#[inline]
|
||||
fn from_i8(n: i8) -> Option<Self> {
|
||||
int_to_int!($t, n)
|
||||
}
|
||||
#[inline]
|
||||
fn from_i16(n: i16) -> Option<Self> {
|
||||
int_to_int!($t, n)
|
||||
}
|
||||
#[inline]
|
||||
fn from_i32(n: i32) -> Option<Self> {
|
||||
int_to_int!($t, n)
|
||||
}
|
||||
#[inline]
|
||||
fn from_i64(n: i64) -> Option<Self> {
|
||||
int_to_int!($t, n)
|
||||
}
|
||||
#[inline]
|
||||
fn from_u8(n: u8) -> Option<Self> {
|
||||
uint_to!($t, n)
|
||||
}
|
||||
#[inline]
|
||||
fn from_u16(n: u16) -> Option<Self> {
|
||||
uint_to!($t, n)
|
||||
}
|
||||
#[inline]
|
||||
fn from_u32(n: u32) -> Option<Self> {
|
||||
uint_to!($t, n)
|
||||
}
|
||||
#[inline]
|
||||
fn from_u64(n: u64) -> Option<Self> {
|
||||
uint_to!($t, n)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_from_primitive_for_uint {
|
||||
($t:ident) => {
|
||||
impl FromPrimitive for $t {
|
||||
#[inline]
|
||||
fn from_i8(n: i8) -> Option<Self> {
|
||||
int_to_uint!($t, n)
|
||||
}
|
||||
#[inline]
|
||||
fn from_i16(n: i16) -> Option<Self> {
|
||||
int_to_uint!($t, n)
|
||||
}
|
||||
#[inline]
|
||||
fn from_i32(n: i32) -> Option<Self> {
|
||||
int_to_uint!($t, n)
|
||||
}
|
||||
#[inline]
|
||||
fn from_i64(n: i64) -> Option<Self> {
|
||||
int_to_uint!($t, n)
|
||||
}
|
||||
#[inline]
|
||||
fn from_u8(n: u8) -> Option<Self> {
|
||||
uint_to!($t, n)
|
||||
}
|
||||
#[inline]
|
||||
fn from_u16(n: u16) -> Option<Self> {
|
||||
uint_to!($t, n)
|
||||
}
|
||||
#[inline]
|
||||
fn from_u32(n: u32) -> Option<Self> {
|
||||
uint_to!($t, n)
|
||||
}
|
||||
#[inline]
|
||||
fn from_u64(n: u64) -> Option<Self> {
|
||||
uint_to!($t, n)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_from_primitive_for_float {
|
||||
($t:ident) => {
|
||||
impl FromPrimitive for $t {
|
||||
#[inline]
|
||||
fn from_i8(n: i8) -> Option<Self> {
|
||||
Some(n as Self)
|
||||
}
|
||||
#[inline]
|
||||
fn from_i16(n: i16) -> Option<Self> {
|
||||
Some(n as Self)
|
||||
}
|
||||
#[inline]
|
||||
fn from_i32(n: i32) -> Option<Self> {
|
||||
Some(n as Self)
|
||||
}
|
||||
#[inline]
|
||||
fn from_i64(n: i64) -> Option<Self> {
|
||||
Some(n as Self)
|
||||
}
|
||||
#[inline]
|
||||
fn from_u8(n: u8) -> Option<Self> {
|
||||
Some(n as Self)
|
||||
}
|
||||
#[inline]
|
||||
fn from_u16(n: u16) -> Option<Self> {
|
||||
Some(n as Self)
|
||||
}
|
||||
#[inline]
|
||||
fn from_u32(n: u32) -> Option<Self> {
|
||||
Some(n as Self)
|
||||
}
|
||||
#[inline]
|
||||
fn from_u64(n: u64) -> Option<Self> {
|
||||
Some(n as Self)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_from_primitive_for_int!(isize);
|
||||
impl_from_primitive_for_int!(i8);
|
||||
impl_from_primitive_for_int!(i16);
|
||||
impl_from_primitive_for_int!(i32);
|
||||
impl_from_primitive_for_int!(i64);
|
||||
impl_from_primitive_for_uint!(usize);
|
||||
impl_from_primitive_for_uint!(u8);
|
||||
impl_from_primitive_for_uint!(u16);
|
||||
impl_from_primitive_for_uint!(u32);
|
||||
impl_from_primitive_for_uint!(u64);
|
||||
impl_from_primitive_for_float!(f32);
|
||||
impl_from_primitive_for_float!(f64);
|
||||
|
||||
serde_if_integer128! {
|
||||
impl FromPrimitive for i128 {
|
||||
#[inline]
|
||||
fn from_i8(n: i8) -> Option<Self> {
|
||||
Some(n as i128)
|
||||
}
|
||||
#[inline]
|
||||
fn from_i16(n: i16) -> Option<Self> {
|
||||
Some(n as i128)
|
||||
}
|
||||
#[inline]
|
||||
fn from_i32(n: i32) -> Option<Self> {
|
||||
Some(n as i128)
|
||||
}
|
||||
#[inline]
|
||||
fn from_i64(n: i64) -> Option<Self> {
|
||||
Some(n as i128)
|
||||
}
|
||||
#[inline]
|
||||
fn from_u8(n: u8) -> Option<Self> {
|
||||
Some(n as i128)
|
||||
}
|
||||
#[inline]
|
||||
fn from_u16(n: u16) -> Option<Self> {
|
||||
Some(n as i128)
|
||||
}
|
||||
#[inline]
|
||||
fn from_u32(n: u32) -> Option<Self> {
|
||||
Some(n as i128)
|
||||
}
|
||||
#[inline]
|
||||
fn from_u64(n: u64) -> Option<Self> {
|
||||
Some(n as i128)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromPrimitive for u128 {
|
||||
#[inline]
|
||||
fn from_i8(n: i8) -> Option<Self> {
|
||||
if n >= 0 {
|
||||
Some(n as u128)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn from_i16(n: i16) -> Option<Self> {
|
||||
if n >= 0 {
|
||||
Some(n as u128)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn from_i32(n: i32) -> Option<Self> {
|
||||
if n >= 0 {
|
||||
Some(n as u128)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn from_i64(n: i64) -> Option<Self> {
|
||||
if n >= 0 {
|
||||
Some(n as u128)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn from_u8(n: u8) -> Option<Self> {
|
||||
Some(n as u128)
|
||||
}
|
||||
#[inline]
|
||||
fn from_u16(n: u16) -> Option<Self> {
|
||||
Some(n as u128)
|
||||
}
|
||||
#[inline]
|
||||
fn from_u32(n: u32) -> Option<Self> {
|
||||
Some(n as u128)
|
||||
}
|
||||
#[inline]
|
||||
fn from_u64(n: u64) -> Option<Self> {
|
||||
Some(n as u128)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
use lib::*;
|
||||
|
||||
use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
|
||||
use de::{
|
||||
Deserialize, Deserializer, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor,
|
||||
};
|
||||
|
||||
/// An efficient way of discarding data from a deserializer.
|
||||
///
|
||||
@@ -8,7 +10,7 @@ use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
|
||||
/// any type, except that it does not store any information about the data that
|
||||
/// gets deserialized.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// use std::fmt;
|
||||
/// use std::marker::PhantomData;
|
||||
///
|
||||
@@ -21,7 +23,7 @@ use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
|
||||
/// ///
|
||||
/// /// For example to deserialize only the element at index 3:
|
||||
/// ///
|
||||
/// /// ```rust
|
||||
/// /// ```
|
||||
/// /// NthElement::new(3).deserialize(deserializer)
|
||||
/// /// ```
|
||||
/// pub struct NthElement<T> {
|
||||
@@ -128,12 +130,28 @@ impl<'de> Visitor<'de> for IgnoredAny {
|
||||
Ok(IgnoredAny)
|
||||
}
|
||||
|
||||
serde_if_integer128! {
|
||||
#[inline]
|
||||
fn visit_i128<E>(self, x: i128) -> Result<Self::Value, E> {
|
||||
let _ = x;
|
||||
Ok(IgnoredAny)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_u64<E>(self, x: u64) -> Result<Self::Value, E> {
|
||||
let _ = x;
|
||||
Ok(IgnoredAny)
|
||||
}
|
||||
|
||||
serde_if_integer128! {
|
||||
#[inline]
|
||||
fn visit_u128<E>(self, x: u128) -> Result<Self::Value, E> {
|
||||
let _ = x;
|
||||
Ok(IgnoredAny)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_f64<E>(self, x: f64) -> Result<Self::Value, E> {
|
||||
let _ = x;
|
||||
@@ -205,6 +223,13 @@ impl<'de> Visitor<'de> for IgnoredAny {
|
||||
let _ = bytes;
|
||||
Ok(IgnoredAny)
|
||||
}
|
||||
|
||||
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: EnumAccess<'de>,
|
||||
{
|
||||
data.variant::<IgnoredAny>()?.1.newtype_variant()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for IgnoredAny {
|
||||
|
||||
+605
-312
File diff suppressed because it is too large
Load Diff
+68
-45
@@ -59,13 +59,13 @@
|
||||
//! - Box\<T\>
|
||||
//! - Box\<\[T\]\>
|
||||
//! - Box\<str\>
|
||||
//! - Rc\<T\>
|
||||
//! - Arc\<T\>
|
||||
//! - Cow\<'a, T\>
|
||||
//! - Cell\<T\>
|
||||
//! - RefCell\<T\>
|
||||
//! - Mutex\<T\>
|
||||
//! - RwLock\<T\>
|
||||
//! - Rc\<T\> *(if* features = ["rc"] *is enabled)*
|
||||
//! - Arc\<T\> *(if* features = ["rc"] *is enabled)*
|
||||
//! - **Collection types**:
|
||||
//! - BTreeMap\<K, V\>
|
||||
//! - BTreeSet\<T\>
|
||||
@@ -89,6 +89,7 @@
|
||||
//! - PathBuf
|
||||
//! - Range\<T\>
|
||||
//! - RangeInclusive\<T\>
|
||||
//! - Bound\<T\>
|
||||
//! - num::NonZero*
|
||||
//! - `!` *(unstable)*
|
||||
//! - **Net types**:
|
||||
@@ -103,7 +104,7 @@
|
||||
//! [`Deserialize`]: ../trait.Deserialize.html
|
||||
//! [`Deserializer`]: ../trait.Deserializer.html
|
||||
//! [`LinkedHashMap<K, V>`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html
|
||||
//! [`bincode`]: https://github.com/TyOverby/bincode
|
||||
//! [`bincode`]: https://github.com/servo/bincode
|
||||
//! [`linked-hash-map`]: https://crates.io/crates/linked-hash-map
|
||||
//! [`serde_derive`]: https://crates.io/crates/serde_derive
|
||||
//! [`serde_json`]: https://github.com/serde-rs/json
|
||||
@@ -117,13 +118,19 @@ use lib::*;
|
||||
|
||||
pub mod value;
|
||||
|
||||
mod from_primitive;
|
||||
mod ignored_any;
|
||||
mod impls;
|
||||
mod utf8;
|
||||
|
||||
pub use self::ignored_any::IgnoredAny;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[doc(no_inline)]
|
||||
pub use std::error::Error as StdError;
|
||||
#[cfg(not(feature = "std"))]
|
||||
#[doc(no_inline)]
|
||||
pub use std_error::Error as StdError;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
macro_rules! declare_error_trait {
|
||||
@@ -153,7 +160,7 @@ macro_rules! declare_error_trait {
|
||||
///
|
||||
/// The message should not be capitalized and should not end with a period.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use std::str::FromStr;
|
||||
/// #
|
||||
/// # struct IpAddr;
|
||||
@@ -173,7 +180,7 @@ macro_rules! declare_error_trait {
|
||||
/// where
|
||||
/// D: Deserializer<'de>,
|
||||
/// {
|
||||
/// let s = try!(String::deserialize(deserializer));
|
||||
/// let s = String::deserialize(deserializer)?;
|
||||
/// s.parse().map_err(de::Error::custom)
|
||||
/// }
|
||||
/// }
|
||||
@@ -237,12 +244,16 @@ macro_rules! declare_error_trait {
|
||||
#[cold]
|
||||
fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self {
|
||||
if expected.is_empty() {
|
||||
Error::custom(format_args!("unknown variant `{}`, there are no variants",
|
||||
variant))
|
||||
Error::custom(format_args!(
|
||||
"unknown variant `{}`, there are no variants",
|
||||
variant
|
||||
))
|
||||
} else {
|
||||
Error::custom(format_args!("unknown variant `{}`, expected {}",
|
||||
variant,
|
||||
OneOf { names: expected }))
|
||||
Error::custom(format_args!(
|
||||
"unknown variant `{}`, expected {}",
|
||||
variant,
|
||||
OneOf { names: expected }
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,12 +262,16 @@ macro_rules! declare_error_trait {
|
||||
#[cold]
|
||||
fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self {
|
||||
if expected.is_empty() {
|
||||
Error::custom(format_args!("unknown field `{}`, there are no fields",
|
||||
field))
|
||||
Error::custom(format_args!(
|
||||
"unknown field `{}`, there are no fields",
|
||||
field
|
||||
))
|
||||
} else {
|
||||
Error::custom(format_args!("unknown field `{}`, expected {}",
|
||||
field,
|
||||
OneOf { names: expected }))
|
||||
Error::custom(format_args!(
|
||||
"unknown field `{}`, expected {}",
|
||||
field,
|
||||
OneOf { names: expected }
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,7 +294,7 @@ macro_rules! declare_error_trait {
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
declare_error_trait!(Error: Sized + error::Error);
|
||||
declare_error_trait!(Error: Sized + StdError);
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
declare_error_trait!(Error: Sized + Debug + Display);
|
||||
@@ -290,7 +305,7 @@ declare_error_trait!(Error: Sized + Debug + Display);
|
||||
/// This is used as an argument to the `invalid_type`, `invalid_value`, and
|
||||
/// `invalid_length` methods of the `Error` trait to build error messages.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use std::fmt;
|
||||
/// #
|
||||
/// # use serde::de::{self, Unexpected, Visitor};
|
||||
@@ -377,7 +392,7 @@ pub enum Unexpected<'a> {
|
||||
}
|
||||
|
||||
impl<'a> fmt::Display for Unexpected<'a> {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
use self::Unexpected::*;
|
||||
match *self {
|
||||
Bool(b) => write!(formatter, "boolean `{}`", b),
|
||||
@@ -415,7 +430,7 @@ impl<'a> fmt::Display for Unexpected<'a> {
|
||||
/// Within the context of a `Visitor` implementation, the `Visitor` itself
|
||||
/// (`&self`) is an implementation of this trait.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use std::fmt;
|
||||
/// #
|
||||
/// # use serde::de::{self, Unexpected, Visitor};
|
||||
@@ -440,7 +455,7 @@ impl<'a> fmt::Display for Unexpected<'a> {
|
||||
///
|
||||
/// Outside of a `Visitor`, `&"..."` can be used.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde::de::{self, Unexpected};
|
||||
/// #
|
||||
/// # fn example<E>() -> Result<(), E>
|
||||
@@ -561,7 +576,7 @@ pub trait Deserialize<'de>: Sized {
|
||||
/// from the input string, but a `from_reader` function may only deserialize
|
||||
/// owned data.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde::de::{Deserialize, DeserializeOwned};
|
||||
/// # use std::io::{Read, Result};
|
||||
/// #
|
||||
@@ -600,7 +615,7 @@ impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
|
||||
///
|
||||
/// The canonical API for stateless deserialization looks like this:
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde::Deserialize;
|
||||
/// #
|
||||
/// # enum Error {}
|
||||
@@ -614,7 +629,7 @@ impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
|
||||
/// Adjusting an API like this to support stateful deserialization is a matter
|
||||
/// of accepting a seed as input:
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde::de::DeserializeSeed;
|
||||
/// #
|
||||
/// # enum Error {}
|
||||
@@ -647,7 +662,7 @@ impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
|
||||
/// into it. This requires stateful deserialization using the `DeserializeSeed`
|
||||
/// trait.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// use std::fmt;
|
||||
/// use std::marker::PhantomData;
|
||||
///
|
||||
@@ -778,7 +793,7 @@ where
|
||||
///
|
||||
/// The role of this trait is to define the deserialization half of the [Serde
|
||||
/// data model], which is a way to categorize every Rust data type into one of
|
||||
/// 29 possible types. Each method of the `Serializer` trait corresponds to one
|
||||
/// 29 possible types. Each method of the `Deserializer` trait corresponds to one
|
||||
/// of the types of the data model.
|
||||
///
|
||||
/// Implementations of `Deserialize` map themselves into this data model by
|
||||
@@ -992,7 +1007,7 @@ pub trait Deserializer<'de>: Sized {
|
||||
/// `Deserializer`.
|
||||
///
|
||||
/// If the `Visitor` would benefit from taking ownership of `String` data,
|
||||
/// indiciate this to the `Deserializer` by using `deserialize_string`
|
||||
/// indicate this to the `Deserializer` by using `deserialize_string`
|
||||
/// instead.
|
||||
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
@@ -1137,7 +1152,7 @@ pub trait Deserializer<'de>: Sized {
|
||||
/// human-readable one and binary formats like Bincode will prefer the
|
||||
/// compact one.
|
||||
///
|
||||
/// ```
|
||||
/// ```edition2018
|
||||
/// # use std::ops::Add;
|
||||
/// # use std::str::FromStr;
|
||||
/// #
|
||||
@@ -1198,6 +1213,20 @@ pub trait Deserializer<'de>: Sized {
|
||||
fn is_human_readable(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
// Not public API.
|
||||
#[cfg(all(not(no_serde_derive), any(feature = "std", feature = "alloc")))]
|
||||
#[doc(hidden)]
|
||||
fn __deserialize_content<V>(
|
||||
self,
|
||||
_: ::actually_private::T,
|
||||
visitor: V,
|
||||
) -> Result<::private::de::Content<'de>, Self::Error>
|
||||
where
|
||||
V: Visitor<'de, Value = ::private::de::Content<'de>>,
|
||||
{
|
||||
self.deserialize_any(visitor)
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1214,7 +1243,7 @@ pub trait Deserializer<'de>: Sized {
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use std::fmt;
|
||||
/// #
|
||||
/// # use serde::de::{self, Unexpected, Visitor};
|
||||
@@ -1255,7 +1284,7 @@ pub trait Visitor<'de>: Sized {
|
||||
/// "an integer between 0 and 64". The message should not be capitalized and
|
||||
/// should not end with a period.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use std::fmt;
|
||||
/// #
|
||||
/// # struct S {
|
||||
@@ -1699,7 +1728,7 @@ pub trait SeqAccess<'de> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, 'a, A> SeqAccess<'de> for &'a mut A
|
||||
impl<'de, 'a, A: ?Sized> SeqAccess<'de> for &'a mut A
|
||||
where
|
||||
A: SeqAccess<'de>,
|
||||
{
|
||||
@@ -1852,7 +1881,7 @@ pub trait MapAccess<'de> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, 'a, A> MapAccess<'de> for &'a mut A
|
||||
impl<'de, 'a, A: ?Sized> MapAccess<'de> for &'a mut A
|
||||
where
|
||||
A: MapAccess<'de>,
|
||||
{
|
||||
@@ -1996,7 +2025,7 @@ pub trait VariantAccess<'de>: Sized {
|
||||
/// If the data contains a different type of variant, the following
|
||||
/// `invalid_type` error should be constructed:
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected};
|
||||
/// #
|
||||
/// # struct X;
|
||||
@@ -2036,7 +2065,7 @@ pub trait VariantAccess<'de>: Sized {
|
||||
/// If the data contains a different type of variant, the following
|
||||
/// `invalid_type` error should be constructed:
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected};
|
||||
/// #
|
||||
/// # struct X;
|
||||
@@ -2092,7 +2121,7 @@ pub trait VariantAccess<'de>: Sized {
|
||||
/// If the data contains a different type of variant, the following
|
||||
/// `invalid_type` error should be constructed:
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected};
|
||||
/// #
|
||||
/// # struct X;
|
||||
@@ -2139,7 +2168,7 @@ pub trait VariantAccess<'de>: Sized {
|
||||
/// If the data contains a different type of variant, the following
|
||||
/// `invalid_type` error should be constructed:
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected};
|
||||
/// #
|
||||
/// # struct X;
|
||||
@@ -2199,14 +2228,10 @@ pub trait VariantAccess<'de>: Sized {
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// #[macro_use]
|
||||
/// extern crate serde_derive;
|
||||
///
|
||||
/// extern crate serde;
|
||||
///
|
||||
/// ```edition2018
|
||||
/// use std::str::FromStr;
|
||||
/// use serde::de::{value, Deserialize, IntoDeserializer};
|
||||
/// use serde::Deserialize;
|
||||
/// use serde::de::{value, IntoDeserializer};
|
||||
///
|
||||
/// #[derive(Deserialize)]
|
||||
/// enum Setting {
|
||||
@@ -2221,8 +2246,6 @@ pub trait VariantAccess<'de>: Sized {
|
||||
/// Self::deserialize(s.into_deserializer())
|
||||
/// }
|
||||
/// }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
pub trait IntoDeserializer<'de, E: Error = value::Error> {
|
||||
/// The type of the deserializer being converted into.
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
use de::{Deserialize, DeserializeSeed, Deserializer};
|
||||
|
||||
/// A DeserializeSeed helper for implementing deserialize_in_place Visitors.
|
||||
///
|
||||
/// Wraps a mutable reference and calls deserialize_in_place on it.
|
||||
pub struct InPlaceSeed<'a, T: 'a>(pub &'a mut T);
|
||||
|
||||
impl<'a, 'de, T> DeserializeSeed<'de> for InPlaceSeed<'a, T>
|
||||
where
|
||||
T: Deserialize<'de>,
|
||||
{
|
||||
type Value = ();
|
||||
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
T::deserialize_in_place(deserializer, self.0)
|
||||
}
|
||||
}
|
||||
+291
-43
@@ -1,14 +1,10 @@
|
||||
//! Building blocks for deserializing basic values using the `IntoDeserializer`
|
||||
//! trait.
|
||||
//!
|
||||
//! ```rust
|
||||
//! #[macro_use]
|
||||
//! extern crate serde_derive;
|
||||
//!
|
||||
//! extern crate serde;
|
||||
//!
|
||||
//! ```edition2018
|
||||
//! use std::str::FromStr;
|
||||
//! use serde::de::{value, Deserialize, IntoDeserializer};
|
||||
//! use serde::Deserialize;
|
||||
//! use serde::de::{value, IntoDeserializer};
|
||||
//!
|
||||
//! #[derive(Deserialize)]
|
||||
//! enum Setting {
|
||||
@@ -23,15 +19,13 @@
|
||||
//! Self::deserialize(s.into_deserializer())
|
||||
//! }
|
||||
//! }
|
||||
//! #
|
||||
//! # fn main() {}
|
||||
//! ```
|
||||
|
||||
use lib::*;
|
||||
|
||||
use self::private::{First, Second};
|
||||
use de::{self, Expected, IntoDeserializer, SeqAccess};
|
||||
use private::de::size_hint;
|
||||
use __private::size_hint;
|
||||
use de::{self, Deserializer, Expected, IntoDeserializer, SeqAccess, Visitor};
|
||||
use ser;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -54,7 +48,7 @@ macro_rules! impl_copy_clone {
|
||||
|
||||
/// A minimal representation of all possible errors that can occur using the
|
||||
/// `IntoDeserializer` trait.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct Error {
|
||||
err: ErrorImpl,
|
||||
}
|
||||
@@ -99,16 +93,25 @@ impl ser::Error for Error {
|
||||
|
||||
impl Display for Error {
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str(&self.err)
|
||||
}
|
||||
|
||||
#[cfg(not(any(feature = "std", feature = "alloc")))]
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("Serde deserialization error")
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for Error {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
let mut debug = formatter.debug_tuple("Error");
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
debug.field(&self.err);
|
||||
debug.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl error::Error for Error {
|
||||
fn description(&self) -> &str {
|
||||
@@ -132,7 +135,6 @@ where
|
||||
}
|
||||
|
||||
/// A deserializer holding a `()`.
|
||||
#[derive(Debug)]
|
||||
pub struct UnitDeserializer<E> {
|
||||
marker: PhantomData<E>,
|
||||
}
|
||||
@@ -166,6 +168,12 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> Debug for UnitDeserializer<E> {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.debug_struct("UnitDeserializer").finish()
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// A deserializer that cannot be instantiated.
|
||||
@@ -214,7 +222,6 @@ macro_rules! primitive_deserializer {
|
||||
($ty:ty, $doc:tt, $name:ident, $method:ident $($cast:tt)*) => {
|
||||
#[doc = "A deserializer holding"]
|
||||
#[doc = $doc]
|
||||
#[derive(Debug)]
|
||||
pub struct $name<E> {
|
||||
value: $ty,
|
||||
marker: PhantomData<E>
|
||||
@@ -255,6 +262,15 @@ macro_rules! primitive_deserializer {
|
||||
visitor.$method(self.value $($cast)*)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> Debug for $name<E> {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter
|
||||
.debug_struct(stringify!($name))
|
||||
.field("value", &self.value)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,7 +294,6 @@ serde_if_integer128! {
|
||||
}
|
||||
|
||||
/// A deserializer holding a `u32`.
|
||||
#[derive(Debug)]
|
||||
pub struct U32Deserializer<E> {
|
||||
value: u32,
|
||||
marker: PhantomData<E>,
|
||||
@@ -349,10 +364,18 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> Debug for U32Deserializer<E> {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter
|
||||
.debug_struct("U32Deserializer")
|
||||
.field("value", &self.value)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// A deserializer holding a `&str`.
|
||||
#[derive(Debug)]
|
||||
pub struct StrDeserializer<'a, E> {
|
||||
value: &'a str,
|
||||
marker: PhantomData<E>,
|
||||
@@ -423,11 +446,19 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, E> Debug for StrDeserializer<'a, E> {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter
|
||||
.debug_struct("StrDeserializer")
|
||||
.field("value", &self.value)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// A deserializer holding a `&str` with a lifetime tied to another
|
||||
/// deserializer.
|
||||
#[derive(Debug)]
|
||||
pub struct BorrowedStrDeserializer<'de, E> {
|
||||
value: &'de str,
|
||||
marker: PhantomData<E>,
|
||||
@@ -494,11 +525,19 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, E> Debug for BorrowedStrDeserializer<'de, E> {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter
|
||||
.debug_struct("BorrowedStrDeserializer")
|
||||
.field("value", &self.value)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// A deserializer holding a `String`.
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
#[derive(Debug)]
|
||||
pub struct StringDeserializer<E> {
|
||||
value: String,
|
||||
marker: PhantomData<E>,
|
||||
@@ -580,11 +619,20 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
impl<E> Debug for StringDeserializer<E> {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter
|
||||
.debug_struct("StringDeserializer")
|
||||
.field("value", &self.value)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// A deserializer holding a `Cow<str>`.
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
#[derive(Debug)]
|
||||
pub struct CowStrDeserializer<'a, E> {
|
||||
value: Cow<'a, str>,
|
||||
marker: PhantomData<E>,
|
||||
@@ -669,29 +717,48 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
impl<'a, E> Debug for CowStrDeserializer<'a, E> {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter
|
||||
.debug_struct("CowStrDeserializer")
|
||||
.field("value", &self.value)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// A deserializer holding a `&[u8]` with a lifetime tied to another
|
||||
/// deserializer.
|
||||
#[derive(Debug)]
|
||||
pub struct BorrowedBytesDeserializer<'de, E> {
|
||||
value: &'de [u8],
|
||||
/// A deserializer holding a `&[u8]`. Always calls [`Visitor::visit_bytes`].
|
||||
pub struct BytesDeserializer<'a, E> {
|
||||
value: &'a [u8],
|
||||
marker: PhantomData<E>,
|
||||
}
|
||||
|
||||
impl_copy_clone!(BorrowedBytesDeserializer<'de>);
|
||||
|
||||
impl<'de, E> BorrowedBytesDeserializer<'de, E> {
|
||||
/// Create a new borrowed deserializer from the given byte slice.
|
||||
pub fn new(value: &'de [u8]) -> BorrowedBytesDeserializer<'de, E> {
|
||||
BorrowedBytesDeserializer {
|
||||
impl<'a, E> BytesDeserializer<'a, E> {
|
||||
/// Create a new deserializer from the given bytes.
|
||||
pub fn new(value: &'a [u8]) -> Self {
|
||||
BytesDeserializer {
|
||||
value: value,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, E> de::Deserializer<'de> for BorrowedBytesDeserializer<'de, E>
|
||||
impl_copy_clone!(BytesDeserializer<'a>);
|
||||
|
||||
impl<'de, 'a, E> IntoDeserializer<'de, E> for &'a [u8]
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
type Deserializer = BytesDeserializer<'a, E>;
|
||||
|
||||
fn into_deserializer(self) -> BytesDeserializer<'a, E> {
|
||||
BytesDeserializer::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, 'a, E> Deserializer<'de> for BytesDeserializer<'a, E>
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
@@ -699,7 +766,55 @@ where
|
||||
|
||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: de::Visitor<'de>,
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
visitor.visit_bytes(self.value)
|
||||
}
|
||||
|
||||
forward_to_deserialize_any! {
|
||||
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
|
||||
bytes byte_buf option unit unit_struct newtype_struct seq tuple
|
||||
tuple_struct map struct enum identifier ignored_any
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, E> Debug for BytesDeserializer<'a, E> {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter
|
||||
.debug_struct("BytesDeserializer")
|
||||
.field("value", &self.value)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// A deserializer holding a `&[u8]` with a lifetime tied to another
|
||||
/// deserializer. Always calls [`Visitor::visit_borrowed_bytes`].
|
||||
pub struct BorrowedBytesDeserializer<'de, E> {
|
||||
value: &'de [u8],
|
||||
marker: PhantomData<E>,
|
||||
}
|
||||
|
||||
impl<'de, E> BorrowedBytesDeserializer<'de, E> {
|
||||
/// Create a new borrowed deserializer from the given borrowed bytes.
|
||||
pub fn new(value: &'de [u8]) -> Self {
|
||||
BorrowedBytesDeserializer {
|
||||
value: value,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_copy_clone!(BorrowedBytesDeserializer<'de>);
|
||||
|
||||
impl<'de, E> Deserializer<'de> for BorrowedBytesDeserializer<'de, E>
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
type Error = E;
|
||||
|
||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
visitor.visit_borrowed_bytes(self.value)
|
||||
}
|
||||
@@ -707,14 +822,23 @@ where
|
||||
forward_to_deserialize_any! {
|
||||
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
|
||||
bytes byte_buf option unit unit_struct newtype_struct seq tuple
|
||||
tuple_struct map struct identifier ignored_any enum
|
||||
tuple_struct map struct enum identifier ignored_any
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, E> Debug for BorrowedBytesDeserializer<'de, E> {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter
|
||||
.debug_struct("BorrowedBytesDeserializer")
|
||||
.field("value", &self.value)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// A deserializer that iterates over a sequence.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone)]
|
||||
pub struct SeqDeserializer<I, E> {
|
||||
iter: iter::Fuse<I>,
|
||||
count: usize,
|
||||
@@ -819,6 +943,19 @@ impl Expected for ExpectedInSeq {
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, E> Debug for SeqDeserializer<I, E>
|
||||
where
|
||||
I: Debug,
|
||||
{
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter
|
||||
.debug_struct("SeqDeserializer")
|
||||
.field("iter", &self.iter)
|
||||
.field("count", &self.count)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
@@ -1040,7 +1177,7 @@ where
|
||||
let value = self.value.take();
|
||||
// Panic because this indicates a bug in the program rather than an
|
||||
// expected failure.
|
||||
let value = value.expect("MapAccess::visit_value called before visit_key");
|
||||
let value = value.expect("MapAccess::next_value called before next_key");
|
||||
seed.deserialize(value.into_deserializer())
|
||||
}
|
||||
|
||||
@@ -1114,7 +1251,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
// Cannot #[derive(Debug)] because of the bound `Second<I::Item>: Debug`.
|
||||
impl<'de, I, E> Debug for MapDeserializer<'de, I, E>
|
||||
where
|
||||
I: Iterator + Debug,
|
||||
@@ -1127,8 +1263,6 @@ where
|
||||
.field("iter", &self.iter)
|
||||
.field("value", &self.value)
|
||||
.field("count", &self.count)
|
||||
.field("lifetime", &self.lifetime)
|
||||
.field("error", &self.error)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
@@ -1293,10 +1427,40 @@ where
|
||||
visitor.visit_map(self.map)
|
||||
}
|
||||
|
||||
fn deserialize_enum<V>(
|
||||
self,
|
||||
_name: &str,
|
||||
_variants: &'static [&'static str],
|
||||
visitor: V,
|
||||
) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: de::Visitor<'de>,
|
||||
{
|
||||
visitor.visit_enum(self)
|
||||
}
|
||||
|
||||
forward_to_deserialize_any! {
|
||||
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
|
||||
bytes byte_buf option unit unit_struct newtype_struct seq tuple
|
||||
tuple_struct map struct enum identifier ignored_any
|
||||
tuple_struct map struct identifier ignored_any
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, A> de::EnumAccess<'de> for MapAccessDeserializer<A>
|
||||
where
|
||||
A: de::MapAccess<'de>,
|
||||
{
|
||||
type Error = A::Error;
|
||||
type Variant = private::MapAsEnum<A>;
|
||||
|
||||
fn variant_seed<T>(mut self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
|
||||
where
|
||||
T: de::DeserializeSeed<'de>,
|
||||
{
|
||||
match self.map.next_key_seed(seed)? {
|
||||
Some(key) => Ok((key, private::map_as_enum(self.map))),
|
||||
None => Err(de::Error::invalid_type(de::Unexpected::Map, &"enum")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1305,9 +1469,8 @@ where
|
||||
mod private {
|
||||
use lib::*;
|
||||
|
||||
use de::{self, Unexpected};
|
||||
use de::{self, DeserializeSeed, Deserializer, MapAccess, Unexpected, VariantAccess, Visitor};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct UnitOnly<E> {
|
||||
marker: PhantomData<E>,
|
||||
}
|
||||
@@ -1366,6 +1529,91 @@ mod private {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MapAsEnum<A> {
|
||||
map: A,
|
||||
}
|
||||
|
||||
pub fn map_as_enum<A>(map: A) -> MapAsEnum<A> {
|
||||
MapAsEnum { map: map }
|
||||
}
|
||||
|
||||
impl<'de, A> VariantAccess<'de> for MapAsEnum<A>
|
||||
where
|
||||
A: MapAccess<'de>,
|
||||
{
|
||||
type Error = A::Error;
|
||||
|
||||
fn unit_variant(mut self) -> Result<(), Self::Error> {
|
||||
self.map.next_value()
|
||||
}
|
||||
|
||||
fn newtype_variant_seed<T>(mut self, seed: T) -> Result<T::Value, Self::Error>
|
||||
where
|
||||
T: DeserializeSeed<'de>,
|
||||
{
|
||||
self.map.next_value_seed(seed)
|
||||
}
|
||||
|
||||
fn tuple_variant<V>(mut self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
self.map.next_value_seed(SeedTupleVariant {
|
||||
len: len,
|
||||
visitor: visitor,
|
||||
})
|
||||
}
|
||||
|
||||
fn struct_variant<V>(
|
||||
mut self,
|
||||
_fields: &'static [&'static str],
|
||||
visitor: V,
|
||||
) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
self.map
|
||||
.next_value_seed(SeedStructVariant { visitor: visitor })
|
||||
}
|
||||
}
|
||||
|
||||
struct SeedTupleVariant<V> {
|
||||
len: usize,
|
||||
visitor: V,
|
||||
}
|
||||
|
||||
impl<'de, V> DeserializeSeed<'de> for SeedTupleVariant<V>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
type Value = V::Value;
|
||||
|
||||
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_tuple(self.len, self.visitor)
|
||||
}
|
||||
}
|
||||
|
||||
struct SeedStructVariant<V> {
|
||||
visitor: V,
|
||||
}
|
||||
|
||||
impl<'de, V> DeserializeSeed<'de> for SeedStructVariant<V>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
type Value = V::Value;
|
||||
|
||||
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_map(self.visitor)
|
||||
}
|
||||
}
|
||||
|
||||
/// Avoid having to restate the generic types on `MapDeserializer`. The
|
||||
/// `Iterator::Item` contains enough information to figure out K and V.
|
||||
pub trait Pair {
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
pub use lib::clone::Clone;
|
||||
pub use lib::convert::{From, Into};
|
||||
pub use lib::default::Default;
|
||||
pub use lib::fmt::{self, Formatter};
|
||||
pub use lib::marker::PhantomData;
|
||||
pub use lib::option::Option::{self, None, Some};
|
||||
pub use lib::result::Result::{self, Err, Ok};
|
||||
|
||||
pub use self::string::from_utf8_lossy;
|
||||
|
||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
||||
pub use lib::Vec;
|
||||
|
||||
mod string {
|
||||
use lib::*;
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
pub fn from_utf8_lossy(bytes: &[u8]) -> Cow<str> {
|
||||
String::from_utf8_lossy(bytes)
|
||||
}
|
||||
|
||||
// The generated code calls this like:
|
||||
//
|
||||
// let value = &_serde::export::from_utf8_lossy(bytes);
|
||||
// Err(_serde::de::Error::unknown_variant(value, VARIANTS))
|
||||
//
|
||||
// so it is okay for the return type to be different from the std case as long
|
||||
// as the above works.
|
||||
#[cfg(not(any(feature = "std", feature = "alloc")))]
|
||||
pub fn from_utf8_lossy(bytes: &[u8]) -> &str {
|
||||
// Three unicode replacement characters if it fails. They look like a
|
||||
// white-on-black question mark. The user will recognize it as invalid
|
||||
// UTF-8.
|
||||
str::from_utf8(bytes).unwrap_or("\u{fffd}\u{fffd}\u{fffd}")
|
||||
}
|
||||
}
|
||||
+15
-19
@@ -1,22 +1,20 @@
|
||||
/// Conditional compilation depending on whether Serde is built with support for
|
||||
/// 128-bit integers.
|
||||
///
|
||||
/// Data formats that wish to support Rust compiler versions older than 1.26 may
|
||||
/// place the i128 / u128 methods of their Serializer and Deserializer behind
|
||||
/// this macro.
|
||||
/// Data formats that wish to support Rust compiler versions older than 1.26
|
||||
/// (or targets that lack 128-bit integers) may place the i128 / u128 methods
|
||||
/// of their Serializer and Deserializer behind this macro.
|
||||
///
|
||||
/// Data formats that require a minimum Rust compiler version of at least 1.26
|
||||
/// do not need to bother with this macro and may assume support for 128-bit
|
||||
/// integers.
|
||||
/// Data formats that require a minimum Rust compiler version of at least 1.26,
|
||||
/// or do not target platforms that lack 128-bit integers, do not need to
|
||||
/// bother with this macro and may assume support for 128-bit integers.
|
||||
///
|
||||
/// ```rust
|
||||
/// #[macro_use]
|
||||
/// extern crate serde;
|
||||
///
|
||||
/// use serde::Serializer;
|
||||
/// # use serde::private::ser::Error;
|
||||
/// ```edition2018
|
||||
/// # use serde::__private::doc::Error;
|
||||
/// #
|
||||
/// # struct MySerializer;
|
||||
/// #
|
||||
/// use serde::{serde_if_integer128, Serializer};
|
||||
///
|
||||
/// impl Serializer for MySerializer {
|
||||
/// type Ok = ();
|
||||
@@ -41,20 +39,18 @@
|
||||
/// }
|
||||
/// }
|
||||
/// #
|
||||
/// # __serialize_unimplemented! {
|
||||
/// # serde::__serialize_unimplemented! {
|
||||
/// # bool i8 i16 i32 u8 u16 u32 u64 f32 f64 char str bytes none some
|
||||
/// # unit unit_struct unit_variant newtype_struct newtype_variant seq
|
||||
/// # tuple tuple_struct tuple_variant map struct struct_variant
|
||||
/// # }
|
||||
/// }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
///
|
||||
/// When Serde is built with support for 128-bit integers, this macro expands
|
||||
/// transparently into just the input tokens.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// macro_rules! serde_if_integer128 {
|
||||
/// ($($tt:tt)*) => {
|
||||
/// $($tt)*
|
||||
@@ -65,12 +61,12 @@
|
||||
/// When built without support for 128-bit integers, this macro expands to
|
||||
/// nothing.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// macro_rules! serde_if_integer128 {
|
||||
/// ($($tt:tt)*) => {};
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(integer128)]
|
||||
#[cfg(not(no_integer128))]
|
||||
#[macro_export]
|
||||
macro_rules! serde_if_integer128 {
|
||||
($($tt:tt)*) => {
|
||||
@@ -78,7 +74,7 @@ macro_rules! serde_if_integer128 {
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(integer128))]
|
||||
#[cfg(no_integer128)]
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! serde_if_integer128 {
|
||||
|
||||
+106
-102
@@ -9,11 +9,9 @@
|
||||
//! these two groups interact with each other, allowing any supported data
|
||||
//! structure to be serialized and deserialized using any supported data format.
|
||||
//!
|
||||
//! See the Serde website [https://serde.rs/] for additional documentation and
|
||||
//! See the Serde website <https://serde.rs/> for additional documentation and
|
||||
//! usage examples.
|
||||
//!
|
||||
//! [https://serde.rs/]: https://serde.rs/
|
||||
//!
|
||||
//! ## Design
|
||||
//!
|
||||
//! Where many other languages rely on runtime reflection for serializing data,
|
||||
@@ -37,8 +35,8 @@
|
||||
//! used for IPC within the Servo rendering engine.
|
||||
//! - [CBOR], a Concise Binary Object Representation designed for small message
|
||||
//! size without the need for version negotiation.
|
||||
//! - [YAML], a popular human-friendly configuration language that ain't markup
|
||||
//! language.
|
||||
//! - [YAML], a self-proclaimed human-friendly configuration language that ain't
|
||||
//! markup language.
|
||||
//! - [MessagePack], an efficient binary format that resembles a compact JSON.
|
||||
//! - [TOML], a minimal configuration format used by [Cargo].
|
||||
//! - [Pickle], a format common in the Python world.
|
||||
@@ -46,17 +44,23 @@
|
||||
//! - [BSON], the data storage and network transfer format used by MongoDB.
|
||||
//! - [Avro], a binary format used within Apache Hadoop, with support for schema
|
||||
//! definition.
|
||||
//! - [Hjson], a variant of JSON designed to be readable and writable by humans.
|
||||
//! - [JSON5], A superset of JSON including some productions from ES5.
|
||||
//! - [URL], the x-www-form-urlencoded format.
|
||||
//! - [JSON5], a superset of JSON including some productions from ES5.
|
||||
//! - [Postcard], a no\_std and embedded-systems friendly compact binary format.
|
||||
//! - [URL] query strings, in the x-www-form-urlencoded format.
|
||||
//! - [Envy], a way to deserialize environment variables into Rust structs.
|
||||
//! *(deserialization only)*
|
||||
//! - [Envy Store], a way to deserialize [AWS Parameter Store] parameters into
|
||||
//! Rust structs. *(deserialization only)*
|
||||
//! - [S-expressions], the textual representation of code and data used by the
|
||||
//! Lisp language family.
|
||||
//! - [D-Bus]'s binary wire format.
|
||||
//! - [FlexBuffers], the schemaless cousin of Google's FlatBuffers zero-copy serialization format.
|
||||
//! - [DynamoDB Items], the format used by [rusoto_dynamodb] to transfer data to
|
||||
//! and from DynamoDB.
|
||||
//!
|
||||
//! [JSON]: https://github.com/serde-rs/json
|
||||
//! [Bincode]: https://github.com/TyOverby/bincode
|
||||
//! [CBOR]: https://github.com/pyfisch/cbor
|
||||
//! [Bincode]: https://github.com/servo/bincode
|
||||
//! [CBOR]: https://github.com/enarx/ciborium
|
||||
//! [YAML]: https://github.com/dtolnay/serde-yaml
|
||||
//! [MessagePack]: https://github.com/3Hren/msgpack-rust
|
||||
//! [TOML]: https://github.com/alexcrichton/toml-rs
|
||||
@@ -64,74 +68,79 @@
|
||||
//! [RON]: https://github.com/ron-rs/ron
|
||||
//! [BSON]: https://github.com/zonyitoo/bson-rs
|
||||
//! [Avro]: https://github.com/flavray/avro-rs
|
||||
//! [Hjson]: https://github.com/laktak/hjson-rust
|
||||
//! [JSON5]: https://github.com/callum-oakley/json5-rs
|
||||
//! [URL]: https://github.com/nox/serde_urlencoded
|
||||
//! [Postcard]: https://github.com/jamesmunns/postcard
|
||||
//! [URL]: https://docs.rs/serde_qs
|
||||
//! [Envy]: https://github.com/softprops/envy
|
||||
//! [Envy Store]: https://github.com/softprops/envy-store
|
||||
//! [Cargo]: http://doc.crates.io/manifest.html
|
||||
//! [Cargo]: https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
//! [AWS Parameter Store]: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html
|
||||
//! [S-expressions]: https://github.com/rotty/lexpr-rs
|
||||
//! [D-Bus]: https://docs.rs/zvariant
|
||||
//! [FlexBuffers]: https://github.com/google/flatbuffers/tree/master/rust/flexbuffers
|
||||
//! [DynamoDB Items]: https://docs.rs/serde_dynamo
|
||||
//! [rusoto_dynamodb]: https://docs.rs/rusoto_dynamodb
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Serde types in rustdoc of other crates get linked to here.
|
||||
#![doc(html_root_url = "https://docs.rs/serde/1.0.81")]
|
||||
#![doc(html_root_url = "https://docs.rs/serde/1.0.135")]
|
||||
// Support using Serde without the standard library!
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
// Unstable functionality only if the user asks for it. For tracking and
|
||||
// discussion of these features please refer to this issue:
|
||||
//
|
||||
// https://github.com/serde-rs/serde/issues/812
|
||||
#![cfg_attr(feature = "unstable", feature(specialization, never_type))]
|
||||
#![cfg_attr(feature = "alloc", feature(alloc))]
|
||||
#![cfg_attr(feature = "unstable", feature(never_type))]
|
||||
#![allow(unknown_lints, bare_trait_objects, deprecated)]
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
|
||||
// Whitelisted clippy lints
|
||||
// Ignored clippy and clippy_pedantic lints
|
||||
#![cfg_attr(
|
||||
feature = "cargo-clippy",
|
||||
allow(
|
||||
cast_lossless,
|
||||
const_static_lifetime,
|
||||
doc_markdown,
|
||||
linkedlist,
|
||||
needless_pass_by_value,
|
||||
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704
|
||||
unnested_or_patterns,
|
||||
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/7768
|
||||
semicolon_if_nothing_returned,
|
||||
// not available in our oldest supported compiler
|
||||
checked_conversions,
|
||||
empty_enum,
|
||||
redundant_field_names,
|
||||
redundant_static_lifetimes,
|
||||
// integer and float ser/de requires these sorts of casts
|
||||
cast_possible_truncation,
|
||||
cast_possible_wrap,
|
||||
cast_sign_loss,
|
||||
// things are often more readable this way
|
||||
cast_lossless,
|
||||
module_name_repetitions,
|
||||
option_if_let_else,
|
||||
single_match_else,
|
||||
type_complexity,
|
||||
unreadable_literal,
|
||||
zero_prefixed_literal
|
||||
use_self,
|
||||
zero_prefixed_literal,
|
||||
// correctly used
|
||||
enum_glob_use,
|
||||
let_underscore_drop,
|
||||
map_err_ignore,
|
||||
result_unit_err,
|
||||
wildcard_imports,
|
||||
// not practical
|
||||
needless_pass_by_value,
|
||||
similar_names,
|
||||
too_many_lines,
|
||||
// preference
|
||||
doc_markdown,
|
||||
unseparated_literal_suffix,
|
||||
// false positive
|
||||
needless_doctest_main,
|
||||
// noisy
|
||||
missing_errors_doc,
|
||||
must_use_candidate,
|
||||
)
|
||||
)]
|
||||
// Whitelisted clippy_pedantic lints
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(
|
||||
// integer and float ser/de requires these sorts of casts
|
||||
cast_possible_truncation,
|
||||
cast_possible_wrap,
|
||||
cast_precision_loss,
|
||||
cast_sign_loss,
|
||||
// simplifies some macros
|
||||
invalid_upcast_comparisons,
|
||||
// things are often more readable this way
|
||||
decimal_literal_representation,
|
||||
option_unwrap_used,
|
||||
result_unwrap_used,
|
||||
shadow_reuse,
|
||||
single_match_else,
|
||||
stutter,
|
||||
use_self,
|
||||
// not practical
|
||||
indexing_slicing,
|
||||
many_single_char_names,
|
||||
missing_docs_in_private_items,
|
||||
similar_names,
|
||||
// alternative is not stable
|
||||
empty_enum,
|
||||
use_debug,
|
||||
))]
|
||||
// Blacklisted Rust lints.
|
||||
//
|
||||
// Compiler bug involving unused_imports:
|
||||
// https://github.com/rust-lang/rust/issues/51661
|
||||
#![deny(missing_docs, /*unused_imports*/)]
|
||||
// Rustc lints.
|
||||
#![deny(missing_docs, unused_imports)]
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -149,7 +158,7 @@ mod lib {
|
||||
pub use std::*;
|
||||
}
|
||||
|
||||
pub use self::core::{cmp, iter, mem, num, slice, str};
|
||||
pub use self::core::{cmp, iter, mem, num, ptr, slice, str};
|
||||
pub use self::core::{f32, f64};
|
||||
pub use self::core::{i16, i32, i64, i8, isize};
|
||||
pub use self::core::{u16, u32, u64, u8, usize};
|
||||
@@ -160,6 +169,7 @@ mod lib {
|
||||
pub use self::core::default::{self, Default};
|
||||
pub use self::core::fmt::{self, Debug, Display};
|
||||
pub use self::core::marker::{self, PhantomData};
|
||||
pub use self::core::num::Wrapping;
|
||||
pub use self::core::ops::Range;
|
||||
pub use self::core::option::{self, Option};
|
||||
pub use self::core::result::{self, Result};
|
||||
@@ -172,7 +182,7 @@ mod lib {
|
||||
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
||||
pub use alloc::string::{String, ToString};
|
||||
#[cfg(feature = "std")]
|
||||
pub use std::string::String;
|
||||
pub use std::string::{String, ToString};
|
||||
|
||||
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
||||
pub use alloc::vec::Vec;
|
||||
@@ -211,19 +221,34 @@ mod lib {
|
||||
#[cfg(feature = "std")]
|
||||
pub use std::io::Write;
|
||||
#[cfg(feature = "std")]
|
||||
pub use std::num::Wrapping;
|
||||
#[cfg(feature = "std")]
|
||||
pub use std::path::{Path, PathBuf};
|
||||
#[cfg(feature = "std")]
|
||||
pub use std::sync::{Mutex, RwLock};
|
||||
#[cfg(feature = "std")]
|
||||
pub use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
#[cfg(any(core_duration, feature = "std"))]
|
||||
pub use self::core::time::Duration;
|
||||
#[cfg(all(feature = "std", not(no_collections_bound), no_ops_bound))]
|
||||
pub use std::collections::Bound;
|
||||
|
||||
#[cfg(range_inclusive)]
|
||||
#[cfg(not(no_core_reverse))]
|
||||
pub use self::core::cmp::Reverse;
|
||||
|
||||
#[cfg(not(no_ops_bound))]
|
||||
pub use self::core::ops::Bound;
|
||||
|
||||
#[cfg(not(no_range_inclusive))]
|
||||
pub use self::core::ops::RangeInclusive;
|
||||
|
||||
#[cfg(all(feature = "std", not(no_std_atomic)))]
|
||||
pub use std::sync::atomic::{
|
||||
AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU8,
|
||||
AtomicUsize, Ordering,
|
||||
};
|
||||
#[cfg(all(feature = "std", not(no_std_atomic64)))]
|
||||
pub use std::sync::atomic::{AtomicI64, AtomicU64};
|
||||
|
||||
#[cfg(any(feature = "std", not(no_core_duration)))]
|
||||
pub use self::core::time::Duration;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -242,50 +267,24 @@ pub use de::{Deserialize, Deserializer};
|
||||
#[doc(inline)]
|
||||
pub use ser::{Serialize, Serializer};
|
||||
|
||||
// Generated code uses these to support no_std. Not public API.
|
||||
// Used by generated code and doc tests. Not public API.
|
||||
#[doc(hidden)]
|
||||
pub mod export;
|
||||
#[path = "private/mod.rs"]
|
||||
pub mod __private;
|
||||
|
||||
// Helpers used by generated code and doc tests. Not public API.
|
||||
#[doc(hidden)]
|
||||
pub mod private;
|
||||
#[allow(unused_imports)]
|
||||
use self::__private as export;
|
||||
#[allow(unused_imports)]
|
||||
use self::__private as private;
|
||||
|
||||
#[path = "de/seed.rs"]
|
||||
mod seed;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
mod std_error;
|
||||
|
||||
// Re-export #[derive(Serialize, Deserialize)].
|
||||
//
|
||||
// This is a workaround for https://github.com/rust-lang/cargo/issues/1286.
|
||||
// Without this re-export, crates that put Serde derives behind a cfg_attr would
|
||||
// need to use some silly feature name that depends on both serde and
|
||||
// serde_derive.
|
||||
//
|
||||
// [features]
|
||||
// serde-impls = ["serde", "serde_derive"]
|
||||
//
|
||||
// [dependencies]
|
||||
// serde = { version = "1.0", optional = true }
|
||||
// serde_derive = { version = "1.0", optional = true }
|
||||
//
|
||||
// # Used like this:
|
||||
// # #[cfg(feature = "serde-impls")]
|
||||
// # #[macro_use]
|
||||
// # extern crate serde_derive;
|
||||
// #
|
||||
// # #[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
|
||||
// # struct S { /* ... */ }
|
||||
//
|
||||
// The re-exported derives allow crates to use "serde" as the name of their
|
||||
// Serde feature which is more intuitive.
|
||||
//
|
||||
// [dependencies]
|
||||
// serde = { version = "1.0", optional = true, features = ["derive"] }
|
||||
//
|
||||
// # Used like this:
|
||||
// # #[cfg(feature = "serde")]
|
||||
// # #[macro_use]
|
||||
// # extern crate serde;
|
||||
// #
|
||||
// # #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
// # struct S { /* ... */ }
|
||||
//
|
||||
// The reason re-exporting is not enabled by default is that disabling it would
|
||||
// be annoying for crates that provide handwritten impls or data formats. They
|
||||
// would need to disable default features and then explicitly re-enable std.
|
||||
@@ -296,3 +295,8 @@ extern crate serde_derive;
|
||||
#[cfg(feature = "serde_derive")]
|
||||
#[doc(hidden)]
|
||||
pub use serde_derive::*;
|
||||
|
||||
#[cfg(all(not(no_serde_derive), any(feature = "std", feature = "alloc")))]
|
||||
mod actually_private {
|
||||
pub struct T;
|
||||
}
|
||||
|
||||
+7
-19
@@ -11,10 +11,8 @@
|
||||
/// input. This requires repetitive implementations of all the [`Deserializer`]
|
||||
/// trait methods.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::forward_to_deserialize_any;
|
||||
/// # use serde::de::{value, Deserializer, Visitor};
|
||||
/// #
|
||||
/// # struct MyDeserializer;
|
||||
@@ -43,18 +41,14 @@
|
||||
/// # tuple_struct map struct enum identifier ignored_any
|
||||
/// # }
|
||||
/// # }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
///
|
||||
/// The `forward_to_deserialize_any!` macro implements these simple forwarding
|
||||
/// methods so that they forward directly to [`Deserializer::deserialize_any`].
|
||||
/// You can choose which methods to forward.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::forward_to_deserialize_any;
|
||||
/// # use serde::de::{value, Deserializer, Visitor};
|
||||
/// #
|
||||
/// # struct MyDeserializer;
|
||||
@@ -77,8 +71,6 @@
|
||||
/// tuple_struct map struct enum identifier ignored_any
|
||||
/// }
|
||||
/// }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
///
|
||||
/// The macro assumes the convention that your `Deserializer` lifetime parameter
|
||||
@@ -86,12 +78,10 @@
|
||||
/// called `V`. A different type parameter and a different lifetime can be
|
||||
/// specified explicitly if necessary.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use std::marker::PhantomData;
|
||||
/// #
|
||||
/// # use serde::forward_to_deserialize_any;
|
||||
/// # use serde::de::{value, Deserializer, Visitor};
|
||||
/// #
|
||||
/// # struct MyDeserializer<V>(PhantomData<V>);
|
||||
@@ -113,8 +103,6 @@
|
||||
/// tuple_struct map struct enum identifier ignored_any
|
||||
/// }
|
||||
/// # }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
///
|
||||
/// [`Deserializer`]: trait.Deserializer.html
|
||||
@@ -136,7 +124,7 @@ macro_rules! forward_to_deserialize_any {
|
||||
macro_rules! forward_to_deserialize_any_method {
|
||||
($func:ident<$l:tt, $v:ident>($($arg:ident : $ty:ty),*)) => {
|
||||
#[inline]
|
||||
fn $func<$v>(self, $($arg: $ty,)* visitor: $v) -> $crate::export::Result<$v::Value, Self::Error>
|
||||
fn $func<$v>(self, $($arg: $ty,)* visitor: $v) -> $crate::__private::Result<$v::Value, Self::Error>
|
||||
where
|
||||
$v: $crate::de::Visitor<$l>,
|
||||
{
|
||||
|
||||
+164
-115
@@ -1,9 +1,10 @@
|
||||
use lib::*;
|
||||
|
||||
use de::{Deserialize, DeserializeSeed, Deserializer, Error, IntoDeserializer, Visitor};
|
||||
use de::value::{BorrowedBytesDeserializer, BytesDeserializer};
|
||||
use de::{Deserialize, Deserializer, Error, IntoDeserializer, Visitor};
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
use de::{MapAccess, Unexpected};
|
||||
use de::{DeserializeSeed, MapAccess, Unexpected};
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
pub use self::content::{
|
||||
@@ -12,6 +13,8 @@ pub use self::content::{
|
||||
TagOrContentField, TagOrContentFieldVisitor, TaggedContentVisitor, UntaggedUnitVisitor,
|
||||
};
|
||||
|
||||
pub use seed::InPlaceSeed;
|
||||
|
||||
/// If the missing field is of type `Option<T>` then treat is as `None`,
|
||||
/// otherwise it is an error.
|
||||
pub fn missing_field<'de, V, E>(field: &'static str) -> Result<V, E>
|
||||
@@ -53,9 +56,10 @@ where
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
pub fn borrow_cow_str<'de: 'a, 'a, D>(deserializer: D) -> Result<Cow<'a, str>, D::Error>
|
||||
pub fn borrow_cow_str<'de: 'a, 'a, D, R>(deserializer: D) -> Result<R, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
R: From<Cow<'a, str>>,
|
||||
{
|
||||
struct CowStrVisitor;
|
||||
|
||||
@@ -121,13 +125,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_str(CowStrVisitor)
|
||||
deserializer.deserialize_str(CowStrVisitor).map(From::from)
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
pub fn borrow_cow_bytes<'de: 'a, 'a, D>(deserializer: D) -> Result<Cow<'a, [u8]>, D::Error>
|
||||
pub fn borrow_cow_bytes<'de: 'a, 'a, D, R>(deserializer: D) -> Result<R, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
R: From<Cow<'a, [u8]>>,
|
||||
{
|
||||
struct CowBytesVisitor;
|
||||
|
||||
@@ -181,30 +186,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_bytes(CowBytesVisitor)
|
||||
}
|
||||
|
||||
pub mod size_hint {
|
||||
use lib::*;
|
||||
|
||||
pub fn from_bounds<I>(iter: &I) -> Option<usize>
|
||||
where
|
||||
I: Iterator,
|
||||
{
|
||||
helper(iter.size_hint())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn cautious(hint: Option<usize>) -> usize {
|
||||
cmp::min(hint.unwrap_or(0), 4096)
|
||||
}
|
||||
|
||||
fn helper(bounds: (usize, Option<usize>)) -> Option<usize> {
|
||||
match bounds {
|
||||
(lower, Some(upper)) if lower == upper => Some(upper),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
deserializer
|
||||
.deserialize_bytes(CowBytesVisitor)
|
||||
.map(From::from)
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
@@ -221,7 +205,8 @@ mod content {
|
||||
|
||||
use lib::*;
|
||||
|
||||
use super::size_hint;
|
||||
use __private::size_hint;
|
||||
use actually_private;
|
||||
use de::{
|
||||
self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, IgnoredAny,
|
||||
MapAccess, SeqAccess, Unexpected, Visitor,
|
||||
@@ -231,7 +216,7 @@ mod content {
|
||||
/// deserializing untagged enums and internally tagged enums.
|
||||
///
|
||||
/// Not public API. Use serde-value instead.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Content<'de> {
|
||||
Bool(bool),
|
||||
|
||||
@@ -310,7 +295,7 @@ mod content {
|
||||
// Untagged and internally tagged enums are only supported in
|
||||
// self-describing formats.
|
||||
let visitor = ContentVisitor { value: PhantomData };
|
||||
deserializer.deserialize_any(visitor)
|
||||
deserializer.__deserialize_content(actually_private::T, visitor)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -820,15 +805,17 @@ mod content {
|
||||
/// Not public API.
|
||||
pub struct TaggedContentVisitor<'de, T> {
|
||||
tag_name: &'static str,
|
||||
expecting: &'static str,
|
||||
value: PhantomData<TaggedContent<'de, T>>,
|
||||
}
|
||||
|
||||
impl<'de, T> TaggedContentVisitor<'de, T> {
|
||||
/// Visitor for the content of an internally tagged enum with the given
|
||||
/// tag name.
|
||||
pub fn new(name: &'static str) -> Self {
|
||||
pub fn new(name: &'static str, expecting: &'static str) -> Self {
|
||||
TaggedContentVisitor {
|
||||
tag_name: name,
|
||||
expecting: expecting,
|
||||
value: PhantomData,
|
||||
}
|
||||
}
|
||||
@@ -857,7 +844,7 @@ mod content {
|
||||
type Value = TaggedContent<'de, T>;
|
||||
|
||||
fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.write_str("internally tagged enum")
|
||||
fmt.write_str(self.expecting)
|
||||
}
|
||||
|
||||
fn visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error>
|
||||
@@ -1036,6 +1023,25 @@ mod content {
|
||||
_ => Err(self.invalid_type(&visitor)),
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_float<V>(self, visitor: V) -> Result<V::Value, E>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
match self.content {
|
||||
Content::F32(v) => visitor.visit_f32(v),
|
||||
Content::F64(v) => visitor.visit_f64(v),
|
||||
Content::U8(v) => visitor.visit_u8(v),
|
||||
Content::U16(v) => visitor.visit_u16(v),
|
||||
Content::U32(v) => visitor.visit_u32(v),
|
||||
Content::U64(v) => visitor.visit_u64(v),
|
||||
Content::I8(v) => visitor.visit_i8(v),
|
||||
Content::I16(v) => visitor.visit_i16(v),
|
||||
Content::I32(v) => visitor.visit_i32(v),
|
||||
Content::I64(v) => visitor.visit_i64(v),
|
||||
_ => Err(self.invalid_type(&visitor)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_content_seq<'de, V, E>(content: Vec<Content<'de>>, visitor: V) -> Result<V::Value, E>
|
||||
@@ -1175,25 +1181,14 @@ mod content {
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
match self.content {
|
||||
Content::F32(v) => visitor.visit_f32(v),
|
||||
Content::F64(v) => visitor.visit_f64(v),
|
||||
Content::U64(v) => visitor.visit_u64(v),
|
||||
Content::I64(v) => visitor.visit_i64(v),
|
||||
_ => Err(self.invalid_type(&visitor)),
|
||||
}
|
||||
self.deserialize_float(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
match self.content {
|
||||
Content::F64(v) => visitor.visit_f64(v),
|
||||
Content::U64(v) => visitor.visit_u64(v),
|
||||
Content::I64(v) => visitor.visit_i64(v),
|
||||
_ => Err(self.invalid_type(&visitor)),
|
||||
}
|
||||
self.deserialize_float(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
@@ -1293,8 +1288,9 @@ mod content {
|
||||
// }
|
||||
//
|
||||
// We want {"topic":"Info"} to deserialize even though
|
||||
// ordinarily unit structs do not deserialize from empty map.
|
||||
// ordinarily unit structs do not deserialize from empty map/seq.
|
||||
Content::Map(ref v) if v.is_empty() => visitor.visit_unit(),
|
||||
Content::Seq(ref v) if v.is_empty() => visitor.visit_unit(),
|
||||
_ => self.deserialize_any(visitor),
|
||||
}
|
||||
}
|
||||
@@ -1420,6 +1416,7 @@ mod content {
|
||||
Content::ByteBuf(v) => visitor.visit_byte_buf(v),
|
||||
Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
|
||||
Content::U8(v) => visitor.visit_u8(v),
|
||||
Content::U64(v) => visitor.visit_u64(v),
|
||||
_ => Err(self.invalid_type(&visitor)),
|
||||
}
|
||||
}
|
||||
@@ -1431,6 +1428,18 @@ mod content {
|
||||
drop(self);
|
||||
visitor.visit_unit()
|
||||
}
|
||||
|
||||
fn __deserialize_content<V>(
|
||||
self,
|
||||
_: actually_private::T,
|
||||
visitor: V,
|
||||
) -> Result<Content<'de>, Self::Error>
|
||||
where
|
||||
V: Visitor<'de, Value = Content<'de>>,
|
||||
{
|
||||
let _ = visitor;
|
||||
Ok(self.content)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, E> ContentDeserializer<'de, E> {
|
||||
@@ -1557,7 +1566,7 @@ mod content {
|
||||
other.unexpected(),
|
||||
&"struct variant",
|
||||
)),
|
||||
_ => Err(de::Error::invalid_type(
|
||||
None => Err(de::Error::invalid_type(
|
||||
de::Unexpected::UnitVariant,
|
||||
&"struct variant",
|
||||
)),
|
||||
@@ -1746,6 +1755,25 @@ mod content {
|
||||
_ => Err(self.invalid_type(&visitor)),
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_float<V>(self, visitor: V) -> Result<V::Value, E>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
match *self.content {
|
||||
Content::F32(v) => visitor.visit_f32(v),
|
||||
Content::F64(v) => visitor.visit_f64(v),
|
||||
Content::U8(v) => visitor.visit_u8(v),
|
||||
Content::U16(v) => visitor.visit_u16(v),
|
||||
Content::U32(v) => visitor.visit_u32(v),
|
||||
Content::U64(v) => visitor.visit_u64(v),
|
||||
Content::I8(v) => visitor.visit_i8(v),
|
||||
Content::I16(v) => visitor.visit_i16(v),
|
||||
Content::I32(v) => visitor.visit_i32(v),
|
||||
Content::I64(v) => visitor.visit_i64(v),
|
||||
_ => Err(self.invalid_type(&visitor)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_content_seq_ref<'a, 'de, V, E>(
|
||||
@@ -1893,25 +1921,14 @@ mod content {
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
match *self.content {
|
||||
Content::F32(v) => visitor.visit_f32(v),
|
||||
Content::F64(v) => visitor.visit_f64(v),
|
||||
Content::U64(v) => visitor.visit_u64(v),
|
||||
Content::I64(v) => visitor.visit_i64(v),
|
||||
_ => Err(self.invalid_type(&visitor)),
|
||||
}
|
||||
self.deserialize_float(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
match *self.content {
|
||||
Content::F64(v) => visitor.visit_f64(v),
|
||||
Content::U64(v) => visitor.visit_u64(v),
|
||||
Content::I64(v) => visitor.visit_i64(v),
|
||||
_ => Err(self.invalid_type(&visitor)),
|
||||
}
|
||||
self.deserialize_float(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
@@ -2123,6 +2140,7 @@ mod content {
|
||||
Content::ByteBuf(ref v) => visitor.visit_bytes(v),
|
||||
Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
|
||||
Content::U8(v) => visitor.visit_u8(v),
|
||||
Content::U64(v) => visitor.visit_u64(v),
|
||||
_ => Err(self.invalid_type(&visitor)),
|
||||
}
|
||||
}
|
||||
@@ -2133,6 +2151,18 @@ mod content {
|
||||
{
|
||||
visitor.visit_unit()
|
||||
}
|
||||
|
||||
fn __deserialize_content<V>(
|
||||
self,
|
||||
_: actually_private::T,
|
||||
visitor: V,
|
||||
) -> Result<Content<'de>, Self::Error>
|
||||
where
|
||||
V: Visitor<'de, Value = Content<'de>>,
|
||||
{
|
||||
let _ = visitor;
|
||||
Ok(self.content.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'de, E> ContentRefDeserializer<'a, 'de, E> {
|
||||
@@ -2246,7 +2276,7 @@ mod content {
|
||||
other.unexpected(),
|
||||
&"struct variant",
|
||||
)),
|
||||
_ => Err(de::Error::invalid_type(
|
||||
None => Err(de::Error::invalid_type(
|
||||
de::Unexpected::UnitVariant,
|
||||
&"struct variant",
|
||||
)),
|
||||
@@ -2468,7 +2498,7 @@ mod content {
|
||||
where
|
||||
M: MapAccess<'de>,
|
||||
{
|
||||
while let Some(_) = try!(access.next_entry::<IgnoredAny, IgnoredAny>()) {}
|
||||
while try!(access.next_entry::<IgnoredAny, IgnoredAny>()).is_some() {}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -2508,6 +2538,13 @@ mod content {
|
||||
{
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn visit_none<E>(self) -> Result<(), E>
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2529,11 +2566,13 @@ pub trait IdentifierDeserializer<'de, E: Error> {
|
||||
fn from(self) -> Self::Deserializer;
|
||||
}
|
||||
|
||||
impl<'de, E> IdentifierDeserializer<'de, E> for u32
|
||||
pub struct Borrowed<'de, T: 'de + ?Sized>(pub &'de T);
|
||||
|
||||
impl<'de, E> IdentifierDeserializer<'de, E> for u64
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
type Deserializer = <u32 as IntoDeserializer<'de, E>>::Deserializer;
|
||||
type Deserializer = <u64 as IntoDeserializer<'de, E>>::Deserializer;
|
||||
|
||||
fn from(self) -> Self::Deserializer {
|
||||
self.into_deserializer()
|
||||
@@ -2545,20 +2584,6 @@ pub struct StrDeserializer<'a, E> {
|
||||
marker: PhantomData<E>,
|
||||
}
|
||||
|
||||
impl<'a, E> IdentifierDeserializer<'a, E> for &'a str
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
type Deserializer = StrDeserializer<'a, E>;
|
||||
|
||||
fn from(self) -> Self::Deserializer {
|
||||
StrDeserializer {
|
||||
value: self,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, 'a, E> Deserializer<'de> for StrDeserializer<'a, E>
|
||||
where
|
||||
E: Error,
|
||||
@@ -2579,26 +2604,12 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BytesDeserializer<'a, E> {
|
||||
value: &'a [u8],
|
||||
pub struct BorrowedStrDeserializer<'de, E> {
|
||||
value: &'de str,
|
||||
marker: PhantomData<E>,
|
||||
}
|
||||
|
||||
impl<'a, E> IdentifierDeserializer<'a, E> for &'a [u8]
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
type Deserializer = BytesDeserializer<'a, E>;
|
||||
|
||||
fn from(self) -> Self::Deserializer {
|
||||
BytesDeserializer {
|
||||
value: self,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, 'a, E> Deserializer<'de> for BytesDeserializer<'a, E>
|
||||
impl<'de, E> Deserializer<'de> for BorrowedStrDeserializer<'de, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -2608,7 +2619,7 @@ where
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
visitor.visit_bytes(self.value)
|
||||
visitor.visit_borrowed_str(self.value)
|
||||
}
|
||||
|
||||
forward_to_deserialize_any! {
|
||||
@@ -2618,21 +2629,53 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// A DeserializeSeed helper for implementing deserialize_in_place Visitors.
|
||||
///
|
||||
/// Wraps a mutable reference and calls deserialize_in_place on it.
|
||||
pub struct InPlaceSeed<'a, T: 'a>(pub &'a mut T);
|
||||
|
||||
impl<'a, 'de, T> DeserializeSeed<'de> for InPlaceSeed<'a, T>
|
||||
impl<'a, E> IdentifierDeserializer<'a, E> for &'a str
|
||||
where
|
||||
T: Deserialize<'de>,
|
||||
E: Error,
|
||||
{
|
||||
type Value = ();
|
||||
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
T::deserialize_in_place(deserializer, self.0)
|
||||
type Deserializer = StrDeserializer<'a, E>;
|
||||
|
||||
fn from(self) -> Self::Deserializer {
|
||||
StrDeserializer {
|
||||
value: self,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, E> IdentifierDeserializer<'de, E> for Borrowed<'de, str>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
type Deserializer = BorrowedStrDeserializer<'de, E>;
|
||||
|
||||
fn from(self) -> Self::Deserializer {
|
||||
BorrowedStrDeserializer {
|
||||
value: self.0,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, E> IdentifierDeserializer<'a, E> for &'a [u8]
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
type Deserializer = BytesDeserializer<'a, E>;
|
||||
|
||||
fn from(self) -> Self::Deserializer {
|
||||
BytesDeserializer::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, E> IdentifierDeserializer<'de, E> for Borrowed<'de, [u8]>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
type Deserializer = BorrowedBytesDeserializer<'de, E>;
|
||||
|
||||
fn from(self) -> Self::Deserializer {
|
||||
BorrowedBytesDeserializer::new(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2709,7 +2752,7 @@ where
|
||||
}
|
||||
|
||||
Err(Error::custom(format_args!(
|
||||
"no variant of enum {} not found in flattened data",
|
||||
"no variant of enum {} found in flattened data",
|
||||
name
|
||||
)))
|
||||
}
|
||||
@@ -2750,6 +2793,13 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
visitor.visit_unit()
|
||||
}
|
||||
|
||||
forward_to_deserialize_other! {
|
||||
deserialize_bool()
|
||||
deserialize_i8()
|
||||
@@ -2767,7 +2817,6 @@ where
|
||||
deserialize_string()
|
||||
deserialize_bytes()
|
||||
deserialize_byte_buf()
|
||||
deserialize_unit()
|
||||
deserialize_unit_struct(&'static str)
|
||||
deserialize_seq()
|
||||
deserialize_tuple(usize)
|
||||
@@ -2808,7 +2857,7 @@ where
|
||||
where
|
||||
T: DeserializeSeed<'de>,
|
||||
{
|
||||
while let Some(item) = self.iter.next() {
|
||||
for item in &mut self.iter {
|
||||
// Items in the vector are nulled out when used by a struct.
|
||||
if let Some((ref key, ref content)) = *item {
|
||||
self.pending_content = Some(content);
|
||||
@@ -2910,7 +2959,7 @@ where
|
||||
where
|
||||
T: DeserializeSeed<'de>,
|
||||
{
|
||||
while let Some(item) = self.iter.next() {
|
||||
for item in &mut self.iter {
|
||||
if let Some((ref key, ref content)) = *item {
|
||||
// Do not take(), instead borrow this entry. The internally tagged
|
||||
// enum does its own buffering so we can't tell whether this entry
|
||||
|
||||
@@ -1,3 +1,35 @@
|
||||
// Used only by Serde doc tests. Not public API.
|
||||
|
||||
use lib::*;
|
||||
|
||||
use ser;
|
||||
|
||||
#[doc(hidden)]
|
||||
#[derive(Debug)]
|
||||
pub struct Error;
|
||||
|
||||
impl ser::Error for Error {
|
||||
fn custom<T>(_: T) -> Self
|
||||
where
|
||||
T: Display,
|
||||
{
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl error::Error for Error {
|
||||
fn description(&self) -> &str {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Error {
|
||||
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! __private_serialize {
|
||||
@@ -10,19 +42,6 @@ macro_rules! __private_serialize {
|
||||
};
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! __private_deserialize {
|
||||
() => {
|
||||
trait Deserialize<'de>: Sized {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: $crate::Deserializer<'de>;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Used only by Serde doc tests. Not public API.
|
||||
#[doc(hidden)]
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! __serialize_unimplemented {
|
||||
@@ -37,7 +56,7 @@ macro_rules! __serialize_unimplemented {
|
||||
#[macro_export]
|
||||
macro_rules! __serialize_unimplemented_method {
|
||||
($func:ident $(<$t:ident>)* ($($arg:ty),*) -> $ret:ident) => {
|
||||
fn $func $(<$t: ?Sized + $crate::Serialize>)* (self $(, _: $arg)*) -> $crate::export::Result<Self::$ret, Self::Error> {
|
||||
fn $func $(<$t: ?Sized + $crate::Serialize>)* (self $(, _: $arg)*) -> $crate::__private::Result<Self::$ret, Self::Error> {
|
||||
unimplemented!()
|
||||
}
|
||||
};
|
||||
@@ -1,4 +1,50 @@
|
||||
mod macros;
|
||||
|
||||
#[cfg(not(no_serde_derive))]
|
||||
pub mod de;
|
||||
#[cfg(not(no_serde_derive))]
|
||||
pub mod ser;
|
||||
|
||||
pub mod size_hint;
|
||||
|
||||
// FIXME: #[cfg(doctest)] once https://github.com/rust-lang/rust/issues/67295 is fixed.
|
||||
pub mod doc;
|
||||
|
||||
pub use lib::clone::Clone;
|
||||
pub use lib::convert::{From, Into};
|
||||
pub use lib::default::Default;
|
||||
pub use lib::fmt::{self, Formatter};
|
||||
pub use lib::marker::PhantomData;
|
||||
pub use lib::option::Option::{self, None, Some};
|
||||
pub use lib::ptr;
|
||||
pub use lib::result::Result::{self, Err, Ok};
|
||||
|
||||
pub use self::string::from_utf8_lossy;
|
||||
|
||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
||||
pub use lib::{ToString, Vec};
|
||||
|
||||
#[cfg(not(no_core_try_from))]
|
||||
pub use lib::convert::TryFrom;
|
||||
|
||||
mod string {
|
||||
use lib::*;
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
pub fn from_utf8_lossy(bytes: &[u8]) -> Cow<str> {
|
||||
String::from_utf8_lossy(bytes)
|
||||
}
|
||||
|
||||
// The generated code calls this like:
|
||||
//
|
||||
// let value = &_serde::__private::from_utf8_lossy(bytes);
|
||||
// Err(_serde::de::Error::unknown_variant(value, VARIANTS))
|
||||
//
|
||||
// so it is okay for the return type to be different from the std case as long
|
||||
// as the above works.
|
||||
#[cfg(not(any(feature = "std", feature = "alloc")))]
|
||||
pub fn from_utf8_lossy(bytes: &[u8]) -> &str {
|
||||
// Three unicode replacement characters if it fails. They look like a
|
||||
// white-on-black question mark. The user will recognize it as invalid
|
||||
// UTF-8.
|
||||
str::from_utf8(bytes).unwrap_or("\u{fffd}\u{fffd}\u{fffd}")
|
||||
}
|
||||
}
|
||||
|
||||
+34
-50
@@ -335,33 +335,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Used only by Serde doc tests. Not public API.
|
||||
#[doc(hidden)]
|
||||
#[derive(Debug)]
|
||||
pub struct Error;
|
||||
|
||||
impl ser::Error for Error {
|
||||
fn custom<T>(_: T) -> Self
|
||||
where
|
||||
T: Display,
|
||||
{
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl error::Error for Error {
|
||||
fn description(&self) -> &str {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Error {
|
||||
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
mod content {
|
||||
use lib::*;
|
||||
@@ -452,7 +425,6 @@ mod content {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Content {
|
||||
Bool(bool),
|
||||
|
||||
@@ -1032,7 +1004,7 @@ impl<'a, M> FlatMapSerializer<'a, M>
|
||||
where
|
||||
M: SerializeMap + 'a,
|
||||
{
|
||||
fn bad_type(self, what: Unsupported) -> M::Error {
|
||||
fn bad_type(what: Unsupported) -> M::Error {
|
||||
ser::Error::custom(format_args!(
|
||||
"can only flatten structs and maps (got {})",
|
||||
what
|
||||
@@ -1057,59 +1029,59 @@ where
|
||||
type SerializeStructVariant = FlatMapSerializeStructVariantAsMapValue<'a, M>;
|
||||
|
||||
fn serialize_bool(self, _: bool) -> Result<Self::Ok, Self::Error> {
|
||||
Err(self.bad_type(Unsupported::Boolean))
|
||||
Err(Self::bad_type(Unsupported::Boolean))
|
||||
}
|
||||
|
||||
fn serialize_i8(self, _: i8) -> Result<Self::Ok, Self::Error> {
|
||||
Err(self.bad_type(Unsupported::Integer))
|
||||
Err(Self::bad_type(Unsupported::Integer))
|
||||
}
|
||||
|
||||
fn serialize_i16(self, _: i16) -> Result<Self::Ok, Self::Error> {
|
||||
Err(self.bad_type(Unsupported::Integer))
|
||||
Err(Self::bad_type(Unsupported::Integer))
|
||||
}
|
||||
|
||||
fn serialize_i32(self, _: i32) -> Result<Self::Ok, Self::Error> {
|
||||
Err(self.bad_type(Unsupported::Integer))
|
||||
Err(Self::bad_type(Unsupported::Integer))
|
||||
}
|
||||
|
||||
fn serialize_i64(self, _: i64) -> Result<Self::Ok, Self::Error> {
|
||||
Err(self.bad_type(Unsupported::Integer))
|
||||
Err(Self::bad_type(Unsupported::Integer))
|
||||
}
|
||||
|
||||
fn serialize_u8(self, _: u8) -> Result<Self::Ok, Self::Error> {
|
||||
Err(self.bad_type(Unsupported::Integer))
|
||||
Err(Self::bad_type(Unsupported::Integer))
|
||||
}
|
||||
|
||||
fn serialize_u16(self, _: u16) -> Result<Self::Ok, Self::Error> {
|
||||
Err(self.bad_type(Unsupported::Integer))
|
||||
Err(Self::bad_type(Unsupported::Integer))
|
||||
}
|
||||
|
||||
fn serialize_u32(self, _: u32) -> Result<Self::Ok, Self::Error> {
|
||||
Err(self.bad_type(Unsupported::Integer))
|
||||
Err(Self::bad_type(Unsupported::Integer))
|
||||
}
|
||||
|
||||
fn serialize_u64(self, _: u64) -> Result<Self::Ok, Self::Error> {
|
||||
Err(self.bad_type(Unsupported::Integer))
|
||||
Err(Self::bad_type(Unsupported::Integer))
|
||||
}
|
||||
|
||||
fn serialize_f32(self, _: f32) -> Result<Self::Ok, Self::Error> {
|
||||
Err(self.bad_type(Unsupported::Float))
|
||||
Err(Self::bad_type(Unsupported::Float))
|
||||
}
|
||||
|
||||
fn serialize_f64(self, _: f64) -> Result<Self::Ok, Self::Error> {
|
||||
Err(self.bad_type(Unsupported::Float))
|
||||
Err(Self::bad_type(Unsupported::Float))
|
||||
}
|
||||
|
||||
fn serialize_char(self, _: char) -> Result<Self::Ok, Self::Error> {
|
||||
Err(self.bad_type(Unsupported::Char))
|
||||
Err(Self::bad_type(Unsupported::Char))
|
||||
}
|
||||
|
||||
fn serialize_str(self, _: &str) -> Result<Self::Ok, Self::Error> {
|
||||
Err(self.bad_type(Unsupported::String))
|
||||
Err(Self::bad_type(Unsupported::String))
|
||||
}
|
||||
|
||||
fn serialize_bytes(self, _: &[u8]) -> Result<Self::Ok, Self::Error> {
|
||||
Err(self.bad_type(Unsupported::ByteArray))
|
||||
Err(Self::bad_type(Unsupported::ByteArray))
|
||||
}
|
||||
|
||||
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
|
||||
@@ -1124,11 +1096,11 @@ where
|
||||
}
|
||||
|
||||
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
|
||||
Err(self.bad_type(Unsupported::Unit))
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok, Self::Error> {
|
||||
Err(self.bad_type(Unsupported::UnitStruct))
|
||||
Err(Self::bad_type(Unsupported::UnitStruct))
|
||||
}
|
||||
|
||||
fn serialize_unit_variant(
|
||||
@@ -1137,7 +1109,7 @@ where
|
||||
_: u32,
|
||||
_: &'static str,
|
||||
) -> Result<Self::Ok, Self::Error> {
|
||||
Err(self.bad_type(Unsupported::Enum))
|
||||
Err(Self::bad_type(Unsupported::Enum))
|
||||
}
|
||||
|
||||
fn serialize_newtype_struct<T: ?Sized>(
|
||||
@@ -1166,11 +1138,11 @@ where
|
||||
}
|
||||
|
||||
fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
|
||||
Err(self.bad_type(Unsupported::Sequence))
|
||||
Err(Self::bad_type(Unsupported::Sequence))
|
||||
}
|
||||
|
||||
fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple, Self::Error> {
|
||||
Err(self.bad_type(Unsupported::Tuple))
|
||||
Err(Self::bad_type(Unsupported::Tuple))
|
||||
}
|
||||
|
||||
fn serialize_tuple_struct(
|
||||
@@ -1178,7 +1150,7 @@ where
|
||||
_: &'static str,
|
||||
_: usize,
|
||||
) -> Result<Self::SerializeTupleStruct, Self::Error> {
|
||||
Err(self.bad_type(Unsupported::TupleStruct))
|
||||
Err(Self::bad_type(Unsupported::TupleStruct))
|
||||
}
|
||||
|
||||
fn serialize_tuple_variant(
|
||||
@@ -1188,7 +1160,7 @@ where
|
||||
_: &'static str,
|
||||
_: usize,
|
||||
) -> Result<Self::SerializeTupleVariant, Self::Error> {
|
||||
Err(self.bad_type(Unsupported::Enum))
|
||||
Err(Self::bad_type(Unsupported::Enum))
|
||||
}
|
||||
|
||||
fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
|
||||
@@ -1243,6 +1215,18 @@ where
|
||||
self.0.serialize_value(value)
|
||||
}
|
||||
|
||||
fn serialize_entry<K: ?Sized, V: ?Sized>(
|
||||
&mut self,
|
||||
key: &K,
|
||||
value: &V,
|
||||
) -> Result<(), Self::Error>
|
||||
where
|
||||
K: Serialize,
|
||||
V: Serialize,
|
||||
{
|
||||
self.0.serialize_entry(key, value)
|
||||
}
|
||||
|
||||
fn end(self) -> Result<(), Self::Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
use lib::*;
|
||||
|
||||
pub fn from_bounds<I>(iter: &I) -> Option<usize>
|
||||
where
|
||||
I: Iterator,
|
||||
{
|
||||
helper(iter.size_hint())
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
#[inline]
|
||||
pub fn cautious(hint: Option<usize>) -> usize {
|
||||
cmp::min(hint.unwrap_or(0), 4096)
|
||||
}
|
||||
|
||||
fn helper(bounds: (usize, Option<usize>)) -> Option<usize> {
|
||||
match bounds {
|
||||
(lower, Some(upper)) if lower == upper => Some(upper),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
use lib::*;
|
||||
use ser::{Error, Impossible, Serialize, Serializer};
|
||||
|
||||
impl Error for fmt::Error {
|
||||
fn custom<T: Display>(_msg: T) -> Self {
|
||||
fmt::Error
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! fmt_primitives {
|
||||
($($f:ident: $t:ty,)*) => {
|
||||
$(
|
||||
fn $f(self, v: $t) -> fmt::Result {
|
||||
Display::fmt(&v, self)
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
/// ```edition2018
|
||||
/// use serde::Serialize;
|
||||
/// use std::fmt::{self, Display};
|
||||
///
|
||||
/// #[derive(Serialize)]
|
||||
/// #[serde(rename_all = "kebab-case")]
|
||||
/// pub enum MessageType {
|
||||
/// StartRequest,
|
||||
/// EndRequest,
|
||||
/// }
|
||||
///
|
||||
/// impl Display for MessageType {
|
||||
/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
/// self.serialize(f)
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
impl<'a, 'b> Serializer for &'a mut fmt::Formatter<'b> {
|
||||
type Ok = ();
|
||||
type Error = fmt::Error;
|
||||
type SerializeSeq = Impossible<(), fmt::Error>;
|
||||
type SerializeTuple = Impossible<(), fmt::Error>;
|
||||
type SerializeTupleStruct = Impossible<(), fmt::Error>;
|
||||
type SerializeTupleVariant = Impossible<(), fmt::Error>;
|
||||
type SerializeMap = Impossible<(), fmt::Error>;
|
||||
type SerializeStruct = Impossible<(), fmt::Error>;
|
||||
type SerializeStructVariant = Impossible<(), fmt::Error>;
|
||||
|
||||
fmt_primitives! {
|
||||
serialize_bool: bool,
|
||||
serialize_i8: i8,
|
||||
serialize_i16: i16,
|
||||
serialize_i32: i32,
|
||||
serialize_i64: i64,
|
||||
serialize_u8: u8,
|
||||
serialize_u16: u16,
|
||||
serialize_u32: u32,
|
||||
serialize_u64: u64,
|
||||
serialize_f32: f32,
|
||||
serialize_f64: f64,
|
||||
serialize_char: char,
|
||||
serialize_str: &str,
|
||||
serialize_unit_struct: &'static str,
|
||||
}
|
||||
|
||||
serde_if_integer128! {
|
||||
fmt_primitives! {
|
||||
serialize_i128: i128,
|
||||
serialize_u128: u128,
|
||||
}
|
||||
}
|
||||
|
||||
fn serialize_unit_variant(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
variant: &'static str,
|
||||
) -> fmt::Result {
|
||||
Display::fmt(variant, self)
|
||||
}
|
||||
|
||||
fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T) -> fmt::Result
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
Serialize::serialize(value, self)
|
||||
}
|
||||
|
||||
fn serialize_bytes(self, _v: &[u8]) -> fmt::Result {
|
||||
Err(fmt::Error)
|
||||
}
|
||||
|
||||
fn serialize_none(self) -> fmt::Result {
|
||||
Err(fmt::Error)
|
||||
}
|
||||
|
||||
fn serialize_some<T: ?Sized>(self, _value: &T) -> fmt::Result
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
Err(fmt::Error)
|
||||
}
|
||||
|
||||
fn serialize_unit(self) -> fmt::Result {
|
||||
Err(fmt::Error)
|
||||
}
|
||||
|
||||
fn serialize_newtype_variant<T: ?Sized>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_value: &T,
|
||||
) -> fmt::Result
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
Err(fmt::Error)
|
||||
}
|
||||
|
||||
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, fmt::Error> {
|
||||
Err(fmt::Error)
|
||||
}
|
||||
|
||||
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, fmt::Error> {
|
||||
Err(fmt::Error)
|
||||
}
|
||||
|
||||
fn serialize_tuple_struct(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_len: usize,
|
||||
) -> Result<Self::SerializeTupleStruct, fmt::Error> {
|
||||
Err(fmt::Error)
|
||||
}
|
||||
|
||||
fn serialize_tuple_variant(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_len: usize,
|
||||
) -> Result<Self::SerializeTupleVariant, fmt::Error> {
|
||||
Err(fmt::Error)
|
||||
}
|
||||
|
||||
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, fmt::Error> {
|
||||
Err(fmt::Error)
|
||||
}
|
||||
|
||||
fn serialize_struct(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_len: usize,
|
||||
) -> Result<Self::SerializeStruct, fmt::Error> {
|
||||
Err(fmt::Error)
|
||||
}
|
||||
|
||||
fn serialize_struct_variant(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_len: usize,
|
||||
) -> Result<Self::SerializeStructVariant, fmt::Error> {
|
||||
Err(fmt::Error)
|
||||
}
|
||||
|
||||
fn collect_str<T: ?Sized>(self, value: &T) -> fmt::Result
|
||||
where
|
||||
T: Display,
|
||||
{
|
||||
Display::fmt(value, self)
|
||||
}
|
||||
}
|
||||
+150
-15
@@ -160,10 +160,12 @@ macro_rules! array_impls {
|
||||
}
|
||||
}
|
||||
|
||||
array_impls!(01 02 03 04 05 06 07 08 09 10
|
||||
11 12 13 14 15 16 17 18 19 20
|
||||
21 22 23 24 25 26 27 28 29 30
|
||||
31 32);
|
||||
array_impls! {
|
||||
01 02 03 04 05 06 07 08 09 10
|
||||
11 12 13 14 15 16 17 18 19 20
|
||||
21 22 23 24 25 26 27 28 29 30
|
||||
31 32
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -237,7 +239,7 @@ where
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[cfg(range_inclusive)]
|
||||
#[cfg(not(no_range_inclusive))]
|
||||
impl<Idx> Serialize for RangeInclusive<Idx>
|
||||
where
|
||||
Idx: Serialize,
|
||||
@@ -256,6 +258,29 @@ where
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[cfg(any(not(no_ops_bound), all(feature = "std", not(no_collections_bound))))]
|
||||
impl<T> Serialize for Bound<T>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
match *self {
|
||||
Bound::Unbounded => serializer.serialize_unit_variant("Bound", 0, "Unbounded"),
|
||||
Bound::Included(ref value) => {
|
||||
serializer.serialize_newtype_variant("Bound", 1, "Included", value)
|
||||
}
|
||||
Bound::Excluded(ref value) => {
|
||||
serializer.serialize_newtype_variant("Bound", 2, "Excluded", value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
impl Serialize for () {
|
||||
#[inline]
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
@@ -442,7 +467,7 @@ where
|
||||
macro_rules! nonzero_integers {
|
||||
( $( $T: ident, )+ ) => {
|
||||
$(
|
||||
#[cfg(num_nonzero)]
|
||||
#[cfg(not(no_num_nonzero))]
|
||||
impl Serialize for num::$T {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
@@ -456,7 +481,6 @@ macro_rules! nonzero_integers {
|
||||
}
|
||||
|
||||
nonzero_integers! {
|
||||
// Not including signed NonZeroI* since they might be removed
|
||||
NonZeroU8,
|
||||
NonZeroU16,
|
||||
NonZeroU32,
|
||||
@@ -464,12 +488,26 @@ nonzero_integers! {
|
||||
NonZeroUsize,
|
||||
}
|
||||
|
||||
#[cfg(not(no_num_nonzero_signed))]
|
||||
nonzero_integers! {
|
||||
NonZeroI8,
|
||||
NonZeroI16,
|
||||
NonZeroI32,
|
||||
NonZeroI64,
|
||||
NonZeroIsize,
|
||||
}
|
||||
|
||||
// Currently 128-bit integers do not work on Emscripten targets so we need an
|
||||
// additional `#[cfg]`
|
||||
serde_if_integer128! {
|
||||
nonzero_integers! {
|
||||
NonZeroU128,
|
||||
}
|
||||
|
||||
#[cfg(not(no_num_nonzero_signed))]
|
||||
nonzero_integers! {
|
||||
NonZeroI128,
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Serialize for Cell<T>
|
||||
@@ -553,7 +591,7 @@ where
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[cfg(any(core_duration, feature = "std"))]
|
||||
#[cfg(any(feature = "std", not(no_core_duration)))]
|
||||
impl Serialize for Duration {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
@@ -578,7 +616,7 @@ impl Serialize for SystemTime {
|
||||
use super::SerializeStruct;
|
||||
let duration_since_epoch = self
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("SystemTime must be later than UNIX_EPOCH");
|
||||
.map_err(|_| S::Error::custom("SystemTime must be later than UNIX_EPOCH"))?;
|
||||
let mut state = try!(serializer.serialize_struct("SystemTime", 2));
|
||||
try!(state.serialize_field("secs_since_epoch", &duration_since_epoch.as_secs()));
|
||||
try!(state.serialize_field("nanos_since_epoch", &duration_since_epoch.subsec_nanos()));
|
||||
@@ -595,7 +633,7 @@ impl Serialize for SystemTime {
|
||||
#[cfg(feature = "std")]
|
||||
macro_rules! serialize_display_bounded_length {
|
||||
($value:expr, $max:expr, $serializer:expr) => {{
|
||||
let mut buffer: [u8; $max] = unsafe { mem::uninitialized() };
|
||||
let mut buffer = [0u8; $max];
|
||||
let remaining_len = {
|
||||
let mut remaining = &mut buffer[..];
|
||||
write!(remaining, "{}", $value).unwrap();
|
||||
@@ -607,7 +645,7 @@ macro_rules! serialize_display_bounded_length {
|
||||
// write! only provides fmt::Formatter to Display implementations, which
|
||||
// has methods write_str and write_char but no method to write arbitrary
|
||||
// bytes. Therefore `written` must be valid UTF-8.
|
||||
let written_str = unsafe { str::from_utf8_unchecked(written) };
|
||||
let written_str = str::from_utf8(written).expect("must be valid UTF-8");
|
||||
$serializer.serialize_str(written_str)
|
||||
}};
|
||||
}
|
||||
@@ -636,6 +674,52 @@ impl Serialize for net::IpAddr {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
const DEC_DIGITS_LUT: &'static [u8] = b"\
|
||||
0001020304050607080910111213141516171819\
|
||||
2021222324252627282930313233343536373839\
|
||||
4041424344454647484950515253545556575859\
|
||||
6061626364656667686970717273747576777879\
|
||||
8081828384858687888990919293949596979899";
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[inline]
|
||||
fn format_u8(mut n: u8, out: &mut [u8]) -> usize {
|
||||
if n >= 100 {
|
||||
let d1 = ((n % 100) << 1) as usize;
|
||||
n /= 100;
|
||||
out[0] = b'0' + n;
|
||||
out[1] = DEC_DIGITS_LUT[d1];
|
||||
out[2] = DEC_DIGITS_LUT[d1 + 1];
|
||||
3
|
||||
} else if n >= 10 {
|
||||
let d1 = (n << 1) as usize;
|
||||
out[0] = DEC_DIGITS_LUT[d1];
|
||||
out[1] = DEC_DIGITS_LUT[d1 + 1];
|
||||
2
|
||||
} else {
|
||||
out[0] = b'0' + n;
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[test]
|
||||
fn test_format_u8() {
|
||||
let mut i = 0u8;
|
||||
|
||||
loop {
|
||||
let mut buf = [0u8; 3];
|
||||
let written = format_u8(i, &mut buf);
|
||||
assert_eq!(i.to_string().as_bytes(), &buf[..written]);
|
||||
|
||||
match i.checked_add(1) {
|
||||
Some(next) => i = next,
|
||||
None => break,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl Serialize for net::Ipv4Addr {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
@@ -645,7 +729,14 @@ impl Serialize for net::Ipv4Addr {
|
||||
if serializer.is_human_readable() {
|
||||
const MAX_LEN: usize = 15;
|
||||
debug_assert_eq!(MAX_LEN, "101.102.103.104".len());
|
||||
serialize_display_bounded_length!(self, MAX_LEN, serializer)
|
||||
let mut buf = [b'.'; MAX_LEN];
|
||||
let mut written = format_u8(self.octets()[0], &mut buf);
|
||||
for oct in &self.octets()[1..] {
|
||||
// Skip over delimiters that we initialized buf with
|
||||
written += format_u8(*oct, &mut buf[written + 1..]) + 1;
|
||||
}
|
||||
// We've only written ASCII bytes to the buffer, so it is valid UTF-8
|
||||
serializer.serialize_str(unsafe { str::from_utf8_unchecked(&buf[..written]) })
|
||||
} else {
|
||||
self.octets().serialize(serializer)
|
||||
}
|
||||
@@ -715,10 +806,10 @@ impl Serialize for net::SocketAddrV6 {
|
||||
S: Serializer,
|
||||
{
|
||||
if serializer.is_human_readable() {
|
||||
const MAX_LEN: usize = 47;
|
||||
const MAX_LEN: usize = 58;
|
||||
debug_assert_eq!(
|
||||
MAX_LEN,
|
||||
"[1001:1002:1003:1004:1005:1006:1007:1008]:65000".len()
|
||||
"[1001:1002:1003:1004:1005:1006:1007:1008%4294967295]:65000".len()
|
||||
);
|
||||
serialize_display_bounded_length!(self, MAX_LEN, serializer)
|
||||
} else {
|
||||
@@ -786,7 +877,6 @@ impl Serialize for OsString {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<T> Serialize for Wrapping<T>
|
||||
where
|
||||
T: Serialize,
|
||||
@@ -799,3 +889,48 @@ where
|
||||
self.0.serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(no_core_reverse))]
|
||||
impl<T> Serialize for Reverse<T>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
#[inline]
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
self.0.serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[cfg(all(feature = "std", not(no_std_atomic)))]
|
||||
macro_rules! atomic_impl {
|
||||
($($ty:ident)*) => {
|
||||
$(
|
||||
impl Serialize for $ty {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
// Matches the atomic ordering used in libcore for the Debug impl
|
||||
self.load(Ordering::SeqCst).serialize(serializer)
|
||||
}
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "std", not(no_std_atomic)))]
|
||||
atomic_impl! {
|
||||
AtomicBool
|
||||
AtomicI8 AtomicI16 AtomicI32 AtomicIsize
|
||||
AtomicU8 AtomicU16 AtomicU32 AtomicUsize
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "std", not(no_std_atomic64)))]
|
||||
atomic_impl! {
|
||||
AtomicI64 AtomicU64
|
||||
}
|
||||
|
||||
@@ -15,12 +15,9 @@ use ser::{
|
||||
/// [`SerializeTuple`], [`SerializeTupleStruct`], [`SerializeTupleVariant`],
|
||||
/// [`SerializeMap`], [`SerializeStruct`], and [`SerializeStructVariant`].
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::ser::{Serializer, Impossible};
|
||||
/// # use serde::private::ser::Error;
|
||||
/// # use serde::__private::doc::Error;
|
||||
/// #
|
||||
/// # struct MySerializer;
|
||||
/// #
|
||||
@@ -44,14 +41,12 @@ use ser::{
|
||||
/// }
|
||||
///
|
||||
/// /* other Serializer methods */
|
||||
/// # __serialize_unimplemented! {
|
||||
/// # serde::__serialize_unimplemented! {
|
||||
/// # bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str bytes none some
|
||||
/// # unit unit_struct unit_variant newtype_struct newtype_variant
|
||||
/// # tuple tuple_struct tuple_variant map struct struct_variant
|
||||
/// # }
|
||||
/// }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
///
|
||||
/// [`Serializer`]: trait.Serializer.html
|
||||
|
||||
+108
-198
@@ -56,13 +56,13 @@
|
||||
//! - PhantomData\<T\>
|
||||
//! - **Wrapper types**:
|
||||
//! - Box\<T\>
|
||||
//! - Rc\<T\>
|
||||
//! - Arc\<T\>
|
||||
//! - Cow\<'a, T\>
|
||||
//! - Cell\<T\>
|
||||
//! - RefCell\<T\>
|
||||
//! - Mutex\<T\>
|
||||
//! - RwLock\<T\>
|
||||
//! - Rc\<T\> *(if* features = ["rc"] *is enabled)*
|
||||
//! - Arc\<T\> *(if* features = ["rc"] *is enabled)*
|
||||
//! - **Collection types**:
|
||||
//! - BTreeMap\<K, V\>
|
||||
//! - BTreeSet\<T\>
|
||||
@@ -84,6 +84,7 @@
|
||||
//! - PathBuf
|
||||
//! - Range\<T\>
|
||||
//! - RangeInclusive\<T\>
|
||||
//! - Bound\<T\>
|
||||
//! - num::NonZero*
|
||||
//! - `!` *(unstable)*
|
||||
//! - **Net types**:
|
||||
@@ -98,7 +99,7 @@
|
||||
//! [`LinkedHashMap<K, V>`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html
|
||||
//! [`Serialize`]: ../trait.Serialize.html
|
||||
//! [`Serializer`]: ../trait.Serializer.html
|
||||
//! [`bincode`]: https://github.com/TyOverby/bincode
|
||||
//! [`bincode`]: https://github.com/servo/bincode
|
||||
//! [`linked-hash-map`]: https://crates.io/crates/linked-hash-map
|
||||
//! [`serde_derive`]: https://crates.io/crates/serde_derive
|
||||
//! [`serde_json`]: https://github.com/serde-rs/json
|
||||
@@ -108,11 +109,19 @@
|
||||
|
||||
use lib::*;
|
||||
|
||||
mod fmt;
|
||||
mod impls;
|
||||
mod impossible;
|
||||
|
||||
pub use self::impossible::Impossible;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[doc(no_inline)]
|
||||
pub use std::error::Error as StdError;
|
||||
#[cfg(not(feature = "std"))]
|
||||
#[doc(no_inline)]
|
||||
pub use std_error::Error as StdError;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
macro_rules! declare_error_trait {
|
||||
@@ -137,7 +146,7 @@ macro_rules! declare_error_trait {
|
||||
/// For example, a filesystem [`Path`] may refuse to serialize
|
||||
/// itself if it contains invalid UTF-8 data.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # struct Path;
|
||||
/// #
|
||||
/// # impl Path {
|
||||
@@ -171,7 +180,7 @@ macro_rules! declare_error_trait {
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
declare_error_trait!(Error: Sized + error::Error);
|
||||
declare_error_trait!(Error: Sized + StdError);
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
declare_error_trait!(Error: Sized + Debug + Display);
|
||||
@@ -210,7 +219,7 @@ pub trait Serialize {
|
||||
/// See the [Implementing `Serialize`] section of the manual for more
|
||||
/// information about how to implement this method.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// use serde::ser::{Serialize, SerializeStruct, Serializer};
|
||||
///
|
||||
/// struct Person {
|
||||
@@ -377,13 +386,10 @@ pub trait Serializer: Sized {
|
||||
|
||||
/// Serialize a `bool` value.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::Serializer;
|
||||
/// #
|
||||
/// # __private_serialize!();
|
||||
/// # serde::__private_serialize!();
|
||||
/// #
|
||||
/// impl Serialize for bool {
|
||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
@@ -393,8 +399,6 @@ pub trait Serializer: Sized {
|
||||
/// serializer.serialize_bool(*self)
|
||||
/// }
|
||||
/// }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error>;
|
||||
|
||||
@@ -404,13 +408,10 @@ pub trait Serializer: Sized {
|
||||
/// reasonable implementation would be to cast the value to `i64` and
|
||||
/// forward to `serialize_i64`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::Serializer;
|
||||
/// #
|
||||
/// # __private_serialize!();
|
||||
/// # serde::__private_serialize!();
|
||||
/// #
|
||||
/// impl Serialize for i8 {
|
||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
@@ -420,8 +421,6 @@ pub trait Serializer: Sized {
|
||||
/// serializer.serialize_i8(*self)
|
||||
/// }
|
||||
/// }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error>;
|
||||
|
||||
@@ -431,13 +430,10 @@ pub trait Serializer: Sized {
|
||||
/// reasonable implementation would be to cast the value to `i64` and
|
||||
/// forward to `serialize_i64`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::Serializer;
|
||||
/// #
|
||||
/// # __private_serialize!();
|
||||
/// # serde::__private_serialize!();
|
||||
/// #
|
||||
/// impl Serialize for i16 {
|
||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
@@ -447,8 +443,6 @@ pub trait Serializer: Sized {
|
||||
/// serializer.serialize_i16(*self)
|
||||
/// }
|
||||
/// }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error>;
|
||||
|
||||
@@ -458,13 +452,10 @@ pub trait Serializer: Sized {
|
||||
/// reasonable implementation would be to cast the value to `i64` and
|
||||
/// forward to `serialize_i64`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::Serializer;
|
||||
/// #
|
||||
/// # __private_serialize!();
|
||||
/// # serde::__private_serialize!();
|
||||
/// #
|
||||
/// impl Serialize for i32 {
|
||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
@@ -474,20 +465,15 @@ pub trait Serializer: Sized {
|
||||
/// serializer.serialize_i32(*self)
|
||||
/// }
|
||||
/// }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error>;
|
||||
|
||||
/// Serialize an `i64` value.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::Serializer;
|
||||
/// #
|
||||
/// # __private_serialize!();
|
||||
/// # serde::__private_serialize!();
|
||||
/// #
|
||||
/// impl Serialize for i64 {
|
||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
@@ -497,21 +483,16 @@ pub trait Serializer: Sized {
|
||||
/// serializer.serialize_i64(*self)
|
||||
/// }
|
||||
/// }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error>;
|
||||
|
||||
serde_if_integer128! {
|
||||
/// Serialize an `i128` value.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::Serializer;
|
||||
/// #
|
||||
/// # __private_serialize!();
|
||||
/// # serde::__private_serialize!();
|
||||
/// #
|
||||
/// impl Serialize for i128 {
|
||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
@@ -521,8 +502,6 @@ pub trait Serializer: Sized {
|
||||
/// serializer.serialize_i128(*self)
|
||||
/// }
|
||||
/// }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
///
|
||||
/// This method is available only on Rust compiler versions >=1.26. The
|
||||
@@ -539,13 +518,10 @@ pub trait Serializer: Sized {
|
||||
/// reasonable implementation would be to cast the value to `u64` and
|
||||
/// forward to `serialize_u64`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::Serializer;
|
||||
/// #
|
||||
/// # __private_serialize!();
|
||||
/// # serde::__private_serialize!();
|
||||
/// #
|
||||
/// impl Serialize for u8 {
|
||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
@@ -555,8 +531,6 @@ pub trait Serializer: Sized {
|
||||
/// serializer.serialize_u8(*self)
|
||||
/// }
|
||||
/// }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error>;
|
||||
|
||||
@@ -566,13 +540,10 @@ pub trait Serializer: Sized {
|
||||
/// reasonable implementation would be to cast the value to `u64` and
|
||||
/// forward to `serialize_u64`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::Serializer;
|
||||
/// #
|
||||
/// # __private_serialize!();
|
||||
/// # serde::__private_serialize!();
|
||||
/// #
|
||||
/// impl Serialize for u16 {
|
||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
@@ -582,8 +553,6 @@ pub trait Serializer: Sized {
|
||||
/// serializer.serialize_u16(*self)
|
||||
/// }
|
||||
/// }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error>;
|
||||
|
||||
@@ -593,13 +562,10 @@ pub trait Serializer: Sized {
|
||||
/// reasonable implementation would be to cast the value to `u64` and
|
||||
/// forward to `serialize_u64`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::Serializer;
|
||||
/// #
|
||||
/// # __private_serialize!();
|
||||
/// # serde::__private_serialize!();
|
||||
/// #
|
||||
/// impl Serialize for u32 {
|
||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
@@ -609,20 +575,15 @@ pub trait Serializer: Sized {
|
||||
/// serializer.serialize_u32(*self)
|
||||
/// }
|
||||
/// }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error>;
|
||||
|
||||
/// Serialize a `u64` value.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::Serializer;
|
||||
/// #
|
||||
/// # __private_serialize!();
|
||||
/// # serde::__private_serialize!();
|
||||
/// #
|
||||
/// impl Serialize for u64 {
|
||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
@@ -632,21 +593,16 @@ pub trait Serializer: Sized {
|
||||
/// serializer.serialize_u64(*self)
|
||||
/// }
|
||||
/// }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error>;
|
||||
|
||||
serde_if_integer128! {
|
||||
/// Serialize a `u128` value.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::Serializer;
|
||||
/// #
|
||||
/// # __private_serialize!();
|
||||
/// # serde::__private_serialize!();
|
||||
/// #
|
||||
/// impl Serialize for u128 {
|
||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
@@ -656,8 +612,6 @@ pub trait Serializer: Sized {
|
||||
/// serializer.serialize_u128(*self)
|
||||
/// }
|
||||
/// }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
///
|
||||
/// This method is available only on Rust compiler versions >=1.26. The
|
||||
@@ -674,13 +628,10 @@ pub trait Serializer: Sized {
|
||||
/// reasonable implementation would be to cast the value to `f64` and
|
||||
/// forward to `serialize_f64`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::Serializer;
|
||||
/// #
|
||||
/// # __private_serialize!();
|
||||
/// # serde::__private_serialize!();
|
||||
/// #
|
||||
/// impl Serialize for f32 {
|
||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
@@ -690,20 +641,15 @@ pub trait Serializer: Sized {
|
||||
/// serializer.serialize_f32(*self)
|
||||
/// }
|
||||
/// }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error>;
|
||||
|
||||
/// Serialize an `f64` value.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::Serializer;
|
||||
/// #
|
||||
/// # __private_serialize!();
|
||||
/// # serde::__private_serialize!();
|
||||
/// #
|
||||
/// impl Serialize for f64 {
|
||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
@@ -713,8 +659,6 @@ pub trait Serializer: Sized {
|
||||
/// serializer.serialize_f64(*self)
|
||||
/// }
|
||||
/// }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error>;
|
||||
|
||||
@@ -723,13 +667,10 @@ pub trait Serializer: Sized {
|
||||
/// If the format does not support characters, it is reasonable to serialize
|
||||
/// it as a single element `str` or a `u32`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::Serializer;
|
||||
/// #
|
||||
/// # __private_serialize!();
|
||||
/// # serde::__private_serialize!();
|
||||
/// #
|
||||
/// impl Serialize for char {
|
||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
@@ -739,20 +680,15 @@ pub trait Serializer: Sized {
|
||||
/// serializer.serialize_char(*self)
|
||||
/// }
|
||||
/// }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error>;
|
||||
|
||||
/// Serialize a `&str`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::Serializer;
|
||||
/// #
|
||||
/// # __private_serialize!();
|
||||
/// # serde::__private_serialize!();
|
||||
/// #
|
||||
/// impl Serialize for str {
|
||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
@@ -762,8 +698,6 @@ pub trait Serializer: Sized {
|
||||
/// serializer.serialize_str(self)
|
||||
/// }
|
||||
/// }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error>;
|
||||
|
||||
@@ -775,12 +709,9 @@ pub trait Serializer: Sized {
|
||||
/// `serialize_seq`. If forwarded, the implementation looks usually just
|
||||
/// like this:
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::ser::{Serializer, SerializeSeq};
|
||||
/// # use serde::private::ser::Error;
|
||||
/// # use serde::__private::doc::Error;
|
||||
/// #
|
||||
/// # struct MySerializer;
|
||||
/// #
|
||||
@@ -796,22 +727,18 @@ pub trait Serializer: Sized {
|
||||
/// seq.end()
|
||||
/// }
|
||||
/// #
|
||||
/// # __serialize_unimplemented! {
|
||||
/// # serde::__serialize_unimplemented! {
|
||||
/// # bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str none some
|
||||
/// # unit unit_struct unit_variant newtype_struct newtype_variant
|
||||
/// # seq tuple tuple_struct tuple_variant map struct struct_variant
|
||||
/// # }
|
||||
/// # }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error>;
|
||||
|
||||
/// Serialize a [`None`] value.
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate serde;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::{Serialize, Serializer};
|
||||
/// #
|
||||
/// # enum Option<T> {
|
||||
@@ -819,7 +746,7 @@ pub trait Serializer: Sized {
|
||||
/// # None,
|
||||
/// # }
|
||||
/// #
|
||||
/// # use Option::{Some, None};
|
||||
/// # use self::Option::{Some, None};
|
||||
/// #
|
||||
/// impl<T> Serialize for Option<T>
|
||||
/// where
|
||||
@@ -844,9 +771,7 @@ pub trait Serializer: Sized {
|
||||
|
||||
/// Serialize a [`Some(T)`] value.
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate serde;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::{Serialize, Serializer};
|
||||
/// #
|
||||
/// # enum Option<T> {
|
||||
@@ -854,7 +779,7 @@ pub trait Serializer: Sized {
|
||||
/// # None,
|
||||
/// # }
|
||||
/// #
|
||||
/// # use Option::{Some, None};
|
||||
/// # use self::Option::{Some, None};
|
||||
/// #
|
||||
/// impl<T> Serialize for Option<T>
|
||||
/// where
|
||||
@@ -881,13 +806,10 @@ pub trait Serializer: Sized {
|
||||
|
||||
/// Serialize a `()` value.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::Serializer;
|
||||
/// #
|
||||
/// # __private_serialize!();
|
||||
/// # serde::__private_serialize!();
|
||||
/// #
|
||||
/// impl Serialize for () {
|
||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
@@ -897,8 +819,6 @@ pub trait Serializer: Sized {
|
||||
/// serializer.serialize_unit()
|
||||
/// }
|
||||
/// }
|
||||
/// #
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
fn serialize_unit(self) -> Result<Self::Ok, Self::Error>;
|
||||
|
||||
@@ -906,7 +826,7 @@ pub trait Serializer: Sized {
|
||||
///
|
||||
/// A reasonable implementation would be to forward to `serialize_unit`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// use serde::{Serialize, Serializer};
|
||||
///
|
||||
/// struct Nothing;
|
||||
@@ -928,7 +848,7 @@ pub trait Serializer: Sized {
|
||||
/// this variant within the enum, and the `variant` is the name of the
|
||||
/// variant.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// use serde::{Serialize, Serializer};
|
||||
///
|
||||
/// enum E {
|
||||
@@ -961,7 +881,7 @@ pub trait Serializer: Sized {
|
||||
/// wrappers around the data they contain. A reasonable implementation would
|
||||
/// be to forward to `value.serialize(self)`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// use serde::{Serialize, Serializer};
|
||||
///
|
||||
/// struct Millimeters(u8);
|
||||
@@ -989,7 +909,7 @@ pub trait Serializer: Sized {
|
||||
/// this variant within the enum, and the `variant` is the name of the
|
||||
/// variant. The `value` is the data contained within this newtype variant.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// use serde::{Serialize, Serializer};
|
||||
///
|
||||
/// enum E {
|
||||
@@ -1027,7 +947,7 @@ pub trait Serializer: Sized {
|
||||
/// not be computable before the sequence is iterated. Some serializers only
|
||||
/// support sequences whose length is known up front.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use std::marker::PhantomData;
|
||||
/// #
|
||||
/// # struct Vec<T>(PhantomData<T>);
|
||||
@@ -1072,7 +992,7 @@ pub trait Serializer: Sized {
|
||||
/// This call must be followed by zero or more calls to `serialize_element`,
|
||||
/// then a call to `end`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// use serde::ser::{Serialize, Serializer, SerializeTuple};
|
||||
///
|
||||
/// # mod fool {
|
||||
@@ -1102,7 +1022,7 @@ pub trait Serializer: Sized {
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// use serde::ser::{Serialize, SerializeTuple, Serializer};
|
||||
///
|
||||
/// const VRAM_SIZE: usize = 386;
|
||||
@@ -1130,7 +1050,7 @@ pub trait Serializer: Sized {
|
||||
/// The `name` is the name of the tuple struct and the `len` is the number
|
||||
/// of data fields that will be serialized.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// use serde::ser::{Serialize, SerializeTupleStruct, Serializer};
|
||||
///
|
||||
/// struct Rgb(u8, u8, u8);
|
||||
@@ -1162,7 +1082,7 @@ pub trait Serializer: Sized {
|
||||
/// this variant within the enum, the `variant` is the name of the variant,
|
||||
/// and the `len` is the number of data fields that will be serialized.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// use serde::ser::{Serialize, SerializeTupleVariant, Serializer};
|
||||
///
|
||||
/// enum E {
|
||||
@@ -1208,7 +1128,7 @@ pub trait Serializer: Sized {
|
||||
/// be computable before the map is iterated. Some serializers only support
|
||||
/// maps whose length is known up front.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use std::marker::PhantomData;
|
||||
/// #
|
||||
/// # struct HashMap<K, V>(PhantomData<K>, PhantomData<V>);
|
||||
@@ -1256,7 +1176,7 @@ pub trait Serializer: Sized {
|
||||
/// The `name` is the name of the struct and the `len` is the number of
|
||||
/// data fields that will be serialized.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// use serde::ser::{Serialize, SerializeStruct, Serializer};
|
||||
///
|
||||
/// struct Rgb {
|
||||
@@ -1292,7 +1212,7 @@ pub trait Serializer: Sized {
|
||||
/// this variant within the enum, the `variant` is the name of the variant,
|
||||
/// and the `len` is the number of data fields that will be serialized.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// use serde::ser::{Serialize, SerializeStructVariant, Serializer};
|
||||
///
|
||||
/// enum E {
|
||||
@@ -1334,7 +1254,7 @@ pub trait Serializer: Sized {
|
||||
/// using [`serialize_seq`]. Implementors should not need to override this
|
||||
/// method.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// use serde::{Serialize, Serializer};
|
||||
///
|
||||
/// struct SecretlyOneHigher {
|
||||
@@ -1358,10 +1278,21 @@ pub trait Serializer: Sized {
|
||||
<I as IntoIterator>::Item: Serialize,
|
||||
{
|
||||
let iter = iter.into_iter();
|
||||
let mut serializer = try!(self.serialize_seq(iter.len_hint()));
|
||||
for item in iter {
|
||||
try!(serializer.serialize_element(&item));
|
||||
let mut serializer = try!(self.serialize_seq(iterator_len_hint(&iter)));
|
||||
|
||||
#[cfg(not(no_iterator_try_fold))]
|
||||
{
|
||||
let mut iter = iter;
|
||||
try!(iter.try_for_each(|item| serializer.serialize_element(&item)));
|
||||
}
|
||||
|
||||
#[cfg(no_iterator_try_fold)]
|
||||
{
|
||||
for item in iter {
|
||||
try!(serializer.serialize_element(&item));
|
||||
}
|
||||
}
|
||||
|
||||
serializer.end()
|
||||
}
|
||||
|
||||
@@ -1371,7 +1302,7 @@ pub trait Serializer: Sized {
|
||||
/// using [`serialize_map`]. Implementors should not need to override this
|
||||
/// method.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// use serde::{Serialize, Serializer};
|
||||
/// use std::collections::BTreeSet;
|
||||
///
|
||||
@@ -1398,10 +1329,21 @@ pub trait Serializer: Sized {
|
||||
I: IntoIterator<Item = (K, V)>,
|
||||
{
|
||||
let iter = iter.into_iter();
|
||||
let mut serializer = try!(self.serialize_map(iter.len_hint()));
|
||||
for (key, value) in iter {
|
||||
try!(serializer.serialize_entry(&key, &value));
|
||||
let mut serializer = try!(self.serialize_map(iterator_len_hint(&iter)));
|
||||
|
||||
#[cfg(not(no_iterator_try_fold))]
|
||||
{
|
||||
let mut iter = iter;
|
||||
try!(iter.try_for_each(|(key, value)| serializer.serialize_entry(&key, &value)));
|
||||
}
|
||||
|
||||
#[cfg(no_iterator_try_fold)]
|
||||
{
|
||||
for (key, value) in iter {
|
||||
try!(serializer.serialize_entry(&key, &value));
|
||||
}
|
||||
}
|
||||
|
||||
serializer.end()
|
||||
}
|
||||
|
||||
@@ -1411,7 +1353,7 @@ pub trait Serializer: Sized {
|
||||
/// delegates to [`serialize_str`]. Serializers are encouraged to provide a
|
||||
/// more efficient implementation if possible.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # struct DateTime;
|
||||
/// #
|
||||
/// # impl DateTime {
|
||||
@@ -1440,10 +1382,7 @@ pub trait Serializer: Sized {
|
||||
where
|
||||
T: Display,
|
||||
{
|
||||
use lib::fmt::Write;
|
||||
let mut string = String::new();
|
||||
write!(string, "{}", value).unwrap();
|
||||
self.serialize_str(&string)
|
||||
self.serialize_str(&value.to_string())
|
||||
}
|
||||
|
||||
/// Serialize a string produced by an implementation of `Display`.
|
||||
@@ -1452,7 +1391,7 @@ pub trait Serializer: Sized {
|
||||
/// of this method. If no more sensible behavior is possible, the
|
||||
/// implementation is expected to return an error.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # struct DateTime;
|
||||
/// #
|
||||
/// # impl DateTime {
|
||||
@@ -1487,7 +1426,7 @@ pub trait Serializer: Sized {
|
||||
/// human-readable one and binary formats like Bincode will prefer the
|
||||
/// compact one.
|
||||
///
|
||||
/// ```
|
||||
/// ```edition2018
|
||||
/// # use std::fmt::{self, Display};
|
||||
/// #
|
||||
/// # struct Timestamp;
|
||||
@@ -1536,7 +1475,7 @@ pub trait Serializer: Sized {
|
||||
///
|
||||
/// # Example use
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use std::marker::PhantomData;
|
||||
/// #
|
||||
/// # struct Vec<T>(PhantomData<T>);
|
||||
@@ -1600,7 +1539,7 @@ pub trait SerializeSeq {
|
||||
///
|
||||
/// # Example use
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// use serde::ser::{Serialize, Serializer, SerializeTuple};
|
||||
///
|
||||
/// # mod fool {
|
||||
@@ -1630,7 +1569,7 @@ pub trait SerializeSeq {
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use std::marker::PhantomData;
|
||||
/// #
|
||||
/// # struct Array<T>(PhantomData<T>);
|
||||
@@ -1700,7 +1639,7 @@ pub trait SerializeTuple {
|
||||
///
|
||||
/// # Example use
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// use serde::ser::{Serialize, SerializeTupleStruct, Serializer};
|
||||
///
|
||||
/// struct Rgb(u8, u8, u8);
|
||||
@@ -1745,7 +1684,7 @@ pub trait SerializeTupleStruct {
|
||||
///
|
||||
/// # Example use
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// use serde::ser::{Serialize, SerializeTupleVariant, Serializer};
|
||||
///
|
||||
/// enum E {
|
||||
@@ -1803,7 +1742,7 @@ pub trait SerializeTupleVariant {
|
||||
///
|
||||
/// # Example use
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use std::marker::PhantomData;
|
||||
/// #
|
||||
/// # struct HashMap<K, V>(PhantomData<K>, PhantomData<V>);
|
||||
@@ -1914,7 +1853,7 @@ pub trait SerializeMap {
|
||||
///
|
||||
/// # Example use
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// use serde::ser::{Serialize, SerializeStruct, Serializer};
|
||||
///
|
||||
/// struct Rgb {
|
||||
@@ -1974,7 +1913,7 @@ pub trait SerializeStruct {
|
||||
///
|
||||
/// # Example use
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// use serde::ser::{Serialize, SerializeStructVariant, Serializer};
|
||||
///
|
||||
/// enum E {
|
||||
@@ -2036,35 +1975,6 @@ pub trait SerializeStructVariant {
|
||||
fn end(self) -> Result<Self::Ok, Self::Error>;
|
||||
}
|
||||
|
||||
trait LenHint: Iterator {
|
||||
fn len_hint(&self) -> Option<usize>;
|
||||
}
|
||||
|
||||
impl<I> LenHint for I
|
||||
where
|
||||
I: Iterator,
|
||||
{
|
||||
#[cfg(not(feature = "unstable"))]
|
||||
fn len_hint(&self) -> Option<usize> {
|
||||
iterator_len_hint(self)
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable")]
|
||||
default fn len_hint(&self) -> Option<usize> {
|
||||
iterator_len_hint(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable")]
|
||||
impl<I> LenHint for I
|
||||
where
|
||||
I: ExactSizeIterator,
|
||||
{
|
||||
fn len_hint(&self) -> Option<usize> {
|
||||
Some(self.len())
|
||||
}
|
||||
}
|
||||
|
||||
fn iterator_len_hint<I>(iter: &I) -> Option<usize>
|
||||
where
|
||||
I: Iterator,
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
use lib::{Debug, Display};
|
||||
|
||||
/// Either a re-export of std::error::Error or a new identical trait, depending
|
||||
/// on whether Serde's "std" feature is enabled.
|
||||
///
|
||||
/// Serde's error traits [`serde::ser::Error`] and [`serde::de::Error`] require
|
||||
/// [`std::error::Error`] as a supertrait, but only when Serde is built with
|
||||
/// "std" enabled. Data formats that don't care about no\_std support should
|
||||
/// generally provide their error types with a `std::error::Error` impl
|
||||
/// directly:
|
||||
///
|
||||
/// ```edition2018
|
||||
/// #[derive(Debug)]
|
||||
/// struct MySerError {...}
|
||||
///
|
||||
/// impl serde::ser::Error for MySerError {...}
|
||||
///
|
||||
/// impl std::fmt::Display for MySerError {...}
|
||||
///
|
||||
/// // We don't support no_std!
|
||||
/// impl std::error::Error for MySerError {}
|
||||
/// ```
|
||||
///
|
||||
/// Data formats that *do* support no\_std may either have a "std" feature of
|
||||
/// their own:
|
||||
///
|
||||
/// ```toml
|
||||
/// [features]
|
||||
/// std = ["serde/std"]
|
||||
/// ```
|
||||
///
|
||||
/// ```edition2018
|
||||
/// #[cfg(feature = "std")]
|
||||
/// impl std::error::Error for MySerError {}
|
||||
/// ```
|
||||
///
|
||||
/// ... or else provide the std Error impl unconditionally via Serde's
|
||||
/// re-export:
|
||||
///
|
||||
/// ```edition2018
|
||||
/// impl serde::ser::StdError for MySerError {}
|
||||
/// ```
|
||||
pub trait Error: Debug + Display {
|
||||
/// The underlying cause of this error, if any.
|
||||
fn source(&self) -> Option<&(Error + 'static)> {
|
||||
None
|
||||
}
|
||||
}
|
||||
+10
-10
@@ -1,19 +1,16 @@
|
||||
[package]
|
||||
name = "serde_derive"
|
||||
version = "1.0.81" # remember to update html_root_url
|
||||
version = "1.0.135" # remember to update html_root_url
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
rust-version = "1.31"
|
||||
license = "MIT OR Apache-2.0"
|
||||
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
|
||||
homepage = "https://serde.rs"
|
||||
repository = "https://github.com/serde-rs/serde"
|
||||
documentation = "https://serde.rs/derive.html"
|
||||
keywords = ["serde", "serialization", "no_std"]
|
||||
readme = "crates-io.md"
|
||||
include = ["Cargo.toml", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
|
||||
[badges]
|
||||
travis-ci = { repository = "serde-rs/serde" }
|
||||
appveyor = { repository = "serde-rs/serde" }
|
||||
include = ["build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
|
||||
[features]
|
||||
default = []
|
||||
@@ -24,9 +21,12 @@ name = "serde_derive"
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "0.4"
|
||||
quote = "0.6.3"
|
||||
syn = { version = "0.15.22", features = ["visit"] }
|
||||
proc-macro2 = "1.0"
|
||||
quote = "1.0"
|
||||
syn = "1.0.60"
|
||||
|
||||
[dev-dependencies]
|
||||
serde = { version = "1.0", path = "../serde" }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
use std::env;
|
||||
use std::process::Command;
|
||||
use std::str;
|
||||
|
||||
// The rustc-cfg strings below are *not* public API. Please let us know by
|
||||
// opening a GitHub issue if your build environment requires some way to enable
|
||||
// these cfgs other than by executing our build script.
|
||||
fn main() {
|
||||
let minor = match rustc_minor_version() {
|
||||
Some(minor) => minor,
|
||||
None => return,
|
||||
};
|
||||
|
||||
// Underscore const names stabilized in Rust 1.37:
|
||||
// https://blog.rust-lang.org/2019/08/15/Rust-1.37.0.html#using-unnamed-const-items-for-macros
|
||||
if minor >= 37 {
|
||||
println!("cargo:rustc-cfg=underscore_consts");
|
||||
}
|
||||
|
||||
// The ptr::addr_of! macro stabilized in Rust 1.51:
|
||||
// https://blog.rust-lang.org/2021/03/25/Rust-1.51.0.html#stabilized-apis
|
||||
if minor >= 51 {
|
||||
println!("cargo:rustc-cfg=ptr_addr_of");
|
||||
}
|
||||
}
|
||||
|
||||
fn rustc_minor_version() -> Option<u32> {
|
||||
let rustc = env::var_os("RUSTC")?;
|
||||
let output = Command::new(rustc).arg("--version").output().ok()?;
|
||||
let version = str::from_utf8(&output.stdout).ok()?;
|
||||
let mut pieces = version.split('.');
|
||||
if pieces.next() != Some("rustc 1") {
|
||||
return None;
|
||||
}
|
||||
pieces.next()?.parse().ok()
|
||||
}
|
||||
+117
-26
@@ -2,10 +2,9 @@ use std::collections::HashSet;
|
||||
|
||||
use syn;
|
||||
use syn::punctuated::{Pair, Punctuated};
|
||||
use syn::visit::{self, Visit};
|
||||
|
||||
use internals::ast::{Container, Data};
|
||||
use internals::attr;
|
||||
use internals::{attr, ungroup};
|
||||
|
||||
use proc_macro2::Span;
|
||||
|
||||
@@ -17,8 +16,8 @@ pub fn without_defaults(generics: &syn::Generics) -> syn::Generics {
|
||||
params: generics
|
||||
.params
|
||||
.iter()
|
||||
.map(|param| match *param {
|
||||
syn::GenericParam::Type(ref param) => syn::GenericParam::Type(syn::TypeParam {
|
||||
.map(|param| match param {
|
||||
syn::GenericParam::Type(param) => syn::GenericParam::Type(syn::TypeParam {
|
||||
eq_token: None,
|
||||
default: None,
|
||||
..param.clone()
|
||||
@@ -50,8 +49,8 @@ pub fn with_where_predicates_from_fields(
|
||||
let predicates = cont
|
||||
.data
|
||||
.all_fields()
|
||||
.flat_map(|field| from_field(&field.attrs))
|
||||
.flat_map(|predicates| predicates.to_vec());
|
||||
.filter_map(|field| from_field(&field.attrs))
|
||||
.flat_map(<[syn::WherePredicate]>::to_vec);
|
||||
|
||||
let mut generics = generics.clone();
|
||||
generics.make_where_clause().predicates.extend(predicates);
|
||||
@@ -63,8 +62,8 @@ pub fn with_where_predicates_from_variants(
|
||||
generics: &syn::Generics,
|
||||
from_variant: fn(&attr::Variant) -> Option<&[syn::WherePredicate]>,
|
||||
) -> syn::Generics {
|
||||
let variants = match cont.data {
|
||||
Data::Enum(ref variants) => variants,
|
||||
let variants = match &cont.data {
|
||||
Data::Enum(variants) => variants,
|
||||
Data::Struct(_, _) => {
|
||||
return generics.clone();
|
||||
}
|
||||
@@ -72,8 +71,8 @@ pub fn with_where_predicates_from_variants(
|
||||
|
||||
let predicates = variants
|
||||
.iter()
|
||||
.flat_map(|variant| from_variant(&variant.attrs))
|
||||
.flat_map(|predicates| predicates.to_vec());
|
||||
.filter_map(|variant| from_variant(&variant.attrs))
|
||||
.flat_map(<[syn::WherePredicate]>::to_vec);
|
||||
|
||||
let mut generics = generics.clone();
|
||||
generics.make_where_clause().predicates.extend(predicates);
|
||||
@@ -112,10 +111,11 @@ pub fn with_bound(
|
||||
// parameters.
|
||||
associated_type_usage: Vec<&'ast syn::TypePath>,
|
||||
}
|
||||
impl<'ast> Visit<'ast> for FindTyParams<'ast> {
|
||||
|
||||
impl<'ast> FindTyParams<'ast> {
|
||||
fn visit_field(&mut self, field: &'ast syn::Field) {
|
||||
if let syn::Type::Path(ref ty) = field.ty {
|
||||
if let Some(Pair::Punctuated(ref t, _)) = ty.path.segments.first() {
|
||||
if let syn::Type::Path(ty) = ungroup(&field.ty) {
|
||||
if let Some(Pair::Punctuated(t, _)) = ty.path.segments.pairs().next() {
|
||||
if self.all_type_params.contains(&t.ident) {
|
||||
self.associated_type_usage.push(ty);
|
||||
}
|
||||
@@ -126,7 +126,7 @@ pub fn with_bound(
|
||||
|
||||
fn visit_path(&mut self, path: &'ast syn::Path) {
|
||||
if let Some(seg) = path.segments.last() {
|
||||
if seg.into_value().ident == "PhantomData" {
|
||||
if seg.ident == "PhantomData" {
|
||||
// Hardcoded exception, because PhantomData<T> implements
|
||||
// Serialize and Deserialize whether or not T implements it.
|
||||
return;
|
||||
@@ -138,7 +138,98 @@ pub fn with_bound(
|
||||
self.relevant_type_params.insert(id.clone());
|
||||
}
|
||||
}
|
||||
visit::visit_path(self, path);
|
||||
for segment in &path.segments {
|
||||
self.visit_path_segment(segment);
|
||||
}
|
||||
}
|
||||
|
||||
// Everything below is simply traversing the syntax tree.
|
||||
|
||||
fn visit_type(&mut self, ty: &'ast syn::Type) {
|
||||
match ty {
|
||||
syn::Type::Array(ty) => self.visit_type(&ty.elem),
|
||||
syn::Type::BareFn(ty) => {
|
||||
for arg in &ty.inputs {
|
||||
self.visit_type(&arg.ty);
|
||||
}
|
||||
self.visit_return_type(&ty.output);
|
||||
}
|
||||
syn::Type::Group(ty) => self.visit_type(&ty.elem),
|
||||
syn::Type::ImplTrait(ty) => {
|
||||
for bound in &ty.bounds {
|
||||
self.visit_type_param_bound(bound);
|
||||
}
|
||||
}
|
||||
syn::Type::Macro(ty) => self.visit_macro(&ty.mac),
|
||||
syn::Type::Paren(ty) => self.visit_type(&ty.elem),
|
||||
syn::Type::Path(ty) => {
|
||||
if let Some(qself) = &ty.qself {
|
||||
self.visit_type(&qself.ty);
|
||||
}
|
||||
self.visit_path(&ty.path);
|
||||
}
|
||||
syn::Type::Ptr(ty) => self.visit_type(&ty.elem),
|
||||
syn::Type::Reference(ty) => self.visit_type(&ty.elem),
|
||||
syn::Type::Slice(ty) => self.visit_type(&ty.elem),
|
||||
syn::Type::TraitObject(ty) => {
|
||||
for bound in &ty.bounds {
|
||||
self.visit_type_param_bound(bound);
|
||||
}
|
||||
}
|
||||
syn::Type::Tuple(ty) => {
|
||||
for elem in &ty.elems {
|
||||
self.visit_type(elem);
|
||||
}
|
||||
}
|
||||
|
||||
syn::Type::Infer(_) | syn::Type::Never(_) | syn::Type::Verbatim(_) => {}
|
||||
|
||||
#[cfg(test)]
|
||||
syn::Type::__TestExhaustive(_) => unimplemented!(),
|
||||
#[cfg(not(test))]
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_path_segment(&mut self, segment: &'ast syn::PathSegment) {
|
||||
self.visit_path_arguments(&segment.arguments);
|
||||
}
|
||||
|
||||
fn visit_path_arguments(&mut self, arguments: &'ast syn::PathArguments) {
|
||||
match arguments {
|
||||
syn::PathArguments::None => {}
|
||||
syn::PathArguments::AngleBracketed(arguments) => {
|
||||
for arg in &arguments.args {
|
||||
match arg {
|
||||
syn::GenericArgument::Type(arg) => self.visit_type(arg),
|
||||
syn::GenericArgument::Binding(arg) => self.visit_type(&arg.ty),
|
||||
syn::GenericArgument::Lifetime(_)
|
||||
| syn::GenericArgument::Constraint(_)
|
||||
| syn::GenericArgument::Const(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
syn::PathArguments::Parenthesized(arguments) => {
|
||||
for argument in &arguments.inputs {
|
||||
self.visit_type(argument);
|
||||
}
|
||||
self.visit_return_type(&arguments.output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_return_type(&mut self, return_type: &'ast syn::ReturnType) {
|
||||
match return_type {
|
||||
syn::ReturnType::Default => {}
|
||||
syn::ReturnType::Type(_, output) => self.visit_type(output),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_type_param_bound(&mut self, bound: &'ast syn::TypeParamBound) {
|
||||
match bound {
|
||||
syn::TypeParamBound::Trait(bound) => self.visit_path(&bound.path),
|
||||
syn::TypeParamBound::Lifetime(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Type parameter should not be considered used by a macro path.
|
||||
@@ -156,12 +247,12 @@ pub fn with_bound(
|
||||
.collect();
|
||||
|
||||
let mut visitor = FindTyParams {
|
||||
all_type_params: all_type_params,
|
||||
all_type_params,
|
||||
relevant_type_params: HashSet::new(),
|
||||
associated_type_usage: Vec::new(),
|
||||
};
|
||||
match cont.data {
|
||||
Data::Enum(ref variants) => {
|
||||
match &cont.data {
|
||||
Data::Enum(variants) => {
|
||||
for variant in variants.iter() {
|
||||
let relevant_fields = variant
|
||||
.fields
|
||||
@@ -172,7 +263,7 @@ pub fn with_bound(
|
||||
}
|
||||
}
|
||||
}
|
||||
Data::Struct(_, ref fields) => {
|
||||
Data::Struct(_, fields) => {
|
||||
for field in fields.iter().filter(|field| filter(&field.attrs, None)) {
|
||||
visitor.visit_field(field.original);
|
||||
}
|
||||
@@ -255,11 +346,11 @@ pub fn with_lifetime_bound(generics: &syn::Generics, lifetime: &str) -> syn::Gen
|
||||
let params = Some(syn::GenericParam::Lifetime(def))
|
||||
.into_iter()
|
||||
.chain(generics.params.iter().cloned().map(|mut param| {
|
||||
match param {
|
||||
syn::GenericParam::Lifetime(ref mut param) => {
|
||||
match &mut param {
|
||||
syn::GenericParam::Lifetime(param) => {
|
||||
param.bounds.push(bound.clone());
|
||||
}
|
||||
syn::GenericParam::Type(ref mut param) => {
|
||||
syn::GenericParam::Type(param) => {
|
||||
param
|
||||
.bounds
|
||||
.push(syn::TypeParamBound::Lifetime(bound.clone()));
|
||||
@@ -271,7 +362,7 @@ pub fn with_lifetime_bound(generics: &syn::Generics, lifetime: &str) -> syn::Gen
|
||||
.collect();
|
||||
|
||||
syn::Generics {
|
||||
params: params,
|
||||
params,
|
||||
..generics.clone()
|
||||
}
|
||||
}
|
||||
@@ -291,14 +382,14 @@ fn type_of_item(cont: &Container) -> syn::Type {
|
||||
.generics
|
||||
.params
|
||||
.iter()
|
||||
.map(|param| match *param {
|
||||
syn::GenericParam::Type(ref param) => {
|
||||
.map(|param| match param {
|
||||
syn::GenericParam::Type(param) => {
|
||||
syn::GenericArgument::Type(syn::Type::Path(syn::TypePath {
|
||||
qself: None,
|
||||
path: param.ident.clone().into(),
|
||||
}))
|
||||
}
|
||||
syn::GenericParam::Lifetime(ref param) => {
|
||||
syn::GenericParam::Lifetime(param) => {
|
||||
syn::GenericArgument::Lifetime(param.lifetime.clone())
|
||||
}
|
||||
syn::GenericParam::Const(_) => {
|
||||
|
||||
+676
-528
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,48 @@
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::format_ident;
|
||||
|
||||
use syn;
|
||||
use try;
|
||||
|
||||
pub fn wrap_in_const(
|
||||
serde_path: Option<&syn::Path>,
|
||||
trait_: &str,
|
||||
ty: &Ident,
|
||||
code: TokenStream,
|
||||
) -> TokenStream {
|
||||
let try_replacement = try::replacement();
|
||||
|
||||
let dummy_const = if cfg!(underscore_consts) {
|
||||
format_ident!("_")
|
||||
} else {
|
||||
format_ident!("_IMPL_{}_FOR_{}", trait_, unraw(ty))
|
||||
};
|
||||
|
||||
let use_serde = match serde_path {
|
||||
Some(path) => quote! {
|
||||
use #path as _serde;
|
||||
},
|
||||
None => quote! {
|
||||
#[allow(unused_extern_crates, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
},
|
||||
};
|
||||
|
||||
quote! {
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const #dummy_const: () = {
|
||||
#use_serde
|
||||
#try_replacement
|
||||
#code
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
fn unraw(ident: &Ident) -> String {
|
||||
// str::trim_start_matches was added in 1.30, trim_left_matches deprecated
|
||||
// in 1.33. We currently support rustc back to 1.15 so we need to continue
|
||||
// to use the deprecated one.
|
||||
ident.to_string().trim_left_matches("r#").to_owned()
|
||||
}
|
||||
@@ -27,9 +27,9 @@ macro_rules! quote_block {
|
||||
pub struct Expr(pub Fragment);
|
||||
impl ToTokens for Expr {
|
||||
fn to_tokens(&self, out: &mut TokenStream) {
|
||||
match self.0 {
|
||||
Fragment::Expr(ref expr) => expr.to_tokens(out),
|
||||
Fragment::Block(ref block) => {
|
||||
match &self.0 {
|
||||
Fragment::Expr(expr) => expr.to_tokens(out),
|
||||
Fragment::Block(block) => {
|
||||
token::Brace::default().surround(out, |out| block.to_tokens(out));
|
||||
}
|
||||
}
|
||||
@@ -40,9 +40,9 @@ impl ToTokens for Expr {
|
||||
pub struct Stmts(pub Fragment);
|
||||
impl ToTokens for Stmts {
|
||||
fn to_tokens(&self, out: &mut TokenStream) {
|
||||
match self.0 {
|
||||
Fragment::Expr(ref expr) => expr.to_tokens(out),
|
||||
Fragment::Block(ref block) => block.to_tokens(out),
|
||||
match &self.0 {
|
||||
Fragment::Expr(expr) => expr.to_tokens(out),
|
||||
Fragment::Block(block) => block.to_tokens(out),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,12 +52,12 @@ impl ToTokens for Stmts {
|
||||
pub struct Match(pub Fragment);
|
||||
impl ToTokens for Match {
|
||||
fn to_tokens(&self, out: &mut TokenStream) {
|
||||
match self.0 {
|
||||
Fragment::Expr(ref expr) => {
|
||||
match &self.0 {
|
||||
Fragment::Expr(expr) => {
|
||||
expr.to_tokens(out);
|
||||
<Token![,]>::default().to_tokens(out);
|
||||
}
|
||||
Fragment::Block(ref block) => {
|
||||
Fragment::Block(block) => {
|
||||
token::Brace::default().surround(out, |out| block.to_tokens(out));
|
||||
}
|
||||
}
|
||||
@@ -66,9 +66,9 @@ impl ToTokens for Match {
|
||||
|
||||
impl AsRef<TokenStream> for Fragment {
|
||||
fn as_ref(&self) -> &TokenStream {
|
||||
match *self {
|
||||
Fragment::Expr(ref expr) => expr,
|
||||
Fragment::Block(ref block) => block,
|
||||
match self {
|
||||
Fragment::Expr(expr) => expr,
|
||||
Fragment::Block(block) => block,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ pub struct Container<'a> {
|
||||
|
||||
/// The fields of a struct or enum.
|
||||
///
|
||||
/// Analagous to `syn::Data`.
|
||||
/// Analogous to `syn::Data`.
|
||||
pub enum Data<'a> {
|
||||
Enum(Vec<Variant<'a>>),
|
||||
Struct(Style, Vec<Field<'a>>),
|
||||
@@ -60,14 +60,16 @@ pub enum Style {
|
||||
|
||||
impl<'a> Container<'a> {
|
||||
/// Convert the raw Syn ast into a parsed container object, collecting errors in `cx`.
|
||||
pub fn from_ast(cx: &Ctxt, item: &'a syn::DeriveInput, derive: Derive) -> Option<Container<'a>> {
|
||||
pub fn from_ast(
|
||||
cx: &Ctxt,
|
||||
item: &'a syn::DeriveInput,
|
||||
derive: Derive,
|
||||
) -> Option<Container<'a>> {
|
||||
let mut attrs = attr::Container::from_ast(cx, item);
|
||||
|
||||
let mut data = match item.data {
|
||||
syn::Data::Enum(ref data) => {
|
||||
Data::Enum(enum_from_ast(cx, &data.variants, attrs.default()))
|
||||
}
|
||||
syn::Data::Struct(ref data) => {
|
||||
let mut data = match &item.data {
|
||||
syn::Data::Enum(data) => Data::Enum(enum_from_ast(cx, &data.variants, attrs.default())),
|
||||
syn::Data::Struct(data) => {
|
||||
let (style, fields) = struct_from_ast(cx, &data.fields, None, attrs.default());
|
||||
Data::Struct(style, fields)
|
||||
}
|
||||
@@ -78,24 +80,26 @@ impl<'a> Container<'a> {
|
||||
};
|
||||
|
||||
let mut has_flatten = false;
|
||||
match data {
|
||||
Data::Enum(ref mut variants) => {
|
||||
match &mut data {
|
||||
Data::Enum(variants) => {
|
||||
for variant in variants {
|
||||
variant.attrs.rename_by_rule(attrs.rename_all());
|
||||
variant.attrs.rename_by_rules(attrs.rename_all_rules());
|
||||
for field in &mut variant.fields {
|
||||
if field.attrs.flatten() {
|
||||
has_flatten = true;
|
||||
}
|
||||
field.attrs.rename_by_rule(variant.attrs.rename_all());
|
||||
field
|
||||
.attrs
|
||||
.rename_by_rules(variant.attrs.rename_all_rules());
|
||||
}
|
||||
}
|
||||
}
|
||||
Data::Struct(_, ref mut fields) => {
|
||||
Data::Struct(_, fields) => {
|
||||
for field in fields {
|
||||
if field.attrs.flatten() {
|
||||
has_flatten = true;
|
||||
}
|
||||
field.attrs.rename_by_rule(attrs.rename_all());
|
||||
field.attrs.rename_by_rules(attrs.rename_all_rules());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,8 +110,8 @@ impl<'a> Container<'a> {
|
||||
|
||||
let mut item = Container {
|
||||
ident: item.ident.clone(),
|
||||
attrs: attrs,
|
||||
data: data,
|
||||
attrs,
|
||||
data,
|
||||
generics: &item.generics,
|
||||
original: item,
|
||||
};
|
||||
@@ -118,11 +122,11 @@ impl<'a> Container<'a> {
|
||||
|
||||
impl<'a> Data<'a> {
|
||||
pub fn all_fields(&'a self) -> Box<Iterator<Item = &'a Field<'a>> + 'a> {
|
||||
match *self {
|
||||
Data::Enum(ref variants) => {
|
||||
match self {
|
||||
Data::Enum(variants) => {
|
||||
Box::new(variants.iter().flat_map(|variant| variant.fields.iter()))
|
||||
}
|
||||
Data::Struct(_, ref fields) => Box::new(fields.iter()),
|
||||
Data::Struct(_, fields) => Box::new(fields.iter()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,9 +148,9 @@ fn enum_from_ast<'a>(
|
||||
struct_from_ast(cx, &variant.fields, Some(&attrs), container_default);
|
||||
Variant {
|
||||
ident: variant.ident.clone(),
|
||||
attrs: attrs,
|
||||
style: style,
|
||||
fields: fields,
|
||||
attrs,
|
||||
style,
|
||||
fields,
|
||||
original: variant,
|
||||
}
|
||||
})
|
||||
@@ -159,16 +163,16 @@ fn struct_from_ast<'a>(
|
||||
attrs: Option<&attr::Variant>,
|
||||
container_default: &attr::Default,
|
||||
) -> (Style, Vec<Field<'a>>) {
|
||||
match *fields {
|
||||
syn::Fields::Named(ref fields) => (
|
||||
match fields {
|
||||
syn::Fields::Named(fields) => (
|
||||
Style::Struct,
|
||||
fields_from_ast(cx, &fields.named, attrs, container_default),
|
||||
),
|
||||
syn::Fields::Unnamed(ref fields) if fields.unnamed.len() == 1 => (
|
||||
syn::Fields::Unnamed(fields) if fields.unnamed.len() == 1 => (
|
||||
Style::Newtype,
|
||||
fields_from_ast(cx, &fields.unnamed, attrs, container_default),
|
||||
),
|
||||
syn::Fields::Unnamed(ref fields) => (
|
||||
syn::Fields::Unnamed(fields) => (
|
||||
Style::Tuple,
|
||||
fields_from_ast(cx, &fields.unnamed, attrs, container_default),
|
||||
),
|
||||
@@ -186,8 +190,8 @@ fn fields_from_ast<'a>(
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, field)| Field {
|
||||
member: match field.ident {
|
||||
Some(ref ident) => syn::Member::Named(ident.clone()),
|
||||
member: match &field.ident {
|
||||
Some(ident) => syn::Member::Named(ident.clone()),
|
||||
None => syn::Member::Unnamed(i.into()),
|
||||
},
|
||||
attrs: attr::Field::from_ast(cx, i, field, attrs, container_default),
|
||||
|
||||
+947
-693
File diff suppressed because it is too large
Load Diff
@@ -5,19 +5,19 @@
|
||||
#[allow(deprecated, unused_imports)]
|
||||
use std::ascii::AsciiExt;
|
||||
|
||||
use std::str::FromStr;
|
||||
use std::fmt::{self, Debug, Display};
|
||||
|
||||
use self::RenameRule::*;
|
||||
|
||||
/// The different possible ways to change case of fields in a struct, or variants in an enum.
|
||||
#[derive(PartialEq)]
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum RenameRule {
|
||||
/// Don't apply a default rename rule.
|
||||
None,
|
||||
/// Rename direct children to "lowercase" style.
|
||||
LowerCase,
|
||||
/// Rename direct children to "UPPERCASE" style.
|
||||
UPPERCASE,
|
||||
UpperCase,
|
||||
/// Rename direct children to "PascalCase" style, as typically used for
|
||||
/// enum variants.
|
||||
PascalCase,
|
||||
@@ -35,13 +35,35 @@ pub enum RenameRule {
|
||||
ScreamingKebabCase,
|
||||
}
|
||||
|
||||
static RENAME_RULES: &[(&str, RenameRule)] = &[
|
||||
("lowercase", LowerCase),
|
||||
("UPPERCASE", UpperCase),
|
||||
("PascalCase", PascalCase),
|
||||
("camelCase", CamelCase),
|
||||
("snake_case", SnakeCase),
|
||||
("SCREAMING_SNAKE_CASE", ScreamingSnakeCase),
|
||||
("kebab-case", KebabCase),
|
||||
("SCREAMING-KEBAB-CASE", ScreamingKebabCase),
|
||||
];
|
||||
|
||||
impl RenameRule {
|
||||
pub fn from_str(rename_all_str: &str) -> Result<Self, ParseError> {
|
||||
for (name, rule) in RENAME_RULES {
|
||||
if rename_all_str == *name {
|
||||
return Ok(*rule);
|
||||
}
|
||||
}
|
||||
Err(ParseError {
|
||||
unknown: rename_all_str,
|
||||
})
|
||||
}
|
||||
|
||||
/// Apply a renaming rule to an enum variant, returning the version expected in the source.
|
||||
pub fn apply_to_variant(&self, variant: &str) -> String {
|
||||
match *self {
|
||||
None | PascalCase => variant.to_owned(),
|
||||
LowerCase => variant.to_ascii_lowercase(),
|
||||
UPPERCASE => variant.to_ascii_uppercase(),
|
||||
UpperCase => variant.to_ascii_uppercase(),
|
||||
CamelCase => variant[..1].to_ascii_lowercase() + &variant[1..],
|
||||
SnakeCase => {
|
||||
let mut snake = String::new();
|
||||
@@ -65,7 +87,7 @@ impl RenameRule {
|
||||
pub fn apply_to_field(&self, field: &str) -> String {
|
||||
match *self {
|
||||
None | LowerCase | SnakeCase => field.to_owned(),
|
||||
UPPERCASE => field.to_ascii_uppercase(),
|
||||
UpperCase => field.to_ascii_uppercase(),
|
||||
PascalCase => {
|
||||
let mut pascal = String::new();
|
||||
let mut capitalize = true;
|
||||
@@ -92,21 +114,22 @@ impl RenameRule {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for RenameRule {
|
||||
type Err = ();
|
||||
pub struct ParseError<'a> {
|
||||
unknown: &'a str,
|
||||
}
|
||||
|
||||
fn from_str(rename_all_str: &str) -> Result<Self, Self::Err> {
|
||||
match rename_all_str {
|
||||
"lowercase" => Ok(LowerCase),
|
||||
"UPPERCASE" => Ok(UPPERCASE),
|
||||
"PascalCase" => Ok(PascalCase),
|
||||
"camelCase" => Ok(CamelCase),
|
||||
"snake_case" => Ok(SnakeCase),
|
||||
"SCREAMING_SNAKE_CASE" => Ok(ScreamingSnakeCase),
|
||||
"kebab-case" => Ok(KebabCase),
|
||||
"SCREAMING-KEBAB-CASE" => Ok(ScreamingKebabCase),
|
||||
_ => Err(()),
|
||||
impl<'a> Display for ParseError<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.write_str("unknown rename rule `rename_all = ")?;
|
||||
Debug::fmt(self.unknown, f)?;
|
||||
f.write_str("`, expected one of ")?;
|
||||
for (i, (name, _rule)) in RENAME_RULES.iter().enumerate() {
|
||||
if i > 0 {
|
||||
f.write_str(", ")?;
|
||||
}
|
||||
Debug::fmt(name, f)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +154,7 @@ fn rename_variants() {
|
||||
] {
|
||||
assert_eq!(None.apply_to_variant(original), original);
|
||||
assert_eq!(LowerCase.apply_to_variant(original), lower);
|
||||
assert_eq!(UPPERCASE.apply_to_variant(original), upper);
|
||||
assert_eq!(UpperCase.apply_to_variant(original), upper);
|
||||
assert_eq!(PascalCase.apply_to_variant(original), original);
|
||||
assert_eq!(CamelCase.apply_to_variant(original), camel);
|
||||
assert_eq!(SnakeCase.apply_to_variant(original), snake);
|
||||
@@ -163,7 +186,7 @@ fn rename_fields() {
|
||||
("z42", "Z42", "Z42", "z42", "Z42", "z42", "Z42"),
|
||||
] {
|
||||
assert_eq!(None.apply_to_field(original), original);
|
||||
assert_eq!(UPPERCASE.apply_to_field(original), upper);
|
||||
assert_eq!(UpperCase.apply_to_field(original), upper);
|
||||
assert_eq!(PascalCase.apply_to_field(original), pascal);
|
||||
assert_eq!(CamelCase.apply_to_field(original), camel);
|
||||
assert_eq!(SnakeCase.apply_to_field(original), original);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use internals::ast::{Container, Data, Field, Style};
|
||||
use internals::attr::{EnumTag, Identifier};
|
||||
use internals::{Ctxt, Derive};
|
||||
use internals::attr::{Identifier, TagType};
|
||||
use internals::{ungroup, Ctxt, Derive};
|
||||
use syn::{Member, Type};
|
||||
|
||||
/// Cross-cutting checks that require looking at more than a single attrs
|
||||
@@ -13,6 +13,7 @@ pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) {
|
||||
check_internal_tag_field_name_conflict(cx, cont);
|
||||
check_adjacent_tag_conflict(cx, cont);
|
||||
check_transparent(cx, cont, derive);
|
||||
check_from_and_try_from(cx, cont);
|
||||
}
|
||||
|
||||
/// Getters are only allowed inside structs (not enums) with the `remote`
|
||||
@@ -31,8 +32,7 @@ fn check_getter(cx: &Ctxt, cont: &Container) {
|
||||
if cont.data.has_getter() && cont.attrs.remote().is_none() {
|
||||
cx.error_spanned_by(
|
||||
cont.original,
|
||||
"#[serde(getter = \"...\")] can only be used in structs \
|
||||
that have #[serde(remote = \"...\")]",
|
||||
"#[serde(getter = \"...\")] can only be used in structs that have #[serde(remote = \"...\")]",
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -41,17 +41,17 @@ fn check_getter(cx: &Ctxt, cont: &Container) {
|
||||
|
||||
/// Flattening has some restrictions we can test.
|
||||
fn check_flatten(cx: &Ctxt, cont: &Container) {
|
||||
match cont.data {
|
||||
Data::Enum(ref variants) => {
|
||||
match &cont.data {
|
||||
Data::Enum(variants) => {
|
||||
for variant in variants {
|
||||
for field in &variant.fields {
|
||||
check_flatten_field(cx, variant.style, field);
|
||||
}
|
||||
}
|
||||
}
|
||||
Data::Struct(style, ref fields) => {
|
||||
Data::Struct(style, fields) => {
|
||||
for field in fields {
|
||||
check_flatten_field(cx, style, field);
|
||||
check_flatten_field(cx, *style, field);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,25 +76,6 @@ fn check_flatten_field(cx: &Ctxt, style: Style, field: &Field) {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
if field.attrs.skip_serializing() {
|
||||
cx.error_spanned_by(
|
||||
field.original,
|
||||
"#[serde(flatten)] can not be combined with \
|
||||
#[serde(skip_serializing)]",
|
||||
);
|
||||
} else if field.attrs.skip_serializing_if().is_some() {
|
||||
cx.error_spanned_by(
|
||||
field.original,
|
||||
"#[serde(flatten)] can not be combined with \
|
||||
#[serde(skip_serializing_if = \"...\")]",
|
||||
);
|
||||
} else if field.attrs.skip_deserializing() {
|
||||
cx.error_spanned_by(
|
||||
field.original,
|
||||
"#[serde(flatten)] can not be combined with \
|
||||
#[serde(skip_deserializing)]",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// The `other` attribute must be used at most once and it must be the last
|
||||
@@ -104,8 +85,8 @@ fn check_flatten_field(cx: &Ctxt, style: Style, field: &Field) {
|
||||
/// `field_identifier` all but possibly one variant must be unit variants. The
|
||||
/// last variant may be a newtype variant which is an implicit "other" case.
|
||||
fn check_identifier(cx: &Ctxt, cont: &Container) {
|
||||
let variants = match cont.data {
|
||||
Data::Enum(ref variants) => variants,
|
||||
let variants = match &cont.data {
|
||||
Data::Enum(variants) => variants,
|
||||
Data::Struct(_, _) => {
|
||||
return;
|
||||
}
|
||||
@@ -127,7 +108,7 @@ fn check_identifier(cx: &Ctxt, cont: &Container) {
|
||||
}
|
||||
|
||||
// Variant with `other` attribute cannot appear in untagged enum
|
||||
(_, Identifier::No, true, &EnumTag::None) => {
|
||||
(_, Identifier::No, true, &TagType::None) => {
|
||||
cx.error_spanned_by(
|
||||
variant.original,
|
||||
"#[serde(other)] cannot appear on untagged enum",
|
||||
@@ -188,8 +169,8 @@ fn check_identifier(cx: &Ctxt, cont: &Container) {
|
||||
/// Skip-(de)serializing attributes are not allowed on variants marked
|
||||
/// (de)serialize_with.
|
||||
fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) {
|
||||
let variants = match cont.data {
|
||||
Data::Enum(ref variants) => variants,
|
||||
let variants = match &cont.data {
|
||||
Data::Enum(variants) => variants,
|
||||
Data::Struct(_, _) => {
|
||||
return;
|
||||
}
|
||||
@@ -198,52 +179,62 @@ fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) {
|
||||
for variant in variants.iter() {
|
||||
if variant.attrs.serialize_with().is_some() {
|
||||
if variant.attrs.skip_serializing() {
|
||||
cx.error_spanned_by(variant.original, format!(
|
||||
"variant `{}` cannot have both #[serde(serialize_with)] and \
|
||||
#[serde(skip_serializing)]",
|
||||
variant.ident
|
||||
));
|
||||
cx.error_spanned_by(
|
||||
variant.original,
|
||||
format!(
|
||||
"variant `{}` cannot have both #[serde(serialize_with)] and #[serde(skip_serializing)]",
|
||||
variant.ident
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
for field in &variant.fields {
|
||||
let member = member_message(&field.member);
|
||||
|
||||
if field.attrs.skip_serializing() {
|
||||
cx.error_spanned_by(variant.original, format!(
|
||||
"variant `{}` cannot have both #[serde(serialize_with)] and \
|
||||
a field {} marked with #[serde(skip_serializing)]",
|
||||
variant.ident, member
|
||||
));
|
||||
cx.error_spanned_by(
|
||||
variant.original,
|
||||
format!(
|
||||
"variant `{}` cannot have both #[serde(serialize_with)] and a field {} marked with #[serde(skip_serializing)]",
|
||||
variant.ident, member
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if field.attrs.skip_serializing_if().is_some() {
|
||||
cx.error_spanned_by(variant.original, format!(
|
||||
"variant `{}` cannot have both #[serde(serialize_with)] and \
|
||||
a field {} marked with #[serde(skip_serializing_if)]",
|
||||
variant.ident, member
|
||||
));
|
||||
cx.error_spanned_by(
|
||||
variant.original,
|
||||
format!(
|
||||
"variant `{}` cannot have both #[serde(serialize_with)] and a field {} marked with #[serde(skip_serializing_if)]",
|
||||
variant.ident, member
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if variant.attrs.deserialize_with().is_some() {
|
||||
if variant.attrs.skip_deserializing() {
|
||||
cx.error_spanned_by(variant.original, format!(
|
||||
"variant `{}` cannot have both #[serde(deserialize_with)] and \
|
||||
#[serde(skip_deserializing)]",
|
||||
variant.ident
|
||||
));
|
||||
cx.error_spanned_by(
|
||||
variant.original,
|
||||
format!(
|
||||
"variant `{}` cannot have both #[serde(deserialize_with)] and #[serde(skip_deserializing)]",
|
||||
variant.ident
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
for field in &variant.fields {
|
||||
if field.attrs.skip_deserializing() {
|
||||
let member = member_message(&field.member);
|
||||
|
||||
cx.error_spanned_by(variant.original, format!(
|
||||
"variant `{}` cannot have both #[serde(deserialize_with)] \
|
||||
and a field {} marked with #[serde(skip_deserializing)]",
|
||||
variant.ident, member
|
||||
));
|
||||
cx.error_spanned_by(
|
||||
variant.original,
|
||||
format!(
|
||||
"variant `{}` cannot have both #[serde(deserialize_with)] and a field {} marked with #[serde(skip_deserializing)]",
|
||||
variant.ident, member
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -255,20 +246,22 @@ fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) {
|
||||
/// duplicate keys in the serialized output and/or ambiguity in
|
||||
/// the to-be-deserialized input.
|
||||
fn check_internal_tag_field_name_conflict(cx: &Ctxt, cont: &Container) {
|
||||
let variants = match cont.data {
|
||||
Data::Enum(ref variants) => variants,
|
||||
let variants = match &cont.data {
|
||||
Data::Enum(variants) => variants,
|
||||
Data::Struct(_, _) => return,
|
||||
};
|
||||
|
||||
let tag = match *cont.attrs.tag() {
|
||||
EnumTag::Internal { ref tag } => tag.as_str(),
|
||||
EnumTag::External | EnumTag::Adjacent { .. } | EnumTag::None => return,
|
||||
let tag = match cont.attrs.tag() {
|
||||
TagType::Internal { tag } => tag.as_str(),
|
||||
TagType::External | TagType::Adjacent { .. } | TagType::None => return,
|
||||
};
|
||||
|
||||
let diagnose_conflict = || cx.error_spanned_by(
|
||||
cont.original,
|
||||
format!("variant field name `{}` conflicts with internal tag", tag),
|
||||
);
|
||||
let diagnose_conflict = || {
|
||||
cx.error_spanned_by(
|
||||
cont.original,
|
||||
format!("variant field name `{}` conflicts with internal tag", tag),
|
||||
);
|
||||
};
|
||||
|
||||
for variant in variants {
|
||||
match variant.style {
|
||||
@@ -278,12 +271,18 @@ fn check_internal_tag_field_name_conflict(cx: &Ctxt, cont: &Container) {
|
||||
let check_de = !field.attrs.skip_deserializing();
|
||||
let name = field.attrs.name();
|
||||
let ser_name = name.serialize_name();
|
||||
let de_name = name.deserialize_name();
|
||||
|
||||
if check_ser && ser_name == tag || check_de && de_name == tag {
|
||||
if check_ser && ser_name == tag {
|
||||
diagnose_conflict();
|
||||
return;
|
||||
}
|
||||
|
||||
for de_name in field.attrs.aliases() {
|
||||
if check_de && de_name == tag {
|
||||
diagnose_conflict();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Style::Unit | Style::Newtype | Style::Tuple => {}
|
||||
@@ -294,19 +293,19 @@ fn check_internal_tag_field_name_conflict(cx: &Ctxt, cont: &Container) {
|
||||
/// In the case of adjacently-tagged enums, the type and the
|
||||
/// contents tag must differ, for the same reason.
|
||||
fn check_adjacent_tag_conflict(cx: &Ctxt, cont: &Container) {
|
||||
let (type_tag, content_tag) = match *cont.attrs.tag() {
|
||||
EnumTag::Adjacent {
|
||||
ref tag,
|
||||
ref content,
|
||||
} => (tag, content),
|
||||
EnumTag::Internal { .. } | EnumTag::External | EnumTag::None => return,
|
||||
let (type_tag, content_tag) = match cont.attrs.tag() {
|
||||
TagType::Adjacent { tag, content } => (tag, content),
|
||||
TagType::Internal { .. } | TagType::External | TagType::None => return,
|
||||
};
|
||||
|
||||
if type_tag == content_tag {
|
||||
cx.error_spanned_by(cont.original, format!(
|
||||
"enum tags `{}` for type and content conflict with each other",
|
||||
type_tag
|
||||
));
|
||||
cx.error_spanned_by(
|
||||
cont.original,
|
||||
format!(
|
||||
"enum tags `{}` for type and content conflict with each other",
|
||||
type_tag
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,6 +322,13 @@ fn check_transparent(cx: &Ctxt, cont: &mut Container, derive: Derive) {
|
||||
);
|
||||
}
|
||||
|
||||
if cont.attrs.type_try_from().is_some() {
|
||||
cx.error_spanned_by(
|
||||
cont.original,
|
||||
"#[serde(transparent)] is not allowed with #[serde(try_from = \"...\")]",
|
||||
);
|
||||
}
|
||||
|
||||
if cont.attrs.type_into().is_some() {
|
||||
cx.error_spanned_by(
|
||||
cont.original,
|
||||
@@ -330,7 +336,7 @@ fn check_transparent(cx: &Ctxt, cont: &mut Container, derive: Derive) {
|
||||
);
|
||||
}
|
||||
|
||||
let fields = match cont.data {
|
||||
let fields = match &mut cont.data {
|
||||
Data::Enum(_) => {
|
||||
cx.error_spanned_by(
|
||||
cont.original,
|
||||
@@ -345,7 +351,7 @@ fn check_transparent(cx: &Ctxt, cont: &mut Container, derive: Derive) {
|
||||
);
|
||||
return;
|
||||
}
|
||||
Data::Struct(_, ref mut fields) => fields,
|
||||
Data::Struct(_, fields) => fields,
|
||||
};
|
||||
|
||||
let mut transparent_field = None;
|
||||
@@ -383,16 +389,16 @@ fn check_transparent(cx: &Ctxt, cont: &mut Container, derive: Derive) {
|
||||
}
|
||||
|
||||
fn member_message(member: &Member) -> String {
|
||||
match *member {
|
||||
Member::Named(ref ident) => format!("`{}`", ident),
|
||||
Member::Unnamed(ref i) => format!("#{}", i.index),
|
||||
match member {
|
||||
Member::Named(ident) => format!("`{}`", ident),
|
||||
Member::Unnamed(i) => format!("#{}", i.index),
|
||||
}
|
||||
}
|
||||
|
||||
fn allow_transparent(field: &Field, derive: Derive) -> bool {
|
||||
if let Type::Path(ref ty) = *field.ty {
|
||||
if let Type::Path(ty) = ungroup(field.ty) {
|
||||
if let Some(seg) = ty.path.segments.last() {
|
||||
if seg.into_value().ident == "PhantomData" {
|
||||
if seg.ident == "PhantomData" {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -403,3 +409,12 @@ fn allow_transparent(field: &Field, derive: Derive) -> bool {
|
||||
Derive::Deserialize => !field.attrs.skip_deserializing() && field.attrs.default().is_none(),
|
||||
}
|
||||
}
|
||||
|
||||
fn check_from_and_try_from(cx: &Ctxt, cont: &mut Container) {
|
||||
if cont.attrs.type_from().is_some() && cont.attrs.type_try_from().is_some() {
|
||||
cx.error_spanned_by(
|
||||
cont.original,
|
||||
"#[serde(from = \"...\")] and #[serde(try_from = \"...\")] conflict with each other",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,11 @@ impl Ctxt {
|
||||
.push(syn::Error::new_spanned(obj.into_token_stream(), msg));
|
||||
}
|
||||
|
||||
/// Add one of Syn's parse errors.
|
||||
pub fn syn_error(&self, err: syn::Error) {
|
||||
self.errors.borrow_mut().as_mut().unwrap().push(err);
|
||||
}
|
||||
|
||||
/// Consume this object, producing a formatted error string if there are errors.
|
||||
pub fn check(self) -> Result<(), Vec<syn::Error>> {
|
||||
let errors = self.errors.borrow_mut().take().unwrap();
|
||||
|
||||
@@ -4,11 +4,25 @@ pub mod attr;
|
||||
mod ctxt;
|
||||
pub use self::ctxt::Ctxt;
|
||||
|
||||
mod receiver;
|
||||
pub use self::receiver::replace_receiver;
|
||||
|
||||
mod case;
|
||||
mod check;
|
||||
mod respan;
|
||||
mod symbol;
|
||||
|
||||
use syn::Type;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum Derive {
|
||||
Serialize,
|
||||
Deserialize,
|
||||
}
|
||||
|
||||
pub fn ungroup(mut ty: &Type) -> &Type {
|
||||
while let Type::Group(group) = ty {
|
||||
ty = &group.elem;
|
||||
}
|
||||
ty
|
||||
}
|
||||
|
||||
@@ -0,0 +1,287 @@
|
||||
use internals::respan::respan;
|
||||
use proc_macro2::Span;
|
||||
use quote::ToTokens;
|
||||
use std::mem;
|
||||
use syn::punctuated::Punctuated;
|
||||
use syn::{
|
||||
parse_quote, Data, DeriveInput, Expr, ExprPath, GenericArgument, GenericParam, Generics, Macro,
|
||||
Path, PathArguments, QSelf, ReturnType, Type, TypeParamBound, TypePath, WherePredicate,
|
||||
};
|
||||
|
||||
pub fn replace_receiver(input: &mut DeriveInput) {
|
||||
let self_ty = {
|
||||
let ident = &input.ident;
|
||||
let ty_generics = input.generics.split_for_impl().1;
|
||||
parse_quote!(#ident #ty_generics)
|
||||
};
|
||||
let mut visitor = ReplaceReceiver(&self_ty);
|
||||
visitor.visit_generics_mut(&mut input.generics);
|
||||
visitor.visit_data_mut(&mut input.data);
|
||||
}
|
||||
|
||||
struct ReplaceReceiver<'a>(&'a TypePath);
|
||||
|
||||
impl ReplaceReceiver<'_> {
|
||||
fn self_ty(&self, span: Span) -> TypePath {
|
||||
let tokens = self.0.to_token_stream();
|
||||
let respanned = respan(tokens, span);
|
||||
syn::parse2(respanned).unwrap()
|
||||
}
|
||||
|
||||
fn self_to_qself(&self, qself: &mut Option<QSelf>, path: &mut Path) {
|
||||
if path.leading_colon.is_some() || path.segments[0].ident != "Self" {
|
||||
return;
|
||||
}
|
||||
|
||||
if path.segments.len() == 1 {
|
||||
self.self_to_expr_path(path);
|
||||
return;
|
||||
}
|
||||
|
||||
let span = path.segments[0].ident.span();
|
||||
*qself = Some(QSelf {
|
||||
lt_token: Token,
|
||||
ty: Box::new(Type::Path(self.self_ty(span))),
|
||||
position: 0,
|
||||
as_token: None,
|
||||
gt_token: Token,
|
||||
});
|
||||
|
||||
path.leading_colon = Some(**path.segments.pairs().next().unwrap().punct().unwrap());
|
||||
|
||||
let segments = mem::replace(&mut path.segments, Punctuated::new());
|
||||
path.segments = segments.into_pairs().skip(1).collect();
|
||||
}
|
||||
|
||||
fn self_to_expr_path(&self, path: &mut Path) {
|
||||
let self_ty = self.self_ty(path.segments[0].ident.span());
|
||||
let variant = mem::replace(path, self_ty.path);
|
||||
for segment in &mut path.segments {
|
||||
if let PathArguments::AngleBracketed(bracketed) = &mut segment.arguments {
|
||||
if bracketed.colon2_token.is_none() && !bracketed.args.is_empty() {
|
||||
bracketed.colon2_token = Some(<Token![::]>::default());
|
||||
}
|
||||
}
|
||||
}
|
||||
if variant.segments.len() > 1 {
|
||||
path.segments.push_punct(<Token![::]>::default());
|
||||
path.segments.extend(variant.segments.into_pairs().skip(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ReplaceReceiver<'_> {
|
||||
// `Self` -> `Receiver`
|
||||
fn visit_type_mut(&mut self, ty: &mut Type) {
|
||||
let span = if let Type::Path(node) = ty {
|
||||
if node.qself.is_none() && node.path.is_ident("Self") {
|
||||
node.path.segments[0].ident.span()
|
||||
} else {
|
||||
self.visit_type_path_mut(node);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
self.visit_type_mut_impl(ty);
|
||||
return;
|
||||
};
|
||||
*ty = self.self_ty(span).into();
|
||||
}
|
||||
|
||||
// `Self::Assoc` -> `<Receiver>::Assoc`
|
||||
fn visit_type_path_mut(&mut self, ty: &mut TypePath) {
|
||||
if ty.qself.is_none() {
|
||||
self.self_to_qself(&mut ty.qself, &mut ty.path);
|
||||
}
|
||||
self.visit_type_path_mut_impl(ty);
|
||||
}
|
||||
|
||||
// `Self::method` -> `<Receiver>::method`
|
||||
fn visit_expr_path_mut(&mut self, expr: &mut ExprPath) {
|
||||
if expr.qself.is_none() {
|
||||
self.self_to_qself(&mut expr.qself, &mut expr.path);
|
||||
}
|
||||
self.visit_expr_path_mut_impl(expr);
|
||||
}
|
||||
|
||||
// Everything below is simply traversing the syntax tree.
|
||||
|
||||
fn visit_type_mut_impl(&mut self, ty: &mut Type) {
|
||||
match ty {
|
||||
Type::Array(ty) => {
|
||||
self.visit_type_mut(&mut ty.elem);
|
||||
self.visit_expr_mut(&mut ty.len);
|
||||
}
|
||||
Type::BareFn(ty) => {
|
||||
for arg in &mut ty.inputs {
|
||||
self.visit_type_mut(&mut arg.ty);
|
||||
}
|
||||
self.visit_return_type_mut(&mut ty.output);
|
||||
}
|
||||
Type::Group(ty) => self.visit_type_mut(&mut ty.elem),
|
||||
Type::ImplTrait(ty) => {
|
||||
for bound in &mut ty.bounds {
|
||||
self.visit_type_param_bound_mut(bound);
|
||||
}
|
||||
}
|
||||
Type::Macro(ty) => self.visit_macro_mut(&mut ty.mac),
|
||||
Type::Paren(ty) => self.visit_type_mut(&mut ty.elem),
|
||||
Type::Path(ty) => {
|
||||
if let Some(qself) = &mut ty.qself {
|
||||
self.visit_type_mut(&mut qself.ty);
|
||||
}
|
||||
self.visit_path_mut(&mut ty.path);
|
||||
}
|
||||
Type::Ptr(ty) => self.visit_type_mut(&mut ty.elem),
|
||||
Type::Reference(ty) => self.visit_type_mut(&mut ty.elem),
|
||||
Type::Slice(ty) => self.visit_type_mut(&mut ty.elem),
|
||||
Type::TraitObject(ty) => {
|
||||
for bound in &mut ty.bounds {
|
||||
self.visit_type_param_bound_mut(bound);
|
||||
}
|
||||
}
|
||||
Type::Tuple(ty) => {
|
||||
for elem in &mut ty.elems {
|
||||
self.visit_type_mut(elem);
|
||||
}
|
||||
}
|
||||
|
||||
Type::Infer(_) | Type::Never(_) | Type::Verbatim(_) => {}
|
||||
|
||||
#[cfg(test)]
|
||||
Type::__TestExhaustive(_) => unimplemented!(),
|
||||
#[cfg(not(test))]
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_type_path_mut_impl(&mut self, ty: &mut TypePath) {
|
||||
if let Some(qself) = &mut ty.qself {
|
||||
self.visit_type_mut(&mut qself.ty);
|
||||
}
|
||||
self.visit_path_mut(&mut ty.path);
|
||||
}
|
||||
|
||||
fn visit_expr_path_mut_impl(&mut self, expr: &mut ExprPath) {
|
||||
if let Some(qself) = &mut expr.qself {
|
||||
self.visit_type_mut(&mut qself.ty);
|
||||
}
|
||||
self.visit_path_mut(&mut expr.path);
|
||||
}
|
||||
|
||||
fn visit_path_mut(&mut self, path: &mut Path) {
|
||||
for segment in &mut path.segments {
|
||||
self.visit_path_arguments_mut(&mut segment.arguments);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_path_arguments_mut(&mut self, arguments: &mut PathArguments) {
|
||||
match arguments {
|
||||
PathArguments::None => {}
|
||||
PathArguments::AngleBracketed(arguments) => {
|
||||
for arg in &mut arguments.args {
|
||||
match arg {
|
||||
GenericArgument::Type(arg) => self.visit_type_mut(arg),
|
||||
GenericArgument::Binding(arg) => self.visit_type_mut(&mut arg.ty),
|
||||
GenericArgument::Lifetime(_)
|
||||
| GenericArgument::Constraint(_)
|
||||
| GenericArgument::Const(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
PathArguments::Parenthesized(arguments) => {
|
||||
for argument in &mut arguments.inputs {
|
||||
self.visit_type_mut(argument);
|
||||
}
|
||||
self.visit_return_type_mut(&mut arguments.output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_return_type_mut(&mut self, return_type: &mut ReturnType) {
|
||||
match return_type {
|
||||
ReturnType::Default => {}
|
||||
ReturnType::Type(_, output) => self.visit_type_mut(output),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_type_param_bound_mut(&mut self, bound: &mut TypeParamBound) {
|
||||
match bound {
|
||||
TypeParamBound::Trait(bound) => self.visit_path_mut(&mut bound.path),
|
||||
TypeParamBound::Lifetime(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_generics_mut(&mut self, generics: &mut Generics) {
|
||||
for param in &mut generics.params {
|
||||
match param {
|
||||
GenericParam::Type(param) => {
|
||||
for bound in &mut param.bounds {
|
||||
self.visit_type_param_bound_mut(bound);
|
||||
}
|
||||
}
|
||||
GenericParam::Lifetime(_) | GenericParam::Const(_) => {}
|
||||
}
|
||||
}
|
||||
if let Some(where_clause) = &mut generics.where_clause {
|
||||
for predicate in &mut where_clause.predicates {
|
||||
match predicate {
|
||||
WherePredicate::Type(predicate) => {
|
||||
self.visit_type_mut(&mut predicate.bounded_ty);
|
||||
for bound in &mut predicate.bounds {
|
||||
self.visit_type_param_bound_mut(bound);
|
||||
}
|
||||
}
|
||||
WherePredicate::Lifetime(_) | WherePredicate::Eq(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_data_mut(&mut self, data: &mut Data) {
|
||||
match data {
|
||||
Data::Struct(data) => {
|
||||
for field in &mut data.fields {
|
||||
self.visit_type_mut(&mut field.ty);
|
||||
}
|
||||
}
|
||||
Data::Enum(data) => {
|
||||
for variant in &mut data.variants {
|
||||
for field in &mut variant.fields {
|
||||
self.visit_type_mut(&mut field.ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
Data::Union(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_expr_mut(&mut self, expr: &mut Expr) {
|
||||
match expr {
|
||||
Expr::Binary(expr) => {
|
||||
self.visit_expr_mut(&mut expr.left);
|
||||
self.visit_expr_mut(&mut expr.right);
|
||||
}
|
||||
Expr::Call(expr) => {
|
||||
self.visit_expr_mut(&mut expr.func);
|
||||
for arg in &mut expr.args {
|
||||
self.visit_expr_mut(arg);
|
||||
}
|
||||
}
|
||||
Expr::Cast(expr) => {
|
||||
self.visit_expr_mut(&mut expr.expr);
|
||||
self.visit_type_mut(&mut expr.ty);
|
||||
}
|
||||
Expr::Field(expr) => self.visit_expr_mut(&mut expr.base),
|
||||
Expr::Index(expr) => {
|
||||
self.visit_expr_mut(&mut expr.expr);
|
||||
self.visit_expr_mut(&mut expr.index);
|
||||
}
|
||||
Expr::Paren(expr) => self.visit_expr_mut(&mut expr.expr),
|
||||
Expr::Path(expr) => self.visit_expr_path_mut(expr),
|
||||
Expr::Unary(expr) => self.visit_expr_mut(&mut expr.expr),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_macro_mut(&mut self, _mac: &mut Macro) {}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
use proc_macro2::{Group, Span, TokenStream, TokenTree};
|
||||
|
||||
pub(crate) fn respan(stream: TokenStream, span: Span) -> TokenStream {
|
||||
stream
|
||||
.into_iter()
|
||||
.map(|token| respan_token(token, span))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn respan_token(mut token: TokenTree, span: Span) -> TokenTree {
|
||||
if let TokenTree::Group(g) = &mut token {
|
||||
*g = Group::new(g.delimiter(), respan(g.stream(), span));
|
||||
}
|
||||
token.set_span(span);
|
||||
token
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
use std::fmt::{self, Display};
|
||||
use syn::{Ident, Path};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Symbol(&'static str);
|
||||
|
||||
pub const ALIAS: Symbol = Symbol("alias");
|
||||
pub const BORROW: Symbol = Symbol("borrow");
|
||||
pub const BOUND: Symbol = Symbol("bound");
|
||||
pub const CONTENT: Symbol = Symbol("content");
|
||||
pub const CRATE: Symbol = Symbol("crate");
|
||||
pub const DEFAULT: Symbol = Symbol("default");
|
||||
pub const DENY_UNKNOWN_FIELDS: Symbol = Symbol("deny_unknown_fields");
|
||||
pub const DESERIALIZE: Symbol = Symbol("deserialize");
|
||||
pub const DESERIALIZE_WITH: Symbol = Symbol("deserialize_with");
|
||||
pub const FIELD_IDENTIFIER: Symbol = Symbol("field_identifier");
|
||||
pub const FLATTEN: Symbol = Symbol("flatten");
|
||||
pub const FROM: Symbol = Symbol("from");
|
||||
pub const GETTER: Symbol = Symbol("getter");
|
||||
pub const INTO: Symbol = Symbol("into");
|
||||
pub const OTHER: Symbol = Symbol("other");
|
||||
pub const REMOTE: Symbol = Symbol("remote");
|
||||
pub const RENAME: Symbol = Symbol("rename");
|
||||
pub const RENAME_ALL: Symbol = Symbol("rename_all");
|
||||
pub const SERDE: Symbol = Symbol("serde");
|
||||
pub const SERIALIZE: Symbol = Symbol("serialize");
|
||||
pub const SERIALIZE_WITH: Symbol = Symbol("serialize_with");
|
||||
pub const SKIP: Symbol = Symbol("skip");
|
||||
pub const SKIP_DESERIALIZING: Symbol = Symbol("skip_deserializing");
|
||||
pub const SKIP_SERIALIZING: Symbol = Symbol("skip_serializing");
|
||||
pub const SKIP_SERIALIZING_IF: Symbol = Symbol("skip_serializing_if");
|
||||
pub const TAG: Symbol = Symbol("tag");
|
||||
pub const TRANSPARENT: Symbol = Symbol("transparent");
|
||||
pub const TRY_FROM: Symbol = Symbol("try_from");
|
||||
pub const UNTAGGED: Symbol = Symbol("untagged");
|
||||
pub const VARIANT_IDENTIFIER: Symbol = Symbol("variant_identifier");
|
||||
pub const WITH: Symbol = Symbol("with");
|
||||
pub const EXPECTING: Symbol = Symbol("expecting");
|
||||
|
||||
impl PartialEq<Symbol> for Ident {
|
||||
fn eq(&self, word: &Symbol) -> bool {
|
||||
self == word.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> PartialEq<Symbol> for &'a Ident {
|
||||
fn eq(&self, word: &Symbol) -> bool {
|
||||
*self == word.0
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<Symbol> for Path {
|
||||
fn eq(&self, word: &Symbol) -> bool {
|
||||
self.is_ident(word.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> PartialEq<Symbol> for &'a Path {
|
||||
fn eq(&self, word: &Symbol) -> bool {
|
||||
self.is_ident(word.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Symbol {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str(self.0)
|
||||
}
|
||||
}
|
||||
+52
-40
@@ -1,8 +1,7 @@
|
||||
//! This crate provides Serde's two derive macros.
|
||||
//!
|
||||
//! ```rust
|
||||
//! # #[macro_use]
|
||||
//! # extern crate serde_derive;
|
||||
//! ```edition2018
|
||||
//! # use serde_derive::{Serialize, Deserialize};
|
||||
//! #
|
||||
//! #[derive(Serialize, Deserialize)]
|
||||
//! # struct S;
|
||||
@@ -14,41 +13,53 @@
|
||||
//!
|
||||
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.81")]
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
|
||||
// Whitelisted clippy lints
|
||||
#![cfg_attr(
|
||||
feature = "cargo-clippy",
|
||||
allow(
|
||||
cyclomatic_complexity,
|
||||
enum_variant_names,
|
||||
needless_pass_by_value,
|
||||
redundant_field_names,
|
||||
too_many_arguments,
|
||||
used_underscore_binding,
|
||||
)
|
||||
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.135")]
|
||||
#![allow(unknown_lints, bare_trait_objects)]
|
||||
// Ignored clippy lints
|
||||
#![allow(
|
||||
// clippy false positive: https://github.com/rust-lang/rust-clippy/issues/7054
|
||||
clippy::branches_sharing_code,
|
||||
clippy::cognitive_complexity,
|
||||
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/7575
|
||||
clippy::collapsible_match,
|
||||
clippy::enum_variant_names,
|
||||
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/6797
|
||||
clippy::manual_map,
|
||||
clippy::match_like_matches_macro,
|
||||
clippy::needless_pass_by_value,
|
||||
clippy::too_many_arguments,
|
||||
clippy::trivially_copy_pass_by_ref,
|
||||
clippy::used_underscore_binding,
|
||||
clippy::wildcard_in_or_patterns,
|
||||
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704
|
||||
clippy::unnested_or_patterns,
|
||||
)]
|
||||
// Whitelisted clippy_pedantic lints
|
||||
#![cfg_attr(
|
||||
feature = "cargo-clippy",
|
||||
allow(
|
||||
cast_possible_truncation,
|
||||
doc_markdown,
|
||||
enum_glob_use,
|
||||
filter_map,
|
||||
indexing_slicing,
|
||||
items_after_statements,
|
||||
match_same_arms,
|
||||
similar_names,
|
||||
single_match_else,
|
||||
stutter,
|
||||
unseparated_literal_suffix,
|
||||
use_self,
|
||||
)
|
||||
// Ignored clippy_pedantic lints
|
||||
#![allow(
|
||||
clippy::cast_possible_truncation,
|
||||
clippy::checked_conversions,
|
||||
clippy::doc_markdown,
|
||||
clippy::enum_glob_use,
|
||||
clippy::indexing_slicing,
|
||||
clippy::items_after_statements,
|
||||
clippy::let_underscore_drop,
|
||||
clippy::manual_assert,
|
||||
clippy::map_err_ignore,
|
||||
clippy::match_same_arms,
|
||||
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/6984
|
||||
clippy::match_wildcard_for_single_variants,
|
||||
clippy::module_name_repetitions,
|
||||
clippy::must_use_candidate,
|
||||
clippy::option_if_let_else,
|
||||
clippy::similar_names,
|
||||
clippy::single_match_else,
|
||||
clippy::struct_excessive_bools,
|
||||
clippy::too_many_lines,
|
||||
clippy::unseparated_literal_suffix,
|
||||
clippy::unused_self,
|
||||
clippy::use_self,
|
||||
clippy::wildcard_imports
|
||||
)]
|
||||
// The `quote!` macro requires deep recursion.
|
||||
#![recursion_limit = "512"]
|
||||
|
||||
#[macro_use]
|
||||
extern crate quote;
|
||||
@@ -69,22 +80,23 @@ mod bound;
|
||||
mod fragment;
|
||||
|
||||
mod de;
|
||||
mod dummy;
|
||||
mod pretend;
|
||||
mod ser;
|
||||
mod try;
|
||||
|
||||
#[proc_macro_derive(Serialize, attributes(serde))]
|
||||
pub fn derive_serialize(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
ser::expand_derive_serialize(&input)
|
||||
let mut input = parse_macro_input!(input as DeriveInput);
|
||||
ser::expand_derive_serialize(&mut input)
|
||||
.unwrap_or_else(to_compile_errors)
|
||||
.into()
|
||||
}
|
||||
|
||||
#[proc_macro_derive(Deserialize, attributes(serde))]
|
||||
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
de::expand_derive_deserialize(&input)
|
||||
let mut input = parse_macro_input!(input as DeriveInput);
|
||||
de::expand_derive_deserialize(&mut input)
|
||||
.unwrap_or_else(to_compile_errors)
|
||||
.into()
|
||||
}
|
||||
|
||||
+108
-47
@@ -1,7 +1,7 @@
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use syn::Ident;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::format_ident;
|
||||
|
||||
use internals::ast::{Container, Data, Field, Style};
|
||||
use internals::ast::{Container, Data, Field, Style, Variant};
|
||||
|
||||
// Suppress dead_code warnings that would otherwise appear when using a remote
|
||||
// derive. Other than this pretend code, a struct annotated with remote derive
|
||||
@@ -20,8 +20,8 @@ use internals::ast::{Container, Data, Field, Style};
|
||||
// 8 | enum EnumDef { V }
|
||||
// | ^
|
||||
//
|
||||
pub fn pretend_used(cont: &Container) -> TokenStream {
|
||||
let pretend_fields = pretend_fields_used(cont);
|
||||
pub fn pretend_used(cont: &Container, is_packed: bool) -> TokenStream {
|
||||
let pretend_fields = pretend_fields_used(cont, is_packed);
|
||||
let pretend_variants = pretend_variants_used(cont);
|
||||
|
||||
quote! {
|
||||
@@ -32,51 +32,119 @@ pub fn pretend_used(cont: &Container) -> TokenStream {
|
||||
|
||||
// For structs with named fields, expands to:
|
||||
//
|
||||
// match None::<&T> {
|
||||
// Some(T { a: __v0, b: __v1 }) => {}
|
||||
// _ => {}
|
||||
// }
|
||||
//
|
||||
// For packed structs on sufficiently new rustc, expands to:
|
||||
//
|
||||
// match None::<&T> {
|
||||
// Some(__v @ T { a: _, b: _ }) => {
|
||||
// let _ = addr_of!(__v.a);
|
||||
// let _ = addr_of!(__v.b);
|
||||
// }
|
||||
// _ => {}
|
||||
// }
|
||||
//
|
||||
// For packed structs on older rustc, we assume Sized and !Drop, and expand to:
|
||||
//
|
||||
// match None::<T> {
|
||||
// Some(T { a: ref __v0, b: ref __v1 }) => {}
|
||||
// Some(T { a: __v0, b: __v1 }) => {}
|
||||
// _ => {}
|
||||
// }
|
||||
//
|
||||
// For enums, expands to the following but only including struct variants:
|
||||
//
|
||||
// match None::<T> {
|
||||
// Some(T::A { a: ref __v0 }) => {}
|
||||
// Some(T::B { b: ref __v0 }) => {}
|
||||
// match None::<&T> {
|
||||
// Some(T::A { a: __v0 }) => {}
|
||||
// Some(T::B { b: __v0 }) => {}
|
||||
// _ => {}
|
||||
// }
|
||||
//
|
||||
// The `ref` is important in case the user has written a Drop impl on their
|
||||
// type. Rust does not allow destructuring a struct or enum that has a Drop
|
||||
// impl.
|
||||
fn pretend_fields_used(cont: &Container) -> TokenStream {
|
||||
fn pretend_fields_used(cont: &Container, is_packed: bool) -> TokenStream {
|
||||
match &cont.data {
|
||||
Data::Enum(variants) => pretend_fields_used_enum(cont, variants),
|
||||
Data::Struct(Style::Struct, fields) => {
|
||||
if is_packed {
|
||||
pretend_fields_used_struct_packed(cont, fields)
|
||||
} else {
|
||||
pretend_fields_used_struct(cont, fields)
|
||||
}
|
||||
}
|
||||
Data::Struct(_, _) => quote!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn pretend_fields_used_struct(cont: &Container, fields: &[Field]) -> TokenStream {
|
||||
let type_ident = &cont.ident;
|
||||
let (_, ty_generics, _) = cont.generics.split_for_impl();
|
||||
|
||||
let patterns = match cont.data {
|
||||
Data::Enum(ref variants) => variants
|
||||
.iter()
|
||||
.filter_map(|variant| match variant.style {
|
||||
Style::Struct => {
|
||||
let variant_ident = &variant.ident;
|
||||
let pat = struct_pattern(&variant.fields);
|
||||
Some(quote!(#type_ident::#variant_ident #pat))
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
Data::Struct(Style::Struct, ref fields) => {
|
||||
let pat = struct_pattern(fields);
|
||||
vec![quote!(#type_ident #pat)]
|
||||
}
|
||||
Data::Struct(_, _) => {
|
||||
return quote!();
|
||||
}
|
||||
};
|
||||
let members = fields.iter().map(|field| &field.member);
|
||||
let placeholders = (0usize..).map(|i| format_ident!("__v{}", i));
|
||||
|
||||
quote! {
|
||||
match _serde::export::None::<#type_ident #ty_generics> {
|
||||
match _serde::__private::None::<&#type_ident #ty_generics> {
|
||||
_serde::__private::Some(#type_ident { #(#members: #placeholders),* }) => {}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn pretend_fields_used_struct_packed(cont: &Container, fields: &[Field]) -> TokenStream {
|
||||
let type_ident = &cont.ident;
|
||||
let (_, ty_generics, _) = cont.generics.split_for_impl();
|
||||
|
||||
let members = fields.iter().map(|field| &field.member).collect::<Vec<_>>();
|
||||
|
||||
#[cfg(ptr_addr_of)]
|
||||
{
|
||||
quote! {
|
||||
match _serde::__private::None::<&#type_ident #ty_generics> {
|
||||
_serde::__private::Some(__v @ #type_ident { #(#members: _),* }) => {
|
||||
#(
|
||||
let _ = _serde::__private::ptr::addr_of!(__v.#members);
|
||||
)*
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(ptr_addr_of))]
|
||||
{
|
||||
let placeholders = (0usize..).map(|i| format_ident!("__v{}", i));
|
||||
|
||||
quote! {
|
||||
match _serde::__private::None::<#type_ident #ty_generics> {
|
||||
_serde::__private::Some(#type_ident { #(#members: #placeholders),* }) => {}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn pretend_fields_used_enum(cont: &Container, variants: &[Variant]) -> TokenStream {
|
||||
let type_ident = &cont.ident;
|
||||
let (_, ty_generics, _) = cont.generics.split_for_impl();
|
||||
|
||||
let patterns = variants
|
||||
.iter()
|
||||
.filter_map(|variant| match variant.style {
|
||||
Style::Struct => {
|
||||
let variant_ident = &variant.ident;
|
||||
let members = variant.fields.iter().map(|field| &field.member);
|
||||
let placeholders = (0usize..).map(|i| format_ident!("__v{}", i));
|
||||
Some(quote!(#type_ident::#variant_ident { #(#members: #placeholders),* }))
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
quote! {
|
||||
match _serde::__private::None::<&#type_ident #ty_generics> {
|
||||
#(
|
||||
_serde::export::Some(#patterns) => {}
|
||||
_serde::__private::Some(#patterns) => {}
|
||||
)*
|
||||
_ => {}
|
||||
}
|
||||
@@ -93,8 +161,8 @@ fn pretend_fields_used(cont: &Container) -> TokenStream {
|
||||
// }
|
||||
//
|
||||
fn pretend_variants_used(cont: &Container) -> TokenStream {
|
||||
let variants = match cont.data {
|
||||
Data::Enum(ref variants) => variants,
|
||||
let variants = match &cont.data {
|
||||
Data::Enum(variants) => variants,
|
||||
Data::Struct(_, _) => {
|
||||
return quote!();
|
||||
}
|
||||
@@ -107,7 +175,7 @@ fn pretend_variants_used(cont: &Container) -> TokenStream {
|
||||
let cases = variants.iter().map(|variant| {
|
||||
let variant_ident = &variant.ident;
|
||||
let placeholders = &(0..variant.fields.len())
|
||||
.map(|i| Ident::new(&format!("__v{}", i), Span::call_site()))
|
||||
.map(|i| format_ident!("__v{}", i))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let pat = match variant.style {
|
||||
@@ -120,8 +188,8 @@ fn pretend_variants_used(cont: &Container) -> TokenStream {
|
||||
};
|
||||
|
||||
quote! {
|
||||
match _serde::export::None {
|
||||
_serde::export::Some((#(#placeholders,)*)) => {
|
||||
match _serde::__private::None {
|
||||
_serde::__private::Some((#(#placeholders,)*)) => {
|
||||
let _ = #type_ident::#variant_ident #turbofish #pat;
|
||||
}
|
||||
_ => {}
|
||||
@@ -131,10 +199,3 @@ fn pretend_variants_used(cont: &Container) -> TokenStream {
|
||||
|
||||
quote!(#(#cases)*)
|
||||
}
|
||||
|
||||
fn struct_pattern(fields: &[Field]) -> TokenStream {
|
||||
let members = fields.iter().map(|field| &field.member);
|
||||
let placeholders =
|
||||
(0..fields.len()).map(|i| Ident::new(&format!("__v{}", i), Span::call_site()));
|
||||
quote!({ #(#members: ref #placeholders),* })
|
||||
}
|
||||
|
||||
+139
-100
@@ -3,39 +3,39 @@ use syn::spanned::Spanned;
|
||||
use syn::{self, Ident, Index, Member};
|
||||
|
||||
use bound;
|
||||
use dummy;
|
||||
use fragment::{Fragment, Match, Stmts};
|
||||
use internals::ast::{Container, Data, Field, Style, Variant};
|
||||
use internals::{attr, Ctxt, Derive};
|
||||
use internals::{attr, replace_receiver, Ctxt, Derive};
|
||||
use pretend;
|
||||
use try;
|
||||
|
||||
pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<TokenStream, Vec<syn::Error>> {
|
||||
pub fn expand_derive_serialize(
|
||||
input: &mut syn::DeriveInput,
|
||||
) -> Result<TokenStream, Vec<syn::Error>> {
|
||||
replace_receiver(input);
|
||||
|
||||
let ctxt = Ctxt::new();
|
||||
let cont = match Container::from_ast(&ctxt, input, Derive::Serialize) {
|
||||
Some(cont) => cont,
|
||||
None => return Err(ctxt.check().unwrap_err()),
|
||||
};
|
||||
precondition(&ctxt, &cont);
|
||||
try!(ctxt.check());
|
||||
ctxt.check()?;
|
||||
|
||||
let ident = &cont.ident;
|
||||
let params = Parameters::new(&cont);
|
||||
let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl();
|
||||
let suffix = ident.to_string().trim_left_matches("r#").to_owned();
|
||||
let dummy_const = Ident::new(
|
||||
&format!("_IMPL_SERIALIZE_FOR_{}", suffix),
|
||||
Span::call_site(),
|
||||
);
|
||||
let body = Stmts(serialize_body(&cont, ¶ms));
|
||||
let serde = cont.attrs.serde_path();
|
||||
|
||||
let impl_block = if let Some(remote) = cont.attrs.remote() {
|
||||
let vis = &input.vis;
|
||||
let used = pretend::pretend_used(&cont);
|
||||
let used = pretend::pretend_used(&cont, params.is_packed);
|
||||
quote! {
|
||||
impl #impl_generics #ident #ty_generics #where_clause {
|
||||
#vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
|
||||
#vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> #serde::__private::Result<__S::Ok, __S::Error>
|
||||
where
|
||||
__S: _serde::Serializer,
|
||||
__S: #serde::Serializer,
|
||||
{
|
||||
#used
|
||||
#body
|
||||
@@ -45,10 +45,10 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<TokenStream,
|
||||
} else {
|
||||
quote! {
|
||||
#[automatically_derived]
|
||||
impl #impl_generics _serde::Serialize for #ident #ty_generics #where_clause {
|
||||
fn serialize<__S>(&self, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
|
||||
impl #impl_generics #serde::Serialize for #ident #ty_generics #where_clause {
|
||||
fn serialize<__S>(&self, __serializer: __S) -> #serde::__private::Result<__S::Ok, __S::Error>
|
||||
where
|
||||
__S: _serde::Serializer,
|
||||
__S: #serde::Serializer,
|
||||
{
|
||||
#body
|
||||
}
|
||||
@@ -56,19 +56,12 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<TokenStream,
|
||||
}
|
||||
};
|
||||
|
||||
let try_replacement = try::replacement();
|
||||
let generated = quote! {
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const #dummy_const: () = {
|
||||
#[allow(unknown_lints)]
|
||||
#[cfg_attr(feature = "cargo-clippy", allow(useless_attribute))]
|
||||
#[allow(rust_2018_idioms)]
|
||||
extern crate serde as _serde;
|
||||
#try_replacement
|
||||
#impl_block
|
||||
};
|
||||
};
|
||||
Ok(generated)
|
||||
Ok(dummy::wrap_in_const(
|
||||
cont.attrs.custom_serde_path(),
|
||||
"SERIALIZE",
|
||||
ident,
|
||||
impl_block,
|
||||
))
|
||||
}
|
||||
|
||||
fn precondition(cx: &Ctxt, cont: &Container) {
|
||||
@@ -98,6 +91,9 @@ struct Parameters {
|
||||
|
||||
/// Type has a `serde(remote = "...")` attribute.
|
||||
is_remote: bool,
|
||||
|
||||
/// Type has a repr(packed) attribute.
|
||||
is_packed: bool,
|
||||
}
|
||||
|
||||
impl Parameters {
|
||||
@@ -114,20 +110,23 @@ impl Parameters {
|
||||
None => cont.ident.clone().into(),
|
||||
};
|
||||
|
||||
let is_packed = cont.attrs.is_packed();
|
||||
|
||||
let generics = build_generics(cont);
|
||||
|
||||
Parameters {
|
||||
self_var: self_var,
|
||||
this: this,
|
||||
generics: generics,
|
||||
is_remote: is_remote,
|
||||
self_var,
|
||||
this,
|
||||
generics,
|
||||
is_remote,
|
||||
is_packed,
|
||||
}
|
||||
}
|
||||
|
||||
/// Type name to use in error messages and `&'static str` arguments to
|
||||
/// various Serializer methods.
|
||||
fn type_name(&self) -> String {
|
||||
self.this.segments.last().unwrap().value().ident.to_string()
|
||||
self.this.segments.last().unwrap().ident.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,15 +174,13 @@ fn serialize_body(cont: &Container, params: &Parameters) -> Fragment {
|
||||
} else if let Some(type_into) = cont.attrs.type_into() {
|
||||
serialize_into(params, type_into)
|
||||
} else {
|
||||
match cont.data {
|
||||
Data::Enum(ref variants) => serialize_enum(params, variants, &cont.attrs),
|
||||
Data::Struct(Style::Struct, ref fields) => {
|
||||
serialize_struct(params, fields, &cont.attrs)
|
||||
}
|
||||
Data::Struct(Style::Tuple, ref fields) => {
|
||||
match &cont.data {
|
||||
Data::Enum(variants) => serialize_enum(params, variants, &cont.attrs),
|
||||
Data::Struct(Style::Struct, fields) => serialize_struct(params, fields, &cont.attrs),
|
||||
Data::Struct(Style::Tuple, fields) => {
|
||||
serialize_tuple_struct(params, fields, &cont.attrs)
|
||||
}
|
||||
Data::Struct(Style::Newtype, ref fields) => {
|
||||
Data::Struct(Style::Newtype, fields) => {
|
||||
serialize_newtype_struct(params, &fields[0], &cont.attrs)
|
||||
}
|
||||
Data::Struct(Style::Unit, _) => serialize_unit_struct(&cont.attrs),
|
||||
@@ -192,8 +189,8 @@ fn serialize_body(cont: &Container, params: &Parameters) -> Fragment {
|
||||
}
|
||||
|
||||
fn serialize_transparent(cont: &Container, params: &Parameters) -> Fragment {
|
||||
let fields = match cont.data {
|
||||
Data::Struct(_, ref fields) => fields,
|
||||
let fields = match &cont.data {
|
||||
Data::Struct(_, fields) => fields,
|
||||
Data::Enum(_) => unreachable!(),
|
||||
};
|
||||
|
||||
@@ -206,7 +203,7 @@ fn serialize_transparent(cont: &Container, params: &Parameters) -> Fragment {
|
||||
None => {
|
||||
let span = transparent_field.original.span();
|
||||
quote_spanned!(span=> _serde::Serialize::serialize)
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
quote_block! {
|
||||
@@ -218,7 +215,7 @@ fn serialize_into(params: &Parameters, type_into: &syn::Type) -> Fragment {
|
||||
let self_var = ¶ms.self_var;
|
||||
quote_block! {
|
||||
_serde::Serialize::serialize(
|
||||
&_serde::export::Into::<#type_into>::into(_serde::export::Clone::clone(#self_var)),
|
||||
&_serde::__private::Into::<#type_into>::into(_serde::__private::Clone::clone(#self_var)),
|
||||
__serializer)
|
||||
}
|
||||
}
|
||||
@@ -270,7 +267,7 @@ fn serialize_tuple_struct(
|
||||
let mut serialized_fields = fields
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|&(_, ref field)| !field.attrs.skip_serializing())
|
||||
.filter(|(_, field)| !field.attrs.skip_serializing())
|
||||
.peekable();
|
||||
|
||||
let let_mut = mut_if(serialized_fields.peek().is_some());
|
||||
@@ -306,6 +303,19 @@ fn serialize_struct(params: &Parameters, fields: &[Field], cattrs: &attr::Contai
|
||||
}
|
||||
}
|
||||
|
||||
fn serialize_struct_tag_field(cattrs: &attr::Container, struct_trait: &StructTrait) -> TokenStream {
|
||||
match cattrs.tag() {
|
||||
attr::TagType::Internal { tag } => {
|
||||
let type_name = cattrs.name().serialize_name();
|
||||
let func = struct_trait.serialize_field(Span::call_site());
|
||||
quote! {
|
||||
try!(#func(&mut __serde_state, #tag, #type_name));
|
||||
}
|
||||
}
|
||||
_ => quote! {},
|
||||
}
|
||||
}
|
||||
|
||||
fn serialize_struct_as_struct(
|
||||
params: &Parameters,
|
||||
fields: &[Field],
|
||||
@@ -316,12 +326,15 @@ fn serialize_struct_as_struct(
|
||||
|
||||
let type_name = cattrs.name().serialize_name();
|
||||
|
||||
let tag_field = serialize_struct_tag_field(cattrs, &StructTrait::SerializeStruct);
|
||||
let tag_field_exists = !tag_field.is_empty();
|
||||
|
||||
let mut serialized_fields = fields
|
||||
.iter()
|
||||
.filter(|&field| !field.attrs.skip_serializing())
|
||||
.peekable();
|
||||
|
||||
let let_mut = mut_if(serialized_fields.peek().is_some());
|
||||
let let_mut = mut_if(serialized_fields.peek().is_some() || tag_field_exists);
|
||||
|
||||
let len = serialized_fields
|
||||
.map(|field| match field.attrs.skip_serializing_if() {
|
||||
@@ -331,10 +344,14 @@ fn serialize_struct_as_struct(
|
||||
quote!(if #path(#field_expr) { 0 } else { 1 })
|
||||
}
|
||||
})
|
||||
.fold(quote!(0), |sum, expr| quote!(#sum + #expr));
|
||||
.fold(
|
||||
quote!(#tag_field_exists as usize),
|
||||
|sum, expr| quote!(#sum + #expr),
|
||||
);
|
||||
|
||||
quote_block! {
|
||||
let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct(__serializer, #type_name, #len));
|
||||
#tag_field
|
||||
#(#serialize_fields)*
|
||||
_serde::ser::SerializeStruct::end(__serde_state)
|
||||
}
|
||||
@@ -348,15 +365,18 @@ fn serialize_struct_as_map(
|
||||
let serialize_fields =
|
||||
serialize_struct_visitor(fields, params, false, &StructTrait::SerializeMap);
|
||||
|
||||
let tag_field = serialize_struct_tag_field(cattrs, &StructTrait::SerializeMap);
|
||||
let tag_field_exists = !tag_field.is_empty();
|
||||
|
||||
let mut serialized_fields = fields
|
||||
.iter()
|
||||
.filter(|&field| !field.attrs.skip_serializing())
|
||||
.peekable();
|
||||
|
||||
let let_mut = mut_if(serialized_fields.peek().is_some());
|
||||
let let_mut = mut_if(serialized_fields.peek().is_some() || tag_field_exists);
|
||||
|
||||
let len = if cattrs.has_flatten() {
|
||||
quote!(_serde::export::None)
|
||||
quote!(_serde::__private::None)
|
||||
} else {
|
||||
let len = serialized_fields
|
||||
.map(|field| match field.attrs.skip_serializing_if() {
|
||||
@@ -366,12 +386,16 @@ fn serialize_struct_as_map(
|
||||
quote!(if #path(#field_expr) { 0 } else { 1 })
|
||||
}
|
||||
})
|
||||
.fold(quote!(0), |sum, expr| quote!(#sum + #expr));
|
||||
quote!(_serde::export::Some(#len))
|
||||
.fold(
|
||||
quote!(#tag_field_exists as usize),
|
||||
|sum, expr| quote!(#sum + #expr),
|
||||
);
|
||||
quote!(_serde::__private::Some(#len))
|
||||
};
|
||||
|
||||
quote_block! {
|
||||
let #let_mut __serde_state = try!(_serde::Serializer::serialize_map(__serializer, #len));
|
||||
#tag_field
|
||||
#(#serialize_fields)*
|
||||
_serde::ser::SerializeMap::end(__serde_state)
|
||||
}
|
||||
@@ -413,7 +437,7 @@ fn serialize_variant(
|
||||
variant_ident
|
||||
);
|
||||
let skipped_err = quote! {
|
||||
_serde::export::Err(_serde::ser::Error::custom(#skipped_msg))
|
||||
_serde::__private::Err(_serde::ser::Error::custom(#skipped_msg))
|
||||
};
|
||||
let fields_pat = match variant.style {
|
||||
Style::Unit => quote!(),
|
||||
@@ -451,18 +475,17 @@ fn serialize_variant(
|
||||
}
|
||||
};
|
||||
|
||||
let body = Match(match *cattrs.tag() {
|
||||
attr::EnumTag::External => {
|
||||
let body = Match(match cattrs.tag() {
|
||||
attr::TagType::External => {
|
||||
serialize_externally_tagged_variant(params, variant, variant_index, cattrs)
|
||||
}
|
||||
attr::EnumTag::Internal { ref tag } => {
|
||||
attr::TagType::Internal { tag } => {
|
||||
serialize_internally_tagged_variant(params, variant, cattrs, tag)
|
||||
}
|
||||
attr::EnumTag::Adjacent {
|
||||
ref tag,
|
||||
ref content,
|
||||
} => serialize_adjacently_tagged_variant(params, variant, cattrs, tag, content),
|
||||
attr::EnumTag::None => serialize_untagged_variant(params, variant, cattrs),
|
||||
attr::TagType::Adjacent { tag, content } => {
|
||||
serialize_adjacently_tagged_variant(params, variant, cattrs, tag, content)
|
||||
}
|
||||
attr::TagType::None => serialize_untagged_variant(params, variant, cattrs),
|
||||
});
|
||||
|
||||
quote! {
|
||||
@@ -493,7 +516,7 @@ fn serialize_externally_tagged_variant(
|
||||
};
|
||||
}
|
||||
|
||||
match variant.style {
|
||||
match effective_style(variant) {
|
||||
Style::Unit => {
|
||||
quote_expr! {
|
||||
_serde::Serializer::serialize_unit_variant(
|
||||
@@ -525,17 +548,17 @@ fn serialize_externally_tagged_variant(
|
||||
}
|
||||
Style::Tuple => serialize_tuple_variant(
|
||||
TupleVariant::ExternallyTagged {
|
||||
type_name: type_name,
|
||||
variant_index: variant_index,
|
||||
variant_name: variant_name,
|
||||
type_name,
|
||||
variant_index,
|
||||
variant_name,
|
||||
},
|
||||
params,
|
||||
&variant.fields,
|
||||
),
|
||||
Style::Struct => serialize_struct_variant(
|
||||
StructVariant::ExternallyTagged {
|
||||
variant_index: variant_index,
|
||||
variant_name: variant_name,
|
||||
variant_index,
|
||||
variant_name,
|
||||
},
|
||||
params,
|
||||
&variant.fields,
|
||||
@@ -559,7 +582,7 @@ fn serialize_internally_tagged_variant(
|
||||
if let Some(path) = variant.attrs.serialize_with() {
|
||||
let ser = wrap_serialize_variant_with(params, path, variant);
|
||||
return quote_expr! {
|
||||
_serde::private::ser::serialize_tagged_newtype(
|
||||
_serde::__private::ser::serialize_tagged_newtype(
|
||||
__serializer,
|
||||
#enum_ident_str,
|
||||
#variant_ident_str,
|
||||
@@ -570,7 +593,7 @@ fn serialize_internally_tagged_variant(
|
||||
};
|
||||
}
|
||||
|
||||
match variant.style {
|
||||
match effective_style(variant) {
|
||||
Style::Unit => {
|
||||
quote_block! {
|
||||
let mut __struct = try!(_serde::Serializer::serialize_struct(
|
||||
@@ -588,7 +611,7 @@ fn serialize_internally_tagged_variant(
|
||||
}
|
||||
|
||||
let span = field.original.span();
|
||||
let func = quote_spanned!(span=> _serde::private::ser::serialize_tagged_newtype);
|
||||
let func = quote_spanned!(span=> _serde::__private::ser::serialize_tagged_newtype);
|
||||
quote_expr! {
|
||||
#func(
|
||||
__serializer,
|
||||
@@ -601,10 +624,7 @@ fn serialize_internally_tagged_variant(
|
||||
}
|
||||
}
|
||||
Style::Struct => serialize_struct_variant(
|
||||
StructVariant::InternallyTagged {
|
||||
tag: tag,
|
||||
variant_name: variant_name,
|
||||
},
|
||||
StructVariant::InternallyTagged { tag, variant_name },
|
||||
params,
|
||||
&variant.fields,
|
||||
&type_name,
|
||||
@@ -630,7 +650,7 @@ fn serialize_adjacently_tagged_variant(
|
||||
_serde::Serialize::serialize(#ser, __serializer)
|
||||
}
|
||||
} else {
|
||||
match variant.style {
|
||||
match effective_style(variant) {
|
||||
Style::Unit => {
|
||||
return quote_block! {
|
||||
let mut __struct = try!(_serde::Serializer::serialize_struct(
|
||||
@@ -699,14 +719,16 @@ fn serialize_adjacently_tagged_variant(
|
||||
quote_block! {
|
||||
struct __AdjacentlyTagged #wrapper_generics #where_clause {
|
||||
data: (#(&'__a #fields_ty,)*),
|
||||
phantom: _serde::export::PhantomData<#this #ty_generics>,
|
||||
phantom: _serde::__private::PhantomData<#this #ty_generics>,
|
||||
}
|
||||
|
||||
impl #wrapper_impl_generics _serde::Serialize for __AdjacentlyTagged #wrapper_ty_generics #where_clause {
|
||||
fn serialize<__S>(&self, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
|
||||
fn serialize<__S>(&self, __serializer: __S) -> _serde::__private::Result<__S::Ok, __S::Error>
|
||||
where
|
||||
__S: _serde::Serializer,
|
||||
{
|
||||
// Elements that have skip_serializing will be unused.
|
||||
#[allow(unused_variables)]
|
||||
let (#(#fields_ident,)*) = self.data;
|
||||
#inner
|
||||
}
|
||||
@@ -719,7 +741,7 @@ fn serialize_adjacently_tagged_variant(
|
||||
try!(_serde::ser::SerializeStruct::serialize_field(
|
||||
&mut __struct, #content, &__AdjacentlyTagged {
|
||||
data: (#(#fields_ident,)*),
|
||||
phantom: _serde::export::PhantomData::<#this #ty_generics>,
|
||||
phantom: _serde::__private::PhantomData::<#this #ty_generics>,
|
||||
}));
|
||||
_serde::ser::SerializeStruct::end(__struct)
|
||||
}
|
||||
@@ -737,7 +759,7 @@ fn serialize_untagged_variant(
|
||||
};
|
||||
}
|
||||
|
||||
match variant.style {
|
||||
match effective_style(variant) {
|
||||
Style::Unit => {
|
||||
quote_expr! {
|
||||
_serde::Serializer::serialize_unit(__serializer)
|
||||
@@ -788,7 +810,7 @@ fn serialize_tuple_variant(
|
||||
let mut serialized_fields = fields
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|&(_, ref field)| !field.attrs.skip_serializing())
|
||||
.filter(|(_, field)| !field.attrs.skip_serializing())
|
||||
.peekable();
|
||||
|
||||
let let_mut = mut_if(serialized_fields.peek().is_some());
|
||||
@@ -855,9 +877,9 @@ fn serialize_struct_variant<'a>(
|
||||
}
|
||||
|
||||
let struct_trait = match context {
|
||||
StructVariant::ExternallyTagged { .. } => (StructTrait::SerializeStructVariant),
|
||||
StructVariant::ExternallyTagged { .. } => StructTrait::SerializeStructVariant,
|
||||
StructVariant::InternallyTagged { .. } | StructVariant::Untagged => {
|
||||
(StructTrait::SerializeStruct)
|
||||
StructTrait::SerializeStruct
|
||||
}
|
||||
};
|
||||
|
||||
@@ -960,18 +982,18 @@ fn serialize_struct_variant_with_flatten<'a>(
|
||||
quote_block! {
|
||||
struct __EnumFlatten #wrapper_generics #where_clause {
|
||||
data: (#(&'__a #fields_ty,)*),
|
||||
phantom: _serde::export::PhantomData<#this #ty_generics>,
|
||||
phantom: _serde::__private::PhantomData<#this #ty_generics>,
|
||||
}
|
||||
|
||||
impl #wrapper_impl_generics _serde::Serialize for __EnumFlatten #wrapper_ty_generics #where_clause {
|
||||
fn serialize<__S>(&self, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
|
||||
fn serialize<__S>(&self, __serializer: __S) -> _serde::__private::Result<__S::Ok, __S::Error>
|
||||
where
|
||||
__S: _serde::Serializer,
|
||||
{
|
||||
let (#(#members,)*) = self.data;
|
||||
let #let_mut __serde_state = try!(_serde::Serializer::serialize_map(
|
||||
__serializer,
|
||||
_serde::export::None));
|
||||
_serde::__private::None));
|
||||
#(#serialize_fields)*
|
||||
_serde::ser::SerializeMap::end(__serde_state)
|
||||
}
|
||||
@@ -984,7 +1006,7 @@ fn serialize_struct_variant_with_flatten<'a>(
|
||||
#variant_name,
|
||||
&__EnumFlatten {
|
||||
data: (#(#members,)*),
|
||||
phantom: _serde::export::PhantomData::<#this #ty_generics>,
|
||||
phantom: _serde::__private::PhantomData::<#this #ty_generics>,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -992,7 +1014,7 @@ fn serialize_struct_variant_with_flatten<'a>(
|
||||
quote_block! {
|
||||
let #let_mut __serde_state = try!(_serde::Serializer::serialize_map(
|
||||
__serializer,
|
||||
_serde::export::None));
|
||||
_serde::__private::None));
|
||||
try!(_serde::ser::SerializeMap::serialize_entry(
|
||||
&mut __serde_state,
|
||||
#tag,
|
||||
@@ -1006,7 +1028,7 @@ fn serialize_struct_variant_with_flatten<'a>(
|
||||
quote_block! {
|
||||
let #let_mut __serde_state = try!(_serde::Serializer::serialize_map(
|
||||
__serializer,
|
||||
_serde::export::None));
|
||||
_serde::__private::None));
|
||||
#(#serialize_fields)*
|
||||
_serde::ser::SerializeMap::end(__serde_state)
|
||||
}
|
||||
@@ -1023,7 +1045,7 @@ fn serialize_tuple_struct_visitor(
|
||||
fields
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|&(_, ref field)| !field.attrs.skip_serializing())
|
||||
.filter(|(_, field)| !field.attrs.skip_serializing())
|
||||
.map(|(i, field)| {
|
||||
let mut field_expr = if is_enum {
|
||||
let id = Ident::new(&format!("__field{}", i), Span::call_site());
|
||||
@@ -1077,7 +1099,7 @@ fn serialize_struct_visitor(
|
||||
let mut field_expr = if is_enum {
|
||||
quote!(#member)
|
||||
} else {
|
||||
get_member(params, field, &member)
|
||||
get_member(params, field, member)
|
||||
};
|
||||
|
||||
let key_expr = field.attrs.name().serialize_name();
|
||||
@@ -1095,7 +1117,7 @@ fn serialize_struct_visitor(
|
||||
let ser = if field.attrs.flatten() {
|
||||
let func = quote_spanned!(span=> _serde::Serialize::serialize);
|
||||
quote! {
|
||||
try!(#func(&#field_expr, _serde::private::ser::FlatMapSerializer(&mut __serde_state)));
|
||||
try!(#func(&#field_expr, _serde::__private::ser::FlatMapSerializer(&mut __serde_state)));
|
||||
}
|
||||
} else {
|
||||
let func = struct_trait.serialize_field(span);
|
||||
@@ -1147,9 +1169,9 @@ fn wrap_serialize_variant_with(
|
||||
.fields
|
||||
.iter()
|
||||
.map(|field| {
|
||||
let id = match field.member {
|
||||
Member::Named(ref ident) => ident.clone(),
|
||||
Member::Unnamed(ref member) => {
|
||||
let id = match &field.member {
|
||||
Member::Named(ident) => ident.clone(),
|
||||
Member::Unnamed(member) => {
|
||||
Ident::new(&format!("__field{}", member.index), Span::call_site())
|
||||
}
|
||||
};
|
||||
@@ -1190,11 +1212,11 @@ fn wrap_serialize_with(
|
||||
quote!({
|
||||
struct __SerializeWith #wrapper_impl_generics #where_clause {
|
||||
values: (#(&'__a #field_tys, )*),
|
||||
phantom: _serde::export::PhantomData<#this #ty_generics>,
|
||||
phantom: _serde::__private::PhantomData<#this #ty_generics>,
|
||||
}
|
||||
|
||||
impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause {
|
||||
fn serialize<__S>(&self, __s: __S) -> _serde::export::Result<__S::Ok, __S::Error>
|
||||
fn serialize<__S>(&self, __s: __S) -> _serde::__private::Result<__S::Ok, __S::Error>
|
||||
where
|
||||
__S: _serde::Serializer,
|
||||
{
|
||||
@@ -1204,7 +1226,7 @@ fn wrap_serialize_with(
|
||||
|
||||
&__SerializeWith {
|
||||
values: (#(#field_exprs, )*),
|
||||
phantom: _serde::export::PhantomData::<#this #ty_generics>,
|
||||
phantom: _serde::__private::PhantomData::<#this #ty_generics>,
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -1226,15 +1248,25 @@ fn mut_if(is_mut: bool) -> Option<TokenStream> {
|
||||
fn get_member(params: &Parameters, field: &Field, member: &Member) -> TokenStream {
|
||||
let self_var = ¶ms.self_var;
|
||||
match (params.is_remote, field.attrs.getter()) {
|
||||
(false, None) => quote!(&#self_var.#member),
|
||||
(false, None) => {
|
||||
if params.is_packed {
|
||||
quote!(&{#self_var.#member})
|
||||
} else {
|
||||
quote!(&#self_var.#member)
|
||||
}
|
||||
}
|
||||
(true, None) => {
|
||||
let inner = quote!(&#self_var.#member);
|
||||
let inner = if params.is_packed {
|
||||
quote!(&{#self_var.#member})
|
||||
} else {
|
||||
quote!(&#self_var.#member)
|
||||
};
|
||||
let ty = field.ty;
|
||||
quote!(_serde::private::ser::constrain::<#ty>(#inner))
|
||||
quote!(_serde::__private::ser::constrain::<#ty>(#inner))
|
||||
}
|
||||
(true, Some(getter)) => {
|
||||
let ty = field.ty;
|
||||
quote!(_serde::private::ser::constrain::<#ty>(&#getter(#self_var)))
|
||||
quote!(_serde::__private::ser::constrain::<#ty>(&#getter(#self_var)))
|
||||
}
|
||||
(false, Some(_)) => {
|
||||
unreachable!("getter is only allowed for remote impls");
|
||||
@@ -1242,6 +1274,13 @@ fn get_member(params: &Parameters, field: &Field, member: &Member) -> TokenStrea
|
||||
}
|
||||
}
|
||||
|
||||
fn effective_style(variant: &Variant) -> Style {
|
||||
match variant.style {
|
||||
Style::Newtype if variant.fields[0].attrs.skip_serializing() => Style::Unit,
|
||||
other => other,
|
||||
}
|
||||
}
|
||||
|
||||
enum StructTrait {
|
||||
SerializeMap,
|
||||
SerializeStruct,
|
||||
|
||||
@@ -13,9 +13,9 @@ pub fn replacement() -> TokenStream {
|
||||
macro_rules! try {
|
||||
(#dollar __expr:expr) => {
|
||||
match #dollar __expr {
|
||||
_serde::export::Ok(__val) => __val,
|
||||
_serde::export::Err(__err) => {
|
||||
return _serde::export::Err(__err);
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
[package]
|
||||
name = "serde_derive_internals"
|
||||
version = "0.24.1" # remember to update html_root_url
|
||||
version = "0.26.0" # remember to update html_root_url
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
rust-version = "1.31"
|
||||
license = "MIT OR Apache-2.0"
|
||||
description = "AST representation used by Serde derive macros. Unstable."
|
||||
homepage = "https://serde.rs"
|
||||
repository = "https://github.com/serde-rs/serde"
|
||||
documentation = "https://docs.rs/serde_derive_internals"
|
||||
keywords = ["serde", "serialization"]
|
||||
include = ["Cargo.toml", "lib.rs", "src/**/*.rs", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
include = ["lib.rs", "src/**/*.rs", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
|
||||
[lib]
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "0.4"
|
||||
syn = { version = "0.15", default-features = false, features = ["derive", "parsing", "clone-impls"] }
|
||||
proc-macro2 = "1.0"
|
||||
quote = "1.0"
|
||||
syn = { version = "1.0.60", default-features = false, features = ["derive", "parsing", "printing", "clone-impls"] }
|
||||
|
||||
[badges]
|
||||
travis-ci = { repository = "serde-rs/serde" }
|
||||
appveyor = { repository = "serde-rs/serde" }
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
use std::path::Path;
|
||||
|
||||
fn main() {
|
||||
// Sometimes on Windows the git checkout does not correctly wire up the
|
||||
// symlink from serde_derive_internals/src to serde_derive/src/internals.
|
||||
// When this happens we'll just build based on relative paths within the git
|
||||
// repo.
|
||||
let mod_behind_symlink = Path::new("src/mod.rs");
|
||||
if !mod_behind_symlink.exists() {
|
||||
println!("cargo:rustc-cfg=serde_build_from_git");
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,49 @@
|
||||
#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.24.1")]
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(
|
||||
feature = "cargo-clippy",
|
||||
allow(
|
||||
cyclomatic_complexity,
|
||||
doc_markdown,
|
||||
match_same_arms,
|
||||
redundant_field_names
|
||||
)
|
||||
#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.26.0")]
|
||||
#![allow(unknown_lints, bare_trait_objects)]
|
||||
// Ignored clippy lints
|
||||
#![allow(
|
||||
clippy::cognitive_complexity,
|
||||
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/7575
|
||||
clippy::collapsible_match,
|
||||
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/6797
|
||||
clippy::manual_map,
|
||||
clippy::missing_panics_doc,
|
||||
clippy::redundant_field_names,
|
||||
clippy::result_unit_err,
|
||||
clippy::should_implement_trait,
|
||||
clippy::trivially_copy_pass_by_ref,
|
||||
clippy::wildcard_in_or_patterns,
|
||||
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704
|
||||
clippy::unnested_or_patterns,
|
||||
)]
|
||||
// Ignored clippy_pedantic lints
|
||||
#![allow(
|
||||
clippy::doc_markdown,
|
||||
clippy::enum_glob_use,
|
||||
clippy::items_after_statements,
|
||||
clippy::let_underscore_drop,
|
||||
clippy::manual_assert,
|
||||
clippy::match_same_arms,
|
||||
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/6984
|
||||
clippy::match_wildcard_for_single_variants,
|
||||
clippy::missing_errors_doc,
|
||||
clippy::module_name_repetitions,
|
||||
clippy::must_use_candidate,
|
||||
clippy::similar_names,
|
||||
clippy::struct_excessive_bools,
|
||||
clippy::too_many_lines,
|
||||
clippy::unused_self,
|
||||
clippy::wildcard_imports
|
||||
)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate syn;
|
||||
|
||||
extern crate proc_macro2;
|
||||
extern crate quote;
|
||||
|
||||
#[path = "src/mod.rs"]
|
||||
#[cfg_attr(serde_build_from_git, path = "../serde_derive/src/internals/mod.rs")]
|
||||
#[cfg_attr(not(serde_build_from_git), path = "src/mod.rs")]
|
||||
mod internals;
|
||||
|
||||
pub use internals::*;
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
[package]
|
||||
name = "serde_test"
|
||||
version = "1.0.81" # remember to update html_root_url
|
||||
version = "1.0.135" # remember to update html_root_url
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
rust-version = "1.15"
|
||||
license = "MIT OR Apache-2.0"
|
||||
description = "Token De/Serializer for testing De/Serialize implementations"
|
||||
homepage = "https://serde.rs"
|
||||
repository = "https://github.com/serde-rs/serde"
|
||||
documentation = "https://docs.serde.rs/serde_test/"
|
||||
keywords = ["serde", "serialization"]
|
||||
readme = "crates-io.md"
|
||||
include = ["Cargo.toml", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
include = ["build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0.60", path = "../serde" }
|
||||
|
||||
[dev-dependencies]
|
||||
serde = { version = "1.0", path = "../serde", features = ["rc"] }
|
||||
serde = { version = "1.0", path = "../serde" }
|
||||
serde_derive = { version = "1.0", path = "../serde_derive" }
|
||||
|
||||
[badges]
|
||||
travis-ci = { repository = "serde-rs/serde" }
|
||||
appveyor = { repository = "serde-rs/serde" }
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
use std::env;
|
||||
use std::process::Command;
|
||||
use std::str::{self, FromStr};
|
||||
|
||||
// The rustc-cfg strings below are *not* public API. Please let us know by
|
||||
// opening a GitHub issue if your build environment requires some way to enable
|
||||
// these cfgs other than by executing our build script.
|
||||
fn main() {
|
||||
let minor = match rustc_minor_version() {
|
||||
Some(minor) => minor,
|
||||
None => return,
|
||||
};
|
||||
|
||||
// #[track_caller] stabilized in Rust 1.46:
|
||||
// https://blog.rust-lang.org/2020/08/27/Rust-1.46.0.html#track_caller
|
||||
if minor >= 46 {
|
||||
println!("cargo:rustc-cfg=track_caller");
|
||||
}
|
||||
}
|
||||
|
||||
fn rustc_minor_version() -> Option<u32> {
|
||||
let rustc = match env::var_os("RUSTC") {
|
||||
Some(rustc) => rustc,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
let output = match Command::new(rustc).arg("--version").output() {
|
||||
Ok(output) => output,
|
||||
Err(_) => return None,
|
||||
};
|
||||
|
||||
let version = match str::from_utf8(&output.stdout) {
|
||||
Ok(version) => version,
|
||||
Err(_) => return None,
|
||||
};
|
||||
|
||||
let mut pieces = version.split('.');
|
||||
if pieces.next() != Some("rustc 1") {
|
||||
return None;
|
||||
}
|
||||
|
||||
let next = match pieces.next() {
|
||||
Some(next) => next,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
u32::from_str(next).ok()
|
||||
}
|
||||
+35
-62
@@ -8,16 +8,10 @@ use std::fmt::Debug;
|
||||
|
||||
/// Runs both `assert_ser_tokens` and `assert_de_tokens`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde_derive;
|
||||
/// #
|
||||
/// # extern crate serde;
|
||||
/// # extern crate serde_test;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::{Serialize, Deserialize};
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||
/// struct S {
|
||||
/// a: u8,
|
||||
@@ -33,8 +27,8 @@ use std::fmt::Debug;
|
||||
/// Token::U8(0),
|
||||
/// Token::StructEnd,
|
||||
/// ]);
|
||||
/// # }
|
||||
/// ```
|
||||
#[cfg_attr(track_caller, track_caller)]
|
||||
pub fn assert_tokens<'de, T>(value: &T, tokens: &'de [Token])
|
||||
where
|
||||
T: Serialize + Deserialize<'de> + PartialEq + Debug,
|
||||
@@ -45,16 +39,10 @@ where
|
||||
|
||||
/// Asserts that `value` serializes to the given `tokens`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde_derive;
|
||||
/// #
|
||||
/// # extern crate serde;
|
||||
/// # extern crate serde_test;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::{Serialize, Deserialize};
|
||||
/// # use serde_test::{assert_ser_tokens, Token};
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||
/// struct S {
|
||||
/// a: u8,
|
||||
@@ -70,9 +58,9 @@ where
|
||||
/// Token::U8(0),
|
||||
/// Token::StructEnd,
|
||||
/// ]);
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn assert_ser_tokens<T>(value: &T, tokens: &[Token])
|
||||
#[cfg_attr(track_caller, track_caller)]
|
||||
pub fn assert_ser_tokens<T: ?Sized>(value: &T, tokens: &[Token])
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
@@ -90,16 +78,11 @@ where
|
||||
/// Asserts that `value` serializes to the given `tokens`, and then yields
|
||||
/// `error`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde_derive;
|
||||
/// #
|
||||
/// # extern crate serde_test;
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// ```edition2018
|
||||
/// use std::sync::{Arc, Mutex};
|
||||
/// use std::thread;
|
||||
///
|
||||
/// use serde::Serialize;
|
||||
/// use serde_test::{assert_ser_tokens_error, Token};
|
||||
///
|
||||
/// #[derive(Serialize)]
|
||||
@@ -107,28 +90,30 @@ where
|
||||
/// lock: Arc<Mutex<u32>>,
|
||||
/// }
|
||||
///
|
||||
/// let example = Example { lock: Arc::new(Mutex::new(0)) };
|
||||
/// let lock = example.lock.clone();
|
||||
/// fn main() {
|
||||
/// let example = Example { lock: Arc::new(Mutex::new(0)) };
|
||||
/// let lock = example.lock.clone();
|
||||
///
|
||||
/// let _ = thread::spawn(move || {
|
||||
/// // This thread will acquire the mutex first, unwrapping the result
|
||||
/// // of `lock` because the lock has not been poisoned.
|
||||
/// let _guard = lock.lock().unwrap();
|
||||
/// let _ = thread::spawn(move || {
|
||||
/// // This thread will acquire the mutex first, unwrapping the result
|
||||
/// // of `lock` because the lock has not been poisoned.
|
||||
/// let _guard = lock.lock().unwrap();
|
||||
///
|
||||
/// // This panic while holding the lock (`_guard` is in scope) will
|
||||
/// // poison the mutex.
|
||||
/// panic!()
|
||||
/// }).join();
|
||||
/// // This panic while holding the lock (`_guard` is in scope) will
|
||||
/// // poison the mutex.
|
||||
/// panic!()
|
||||
/// }).join();
|
||||
///
|
||||
/// let expected = &[
|
||||
/// Token::Struct { name: "Example", len: 1 },
|
||||
/// Token::Str("lock"),
|
||||
/// ];
|
||||
/// let error = "lock poison error while serializing";
|
||||
/// assert_ser_tokens_error(&example, expected, error);
|
||||
/// # }
|
||||
/// let expected = &[
|
||||
/// Token::Struct { name: "Example", len: 1 },
|
||||
/// Token::Str("lock"),
|
||||
/// ];
|
||||
/// let error = "lock poison error while serializing";
|
||||
/// assert_ser_tokens_error(&example, expected, error);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn assert_ser_tokens_error<T>(value: &T, tokens: &[Token], error: &str)
|
||||
#[cfg_attr(track_caller, track_caller)]
|
||||
pub fn assert_ser_tokens_error<T: ?Sized>(value: &T, tokens: &[Token], error: &str)
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
@@ -145,16 +130,10 @@ where
|
||||
|
||||
/// Asserts that the given `tokens` deserialize into `value`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde_derive;
|
||||
/// #
|
||||
/// # extern crate serde;
|
||||
/// # extern crate serde_test;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::{Serialize, Deserialize};
|
||||
/// # use serde_test::{assert_de_tokens, Token};
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||
/// struct S {
|
||||
/// a: u8,
|
||||
@@ -170,8 +149,8 @@ where
|
||||
/// Token::U8(0),
|
||||
/// Token::StructEnd,
|
||||
/// ]);
|
||||
/// # }
|
||||
/// ```
|
||||
#[cfg_attr(track_caller, track_caller)]
|
||||
pub fn assert_de_tokens<'de, T>(value: &T, tokens: &'de [Token])
|
||||
where
|
||||
T: Deserialize<'de> + PartialEq + Debug,
|
||||
@@ -205,16 +184,10 @@ where
|
||||
|
||||
/// Asserts that the given `tokens` yield `error` when deserializing.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde_derive;
|
||||
/// #
|
||||
/// # extern crate serde;
|
||||
/// # extern crate serde_test;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::{Serialize, Deserialize};
|
||||
/// # use serde_test::{assert_de_tokens_error, Token};
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||
/// #[serde(deny_unknown_fields)]
|
||||
/// struct S {
|
||||
@@ -229,8 +202,8 @@ where
|
||||
/// ],
|
||||
/// "unknown field `x`, expected `a` or `b`",
|
||||
/// );
|
||||
/// # }
|
||||
/// ```
|
||||
#[cfg_attr(track_caller, track_caller)]
|
||||
pub fn assert_de_tokens_error<'de, T>(tokens: &'de [Token], error: &str)
|
||||
where
|
||||
T: Deserialize<'de>,
|
||||
|
||||
@@ -14,10 +14,7 @@ pub struct Compact<T: ?Sized>(T);
|
||||
/// Trait to determine whether a value is represented in human-readable or
|
||||
/// compact form.
|
||||
///
|
||||
/// ```
|
||||
/// extern crate serde;
|
||||
/// extern crate serde_test;
|
||||
///
|
||||
/// ```edition2018
|
||||
/// use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
/// use serde_test::{assert_tokens, Configure, Token};
|
||||
///
|
||||
@@ -780,6 +777,17 @@ macro_rules! impl_deserializer {
|
||||
{
|
||||
self.0.next_value_seed($wrapper(seed))
|
||||
}
|
||||
fn next_entry_seed<K, V>(
|
||||
&mut self,
|
||||
kseed: K,
|
||||
vseed: V,
|
||||
) -> Result<Option<(K::Value, V::Value)>, D::Error>
|
||||
where
|
||||
K: DeserializeSeed<'de>,
|
||||
V: DeserializeSeed<'de>,
|
||||
{
|
||||
self.0.next_entry_seed($wrapper(kseed), $wrapper(vseed))
|
||||
}
|
||||
fn size_hint(&self) -> Option<usize> {
|
||||
self.0.size_hint()
|
||||
}
|
||||
|
||||
+37
-11
@@ -89,11 +89,11 @@ impl<'de> Deserializer<'de> {
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
let value = try!(visitor.visit_seq(DeserializerSeqVisitor {
|
||||
let value = visitor.visit_seq(DeserializerSeqVisitor {
|
||||
de: self,
|
||||
len: len,
|
||||
end: end,
|
||||
},));
|
||||
})?;
|
||||
assert_next_token!(self, end);
|
||||
Ok(value)
|
||||
}
|
||||
@@ -107,11 +107,11 @@ impl<'de> Deserializer<'de> {
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
let value = try!(visitor.visit_map(DeserializerMapVisitor {
|
||||
let value = visitor.visit_map(DeserializerMapVisitor {
|
||||
de: self,
|
||||
len: len,
|
||||
end: end,
|
||||
},));
|
||||
})?;
|
||||
assert_next_token!(self, end);
|
||||
Ok(value)
|
||||
}
|
||||
@@ -168,14 +168,42 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||
self.next_token();
|
||||
visitor.visit_str(variant)
|
||||
}
|
||||
(Token::BorrowedStr(variant), Token::Unit) => {
|
||||
self.next_token();
|
||||
visitor.visit_borrowed_str(variant)
|
||||
}
|
||||
(Token::String(variant), Token::Unit) => {
|
||||
self.next_token();
|
||||
visitor.visit_string(variant.to_string())
|
||||
}
|
||||
(Token::Bytes(variant), Token::Unit) => {
|
||||
self.next_token();
|
||||
visitor.visit_bytes(variant)
|
||||
}
|
||||
(Token::BorrowedBytes(variant), Token::Unit) => {
|
||||
self.next_token();
|
||||
visitor.visit_borrowed_bytes(variant)
|
||||
}
|
||||
(Token::ByteBuf(variant), Token::Unit) => {
|
||||
self.next_token();
|
||||
visitor.visit_byte_buf(variant.to_vec())
|
||||
}
|
||||
(Token::U8(variant), Token::Unit) => {
|
||||
self.next_token();
|
||||
visitor.visit_u8(variant)
|
||||
}
|
||||
(Token::U16(variant), Token::Unit) => {
|
||||
self.next_token();
|
||||
visitor.visit_u16(variant)
|
||||
}
|
||||
(Token::U32(variant), Token::Unit) => {
|
||||
self.next_token();
|
||||
visitor.visit_u32(variant)
|
||||
}
|
||||
(Token::U64(variant), Token::Unit) => {
|
||||
self.next_token();
|
||||
visitor.visit_u64(variant)
|
||||
}
|
||||
(variant, Token::Unit) => unexpected!(variant),
|
||||
(variant, _) => {
|
||||
visitor.visit_map(EnumMapVisitor::new(self, variant, EnumFormat::Any))
|
||||
@@ -250,9 +278,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
||||
{
|
||||
visitor.visit_enum(DeserializerEnumVisitor { de: self })
|
||||
}
|
||||
_ => {
|
||||
unexpected!(self.next_token());
|
||||
}
|
||||
_ => self.deserialize_any(visitor),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -456,11 +482,11 @@ impl<'de, 'a> EnumAccess<'de> for DeserializerEnumVisitor<'a, 'de> {
|
||||
| Token::TupleVariant { variant: v, .. }
|
||||
| Token::StructVariant { variant: v, .. } => {
|
||||
let de = v.into_deserializer();
|
||||
let value = try!(seed.deserialize(de));
|
||||
let value = seed.deserialize(de)?;
|
||||
Ok((value, self))
|
||||
}
|
||||
_ => {
|
||||
let value = try!(seed.deserialize(&mut *self.de));
|
||||
let value = seed.deserialize(&mut *self.de)?;
|
||||
Ok((value, self))
|
||||
}
|
||||
}
|
||||
@@ -613,7 +639,7 @@ impl<'de, 'a> MapAccess<'de> for EnumMapVisitor<'a, 'de> {
|
||||
len: None,
|
||||
end: Token::TupleVariantEnd,
|
||||
};
|
||||
try!(seed.deserialize(SeqAccessDeserializer::new(visitor)))
|
||||
seed.deserialize(SeqAccessDeserializer::new(visitor))?
|
||||
};
|
||||
assert_next_token!(self.de, Token::TupleVariantEnd);
|
||||
Ok(value)
|
||||
@@ -625,7 +651,7 @@ impl<'de, 'a> MapAccess<'de> for EnumMapVisitor<'a, 'de> {
|
||||
len: None,
|
||||
end: Token::StructVariantEnd,
|
||||
};
|
||||
try!(seed.deserialize(MapAccessDeserializer::new(visitor)))
|
||||
seed.deserialize(MapAccessDeserializer::new(visitor))?
|
||||
};
|
||||
assert_next_token!(self.de, Token::StructVariantEnd);
|
||||
Ok(value)
|
||||
|
||||
+13
-18
@@ -24,19 +24,10 @@
|
||||
//!
|
||||
//! [`linked-hash-map`]: https://github.com/contain-rs/linked-hash-map
|
||||
//!
|
||||
//! ```rust
|
||||
//! # extern crate serde;
|
||||
//! #
|
||||
//! # macro_rules! ignore {
|
||||
//! # ($($tt:tt)+) => {}
|
||||
//! # }
|
||||
//! #
|
||||
//! # ignore! {
|
||||
//! extern crate linked_hash_map;
|
||||
//! ```edition2018
|
||||
//! # const IGNORE: &str = stringify! {
|
||||
//! use linked_hash_map::LinkedHashMap;
|
||||
//! # }
|
||||
//!
|
||||
//! extern crate serde_test;
|
||||
//! # };
|
||||
//! use serde_test::{Token, assert_tokens};
|
||||
//!
|
||||
//! # use std::fmt;
|
||||
@@ -153,19 +144,23 @@
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.81")]
|
||||
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.135")]
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
|
||||
// Whitelisted clippy lints
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp))]
|
||||
// Whitelisted clippy_pedantic lints
|
||||
// Ignored clippy lints
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp, needless_doctest_main))]
|
||||
// Ignored clippy_pedantic lints
|
||||
#![cfg_attr(
|
||||
feature = "cargo-clippy",
|
||||
allow(
|
||||
cloned_instead_of_copied,
|
||||
empty_line_after_outer_attr,
|
||||
manual_assert,
|
||||
missing_docs_in_private_items,
|
||||
missing_panics_doc,
|
||||
module_name_repetitions,
|
||||
must_use_candidate,
|
||||
redundant_field_names,
|
||||
stutter,
|
||||
too_many_lines,
|
||||
use_debug,
|
||||
use_self
|
||||
)
|
||||
|
||||
+18
-18
@@ -32,18 +32,18 @@ impl<'a> Serializer<'a> {
|
||||
}
|
||||
|
||||
macro_rules! assert_next_token {
|
||||
($ser:expr, $expected:ident) => {
|
||||
assert_next_token!($ser, stringify!($expected), Token::$expected, true);
|
||||
};
|
||||
($ser:expr, $expected:ident($v:expr)) => {
|
||||
($ser:expr, $actual:ident) => {{
|
||||
assert_next_token!($ser, stringify!($actual), Token::$actual, true);
|
||||
}};
|
||||
($ser:expr, $actual:ident($v:expr)) => {{
|
||||
assert_next_token!(
|
||||
$ser,
|
||||
format_args!(concat!(stringify!($expected), "({:?})"), $v),
|
||||
Token::$expected(v),
|
||||
format_args!(concat!(stringify!($actual), "({:?})"), $v),
|
||||
Token::$actual(v),
|
||||
v == $v
|
||||
);
|
||||
};
|
||||
($ser:expr, $expected:ident { $($k:ident),* }) => {
|
||||
}};
|
||||
($ser:expr, $actual:ident { $($k:ident),* }) => {{
|
||||
let compare = ($($k,)*);
|
||||
let field_format = || {
|
||||
use std::fmt::Write;
|
||||
@@ -55,21 +55,21 @@ macro_rules! assert_next_token {
|
||||
};
|
||||
assert_next_token!(
|
||||
$ser,
|
||||
format_args!(concat!(stringify!($expected), " {{ {}}}"), field_format()),
|
||||
Token::$expected { $($k),* },
|
||||
format_args!(concat!(stringify!($actual), " {{ {}}}"), field_format()),
|
||||
Token::$actual { $($k),* },
|
||||
($($k,)*) == compare
|
||||
);
|
||||
};
|
||||
($ser:expr, $expected:expr, $pat:pat, $guard:expr) => {
|
||||
}};
|
||||
($ser:expr, $actual:expr, $pat:pat, $guard:expr) => {
|
||||
match $ser.next_token() {
|
||||
Some($pat) if $guard => {}
|
||||
Some(other) => {
|
||||
Some(expected) => {
|
||||
panic!("expected Token::{} but serialized as {}",
|
||||
$expected, other);
|
||||
expected, $actual);
|
||||
}
|
||||
None => {
|
||||
panic!("expected Token::{} after end of serialized tokens",
|
||||
$expected);
|
||||
panic!("expected end of tokens, but {} was serialized",
|
||||
$actual);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -427,7 +427,7 @@ impl<'s, 'a> ser::SerializeStruct for &'s mut Serializer<'a> {
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
try!(key.serialize(&mut **self));
|
||||
key.serialize(&mut **self)?;
|
||||
value.serialize(&mut **self)
|
||||
}
|
||||
|
||||
@@ -449,7 +449,7 @@ impl<'s, 'a> ser::SerializeStructVariant for Variant<'s, 'a> {
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
try!(key.serialize(&mut *self.ser));
|
||||
key.serialize(&mut *self.ser)?;
|
||||
value.serialize(&mut *self.ser)
|
||||
}
|
||||
|
||||
|
||||
+39
-84
@@ -4,7 +4,7 @@ use std::fmt::{self, Debug, Display};
|
||||
pub enum Token {
|
||||
/// A serialized `bool`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// assert_tokens(&true, &[Token::Bool(true)]);
|
||||
@@ -13,7 +13,7 @@ pub enum Token {
|
||||
|
||||
/// A serialized `i8`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// assert_tokens(&0i8, &[Token::I8(0)]);
|
||||
@@ -22,7 +22,7 @@ pub enum Token {
|
||||
|
||||
/// A serialized `i16`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// assert_tokens(&0i16, &[Token::I16(0)]);
|
||||
@@ -31,7 +31,7 @@ pub enum Token {
|
||||
|
||||
/// A serialized `i32`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// assert_tokens(&0i32, &[Token::I32(0)]);
|
||||
@@ -40,7 +40,7 @@ pub enum Token {
|
||||
|
||||
/// A serialized `i64`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// assert_tokens(&0i64, &[Token::I64(0)]);
|
||||
@@ -49,7 +49,7 @@ pub enum Token {
|
||||
|
||||
/// A serialized `u8`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// assert_tokens(&0u8, &[Token::U8(0)]);
|
||||
@@ -58,7 +58,7 @@ pub enum Token {
|
||||
|
||||
/// A serialized `u16`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// assert_tokens(&0u16, &[Token::U16(0)]);
|
||||
@@ -67,7 +67,7 @@ pub enum Token {
|
||||
|
||||
/// A serialized `u32`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// assert_tokens(&0u32, &[Token::U32(0)]);
|
||||
@@ -76,7 +76,7 @@ pub enum Token {
|
||||
|
||||
/// A serialized `u64`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// assert_tokens(&0u64, &[Token::U64(0)]);
|
||||
@@ -85,7 +85,7 @@ pub enum Token {
|
||||
|
||||
/// A serialized `f32`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// assert_tokens(&0f32, &[Token::F32(0.0)]);
|
||||
@@ -94,7 +94,7 @@ pub enum Token {
|
||||
|
||||
/// A serialized `f64`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// assert_tokens(&0f64, &[Token::F64(0.0)]);
|
||||
@@ -103,7 +103,7 @@ pub enum Token {
|
||||
|
||||
/// A serialized `char`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// assert_tokens(&'\n', &[Token::Char('\n')]);
|
||||
@@ -112,7 +112,7 @@ pub enum Token {
|
||||
|
||||
/// A serialized `str`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// let s = String::from("transient");
|
||||
@@ -122,7 +122,7 @@ pub enum Token {
|
||||
|
||||
/// A borrowed `str`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// let s: &str = "borrowed";
|
||||
@@ -132,7 +132,7 @@ pub enum Token {
|
||||
|
||||
/// A serialized `String`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// let s = String::from("owned");
|
||||
@@ -151,7 +151,7 @@ pub enum Token {
|
||||
|
||||
/// A serialized `Option<T>` containing none.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// let opt = None::<char>;
|
||||
@@ -163,7 +163,7 @@ pub enum Token {
|
||||
///
|
||||
/// The tokens of the value follow after this header.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// let opt = Some('c');
|
||||
@@ -176,7 +176,7 @@ pub enum Token {
|
||||
|
||||
/// A serialized `()`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// assert_tokens(&(), &[Token::Unit]);
|
||||
@@ -185,13 +185,8 @@ pub enum Token {
|
||||
|
||||
/// A serialized unit struct of the given name.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde_derive;
|
||||
/// #
|
||||
/// # extern crate serde;
|
||||
/// # extern crate serde_test;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::{Serialize, Deserialize};
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// # fn main() {
|
||||
@@ -205,13 +200,8 @@ pub enum Token {
|
||||
|
||||
/// A unit variant of an enum.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde_derive;
|
||||
/// #
|
||||
/// # extern crate serde;
|
||||
/// # extern crate serde_test;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::{Serialize, Deserialize};
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// # fn main() {
|
||||
@@ -233,13 +223,8 @@ pub enum Token {
|
||||
///
|
||||
/// After this header is the value contained in the newtype struct.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde_derive;
|
||||
/// #
|
||||
/// # extern crate serde;
|
||||
/// # extern crate serde_test;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::{Serialize, Deserialize};
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// # fn main() {
|
||||
@@ -259,13 +244,8 @@ pub enum Token {
|
||||
///
|
||||
/// After this header is the value contained in the newtype variant.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde_derive;
|
||||
/// #
|
||||
/// # extern crate serde;
|
||||
/// # extern crate serde_test;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::{Serialize, Deserialize};
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// # fn main() {
|
||||
@@ -291,7 +271,7 @@ pub enum Token {
|
||||
/// After this header are the elements of the sequence, followed by
|
||||
/// `SeqEnd`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// let vec = vec!['a', 'b', 'c'];
|
||||
@@ -312,7 +292,7 @@ pub enum Token {
|
||||
///
|
||||
/// After this header are the elements of the tuple, followed by `TupleEnd`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// let tuple = ('a', 100);
|
||||
@@ -333,13 +313,8 @@ pub enum Token {
|
||||
/// After this header are the fields of the tuple struct, followed by
|
||||
/// `TupleStructEnd`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde_derive;
|
||||
/// #
|
||||
/// # extern crate serde;
|
||||
/// # extern crate serde_test;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::{Serialize, Deserialize};
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// # fn main() {
|
||||
@@ -365,13 +340,8 @@ pub enum Token {
|
||||
/// After this header are the fields of the tuple variant, followed by
|
||||
/// `TupleVariantEnd`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde_derive;
|
||||
/// #
|
||||
/// # extern crate serde;
|
||||
/// # extern crate serde_test;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::{Serialize, Deserialize};
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// # fn main() {
|
||||
@@ -402,7 +372,7 @@ pub enum Token {
|
||||
///
|
||||
/// After this header are the entries of the map, followed by `MapEnd`.
|
||||
///
|
||||
/// ```rust
|
||||
/// ```edition2018
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// use std::collections::BTreeMap;
|
||||
@@ -429,13 +399,8 @@ pub enum Token {
|
||||
///
|
||||
/// After this header are the fields of the struct, followed by `StructEnd`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde_derive;
|
||||
/// #
|
||||
/// # extern crate serde;
|
||||
/// # extern crate serde_test;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::{Serialize, Deserialize};
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// # fn main() {
|
||||
@@ -466,13 +431,8 @@ pub enum Token {
|
||||
/// After this header are the fields of the struct variant, followed by
|
||||
/// `StructVariantEnd`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde_derive;
|
||||
/// #
|
||||
/// # extern crate serde;
|
||||
/// # extern crate serde_test;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::{Serialize, Deserialize};
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// # fn main() {
|
||||
@@ -501,13 +461,8 @@ pub enum Token {
|
||||
|
||||
/// The header to an enum of the given name.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #[macro_use]
|
||||
/// # extern crate serde_derive;
|
||||
/// #
|
||||
/// # extern crate serde;
|
||||
/// # extern crate serde_test;
|
||||
/// #
|
||||
/// ```edition2018
|
||||
/// # use serde::{Serialize, Deserialize};
|
||||
/// # use serde_test::{assert_tokens, Token};
|
||||
/// #
|
||||
/// # fn main() {
|
||||
|
||||
+14
-6
@@ -2,17 +2,25 @@
|
||||
name = "serde_test_suite"
|
||||
version = "0.0.0"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||
edition = "2018"
|
||||
publish = false
|
||||
build = "build.rs"
|
||||
|
||||
[features]
|
||||
unstable = ["serde/unstable", "compiletest_rs"]
|
||||
expandtest = []
|
||||
unstable = ["serde/unstable"]
|
||||
|
||||
[dependencies]
|
||||
serde = { path = "../serde" }
|
||||
|
||||
[build-dependencies]
|
||||
toolchain_find = "0.1"
|
||||
|
||||
[dev-dependencies]
|
||||
fnv = "1.0"
|
||||
rustc-serialize = "0.3.16"
|
||||
serde = { path = "../serde", features = ["rc"] }
|
||||
macrotest = "=1.0.0"
|
||||
rustversion = "1.0"
|
||||
serde = { path = "../serde", features = ["rc", "derive"] }
|
||||
serde_derive = { path = "../serde_derive", features = ["deserialize_in_place"] }
|
||||
serde_test = { path = "../serde_test" }
|
||||
|
||||
[dependencies]
|
||||
compiletest_rs = { version = "0.3", optional = true, features = ["stable"] }
|
||||
trybuild = { version = "1.0.49", features = ["diff"] }
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
use std::process::{Command, ExitStatus, Stdio};
|
||||
|
||||
fn has_cargo_expand() -> bool {
|
||||
let cargo_expand = if cfg!(windows) {
|
||||
"cargo-expand.exe"
|
||||
} else {
|
||||
"cargo-expand"
|
||||
};
|
||||
|
||||
Command::new(cargo_expand)
|
||||
.arg("--version")
|
||||
.stdin(Stdio::null())
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.status()
|
||||
.as_ref()
|
||||
.map(ExitStatus::success)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
fn has_rustfmt() -> bool {
|
||||
toolchain_find::find_installed_component("rustfmt").is_some()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
if cfg!(feature = "expandtest") && has_cargo_expand() && has_rustfmt() {
|
||||
println!("cargo:rustc-cfg=expandtest");
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
[package]
|
||||
name = "serde_test_suite_deps"
|
||||
version = "0.0.0"
|
||||
authors = ["David Tolnay <dtolnay@gmail.com>"]
|
||||
publish = false
|
||||
|
||||
[workspace]
|
||||
|
||||
[dependencies]
|
||||
serde = { path = "../../serde" }
|
||||
serde_derive = { path = "../../serde_derive" }
|
||||
@@ -1,3 +0,0 @@
|
||||
#![feature(/*=============================================]
|
||||
#![=== Serde test suite requires a nightly compiler. ===]
|
||||
#![====================================================*/)]
|
||||
@@ -1,11 +1,11 @@
|
||||
[package]
|
||||
name = "serde_derive_tests_no_std"
|
||||
version = "0.0.0"
|
||||
edition = "2018"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
libc = { version = "0.2", default-features = false }
|
||||
serde = { path = "../../serde", default-features = false }
|
||||
serde_derive = { path = "../../serde_derive" }
|
||||
serde = { path = "../../serde", default-features = false, features = ["derive"] }
|
||||
|
||||
[workspace]
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#![feature(lang_items, start)]
|
||||
#![no_std]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
#[start]
|
||||
fn start(_argc: isize, _argv: *const *const u8) -> isize {
|
||||
0
|
||||
@@ -21,8 +19,7 @@ fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct Unit;
|
||||
|
||||
@@ -22,7 +22,7 @@ impl<'de> Visitor<'de> for ByteBufVisitor {
|
||||
V: SeqAccess<'de>,
|
||||
{
|
||||
let mut values = Vec::new();
|
||||
while let Some(value) = try!(visitor.next_element()) {
|
||||
while let Some(value) = visitor.next_element()? {
|
||||
values.push(value);
|
||||
}
|
||||
Ok(values)
|
||||
|
||||
@@ -1,15 +1,7 @@
|
||||
#![cfg(feature = "unstable")]
|
||||
|
||||
extern crate compiletest_rs as compiletest;
|
||||
|
||||
#[cfg_attr(target_os = "emscripten", ignore)]
|
||||
#[rustversion::attr(not(nightly), ignore)]
|
||||
#[test]
|
||||
fn ui() {
|
||||
let config = compiletest::Config {
|
||||
mode: compiletest::common::Mode::Ui,
|
||||
src_base: std::path::PathBuf::from("tests/ui"),
|
||||
target_rustcflags: Some("-L deps/target/debug/deps".to_owned()),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
compiletest::run_tests(&config);
|
||||
let t = trybuild::TestCases::new();
|
||||
t.compile_fail("tests/ui/**/*.rs");
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
enum DeEnum<B, C, D> {
|
||||
Unit,
|
||||
Seq(i8, B, C, D),
|
||||
Map { a: i8, b: B, c: C, d: D },
|
||||
|
||||
// Make sure we can support more than one variant.
|
||||
_Unit2,
|
||||
_Seq2(i8, B, C, D),
|
||||
_Map2 { a: i8, b: B, c: C, d: D },
|
||||
}
|
||||
@@ -0,0 +1,410 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
trait AssociatedType {
|
||||
type X;
|
||||
}
|
||||
impl AssociatedType for i32 {
|
||||
type X = i32;
|
||||
}
|
||||
struct DefaultTyParam<T: AssociatedType<X = i32> = i32> {
|
||||
phantom: PhantomData<T>,
|
||||
}
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _: () = {
|
||||
#[allow(unused_extern_crates, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
impl<T: AssociatedType<X = i32>> _serde::Serialize for DefaultTyParam<T> {
|
||||
fn serialize<__S>(
|
||||
&self,
|
||||
__serializer: __S,
|
||||
) -> _serde::__private::Result<__S::Ok, __S::Error>
|
||||
where
|
||||
__S: _serde::Serializer,
|
||||
{
|
||||
let mut __serde_state = match _serde::Serializer::serialize_struct(
|
||||
__serializer,
|
||||
"DefaultTyParam",
|
||||
false as usize + 1,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeStruct::serialize_field(
|
||||
&mut __serde_state,
|
||||
"phantom",
|
||||
&self.phantom,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
_serde::ser::SerializeStruct::end(__serde_state)
|
||||
}
|
||||
}
|
||||
};
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _: () = {
|
||||
#[allow(unused_extern_crates, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
impl<'de, T: AssociatedType<X = i32>> _serde::Deserialize<'de> for DefaultTyParam<T> {
|
||||
fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
#[allow(non_camel_case_types)]
|
||||
enum __Field {
|
||||
__field0,
|
||||
__ignore,
|
||||
}
|
||||
struct __FieldVisitor;
|
||||
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
|
||||
type Value = __Field;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(__formatter, "field identifier")
|
||||
}
|
||||
fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
0u64 => _serde::__private::Ok(__Field::__field0),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
fn visit_str<__E>(
|
||||
self,
|
||||
__value: &str,
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
"phantom" => _serde::__private::Ok(__Field::__field0),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
fn visit_bytes<__E>(
|
||||
self,
|
||||
__value: &[u8],
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
b"phantom" => _serde::__private::Ok(__Field::__field0),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'de> _serde::Deserialize<'de> for __Field {
|
||||
#[inline]
|
||||
fn deserialize<__D>(
|
||||
__deserializer: __D,
|
||||
) -> _serde::__private::Result<Self, __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
|
||||
}
|
||||
}
|
||||
struct __Visitor<'de, T: AssociatedType<X = i32>> {
|
||||
marker: _serde::__private::PhantomData<DefaultTyParam<T>>,
|
||||
lifetime: _serde::__private::PhantomData<&'de ()>,
|
||||
}
|
||||
impl<'de, T: AssociatedType<X = i32>> _serde::de::Visitor<'de> for __Visitor<'de, T> {
|
||||
type Value = DefaultTyParam<T>;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(__formatter, "struct DefaultTyParam")
|
||||
}
|
||||
#[inline]
|
||||
fn visit_seq<__A>(
|
||||
self,
|
||||
mut __seq: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::SeqAccess<'de>,
|
||||
{
|
||||
let __field0 = match match _serde::de::SeqAccess::next_element::<PhantomData<T>>(
|
||||
&mut __seq,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
_serde::__private::Some(__value) => __value,
|
||||
_serde::__private::None => {
|
||||
return _serde::__private::Err(_serde::de::Error::invalid_length(
|
||||
0usize,
|
||||
&"struct DefaultTyParam with 1 element",
|
||||
));
|
||||
}
|
||||
};
|
||||
_serde::__private::Ok(DefaultTyParam { phantom: __field0 })
|
||||
}
|
||||
#[inline]
|
||||
fn visit_map<__A>(
|
||||
self,
|
||||
mut __map: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::MapAccess<'de>,
|
||||
{
|
||||
let mut __field0: _serde::__private::Option<PhantomData<T>> =
|
||||
_serde::__private::None;
|
||||
while let _serde::__private::Some(__key) =
|
||||
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
}
|
||||
{
|
||||
match __key {
|
||||
__Field::__field0 => {
|
||||
if _serde::__private::Option::is_some(&__field0) {
|
||||
return _serde::__private::Err(
|
||||
<__A::Error as _serde::de::Error>::duplicate_field(
|
||||
"phantom",
|
||||
),
|
||||
);
|
||||
}
|
||||
__field0 = _serde::__private::Some(
|
||||
match _serde::de::MapAccess::next_value::<PhantomData<T>>(
|
||||
&mut __map,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
let _ = match _serde::de::MapAccess::next_value::<
|
||||
_serde::de::IgnoredAny,
|
||||
>(&mut __map)
|
||||
{
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
let __field0 = match __field0 {
|
||||
_serde::__private::Some(__field0) => __field0,
|
||||
_serde::__private::None => {
|
||||
match _serde::__private::de::missing_field("phantom") {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
_serde::__private::Ok(DefaultTyParam { phantom: __field0 })
|
||||
}
|
||||
}
|
||||
const FIELDS: &'static [&'static str] = &["phantom"];
|
||||
_serde::Deserializer::deserialize_struct(
|
||||
__deserializer,
|
||||
"DefaultTyParam",
|
||||
FIELDS,
|
||||
__Visitor {
|
||||
marker: _serde::__private::PhantomData::<DefaultTyParam<T>>,
|
||||
lifetime: _serde::__private::PhantomData,
|
||||
},
|
||||
)
|
||||
}
|
||||
fn deserialize_in_place<__D>(
|
||||
__deserializer: __D,
|
||||
__place: &mut Self,
|
||||
) -> _serde::__private::Result<(), __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
#[allow(non_camel_case_types)]
|
||||
enum __Field {
|
||||
__field0,
|
||||
__ignore,
|
||||
}
|
||||
struct __FieldVisitor;
|
||||
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
|
||||
type Value = __Field;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(__formatter, "field identifier")
|
||||
}
|
||||
fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
0u64 => _serde::__private::Ok(__Field::__field0),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
fn visit_str<__E>(
|
||||
self,
|
||||
__value: &str,
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
"phantom" => _serde::__private::Ok(__Field::__field0),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
fn visit_bytes<__E>(
|
||||
self,
|
||||
__value: &[u8],
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
b"phantom" => _serde::__private::Ok(__Field::__field0),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'de> _serde::Deserialize<'de> for __Field {
|
||||
#[inline]
|
||||
fn deserialize<__D>(
|
||||
__deserializer: __D,
|
||||
) -> _serde::__private::Result<Self, __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
|
||||
}
|
||||
}
|
||||
struct __Visitor<'de, 'place, T: AssociatedType<X = i32> + 'place> {
|
||||
place: &'place mut DefaultTyParam<T>,
|
||||
lifetime: _serde::__private::PhantomData<&'de ()>,
|
||||
}
|
||||
impl<'de, 'place, T: AssociatedType<X = i32> + 'place> _serde::de::Visitor<'de>
|
||||
for __Visitor<'de, 'place, T>
|
||||
{
|
||||
type Value = ();
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(__formatter, "struct DefaultTyParam")
|
||||
}
|
||||
#[inline]
|
||||
fn visit_seq<__A>(
|
||||
self,
|
||||
mut __seq: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::SeqAccess<'de>,
|
||||
{
|
||||
if let _serde::__private::None = match _serde::de::SeqAccess::next_element_seed(
|
||||
&mut __seq,
|
||||
_serde::__private::de::InPlaceSeed(&mut self.place.phantom),
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
return _serde::__private::Err(_serde::de::Error::invalid_length(
|
||||
0usize,
|
||||
&"struct DefaultTyParam with 1 element",
|
||||
));
|
||||
}
|
||||
_serde::__private::Ok(())
|
||||
}
|
||||
#[inline]
|
||||
fn visit_map<__A>(
|
||||
self,
|
||||
mut __map: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::MapAccess<'de>,
|
||||
{
|
||||
let mut __field0: bool = false;
|
||||
while let _serde::__private::Some(__key) =
|
||||
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
}
|
||||
{
|
||||
match __key {
|
||||
__Field::__field0 => {
|
||||
if __field0 {
|
||||
return _serde::__private::Err(
|
||||
<__A::Error as _serde::de::Error>::duplicate_field(
|
||||
"phantom",
|
||||
),
|
||||
);
|
||||
}
|
||||
match _serde::de::MapAccess::next_value_seed(
|
||||
&mut __map,
|
||||
_serde::__private::de::InPlaceSeed(&mut self.place.phantom),
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
__field0 = true;
|
||||
}
|
||||
_ => {
|
||||
let _ = match _serde::de::MapAccess::next_value::<
|
||||
_serde::de::IgnoredAny,
|
||||
>(&mut __map)
|
||||
{
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
if !__field0 {
|
||||
self.place.phantom = match _serde::__private::de::missing_field("phantom") {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
};
|
||||
_serde::__private::Ok(())
|
||||
}
|
||||
}
|
||||
const FIELDS: &'static [&'static str] = &["phantom"];
|
||||
_serde::Deserializer::deserialize_struct(
|
||||
__deserializer,
|
||||
"DefaultTyParam",
|
||||
FIELDS,
|
||||
__Visitor {
|
||||
place: __place,
|
||||
lifetime: _serde::__private::PhantomData,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
trait AssociatedType {
|
||||
type X;
|
||||
}
|
||||
|
||||
impl AssociatedType for i32 {
|
||||
type X = i32;
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct DefaultTyParam<T: AssociatedType<X = i32> = i32> {
|
||||
phantom: PhantomData<T>,
|
||||
}
|
||||
@@ -0,0 +1,590 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
pub enum GenericEnum<T, U> {
|
||||
Unit,
|
||||
NewType(T),
|
||||
Seq(T, U),
|
||||
Map { x: T, y: U },
|
||||
}
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _: () = {
|
||||
#[allow(unused_extern_crates, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
impl<T, U> _serde::Serialize for GenericEnum<T, U>
|
||||
where
|
||||
T: _serde::Serialize,
|
||||
U: _serde::Serialize,
|
||||
{
|
||||
fn serialize<__S>(
|
||||
&self,
|
||||
__serializer: __S,
|
||||
) -> _serde::__private::Result<__S::Ok, __S::Error>
|
||||
where
|
||||
__S: _serde::Serializer,
|
||||
{
|
||||
match *self {
|
||||
GenericEnum::Unit => _serde::Serializer::serialize_unit_variant(
|
||||
__serializer,
|
||||
"GenericEnum",
|
||||
0u32,
|
||||
"Unit",
|
||||
),
|
||||
GenericEnum::NewType(ref __field0) => {
|
||||
_serde::Serializer::serialize_newtype_variant(
|
||||
__serializer,
|
||||
"GenericEnum",
|
||||
1u32,
|
||||
"NewType",
|
||||
__field0,
|
||||
)
|
||||
}
|
||||
GenericEnum::Seq(ref __field0, ref __field1) => {
|
||||
let mut __serde_state = match _serde::Serializer::serialize_tuple_variant(
|
||||
__serializer,
|
||||
"GenericEnum",
|
||||
2u32,
|
||||
"Seq",
|
||||
0 + 1 + 1,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeTupleVariant::serialize_field(
|
||||
&mut __serde_state,
|
||||
__field0,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeTupleVariant::serialize_field(
|
||||
&mut __serde_state,
|
||||
__field1,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
_serde::ser::SerializeTupleVariant::end(__serde_state)
|
||||
}
|
||||
GenericEnum::Map { ref x, ref y } => {
|
||||
let mut __serde_state = match _serde::Serializer::serialize_struct_variant(
|
||||
__serializer,
|
||||
"GenericEnum",
|
||||
3u32,
|
||||
"Map",
|
||||
0 + 1 + 1,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeStructVariant::serialize_field(
|
||||
&mut __serde_state,
|
||||
"x",
|
||||
x,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeStructVariant::serialize_field(
|
||||
&mut __serde_state,
|
||||
"y",
|
||||
y,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
_serde::ser::SerializeStructVariant::end(__serde_state)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _: () = {
|
||||
#[allow(unused_extern_crates, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
impl<'de, T, U> _serde::Deserialize<'de> for GenericEnum<T, U>
|
||||
where
|
||||
T: _serde::Deserialize<'de>,
|
||||
U: _serde::Deserialize<'de>,
|
||||
{
|
||||
fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
#[allow(non_camel_case_types)]
|
||||
enum __Field {
|
||||
__field0,
|
||||
__field1,
|
||||
__field2,
|
||||
__field3,
|
||||
}
|
||||
struct __FieldVisitor;
|
||||
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
|
||||
type Value = __Field;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(__formatter, "variant identifier")
|
||||
}
|
||||
fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
0u64 => _serde::__private::Ok(__Field::__field0),
|
||||
1u64 => _serde::__private::Ok(__Field::__field1),
|
||||
2u64 => _serde::__private::Ok(__Field::__field2),
|
||||
3u64 => _serde::__private::Ok(__Field::__field3),
|
||||
_ => _serde::__private::Err(_serde::de::Error::invalid_value(
|
||||
_serde::de::Unexpected::Unsigned(__value),
|
||||
&"variant index 0 <= i < 4",
|
||||
)),
|
||||
}
|
||||
}
|
||||
fn visit_str<__E>(
|
||||
self,
|
||||
__value: &str,
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
"Unit" => _serde::__private::Ok(__Field::__field0),
|
||||
"NewType" => _serde::__private::Ok(__Field::__field1),
|
||||
"Seq" => _serde::__private::Ok(__Field::__field2),
|
||||
"Map" => _serde::__private::Ok(__Field::__field3),
|
||||
_ => _serde::__private::Err(_serde::de::Error::unknown_variant(
|
||||
__value, VARIANTS,
|
||||
)),
|
||||
}
|
||||
}
|
||||
fn visit_bytes<__E>(
|
||||
self,
|
||||
__value: &[u8],
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
b"Unit" => _serde::__private::Ok(__Field::__field0),
|
||||
b"NewType" => _serde::__private::Ok(__Field::__field1),
|
||||
b"Seq" => _serde::__private::Ok(__Field::__field2),
|
||||
b"Map" => _serde::__private::Ok(__Field::__field3),
|
||||
_ => {
|
||||
let __value = &_serde::__private::from_utf8_lossy(__value);
|
||||
_serde::__private::Err(_serde::de::Error::unknown_variant(
|
||||
__value, VARIANTS,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'de> _serde::Deserialize<'de> for __Field {
|
||||
#[inline]
|
||||
fn deserialize<__D>(
|
||||
__deserializer: __D,
|
||||
) -> _serde::__private::Result<Self, __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
|
||||
}
|
||||
}
|
||||
struct __Visitor<'de, T, U>
|
||||
where
|
||||
T: _serde::Deserialize<'de>,
|
||||
U: _serde::Deserialize<'de>,
|
||||
{
|
||||
marker: _serde::__private::PhantomData<GenericEnum<T, U>>,
|
||||
lifetime: _serde::__private::PhantomData<&'de ()>,
|
||||
}
|
||||
impl<'de, T, U> _serde::de::Visitor<'de> for __Visitor<'de, T, U>
|
||||
where
|
||||
T: _serde::Deserialize<'de>,
|
||||
U: _serde::Deserialize<'de>,
|
||||
{
|
||||
type Value = GenericEnum<T, U>;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(__formatter, "enum GenericEnum")
|
||||
}
|
||||
fn visit_enum<__A>(
|
||||
self,
|
||||
__data: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::EnumAccess<'de>,
|
||||
{
|
||||
match match _serde::de::EnumAccess::variant(__data) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
(__Field::__field0, __variant) => {
|
||||
match _serde::de::VariantAccess::unit_variant(__variant) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
_serde::__private::Ok(GenericEnum::Unit)
|
||||
}
|
||||
(__Field::__field1, __variant) => _serde::__private::Result::map(
|
||||
_serde::de::VariantAccess::newtype_variant::<T>(__variant),
|
||||
GenericEnum::NewType,
|
||||
),
|
||||
(__Field::__field2, __variant) => {
|
||||
struct __Visitor<'de, T, U>
|
||||
where
|
||||
T: _serde::Deserialize<'de>,
|
||||
U: _serde::Deserialize<'de>,
|
||||
{
|
||||
marker: _serde::__private::PhantomData<GenericEnum<T, U>>,
|
||||
lifetime: _serde::__private::PhantomData<&'de ()>,
|
||||
}
|
||||
impl<'de, T, U> _serde::de::Visitor<'de> for __Visitor<'de, T, U>
|
||||
where
|
||||
T: _serde::Deserialize<'de>,
|
||||
U: _serde::Deserialize<'de>,
|
||||
{
|
||||
type Value = GenericEnum<T, U>;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result
|
||||
{
|
||||
_serde::__private::Formatter::write_str(
|
||||
__formatter,
|
||||
"tuple variant GenericEnum::Seq",
|
||||
)
|
||||
}
|
||||
#[inline]
|
||||
fn visit_seq<__A>(
|
||||
self,
|
||||
mut __seq: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::SeqAccess<'de>,
|
||||
{
|
||||
let __field0 = match match _serde::de::SeqAccess::next_element::<
|
||||
T,
|
||||
>(
|
||||
&mut __seq
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
_serde::__private::Some(__value) => __value,
|
||||
_serde::__private::None => {
|
||||
return _serde :: __private :: Err (_serde :: de :: Error :: invalid_length (0usize , & "tuple variant GenericEnum::Seq with 2 elements")) ;
|
||||
}
|
||||
};
|
||||
let __field1 = match match _serde::de::SeqAccess::next_element::<
|
||||
U,
|
||||
>(
|
||||
&mut __seq
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
_serde::__private::Some(__value) => __value,
|
||||
_serde::__private::None => {
|
||||
return _serde :: __private :: Err (_serde :: de :: Error :: invalid_length (1usize , & "tuple variant GenericEnum::Seq with 2 elements")) ;
|
||||
}
|
||||
};
|
||||
_serde::__private::Ok(GenericEnum::Seq(__field0, __field1))
|
||||
}
|
||||
}
|
||||
_serde::de::VariantAccess::tuple_variant(
|
||||
__variant,
|
||||
2usize,
|
||||
__Visitor {
|
||||
marker: _serde::__private::PhantomData::<GenericEnum<T, U>>,
|
||||
lifetime: _serde::__private::PhantomData,
|
||||
},
|
||||
)
|
||||
}
|
||||
(__Field::__field3, __variant) => {
|
||||
#[allow(non_camel_case_types)]
|
||||
enum __Field {
|
||||
__field0,
|
||||
__field1,
|
||||
__ignore,
|
||||
}
|
||||
struct __FieldVisitor;
|
||||
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
|
||||
type Value = __Field;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result
|
||||
{
|
||||
_serde::__private::Formatter::write_str(
|
||||
__formatter,
|
||||
"field identifier",
|
||||
)
|
||||
}
|
||||
fn visit_u64<__E>(
|
||||
self,
|
||||
__value: u64,
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
0u64 => _serde::__private::Ok(__Field::__field0),
|
||||
1u64 => _serde::__private::Ok(__Field::__field1),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
fn visit_str<__E>(
|
||||
self,
|
||||
__value: &str,
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
"x" => _serde::__private::Ok(__Field::__field0),
|
||||
"y" => _serde::__private::Ok(__Field::__field1),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
fn visit_bytes<__E>(
|
||||
self,
|
||||
__value: &[u8],
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
b"x" => _serde::__private::Ok(__Field::__field0),
|
||||
b"y" => _serde::__private::Ok(__Field::__field1),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'de> _serde::Deserialize<'de> for __Field {
|
||||
#[inline]
|
||||
fn deserialize<__D>(
|
||||
__deserializer: __D,
|
||||
) -> _serde::__private::Result<Self, __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
_serde::Deserializer::deserialize_identifier(
|
||||
__deserializer,
|
||||
__FieldVisitor,
|
||||
)
|
||||
}
|
||||
}
|
||||
struct __Visitor<'de, T, U>
|
||||
where
|
||||
T: _serde::Deserialize<'de>,
|
||||
U: _serde::Deserialize<'de>,
|
||||
{
|
||||
marker: _serde::__private::PhantomData<GenericEnum<T, U>>,
|
||||
lifetime: _serde::__private::PhantomData<&'de ()>,
|
||||
}
|
||||
impl<'de, T, U> _serde::de::Visitor<'de> for __Visitor<'de, T, U>
|
||||
where
|
||||
T: _serde::Deserialize<'de>,
|
||||
U: _serde::Deserialize<'de>,
|
||||
{
|
||||
type Value = GenericEnum<T, U>;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result
|
||||
{
|
||||
_serde::__private::Formatter::write_str(
|
||||
__formatter,
|
||||
"struct variant GenericEnum::Map",
|
||||
)
|
||||
}
|
||||
#[inline]
|
||||
fn visit_seq<__A>(
|
||||
self,
|
||||
mut __seq: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::SeqAccess<'de>,
|
||||
{
|
||||
let __field0 = match match _serde::de::SeqAccess::next_element::<
|
||||
T,
|
||||
>(
|
||||
&mut __seq
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
_serde::__private::Some(__value) => __value,
|
||||
_serde::__private::None => {
|
||||
return _serde :: __private :: Err (_serde :: de :: Error :: invalid_length (0usize , & "struct variant GenericEnum::Map with 2 elements")) ;
|
||||
}
|
||||
};
|
||||
let __field1 = match match _serde::de::SeqAccess::next_element::<
|
||||
U,
|
||||
>(
|
||||
&mut __seq
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
_serde::__private::Some(__value) => __value,
|
||||
_serde::__private::None => {
|
||||
return _serde :: __private :: Err (_serde :: de :: Error :: invalid_length (1usize , & "struct variant GenericEnum::Map with 2 elements")) ;
|
||||
}
|
||||
};
|
||||
_serde::__private::Ok(GenericEnum::Map {
|
||||
x: __field0,
|
||||
y: __field1,
|
||||
})
|
||||
}
|
||||
#[inline]
|
||||
fn visit_map<__A>(
|
||||
self,
|
||||
mut __map: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::MapAccess<'de>,
|
||||
{
|
||||
let mut __field0: _serde::__private::Option<T> =
|
||||
_serde::__private::None;
|
||||
let mut __field1: _serde::__private::Option<U> =
|
||||
_serde::__private::None;
|
||||
while let _serde::__private::Some(__key) =
|
||||
match _serde::de::MapAccess::next_key::<__Field>(&mut __map)
|
||||
{
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
}
|
||||
{
|
||||
match __key {
|
||||
__Field::__field0 => {
|
||||
if _serde::__private::Option::is_some(&__field0) {
|
||||
return _serde :: __private :: Err (< __A :: Error as _serde :: de :: Error > :: duplicate_field ("x")) ;
|
||||
}
|
||||
__field0 = _serde::__private::Some(
|
||||
match _serde::de::MapAccess::next_value::<T>(
|
||||
&mut __map,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
__Field::__field1 => {
|
||||
if _serde::__private::Option::is_some(&__field1) {
|
||||
return _serde :: __private :: Err (< __A :: Error as _serde :: de :: Error > :: duplicate_field ("y")) ;
|
||||
}
|
||||
__field1 = _serde::__private::Some(
|
||||
match _serde::de::MapAccess::next_value::<U>(
|
||||
&mut __map,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
let _ = match _serde::de::MapAccess::next_value::<
|
||||
_serde::de::IgnoredAny,
|
||||
>(
|
||||
&mut __map
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
let __field0 = match __field0 {
|
||||
_serde::__private::Some(__field0) => __field0,
|
||||
_serde::__private::None => {
|
||||
match _serde::__private::de::missing_field("x") {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
let __field1 = match __field1 {
|
||||
_serde::__private::Some(__field1) => __field1,
|
||||
_serde::__private::None => {
|
||||
match _serde::__private::de::missing_field("y") {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
_serde::__private::Ok(GenericEnum::Map {
|
||||
x: __field0,
|
||||
y: __field1,
|
||||
})
|
||||
}
|
||||
}
|
||||
const FIELDS: &'static [&'static str] = &["x", "y"];
|
||||
_serde::de::VariantAccess::struct_variant(
|
||||
__variant,
|
||||
FIELDS,
|
||||
__Visitor {
|
||||
marker: _serde::__private::PhantomData::<GenericEnum<T, U>>,
|
||||
lifetime: _serde::__private::PhantomData,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const VARIANTS: &'static [&'static str] = &["Unit", "NewType", "Seq", "Map"];
|
||||
_serde::Deserializer::deserialize_enum(
|
||||
__deserializer,
|
||||
"GenericEnum",
|
||||
VARIANTS,
|
||||
__Visitor {
|
||||
marker: _serde::__private::PhantomData::<GenericEnum<T, U>>,
|
||||
lifetime: _serde::__private::PhantomData,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub enum GenericEnum<T, U> {
|
||||
Unit,
|
||||
NewType(T),
|
||||
Seq(T, U),
|
||||
Map { x: T, y: U },
|
||||
}
|
||||
@@ -0,0 +1,594 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
pub struct GenericStruct<T> {
|
||||
x: T,
|
||||
}
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _: () = {
|
||||
#[allow(unused_extern_crates, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
impl<T> _serde::Serialize for GenericStruct<T>
|
||||
where
|
||||
T: _serde::Serialize,
|
||||
{
|
||||
fn serialize<__S>(
|
||||
&self,
|
||||
__serializer: __S,
|
||||
) -> _serde::__private::Result<__S::Ok, __S::Error>
|
||||
where
|
||||
__S: _serde::Serializer,
|
||||
{
|
||||
let mut __serde_state = match _serde::Serializer::serialize_struct(
|
||||
__serializer,
|
||||
"GenericStruct",
|
||||
false as usize + 1,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeStruct::serialize_field(&mut __serde_state, "x", &self.x) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
_serde::ser::SerializeStruct::end(__serde_state)
|
||||
}
|
||||
}
|
||||
};
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _: () = {
|
||||
#[allow(unused_extern_crates, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
impl<'de, T> _serde::Deserialize<'de> for GenericStruct<T>
|
||||
where
|
||||
T: _serde::Deserialize<'de>,
|
||||
{
|
||||
fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
#[allow(non_camel_case_types)]
|
||||
enum __Field {
|
||||
__field0,
|
||||
__ignore,
|
||||
}
|
||||
struct __FieldVisitor;
|
||||
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
|
||||
type Value = __Field;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(__formatter, "field identifier")
|
||||
}
|
||||
fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
0u64 => _serde::__private::Ok(__Field::__field0),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
fn visit_str<__E>(
|
||||
self,
|
||||
__value: &str,
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
"x" => _serde::__private::Ok(__Field::__field0),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
fn visit_bytes<__E>(
|
||||
self,
|
||||
__value: &[u8],
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
b"x" => _serde::__private::Ok(__Field::__field0),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'de> _serde::Deserialize<'de> for __Field {
|
||||
#[inline]
|
||||
fn deserialize<__D>(
|
||||
__deserializer: __D,
|
||||
) -> _serde::__private::Result<Self, __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
|
||||
}
|
||||
}
|
||||
struct __Visitor<'de, T>
|
||||
where
|
||||
T: _serde::Deserialize<'de>,
|
||||
{
|
||||
marker: _serde::__private::PhantomData<GenericStruct<T>>,
|
||||
lifetime: _serde::__private::PhantomData<&'de ()>,
|
||||
}
|
||||
impl<'de, T> _serde::de::Visitor<'de> for __Visitor<'de, T>
|
||||
where
|
||||
T: _serde::Deserialize<'de>,
|
||||
{
|
||||
type Value = GenericStruct<T>;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(__formatter, "struct GenericStruct")
|
||||
}
|
||||
#[inline]
|
||||
fn visit_seq<__A>(
|
||||
self,
|
||||
mut __seq: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::SeqAccess<'de>,
|
||||
{
|
||||
let __field0 = match match _serde::de::SeqAccess::next_element::<T>(&mut __seq)
|
||||
{
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
_serde::__private::Some(__value) => __value,
|
||||
_serde::__private::None => {
|
||||
return _serde::__private::Err(_serde::de::Error::invalid_length(
|
||||
0usize,
|
||||
&"struct GenericStruct with 1 element",
|
||||
));
|
||||
}
|
||||
};
|
||||
_serde::__private::Ok(GenericStruct { x: __field0 })
|
||||
}
|
||||
#[inline]
|
||||
fn visit_map<__A>(
|
||||
self,
|
||||
mut __map: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::MapAccess<'de>,
|
||||
{
|
||||
let mut __field0: _serde::__private::Option<T> = _serde::__private::None;
|
||||
while let _serde::__private::Some(__key) =
|
||||
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
}
|
||||
{
|
||||
match __key {
|
||||
__Field::__field0 => {
|
||||
if _serde::__private::Option::is_some(&__field0) {
|
||||
return _serde::__private::Err(
|
||||
<__A::Error as _serde::de::Error>::duplicate_field("x"),
|
||||
);
|
||||
}
|
||||
__field0 = _serde::__private::Some(
|
||||
match _serde::de::MapAccess::next_value::<T>(&mut __map) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
let _ = match _serde::de::MapAccess::next_value::<
|
||||
_serde::de::IgnoredAny,
|
||||
>(&mut __map)
|
||||
{
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
let __field0 = match __field0 {
|
||||
_serde::__private::Some(__field0) => __field0,
|
||||
_serde::__private::None => {
|
||||
match _serde::__private::de::missing_field("x") {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
_serde::__private::Ok(GenericStruct { x: __field0 })
|
||||
}
|
||||
}
|
||||
const FIELDS: &'static [&'static str] = &["x"];
|
||||
_serde::Deserializer::deserialize_struct(
|
||||
__deserializer,
|
||||
"GenericStruct",
|
||||
FIELDS,
|
||||
__Visitor {
|
||||
marker: _serde::__private::PhantomData::<GenericStruct<T>>,
|
||||
lifetime: _serde::__private::PhantomData,
|
||||
},
|
||||
)
|
||||
}
|
||||
fn deserialize_in_place<__D>(
|
||||
__deserializer: __D,
|
||||
__place: &mut Self,
|
||||
) -> _serde::__private::Result<(), __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
#[allow(non_camel_case_types)]
|
||||
enum __Field {
|
||||
__field0,
|
||||
__ignore,
|
||||
}
|
||||
struct __FieldVisitor;
|
||||
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
|
||||
type Value = __Field;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(__formatter, "field identifier")
|
||||
}
|
||||
fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
0u64 => _serde::__private::Ok(__Field::__field0),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
fn visit_str<__E>(
|
||||
self,
|
||||
__value: &str,
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
"x" => _serde::__private::Ok(__Field::__field0),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
fn visit_bytes<__E>(
|
||||
self,
|
||||
__value: &[u8],
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
b"x" => _serde::__private::Ok(__Field::__field0),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'de> _serde::Deserialize<'de> for __Field {
|
||||
#[inline]
|
||||
fn deserialize<__D>(
|
||||
__deserializer: __D,
|
||||
) -> _serde::__private::Result<Self, __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
|
||||
}
|
||||
}
|
||||
struct __Visitor<'de, 'place, T: 'place>
|
||||
where
|
||||
T: _serde::Deserialize<'de>,
|
||||
{
|
||||
place: &'place mut GenericStruct<T>,
|
||||
lifetime: _serde::__private::PhantomData<&'de ()>,
|
||||
}
|
||||
impl<'de, 'place, T: 'place> _serde::de::Visitor<'de> for __Visitor<'de, 'place, T>
|
||||
where
|
||||
T: _serde::Deserialize<'de>,
|
||||
{
|
||||
type Value = ();
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(__formatter, "struct GenericStruct")
|
||||
}
|
||||
#[inline]
|
||||
fn visit_seq<__A>(
|
||||
self,
|
||||
mut __seq: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::SeqAccess<'de>,
|
||||
{
|
||||
if let _serde::__private::None = match _serde::de::SeqAccess::next_element_seed(
|
||||
&mut __seq,
|
||||
_serde::__private::de::InPlaceSeed(&mut self.place.x),
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
return _serde::__private::Err(_serde::de::Error::invalid_length(
|
||||
0usize,
|
||||
&"struct GenericStruct with 1 element",
|
||||
));
|
||||
}
|
||||
_serde::__private::Ok(())
|
||||
}
|
||||
#[inline]
|
||||
fn visit_map<__A>(
|
||||
self,
|
||||
mut __map: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::MapAccess<'de>,
|
||||
{
|
||||
let mut __field0: bool = false;
|
||||
while let _serde::__private::Some(__key) =
|
||||
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
}
|
||||
{
|
||||
match __key {
|
||||
__Field::__field0 => {
|
||||
if __field0 {
|
||||
return _serde::__private::Err(
|
||||
<__A::Error as _serde::de::Error>::duplicate_field("x"),
|
||||
);
|
||||
}
|
||||
match _serde::de::MapAccess::next_value_seed(
|
||||
&mut __map,
|
||||
_serde::__private::de::InPlaceSeed(&mut self.place.x),
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
__field0 = true;
|
||||
}
|
||||
_ => {
|
||||
let _ = match _serde::de::MapAccess::next_value::<
|
||||
_serde::de::IgnoredAny,
|
||||
>(&mut __map)
|
||||
{
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
if !__field0 {
|
||||
self.place.x = match _serde::__private::de::missing_field("x") {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
};
|
||||
_serde::__private::Ok(())
|
||||
}
|
||||
}
|
||||
const FIELDS: &'static [&'static str] = &["x"];
|
||||
_serde::Deserializer::deserialize_struct(
|
||||
__deserializer,
|
||||
"GenericStruct",
|
||||
FIELDS,
|
||||
__Visitor {
|
||||
place: __place,
|
||||
lifetime: _serde::__private::PhantomData,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
pub struct GenericNewTypeStruct<T>(T);
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _: () = {
|
||||
#[allow(unused_extern_crates, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
impl<T> _serde::Serialize for GenericNewTypeStruct<T>
|
||||
where
|
||||
T: _serde::Serialize,
|
||||
{
|
||||
fn serialize<__S>(
|
||||
&self,
|
||||
__serializer: __S,
|
||||
) -> _serde::__private::Result<__S::Ok, __S::Error>
|
||||
where
|
||||
__S: _serde::Serializer,
|
||||
{
|
||||
_serde::Serializer::serialize_newtype_struct(
|
||||
__serializer,
|
||||
"GenericNewTypeStruct",
|
||||
&self.0,
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _: () = {
|
||||
#[allow(unused_extern_crates, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
impl<'de, T> _serde::Deserialize<'de> for GenericNewTypeStruct<T>
|
||||
where
|
||||
T: _serde::Deserialize<'de>,
|
||||
{
|
||||
fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
struct __Visitor<'de, T>
|
||||
where
|
||||
T: _serde::Deserialize<'de>,
|
||||
{
|
||||
marker: _serde::__private::PhantomData<GenericNewTypeStruct<T>>,
|
||||
lifetime: _serde::__private::PhantomData<&'de ()>,
|
||||
}
|
||||
impl<'de, T> _serde::de::Visitor<'de> for __Visitor<'de, T>
|
||||
where
|
||||
T: _serde::Deserialize<'de>,
|
||||
{
|
||||
type Value = GenericNewTypeStruct<T>;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(
|
||||
__formatter,
|
||||
"tuple struct GenericNewTypeStruct",
|
||||
)
|
||||
}
|
||||
#[inline]
|
||||
fn visit_newtype_struct<__E>(
|
||||
self,
|
||||
__e: __E,
|
||||
) -> _serde::__private::Result<Self::Value, __E::Error>
|
||||
where
|
||||
__E: _serde::Deserializer<'de>,
|
||||
{
|
||||
let __field0: T = match <T as _serde::Deserialize>::deserialize(__e) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
_serde::__private::Ok(GenericNewTypeStruct(__field0))
|
||||
}
|
||||
#[inline]
|
||||
fn visit_seq<__A>(
|
||||
self,
|
||||
mut __seq: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::SeqAccess<'de>,
|
||||
{
|
||||
let __field0 = match match _serde::de::SeqAccess::next_element::<T>(&mut __seq)
|
||||
{
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
_serde::__private::Some(__value) => __value,
|
||||
_serde::__private::None => {
|
||||
return _serde::__private::Err(_serde::de::Error::invalid_length(
|
||||
0usize,
|
||||
&"tuple struct GenericNewTypeStruct with 1 element",
|
||||
));
|
||||
}
|
||||
};
|
||||
_serde::__private::Ok(GenericNewTypeStruct(__field0))
|
||||
}
|
||||
}
|
||||
_serde::Deserializer::deserialize_newtype_struct(
|
||||
__deserializer,
|
||||
"GenericNewTypeStruct",
|
||||
__Visitor {
|
||||
marker: _serde::__private::PhantomData::<GenericNewTypeStruct<T>>,
|
||||
lifetime: _serde::__private::PhantomData,
|
||||
},
|
||||
)
|
||||
}
|
||||
fn deserialize_in_place<__D>(
|
||||
__deserializer: __D,
|
||||
__place: &mut Self,
|
||||
) -> _serde::__private::Result<(), __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
struct __Visitor<'de, 'place, T: 'place>
|
||||
where
|
||||
T: _serde::Deserialize<'de>,
|
||||
{
|
||||
place: &'place mut GenericNewTypeStruct<T>,
|
||||
lifetime: _serde::__private::PhantomData<&'de ()>,
|
||||
}
|
||||
impl<'de, 'place, T: 'place> _serde::de::Visitor<'de> for __Visitor<'de, 'place, T>
|
||||
where
|
||||
T: _serde::Deserialize<'de>,
|
||||
{
|
||||
type Value = ();
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(
|
||||
__formatter,
|
||||
"tuple struct GenericNewTypeStruct",
|
||||
)
|
||||
}
|
||||
#[inline]
|
||||
fn visit_newtype_struct<__E>(
|
||||
self,
|
||||
__e: __E,
|
||||
) -> _serde::__private::Result<Self::Value, __E::Error>
|
||||
where
|
||||
__E: _serde::Deserializer<'de>,
|
||||
{
|
||||
_serde::Deserialize::deserialize_in_place(__e, &mut self.place.0)
|
||||
}
|
||||
#[inline]
|
||||
fn visit_seq<__A>(
|
||||
self,
|
||||
mut __seq: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::SeqAccess<'de>,
|
||||
{
|
||||
if let _serde::__private::None = match _serde::de::SeqAccess::next_element_seed(
|
||||
&mut __seq,
|
||||
_serde::__private::de::InPlaceSeed(&mut self.place.0),
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
return _serde::__private::Err(_serde::de::Error::invalid_length(
|
||||
0usize,
|
||||
&"tuple struct GenericNewTypeStruct with 1 element",
|
||||
));
|
||||
}
|
||||
_serde::__private::Ok(())
|
||||
}
|
||||
}
|
||||
_serde::Deserializer::deserialize_newtype_struct(
|
||||
__deserializer,
|
||||
"GenericNewTypeStruct",
|
||||
__Visitor {
|
||||
place: __place,
|
||||
lifetime: _serde::__private::PhantomData,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct GenericStruct<T> {
|
||||
x: T,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct GenericNewTypeStruct<T>(T);
|
||||
@@ -0,0 +1,172 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
pub struct GenericTupleStruct<T, U>(T, U);
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _: () = {
|
||||
#[allow(unused_extern_crates, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
impl<'de, T, U> _serde::Deserialize<'de> for GenericTupleStruct<T, U>
|
||||
where
|
||||
T: _serde::Deserialize<'de>,
|
||||
U: _serde::Deserialize<'de>,
|
||||
{
|
||||
fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
struct __Visitor<'de, T, U>
|
||||
where
|
||||
T: _serde::Deserialize<'de>,
|
||||
U: _serde::Deserialize<'de>,
|
||||
{
|
||||
marker: _serde::__private::PhantomData<GenericTupleStruct<T, U>>,
|
||||
lifetime: _serde::__private::PhantomData<&'de ()>,
|
||||
}
|
||||
impl<'de, T, U> _serde::de::Visitor<'de> for __Visitor<'de, T, U>
|
||||
where
|
||||
T: _serde::Deserialize<'de>,
|
||||
U: _serde::Deserialize<'de>,
|
||||
{
|
||||
type Value = GenericTupleStruct<T, U>;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(
|
||||
__formatter,
|
||||
"tuple struct GenericTupleStruct",
|
||||
)
|
||||
}
|
||||
#[inline]
|
||||
fn visit_seq<__A>(
|
||||
self,
|
||||
mut __seq: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::SeqAccess<'de>,
|
||||
{
|
||||
let __field0 = match match _serde::de::SeqAccess::next_element::<T>(&mut __seq)
|
||||
{
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
_serde::__private::Some(__value) => __value,
|
||||
_serde::__private::None => {
|
||||
return _serde::__private::Err(_serde::de::Error::invalid_length(
|
||||
0usize,
|
||||
&"tuple struct GenericTupleStruct with 2 elements",
|
||||
));
|
||||
}
|
||||
};
|
||||
let __field1 = match match _serde::de::SeqAccess::next_element::<U>(&mut __seq)
|
||||
{
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
_serde::__private::Some(__value) => __value,
|
||||
_serde::__private::None => {
|
||||
return _serde::__private::Err(_serde::de::Error::invalid_length(
|
||||
1usize,
|
||||
&"tuple struct GenericTupleStruct with 2 elements",
|
||||
));
|
||||
}
|
||||
};
|
||||
_serde::__private::Ok(GenericTupleStruct(__field0, __field1))
|
||||
}
|
||||
}
|
||||
_serde::Deserializer::deserialize_tuple_struct(
|
||||
__deserializer,
|
||||
"GenericTupleStruct",
|
||||
2usize,
|
||||
__Visitor {
|
||||
marker: _serde::__private::PhantomData::<GenericTupleStruct<T, U>>,
|
||||
lifetime: _serde::__private::PhantomData,
|
||||
},
|
||||
)
|
||||
}
|
||||
fn deserialize_in_place<__D>(
|
||||
__deserializer: __D,
|
||||
__place: &mut Self,
|
||||
) -> _serde::__private::Result<(), __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
struct __Visitor<'de, 'place, T: 'place, U: 'place>
|
||||
where
|
||||
T: _serde::Deserialize<'de>,
|
||||
U: _serde::Deserialize<'de>,
|
||||
{
|
||||
place: &'place mut GenericTupleStruct<T, U>,
|
||||
lifetime: _serde::__private::PhantomData<&'de ()>,
|
||||
}
|
||||
impl<'de, 'place, T: 'place, U: 'place> _serde::de::Visitor<'de> for __Visitor<'de, 'place, T, U>
|
||||
where
|
||||
T: _serde::Deserialize<'de>,
|
||||
U: _serde::Deserialize<'de>,
|
||||
{
|
||||
type Value = ();
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(
|
||||
__formatter,
|
||||
"tuple struct GenericTupleStruct",
|
||||
)
|
||||
}
|
||||
#[inline]
|
||||
fn visit_seq<__A>(
|
||||
self,
|
||||
mut __seq: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::SeqAccess<'de>,
|
||||
{
|
||||
if let _serde::__private::None = match _serde::de::SeqAccess::next_element_seed(
|
||||
&mut __seq,
|
||||
_serde::__private::de::InPlaceSeed(&mut self.place.0),
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
return _serde::__private::Err(_serde::de::Error::invalid_length(
|
||||
0usize,
|
||||
&"tuple struct GenericTupleStruct with 2 elements",
|
||||
));
|
||||
}
|
||||
if let _serde::__private::None = match _serde::de::SeqAccess::next_element_seed(
|
||||
&mut __seq,
|
||||
_serde::__private::de::InPlaceSeed(&mut self.place.1),
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
return _serde::__private::Err(_serde::de::Error::invalid_length(
|
||||
1usize,
|
||||
&"tuple struct GenericTupleStruct with 2 elements",
|
||||
));
|
||||
}
|
||||
_serde::__private::Ok(())
|
||||
}
|
||||
}
|
||||
_serde::Deserializer::deserialize_tuple_struct(
|
||||
__deserializer,
|
||||
"GenericTupleStruct",
|
||||
2usize,
|
||||
__Visitor {
|
||||
place: __place,
|
||||
lifetime: _serde::__private::PhantomData,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct GenericTupleStruct<T, U>(T, U);
|
||||
@@ -0,0 +1,607 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
enum Lifetimes<'a> {
|
||||
LifetimeSeq(&'a i32),
|
||||
NoLifetimeSeq(i32),
|
||||
LifetimeMap { a: &'a i32 },
|
||||
NoLifetimeMap { a: i32 },
|
||||
}
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _: () = {
|
||||
#[allow(unused_extern_crates, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
impl<'a> _serde::Serialize for Lifetimes<'a> {
|
||||
fn serialize<__S>(
|
||||
&self,
|
||||
__serializer: __S,
|
||||
) -> _serde::__private::Result<__S::Ok, __S::Error>
|
||||
where
|
||||
__S: _serde::Serializer,
|
||||
{
|
||||
match *self {
|
||||
Lifetimes::LifetimeSeq(ref __field0) => {
|
||||
_serde::Serializer::serialize_newtype_variant(
|
||||
__serializer,
|
||||
"Lifetimes",
|
||||
0u32,
|
||||
"LifetimeSeq",
|
||||
__field0,
|
||||
)
|
||||
}
|
||||
Lifetimes::NoLifetimeSeq(ref __field0) => {
|
||||
_serde::Serializer::serialize_newtype_variant(
|
||||
__serializer,
|
||||
"Lifetimes",
|
||||
1u32,
|
||||
"NoLifetimeSeq",
|
||||
__field0,
|
||||
)
|
||||
}
|
||||
Lifetimes::LifetimeMap { ref a } => {
|
||||
let mut __serde_state = match _serde::Serializer::serialize_struct_variant(
|
||||
__serializer,
|
||||
"Lifetimes",
|
||||
2u32,
|
||||
"LifetimeMap",
|
||||
0 + 1,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeStructVariant::serialize_field(
|
||||
&mut __serde_state,
|
||||
"a",
|
||||
a,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
_serde::ser::SerializeStructVariant::end(__serde_state)
|
||||
}
|
||||
Lifetimes::NoLifetimeMap { ref a } => {
|
||||
let mut __serde_state = match _serde::Serializer::serialize_struct_variant(
|
||||
__serializer,
|
||||
"Lifetimes",
|
||||
3u32,
|
||||
"NoLifetimeMap",
|
||||
0 + 1,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeStructVariant::serialize_field(
|
||||
&mut __serde_state,
|
||||
"a",
|
||||
a,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
_serde::ser::SerializeStructVariant::end(__serde_state)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _: () = {
|
||||
#[allow(unused_extern_crates, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
impl<'de, 'a> _serde::Deserialize<'de> for Lifetimes<'a> {
|
||||
fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
#[allow(non_camel_case_types)]
|
||||
enum __Field {
|
||||
__field0,
|
||||
__field1,
|
||||
__field2,
|
||||
__field3,
|
||||
}
|
||||
struct __FieldVisitor;
|
||||
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
|
||||
type Value = __Field;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(__formatter, "variant identifier")
|
||||
}
|
||||
fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
0u64 => _serde::__private::Ok(__Field::__field0),
|
||||
1u64 => _serde::__private::Ok(__Field::__field1),
|
||||
2u64 => _serde::__private::Ok(__Field::__field2),
|
||||
3u64 => _serde::__private::Ok(__Field::__field3),
|
||||
_ => _serde::__private::Err(_serde::de::Error::invalid_value(
|
||||
_serde::de::Unexpected::Unsigned(__value),
|
||||
&"variant index 0 <= i < 4",
|
||||
)),
|
||||
}
|
||||
}
|
||||
fn visit_str<__E>(
|
||||
self,
|
||||
__value: &str,
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
"LifetimeSeq" => _serde::__private::Ok(__Field::__field0),
|
||||
"NoLifetimeSeq" => _serde::__private::Ok(__Field::__field1),
|
||||
"LifetimeMap" => _serde::__private::Ok(__Field::__field2),
|
||||
"NoLifetimeMap" => _serde::__private::Ok(__Field::__field3),
|
||||
_ => _serde::__private::Err(_serde::de::Error::unknown_variant(
|
||||
__value, VARIANTS,
|
||||
)),
|
||||
}
|
||||
}
|
||||
fn visit_bytes<__E>(
|
||||
self,
|
||||
__value: &[u8],
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
b"LifetimeSeq" => _serde::__private::Ok(__Field::__field0),
|
||||
b"NoLifetimeSeq" => _serde::__private::Ok(__Field::__field1),
|
||||
b"LifetimeMap" => _serde::__private::Ok(__Field::__field2),
|
||||
b"NoLifetimeMap" => _serde::__private::Ok(__Field::__field3),
|
||||
_ => {
|
||||
let __value = &_serde::__private::from_utf8_lossy(__value);
|
||||
_serde::__private::Err(_serde::de::Error::unknown_variant(
|
||||
__value, VARIANTS,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'de> _serde::Deserialize<'de> for __Field {
|
||||
#[inline]
|
||||
fn deserialize<__D>(
|
||||
__deserializer: __D,
|
||||
) -> _serde::__private::Result<Self, __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
|
||||
}
|
||||
}
|
||||
struct __Visitor<'de, 'a> {
|
||||
marker: _serde::__private::PhantomData<Lifetimes<'a>>,
|
||||
lifetime: _serde::__private::PhantomData<&'de ()>,
|
||||
}
|
||||
impl<'de, 'a> _serde::de::Visitor<'de> for __Visitor<'de, 'a> {
|
||||
type Value = Lifetimes<'a>;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(__formatter, "enum Lifetimes")
|
||||
}
|
||||
fn visit_enum<__A>(
|
||||
self,
|
||||
__data: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::EnumAccess<'de>,
|
||||
{
|
||||
match match _serde::de::EnumAccess::variant(__data) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
(__Field::__field0, __variant) => _serde::__private::Result::map(
|
||||
_serde::de::VariantAccess::newtype_variant::<&'a i32>(__variant),
|
||||
Lifetimes::LifetimeSeq,
|
||||
),
|
||||
(__Field::__field1, __variant) => _serde::__private::Result::map(
|
||||
_serde::de::VariantAccess::newtype_variant::<i32>(__variant),
|
||||
Lifetimes::NoLifetimeSeq,
|
||||
),
|
||||
(__Field::__field2, __variant) => {
|
||||
#[allow(non_camel_case_types)]
|
||||
enum __Field {
|
||||
__field0,
|
||||
__ignore,
|
||||
}
|
||||
struct __FieldVisitor;
|
||||
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
|
||||
type Value = __Field;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result
|
||||
{
|
||||
_serde::__private::Formatter::write_str(
|
||||
__formatter,
|
||||
"field identifier",
|
||||
)
|
||||
}
|
||||
fn visit_u64<__E>(
|
||||
self,
|
||||
__value: u64,
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
0u64 => _serde::__private::Ok(__Field::__field0),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
fn visit_str<__E>(
|
||||
self,
|
||||
__value: &str,
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
"a" => _serde::__private::Ok(__Field::__field0),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
fn visit_bytes<__E>(
|
||||
self,
|
||||
__value: &[u8],
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
b"a" => _serde::__private::Ok(__Field::__field0),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'de> _serde::Deserialize<'de> for __Field {
|
||||
#[inline]
|
||||
fn deserialize<__D>(
|
||||
__deserializer: __D,
|
||||
) -> _serde::__private::Result<Self, __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
_serde::Deserializer::deserialize_identifier(
|
||||
__deserializer,
|
||||
__FieldVisitor,
|
||||
)
|
||||
}
|
||||
}
|
||||
struct __Visitor<'de, 'a> {
|
||||
marker: _serde::__private::PhantomData<Lifetimes<'a>>,
|
||||
lifetime: _serde::__private::PhantomData<&'de ()>,
|
||||
}
|
||||
impl<'de, 'a> _serde::de::Visitor<'de> for __Visitor<'de, 'a> {
|
||||
type Value = Lifetimes<'a>;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result
|
||||
{
|
||||
_serde::__private::Formatter::write_str(
|
||||
__formatter,
|
||||
"struct variant Lifetimes::LifetimeMap",
|
||||
)
|
||||
}
|
||||
#[inline]
|
||||
fn visit_seq<__A>(
|
||||
self,
|
||||
mut __seq: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::SeqAccess<'de>,
|
||||
{
|
||||
let __field0 = match match _serde::de::SeqAccess::next_element::<
|
||||
&'a i32,
|
||||
>(
|
||||
&mut __seq
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
_serde::__private::Some(__value) => __value,
|
||||
_serde::__private::None => {
|
||||
return _serde :: __private :: Err (_serde :: de :: Error :: invalid_length (0usize , & "struct variant Lifetimes::LifetimeMap with 1 element")) ;
|
||||
}
|
||||
};
|
||||
_serde::__private::Ok(Lifetimes::LifetimeMap { a: __field0 })
|
||||
}
|
||||
#[inline]
|
||||
fn visit_map<__A>(
|
||||
self,
|
||||
mut __map: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::MapAccess<'de>,
|
||||
{
|
||||
let mut __field0: _serde::__private::Option<&'a i32> =
|
||||
_serde::__private::None;
|
||||
while let _serde::__private::Some(__key) =
|
||||
match _serde::de::MapAccess::next_key::<__Field>(&mut __map)
|
||||
{
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
}
|
||||
{
|
||||
match __key {
|
||||
__Field::__field0 => {
|
||||
if _serde::__private::Option::is_some(&__field0) {
|
||||
return _serde :: __private :: Err (< __A :: Error as _serde :: de :: Error > :: duplicate_field ("a")) ;
|
||||
}
|
||||
__field0 = _serde::__private::Some(
|
||||
match _serde::de::MapAccess::next_value::<&'a i32>(
|
||||
&mut __map,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
let _ = match _serde::de::MapAccess::next_value::<
|
||||
_serde::de::IgnoredAny,
|
||||
>(
|
||||
&mut __map
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
let __field0 = match __field0 {
|
||||
_serde::__private::Some(__field0) => __field0,
|
||||
_serde::__private::None => {
|
||||
match _serde::__private::de::missing_field("a") {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
_serde::__private::Ok(Lifetimes::LifetimeMap { a: __field0 })
|
||||
}
|
||||
}
|
||||
const FIELDS: &'static [&'static str] = &["a"];
|
||||
_serde::de::VariantAccess::struct_variant(
|
||||
__variant,
|
||||
FIELDS,
|
||||
__Visitor {
|
||||
marker: _serde::__private::PhantomData::<Lifetimes<'a>>,
|
||||
lifetime: _serde::__private::PhantomData,
|
||||
},
|
||||
)
|
||||
}
|
||||
(__Field::__field3, __variant) => {
|
||||
#[allow(non_camel_case_types)]
|
||||
enum __Field {
|
||||
__field0,
|
||||
__ignore,
|
||||
}
|
||||
struct __FieldVisitor;
|
||||
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
|
||||
type Value = __Field;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result
|
||||
{
|
||||
_serde::__private::Formatter::write_str(
|
||||
__formatter,
|
||||
"field identifier",
|
||||
)
|
||||
}
|
||||
fn visit_u64<__E>(
|
||||
self,
|
||||
__value: u64,
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
0u64 => _serde::__private::Ok(__Field::__field0),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
fn visit_str<__E>(
|
||||
self,
|
||||
__value: &str,
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
"a" => _serde::__private::Ok(__Field::__field0),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
fn visit_bytes<__E>(
|
||||
self,
|
||||
__value: &[u8],
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
b"a" => _serde::__private::Ok(__Field::__field0),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'de> _serde::Deserialize<'de> for __Field {
|
||||
#[inline]
|
||||
fn deserialize<__D>(
|
||||
__deserializer: __D,
|
||||
) -> _serde::__private::Result<Self, __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
_serde::Deserializer::deserialize_identifier(
|
||||
__deserializer,
|
||||
__FieldVisitor,
|
||||
)
|
||||
}
|
||||
}
|
||||
struct __Visitor<'de, 'a> {
|
||||
marker: _serde::__private::PhantomData<Lifetimes<'a>>,
|
||||
lifetime: _serde::__private::PhantomData<&'de ()>,
|
||||
}
|
||||
impl<'de, 'a> _serde::de::Visitor<'de> for __Visitor<'de, 'a> {
|
||||
type Value = Lifetimes<'a>;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result
|
||||
{
|
||||
_serde::__private::Formatter::write_str(
|
||||
__formatter,
|
||||
"struct variant Lifetimes::NoLifetimeMap",
|
||||
)
|
||||
}
|
||||
#[inline]
|
||||
fn visit_seq<__A>(
|
||||
self,
|
||||
mut __seq: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::SeqAccess<'de>,
|
||||
{
|
||||
let __field0 = match match _serde::de::SeqAccess::next_element::<
|
||||
i32,
|
||||
>(
|
||||
&mut __seq
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
_serde::__private::Some(__value) => __value,
|
||||
_serde::__private::None => {
|
||||
return _serde :: __private :: Err (_serde :: de :: Error :: invalid_length (0usize , & "struct variant Lifetimes::NoLifetimeMap with 1 element")) ;
|
||||
}
|
||||
};
|
||||
_serde::__private::Ok(Lifetimes::NoLifetimeMap { a: __field0 })
|
||||
}
|
||||
#[inline]
|
||||
fn visit_map<__A>(
|
||||
self,
|
||||
mut __map: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::MapAccess<'de>,
|
||||
{
|
||||
let mut __field0: _serde::__private::Option<i32> =
|
||||
_serde::__private::None;
|
||||
while let _serde::__private::Some(__key) =
|
||||
match _serde::de::MapAccess::next_key::<__Field>(&mut __map)
|
||||
{
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
}
|
||||
{
|
||||
match __key {
|
||||
__Field::__field0 => {
|
||||
if _serde::__private::Option::is_some(&__field0) {
|
||||
return _serde :: __private :: Err (< __A :: Error as _serde :: de :: Error > :: duplicate_field ("a")) ;
|
||||
}
|
||||
__field0 = _serde::__private::Some(
|
||||
match _serde::de::MapAccess::next_value::<i32>(
|
||||
&mut __map,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
let _ = match _serde::de::MapAccess::next_value::<
|
||||
_serde::de::IgnoredAny,
|
||||
>(
|
||||
&mut __map
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
let __field0 = match __field0 {
|
||||
_serde::__private::Some(__field0) => __field0,
|
||||
_serde::__private::None => {
|
||||
match _serde::__private::de::missing_field("a") {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
_serde::__private::Ok(Lifetimes::NoLifetimeMap { a: __field0 })
|
||||
}
|
||||
}
|
||||
const FIELDS: &'static [&'static str] = &["a"];
|
||||
_serde::de::VariantAccess::struct_variant(
|
||||
__variant,
|
||||
FIELDS,
|
||||
__Visitor {
|
||||
marker: _serde::__private::PhantomData::<Lifetimes<'a>>,
|
||||
lifetime: _serde::__private::PhantomData,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const VARIANTS: &'static [&'static str] = &[
|
||||
"LifetimeSeq",
|
||||
"NoLifetimeSeq",
|
||||
"LifetimeMap",
|
||||
"NoLifetimeMap",
|
||||
];
|
||||
_serde::Deserializer::deserialize_enum(
|
||||
__deserializer,
|
||||
"Lifetimes",
|
||||
VARIANTS,
|
||||
__Visitor {
|
||||
marker: _serde::__private::PhantomData::<Lifetimes<'a>>,
|
||||
lifetime: _serde::__private::PhantomData,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
enum Lifetimes<'a> {
|
||||
LifetimeSeq(&'a i32),
|
||||
NoLifetimeSeq(i32),
|
||||
LifetimeMap { a: &'a i32 },
|
||||
NoLifetimeMap { a: i32 },
|
||||
}
|
||||
@@ -0,0 +1,628 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
struct SerNamedMap<'a, 'b, A: 'a, B: 'b, C> {
|
||||
a: &'a A,
|
||||
b: &'b mut B,
|
||||
c: C,
|
||||
}
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _: () = {
|
||||
#[allow(unused_extern_crates, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
impl<'a, 'b, A: 'a, B: 'b, C> _serde::Serialize for SerNamedMap<'a, 'b, A, B, C>
|
||||
where
|
||||
A: _serde::Serialize,
|
||||
B: _serde::Serialize,
|
||||
C: _serde::Serialize,
|
||||
{
|
||||
fn serialize<__S>(
|
||||
&self,
|
||||
__serializer: __S,
|
||||
) -> _serde::__private::Result<__S::Ok, __S::Error>
|
||||
where
|
||||
__S: _serde::Serializer,
|
||||
{
|
||||
let mut __serde_state = match _serde::Serializer::serialize_struct(
|
||||
__serializer,
|
||||
"SerNamedMap",
|
||||
false as usize + 1 + 1 + 1,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeStruct::serialize_field(&mut __serde_state, "a", &self.a) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeStruct::serialize_field(&mut __serde_state, "b", &self.b) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeStruct::serialize_field(&mut __serde_state, "c", &self.c) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
_serde::ser::SerializeStruct::end(__serde_state)
|
||||
}
|
||||
}
|
||||
};
|
||||
struct DeNamedMap<A, B, C> {
|
||||
a: A,
|
||||
b: B,
|
||||
c: C,
|
||||
}
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _: () = {
|
||||
#[allow(unused_extern_crates, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
impl<'de, A, B, C> _serde::Deserialize<'de> for DeNamedMap<A, B, C>
|
||||
where
|
||||
A: _serde::Deserialize<'de>,
|
||||
B: _serde::Deserialize<'de>,
|
||||
C: _serde::Deserialize<'de>,
|
||||
{
|
||||
fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
#[allow(non_camel_case_types)]
|
||||
enum __Field {
|
||||
__field0,
|
||||
__field1,
|
||||
__field2,
|
||||
__ignore,
|
||||
}
|
||||
struct __FieldVisitor;
|
||||
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
|
||||
type Value = __Field;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(__formatter, "field identifier")
|
||||
}
|
||||
fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
0u64 => _serde::__private::Ok(__Field::__field0),
|
||||
1u64 => _serde::__private::Ok(__Field::__field1),
|
||||
2u64 => _serde::__private::Ok(__Field::__field2),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
fn visit_str<__E>(
|
||||
self,
|
||||
__value: &str,
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
"a" => _serde::__private::Ok(__Field::__field0),
|
||||
"b" => _serde::__private::Ok(__Field::__field1),
|
||||
"c" => _serde::__private::Ok(__Field::__field2),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
fn visit_bytes<__E>(
|
||||
self,
|
||||
__value: &[u8],
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
b"a" => _serde::__private::Ok(__Field::__field0),
|
||||
b"b" => _serde::__private::Ok(__Field::__field1),
|
||||
b"c" => _serde::__private::Ok(__Field::__field2),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'de> _serde::Deserialize<'de> for __Field {
|
||||
#[inline]
|
||||
fn deserialize<__D>(
|
||||
__deserializer: __D,
|
||||
) -> _serde::__private::Result<Self, __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
|
||||
}
|
||||
}
|
||||
struct __Visitor<'de, A, B, C>
|
||||
where
|
||||
A: _serde::Deserialize<'de>,
|
||||
B: _serde::Deserialize<'de>,
|
||||
C: _serde::Deserialize<'de>,
|
||||
{
|
||||
marker: _serde::__private::PhantomData<DeNamedMap<A, B, C>>,
|
||||
lifetime: _serde::__private::PhantomData<&'de ()>,
|
||||
}
|
||||
impl<'de, A, B, C> _serde::de::Visitor<'de> for __Visitor<'de, A, B, C>
|
||||
where
|
||||
A: _serde::Deserialize<'de>,
|
||||
B: _serde::Deserialize<'de>,
|
||||
C: _serde::Deserialize<'de>,
|
||||
{
|
||||
type Value = DeNamedMap<A, B, C>;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(__formatter, "struct DeNamedMap")
|
||||
}
|
||||
#[inline]
|
||||
fn visit_seq<__A>(
|
||||
self,
|
||||
mut __seq: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::SeqAccess<'de>,
|
||||
{
|
||||
let __field0 = match match _serde::de::SeqAccess::next_element::<A>(&mut __seq)
|
||||
{
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
_serde::__private::Some(__value) => __value,
|
||||
_serde::__private::None => {
|
||||
return _serde::__private::Err(_serde::de::Error::invalid_length(
|
||||
0usize,
|
||||
&"struct DeNamedMap with 3 elements",
|
||||
));
|
||||
}
|
||||
};
|
||||
let __field1 = match match _serde::de::SeqAccess::next_element::<B>(&mut __seq)
|
||||
{
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
_serde::__private::Some(__value) => __value,
|
||||
_serde::__private::None => {
|
||||
return _serde::__private::Err(_serde::de::Error::invalid_length(
|
||||
1usize,
|
||||
&"struct DeNamedMap with 3 elements",
|
||||
));
|
||||
}
|
||||
};
|
||||
let __field2 = match match _serde::de::SeqAccess::next_element::<C>(&mut __seq)
|
||||
{
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
_serde::__private::Some(__value) => __value,
|
||||
_serde::__private::None => {
|
||||
return _serde::__private::Err(_serde::de::Error::invalid_length(
|
||||
2usize,
|
||||
&"struct DeNamedMap with 3 elements",
|
||||
));
|
||||
}
|
||||
};
|
||||
_serde::__private::Ok(DeNamedMap {
|
||||
a: __field0,
|
||||
b: __field1,
|
||||
c: __field2,
|
||||
})
|
||||
}
|
||||
#[inline]
|
||||
fn visit_map<__A>(
|
||||
self,
|
||||
mut __map: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::MapAccess<'de>,
|
||||
{
|
||||
let mut __field0: _serde::__private::Option<A> = _serde::__private::None;
|
||||
let mut __field1: _serde::__private::Option<B> = _serde::__private::None;
|
||||
let mut __field2: _serde::__private::Option<C> = _serde::__private::None;
|
||||
while let _serde::__private::Some(__key) =
|
||||
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
}
|
||||
{
|
||||
match __key {
|
||||
__Field::__field0 => {
|
||||
if _serde::__private::Option::is_some(&__field0) {
|
||||
return _serde::__private::Err(
|
||||
<__A::Error as _serde::de::Error>::duplicate_field("a"),
|
||||
);
|
||||
}
|
||||
__field0 = _serde::__private::Some(
|
||||
match _serde::de::MapAccess::next_value::<A>(&mut __map) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
__Field::__field1 => {
|
||||
if _serde::__private::Option::is_some(&__field1) {
|
||||
return _serde::__private::Err(
|
||||
<__A::Error as _serde::de::Error>::duplicate_field("b"),
|
||||
);
|
||||
}
|
||||
__field1 = _serde::__private::Some(
|
||||
match _serde::de::MapAccess::next_value::<B>(&mut __map) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
__Field::__field2 => {
|
||||
if _serde::__private::Option::is_some(&__field2) {
|
||||
return _serde::__private::Err(
|
||||
<__A::Error as _serde::de::Error>::duplicate_field("c"),
|
||||
);
|
||||
}
|
||||
__field2 = _serde::__private::Some(
|
||||
match _serde::de::MapAccess::next_value::<C>(&mut __map) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
let _ = match _serde::de::MapAccess::next_value::<
|
||||
_serde::de::IgnoredAny,
|
||||
>(&mut __map)
|
||||
{
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
let __field0 = match __field0 {
|
||||
_serde::__private::Some(__field0) => __field0,
|
||||
_serde::__private::None => {
|
||||
match _serde::__private::de::missing_field("a") {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
let __field1 = match __field1 {
|
||||
_serde::__private::Some(__field1) => __field1,
|
||||
_serde::__private::None => {
|
||||
match _serde::__private::de::missing_field("b") {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
let __field2 = match __field2 {
|
||||
_serde::__private::Some(__field2) => __field2,
|
||||
_serde::__private::None => {
|
||||
match _serde::__private::de::missing_field("c") {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
_serde::__private::Ok(DeNamedMap {
|
||||
a: __field0,
|
||||
b: __field1,
|
||||
c: __field2,
|
||||
})
|
||||
}
|
||||
}
|
||||
const FIELDS: &'static [&'static str] = &["a", "b", "c"];
|
||||
_serde::Deserializer::deserialize_struct(
|
||||
__deserializer,
|
||||
"DeNamedMap",
|
||||
FIELDS,
|
||||
__Visitor {
|
||||
marker: _serde::__private::PhantomData::<DeNamedMap<A, B, C>>,
|
||||
lifetime: _serde::__private::PhantomData,
|
||||
},
|
||||
)
|
||||
}
|
||||
fn deserialize_in_place<__D>(
|
||||
__deserializer: __D,
|
||||
__place: &mut Self,
|
||||
) -> _serde::__private::Result<(), __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
#[allow(non_camel_case_types)]
|
||||
enum __Field {
|
||||
__field0,
|
||||
__field1,
|
||||
__field2,
|
||||
__ignore,
|
||||
}
|
||||
struct __FieldVisitor;
|
||||
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
|
||||
type Value = __Field;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(__formatter, "field identifier")
|
||||
}
|
||||
fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
0u64 => _serde::__private::Ok(__Field::__field0),
|
||||
1u64 => _serde::__private::Ok(__Field::__field1),
|
||||
2u64 => _serde::__private::Ok(__Field::__field2),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
fn visit_str<__E>(
|
||||
self,
|
||||
__value: &str,
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
"a" => _serde::__private::Ok(__Field::__field0),
|
||||
"b" => _serde::__private::Ok(__Field::__field1),
|
||||
"c" => _serde::__private::Ok(__Field::__field2),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
fn visit_bytes<__E>(
|
||||
self,
|
||||
__value: &[u8],
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
b"a" => _serde::__private::Ok(__Field::__field0),
|
||||
b"b" => _serde::__private::Ok(__Field::__field1),
|
||||
b"c" => _serde::__private::Ok(__Field::__field2),
|
||||
_ => _serde::__private::Ok(__Field::__ignore),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'de> _serde::Deserialize<'de> for __Field {
|
||||
#[inline]
|
||||
fn deserialize<__D>(
|
||||
__deserializer: __D,
|
||||
) -> _serde::__private::Result<Self, __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
|
||||
}
|
||||
}
|
||||
struct __Visitor<'de, 'place, A: 'place, B: 'place, C: 'place>
|
||||
where
|
||||
A: _serde::Deserialize<'de>,
|
||||
B: _serde::Deserialize<'de>,
|
||||
C: _serde::Deserialize<'de>,
|
||||
{
|
||||
place: &'place mut DeNamedMap<A, B, C>,
|
||||
lifetime: _serde::__private::PhantomData<&'de ()>,
|
||||
}
|
||||
impl<'de, 'place, A: 'place, B: 'place, C: 'place> _serde::de::Visitor<'de>
|
||||
for __Visitor<'de, 'place, A, B, C>
|
||||
where
|
||||
A: _serde::Deserialize<'de>,
|
||||
B: _serde::Deserialize<'de>,
|
||||
C: _serde::Deserialize<'de>,
|
||||
{
|
||||
type Value = ();
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(__formatter, "struct DeNamedMap")
|
||||
}
|
||||
#[inline]
|
||||
fn visit_seq<__A>(
|
||||
self,
|
||||
mut __seq: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::SeqAccess<'de>,
|
||||
{
|
||||
if let _serde::__private::None = match _serde::de::SeqAccess::next_element_seed(
|
||||
&mut __seq,
|
||||
_serde::__private::de::InPlaceSeed(&mut self.place.a),
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
return _serde::__private::Err(_serde::de::Error::invalid_length(
|
||||
0usize,
|
||||
&"struct DeNamedMap with 3 elements",
|
||||
));
|
||||
}
|
||||
if let _serde::__private::None = match _serde::de::SeqAccess::next_element_seed(
|
||||
&mut __seq,
|
||||
_serde::__private::de::InPlaceSeed(&mut self.place.b),
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
return _serde::__private::Err(_serde::de::Error::invalid_length(
|
||||
1usize,
|
||||
&"struct DeNamedMap with 3 elements",
|
||||
));
|
||||
}
|
||||
if let _serde::__private::None = match _serde::de::SeqAccess::next_element_seed(
|
||||
&mut __seq,
|
||||
_serde::__private::de::InPlaceSeed(&mut self.place.c),
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
return _serde::__private::Err(_serde::de::Error::invalid_length(
|
||||
2usize,
|
||||
&"struct DeNamedMap with 3 elements",
|
||||
));
|
||||
}
|
||||
_serde::__private::Ok(())
|
||||
}
|
||||
#[inline]
|
||||
fn visit_map<__A>(
|
||||
self,
|
||||
mut __map: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::MapAccess<'de>,
|
||||
{
|
||||
let mut __field0: bool = false;
|
||||
let mut __field1: bool = false;
|
||||
let mut __field2: bool = false;
|
||||
while let _serde::__private::Some(__key) =
|
||||
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
}
|
||||
{
|
||||
match __key {
|
||||
__Field::__field0 => {
|
||||
if __field0 {
|
||||
return _serde::__private::Err(
|
||||
<__A::Error as _serde::de::Error>::duplicate_field("a"),
|
||||
);
|
||||
}
|
||||
match _serde::de::MapAccess::next_value_seed(
|
||||
&mut __map,
|
||||
_serde::__private::de::InPlaceSeed(&mut self.place.a),
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
__field0 = true;
|
||||
}
|
||||
__Field::__field1 => {
|
||||
if __field1 {
|
||||
return _serde::__private::Err(
|
||||
<__A::Error as _serde::de::Error>::duplicate_field("b"),
|
||||
);
|
||||
}
|
||||
match _serde::de::MapAccess::next_value_seed(
|
||||
&mut __map,
|
||||
_serde::__private::de::InPlaceSeed(&mut self.place.b),
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
__field1 = true;
|
||||
}
|
||||
__Field::__field2 => {
|
||||
if __field2 {
|
||||
return _serde::__private::Err(
|
||||
<__A::Error as _serde::de::Error>::duplicate_field("c"),
|
||||
);
|
||||
}
|
||||
match _serde::de::MapAccess::next_value_seed(
|
||||
&mut __map,
|
||||
_serde::__private::de::InPlaceSeed(&mut self.place.c),
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
__field2 = true;
|
||||
}
|
||||
_ => {
|
||||
let _ = match _serde::de::MapAccess::next_value::<
|
||||
_serde::de::IgnoredAny,
|
||||
>(&mut __map)
|
||||
{
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
if !__field0 {
|
||||
self.place.a = match _serde::__private::de::missing_field("a") {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
};
|
||||
if !__field1 {
|
||||
self.place.b = match _serde::__private::de::missing_field("b") {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
};
|
||||
if !__field2 {
|
||||
self.place.c = match _serde::__private::de::missing_field("c") {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
};
|
||||
_serde::__private::Ok(())
|
||||
}
|
||||
}
|
||||
const FIELDS: &'static [&'static str] = &["a", "b", "c"];
|
||||
_serde::Deserializer::deserialize_struct(
|
||||
__deserializer,
|
||||
"DeNamedMap",
|
||||
FIELDS,
|
||||
__Visitor {
|
||||
place: __place,
|
||||
lifetime: _serde::__private::PhantomData,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct SerNamedMap<'a, 'b, A: 'a, B: 'b, C> {
|
||||
a: &'a A,
|
||||
b: &'b mut B,
|
||||
c: C,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct DeNamedMap<A, B, C> {
|
||||
a: A,
|
||||
b: B,
|
||||
c: C,
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
struct SerNamedTuple<'a, 'b, A: 'a, B: 'b, C>(&'a A, &'b mut B, C);
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _: () = {
|
||||
#[allow(unused_extern_crates, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
impl<'a, 'b, A: 'a, B: 'b, C> _serde::Serialize for SerNamedTuple<'a, 'b, A, B, C>
|
||||
where
|
||||
A: _serde::Serialize,
|
||||
B: _serde::Serialize,
|
||||
C: _serde::Serialize,
|
||||
{
|
||||
fn serialize<__S>(
|
||||
&self,
|
||||
__serializer: __S,
|
||||
) -> _serde::__private::Result<__S::Ok, __S::Error>
|
||||
where
|
||||
__S: _serde::Serializer,
|
||||
{
|
||||
let mut __serde_state = match _serde::Serializer::serialize_tuple_struct(
|
||||
__serializer,
|
||||
"SerNamedTuple",
|
||||
0 + 1 + 1 + 1,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeTupleStruct::serialize_field(&mut __serde_state, &self.0) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeTupleStruct::serialize_field(&mut __serde_state, &self.1) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeTupleStruct::serialize_field(&mut __serde_state, &self.2) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
_serde::ser::SerializeTupleStruct::end(__serde_state)
|
||||
}
|
||||
}
|
||||
};
|
||||
struct DeNamedTuple<A, B, C>(A, B, C);
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _: () = {
|
||||
#[allow(unused_extern_crates, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
impl<'de, A, B, C> _serde::Deserialize<'de> for DeNamedTuple<A, B, C>
|
||||
where
|
||||
A: _serde::Deserialize<'de>,
|
||||
B: _serde::Deserialize<'de>,
|
||||
C: _serde::Deserialize<'de>,
|
||||
{
|
||||
fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
struct __Visitor<'de, A, B, C>
|
||||
where
|
||||
A: _serde::Deserialize<'de>,
|
||||
B: _serde::Deserialize<'de>,
|
||||
C: _serde::Deserialize<'de>,
|
||||
{
|
||||
marker: _serde::__private::PhantomData<DeNamedTuple<A, B, C>>,
|
||||
lifetime: _serde::__private::PhantomData<&'de ()>,
|
||||
}
|
||||
impl<'de, A, B, C> _serde::de::Visitor<'de> for __Visitor<'de, A, B, C>
|
||||
where
|
||||
A: _serde::Deserialize<'de>,
|
||||
B: _serde::Deserialize<'de>,
|
||||
C: _serde::Deserialize<'de>,
|
||||
{
|
||||
type Value = DeNamedTuple<A, B, C>;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(
|
||||
__formatter,
|
||||
"tuple struct DeNamedTuple",
|
||||
)
|
||||
}
|
||||
#[inline]
|
||||
fn visit_seq<__A>(
|
||||
self,
|
||||
mut __seq: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::SeqAccess<'de>,
|
||||
{
|
||||
let __field0 = match match _serde::de::SeqAccess::next_element::<A>(&mut __seq)
|
||||
{
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
_serde::__private::Some(__value) => __value,
|
||||
_serde::__private::None => {
|
||||
return _serde::__private::Err(_serde::de::Error::invalid_length(
|
||||
0usize,
|
||||
&"tuple struct DeNamedTuple with 3 elements",
|
||||
));
|
||||
}
|
||||
};
|
||||
let __field1 = match match _serde::de::SeqAccess::next_element::<B>(&mut __seq)
|
||||
{
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
_serde::__private::Some(__value) => __value,
|
||||
_serde::__private::None => {
|
||||
return _serde::__private::Err(_serde::de::Error::invalid_length(
|
||||
1usize,
|
||||
&"tuple struct DeNamedTuple with 3 elements",
|
||||
));
|
||||
}
|
||||
};
|
||||
let __field2 = match match _serde::de::SeqAccess::next_element::<C>(&mut __seq)
|
||||
{
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
_serde::__private::Some(__value) => __value,
|
||||
_serde::__private::None => {
|
||||
return _serde::__private::Err(_serde::de::Error::invalid_length(
|
||||
2usize,
|
||||
&"tuple struct DeNamedTuple with 3 elements",
|
||||
));
|
||||
}
|
||||
};
|
||||
_serde::__private::Ok(DeNamedTuple(__field0, __field1, __field2))
|
||||
}
|
||||
}
|
||||
_serde::Deserializer::deserialize_tuple_struct(
|
||||
__deserializer,
|
||||
"DeNamedTuple",
|
||||
3usize,
|
||||
__Visitor {
|
||||
marker: _serde::__private::PhantomData::<DeNamedTuple<A, B, C>>,
|
||||
lifetime: _serde::__private::PhantomData,
|
||||
},
|
||||
)
|
||||
}
|
||||
fn deserialize_in_place<__D>(
|
||||
__deserializer: __D,
|
||||
__place: &mut Self,
|
||||
) -> _serde::__private::Result<(), __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
struct __Visitor<'de, 'place, A: 'place, B: 'place, C: 'place>
|
||||
where
|
||||
A: _serde::Deserialize<'de>,
|
||||
B: _serde::Deserialize<'de>,
|
||||
C: _serde::Deserialize<'de>,
|
||||
{
|
||||
place: &'place mut DeNamedTuple<A, B, C>,
|
||||
lifetime: _serde::__private::PhantomData<&'de ()>,
|
||||
}
|
||||
impl<'de, 'place, A: 'place, B: 'place, C: 'place> _serde::de::Visitor<'de>
|
||||
for __Visitor<'de, 'place, A, B, C>
|
||||
where
|
||||
A: _serde::Deserialize<'de>,
|
||||
B: _serde::Deserialize<'de>,
|
||||
C: _serde::Deserialize<'de>,
|
||||
{
|
||||
type Value = ();
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(
|
||||
__formatter,
|
||||
"tuple struct DeNamedTuple",
|
||||
)
|
||||
}
|
||||
#[inline]
|
||||
fn visit_seq<__A>(
|
||||
self,
|
||||
mut __seq: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::SeqAccess<'de>,
|
||||
{
|
||||
if let _serde::__private::None = match _serde::de::SeqAccess::next_element_seed(
|
||||
&mut __seq,
|
||||
_serde::__private::de::InPlaceSeed(&mut self.place.0),
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
return _serde::__private::Err(_serde::de::Error::invalid_length(
|
||||
0usize,
|
||||
&"tuple struct DeNamedTuple with 3 elements",
|
||||
));
|
||||
}
|
||||
if let _serde::__private::None = match _serde::de::SeqAccess::next_element_seed(
|
||||
&mut __seq,
|
||||
_serde::__private::de::InPlaceSeed(&mut self.place.1),
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
return _serde::__private::Err(_serde::de::Error::invalid_length(
|
||||
1usize,
|
||||
&"tuple struct DeNamedTuple with 3 elements",
|
||||
));
|
||||
}
|
||||
if let _serde::__private::None = match _serde::de::SeqAccess::next_element_seed(
|
||||
&mut __seq,
|
||||
_serde::__private::de::InPlaceSeed(&mut self.place.2),
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
} {
|
||||
return _serde::__private::Err(_serde::de::Error::invalid_length(
|
||||
2usize,
|
||||
&"tuple struct DeNamedTuple with 3 elements",
|
||||
));
|
||||
}
|
||||
_serde::__private::Ok(())
|
||||
}
|
||||
}
|
||||
_serde::Deserializer::deserialize_tuple_struct(
|
||||
__deserializer,
|
||||
"DeNamedTuple",
|
||||
3usize,
|
||||
__Visitor {
|
||||
place: __place,
|
||||
lifetime: _serde::__private::PhantomData,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct SerNamedTuple<'a, 'b, A: 'a, B: 'b, C>(&'a A, &'b mut B, C);
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct DeNamedTuple<A, B, C>(A, B, C);
|
||||
@@ -0,0 +1,52 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
struct NamedUnit;
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _: () = {
|
||||
#[allow(unused_extern_crates, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
impl _serde::Serialize for NamedUnit {
|
||||
fn serialize<__S>(
|
||||
&self,
|
||||
__serializer: __S,
|
||||
) -> _serde::__private::Result<__S::Ok, __S::Error>
|
||||
where
|
||||
__S: _serde::Serializer,
|
||||
{
|
||||
_serde::Serializer::serialize_unit_struct(__serializer, "NamedUnit")
|
||||
}
|
||||
}
|
||||
};
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _: () = {
|
||||
#[allow(unused_extern_crates, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
impl<'de> _serde::Deserialize<'de> for NamedUnit {
|
||||
fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
struct __Visitor;
|
||||
impl<'de> _serde::de::Visitor<'de> for __Visitor {
|
||||
type Value = NamedUnit;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(__formatter, "unit struct NamedUnit")
|
||||
}
|
||||
#[inline]
|
||||
fn visit_unit<__E>(self) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
_serde::__private::Ok(NamedUnit)
|
||||
}
|
||||
}
|
||||
_serde::Deserializer::deserialize_unit_struct(__deserializer, "NamedUnit", __Visitor)
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct NamedUnit;
|
||||
@@ -0,0 +1,271 @@
|
||||
use serde::Serialize;
|
||||
enum SerEnum<'a, B: 'a, C: 'a, D>
|
||||
where
|
||||
D: 'a,
|
||||
{
|
||||
Unit,
|
||||
Seq(i8, B, &'a C, &'a mut D),
|
||||
Map { a: i8, b: B, c: &'a C, d: &'a mut D },
|
||||
_Unit2,
|
||||
_Seq2(i8, B, &'a C, &'a mut D),
|
||||
_Map2 { a: i8, b: B, c: &'a C, d: &'a mut D },
|
||||
}
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _: () = {
|
||||
#[allow(unused_extern_crates, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
impl<'a, B: 'a, C: 'a, D> _serde::Serialize for SerEnum<'a, B, C, D>
|
||||
where
|
||||
D: 'a,
|
||||
B: _serde::Serialize,
|
||||
C: _serde::Serialize,
|
||||
D: _serde::Serialize,
|
||||
{
|
||||
fn serialize<__S>(
|
||||
&self,
|
||||
__serializer: __S,
|
||||
) -> _serde::__private::Result<__S::Ok, __S::Error>
|
||||
where
|
||||
__S: _serde::Serializer,
|
||||
{
|
||||
match *self {
|
||||
SerEnum::Unit => _serde::Serializer::serialize_unit_variant(
|
||||
__serializer,
|
||||
"SerEnum",
|
||||
0u32,
|
||||
"Unit",
|
||||
),
|
||||
SerEnum::Seq(ref __field0, ref __field1, ref __field2, ref __field3) => {
|
||||
let mut __serde_state = match _serde::Serializer::serialize_tuple_variant(
|
||||
__serializer,
|
||||
"SerEnum",
|
||||
1u32,
|
||||
"Seq",
|
||||
0 + 1 + 1 + 1 + 1,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeTupleVariant::serialize_field(
|
||||
&mut __serde_state,
|
||||
__field0,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeTupleVariant::serialize_field(
|
||||
&mut __serde_state,
|
||||
__field1,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeTupleVariant::serialize_field(
|
||||
&mut __serde_state,
|
||||
__field2,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeTupleVariant::serialize_field(
|
||||
&mut __serde_state,
|
||||
__field3,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
_serde::ser::SerializeTupleVariant::end(__serde_state)
|
||||
}
|
||||
SerEnum::Map {
|
||||
ref a,
|
||||
ref b,
|
||||
ref c,
|
||||
ref d,
|
||||
} => {
|
||||
let mut __serde_state = match _serde::Serializer::serialize_struct_variant(
|
||||
__serializer,
|
||||
"SerEnum",
|
||||
2u32,
|
||||
"Map",
|
||||
0 + 1 + 1 + 1 + 1,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeStructVariant::serialize_field(
|
||||
&mut __serde_state,
|
||||
"a",
|
||||
a,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeStructVariant::serialize_field(
|
||||
&mut __serde_state,
|
||||
"b",
|
||||
b,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeStructVariant::serialize_field(
|
||||
&mut __serde_state,
|
||||
"c",
|
||||
c,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeStructVariant::serialize_field(
|
||||
&mut __serde_state,
|
||||
"d",
|
||||
d,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
_serde::ser::SerializeStructVariant::end(__serde_state)
|
||||
}
|
||||
SerEnum::_Unit2 => _serde::Serializer::serialize_unit_variant(
|
||||
__serializer,
|
||||
"SerEnum",
|
||||
3u32,
|
||||
"_Unit2",
|
||||
),
|
||||
SerEnum::_Seq2(ref __field0, ref __field1, ref __field2, ref __field3) => {
|
||||
let mut __serde_state = match _serde::Serializer::serialize_tuple_variant(
|
||||
__serializer,
|
||||
"SerEnum",
|
||||
4u32,
|
||||
"_Seq2",
|
||||
0 + 1 + 1 + 1 + 1,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeTupleVariant::serialize_field(
|
||||
&mut __serde_state,
|
||||
__field0,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeTupleVariant::serialize_field(
|
||||
&mut __serde_state,
|
||||
__field1,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeTupleVariant::serialize_field(
|
||||
&mut __serde_state,
|
||||
__field2,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeTupleVariant::serialize_field(
|
||||
&mut __serde_state,
|
||||
__field3,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
_serde::ser::SerializeTupleVariant::end(__serde_state)
|
||||
}
|
||||
SerEnum::_Map2 {
|
||||
ref a,
|
||||
ref b,
|
||||
ref c,
|
||||
ref d,
|
||||
} => {
|
||||
let mut __serde_state = match _serde::Serializer::serialize_struct_variant(
|
||||
__serializer,
|
||||
"SerEnum",
|
||||
5u32,
|
||||
"_Map2",
|
||||
0 + 1 + 1 + 1 + 1,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeStructVariant::serialize_field(
|
||||
&mut __serde_state,
|
||||
"a",
|
||||
a,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeStructVariant::serialize_field(
|
||||
&mut __serde_state,
|
||||
"b",
|
||||
b,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeStructVariant::serialize_field(
|
||||
&mut __serde_state,
|
||||
"c",
|
||||
c,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
match _serde::ser::SerializeStructVariant::serialize_field(
|
||||
&mut __serde_state,
|
||||
"d",
|
||||
d,
|
||||
) {
|
||||
_serde::__private::Ok(__val) => __val,
|
||||
_serde::__private::Err(__err) => {
|
||||
return _serde::__private::Err(__err);
|
||||
}
|
||||
};
|
||||
_serde::ser::SerializeStructVariant::end(__serde_state)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
enum SerEnum<'a, B: 'a, C: 'a, D>
|
||||
where
|
||||
D: 'a,
|
||||
{
|
||||
Unit,
|
||||
Seq(i8, B, &'a C, &'a mut D),
|
||||
Map { a: i8, b: B, c: &'a C, d: &'a mut D },
|
||||
|
||||
// Make sure we can support more than one variant.
|
||||
_Unit2,
|
||||
_Seq2(i8, B, &'a C, &'a mut D),
|
||||
_Map2 { a: i8, b: B, c: &'a C, d: &'a mut D },
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
enum Void {}
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _: () = {
|
||||
#[allow(unused_extern_crates, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
impl _serde::Serialize for Void {
|
||||
fn serialize<__S>(
|
||||
&self,
|
||||
__serializer: __S,
|
||||
) -> _serde::__private::Result<__S::Ok, __S::Error>
|
||||
where
|
||||
__S: _serde::Serializer,
|
||||
{
|
||||
match *self {}
|
||||
}
|
||||
}
|
||||
};
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _: () = {
|
||||
#[allow(unused_extern_crates, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
impl<'de> _serde::Deserialize<'de> for Void {
|
||||
fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
#[allow(non_camel_case_types)]
|
||||
enum __Field {}
|
||||
struct __FieldVisitor;
|
||||
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
|
||||
type Value = __Field;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(__formatter, "variant identifier")
|
||||
}
|
||||
fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
_ => _serde::__private::Err(_serde::de::Error::invalid_value(
|
||||
_serde::de::Unexpected::Unsigned(__value),
|
||||
&"variant index 0 <= i < 0",
|
||||
)),
|
||||
}
|
||||
}
|
||||
fn visit_str<__E>(
|
||||
self,
|
||||
__value: &str,
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
_ => _serde::__private::Err(_serde::de::Error::unknown_variant(
|
||||
__value, VARIANTS,
|
||||
)),
|
||||
}
|
||||
}
|
||||
fn visit_bytes<__E>(
|
||||
self,
|
||||
__value: &[u8],
|
||||
) -> _serde::__private::Result<Self::Value, __E>
|
||||
where
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
_ => {
|
||||
let __value = &_serde::__private::from_utf8_lossy(__value);
|
||||
_serde::__private::Err(_serde::de::Error::unknown_variant(
|
||||
__value, VARIANTS,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'de> _serde::Deserialize<'de> for __Field {
|
||||
#[inline]
|
||||
fn deserialize<__D>(
|
||||
__deserializer: __D,
|
||||
) -> _serde::__private::Result<Self, __D::Error>
|
||||
where
|
||||
__D: _serde::Deserializer<'de>,
|
||||
{
|
||||
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
|
||||
}
|
||||
}
|
||||
struct __Visitor<'de> {
|
||||
marker: _serde::__private::PhantomData<Void>,
|
||||
lifetime: _serde::__private::PhantomData<&'de ()>,
|
||||
}
|
||||
impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
|
||||
type Value = Void;
|
||||
fn expecting(
|
||||
&self,
|
||||
__formatter: &mut _serde::__private::Formatter,
|
||||
) -> _serde::__private::fmt::Result {
|
||||
_serde::__private::Formatter::write_str(__formatter, "enum Void")
|
||||
}
|
||||
fn visit_enum<__A>(
|
||||
self,
|
||||
__data: __A,
|
||||
) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||
where
|
||||
__A: _serde::de::EnumAccess<'de>,
|
||||
{
|
||||
_serde::__private::Result::map(
|
||||
_serde::de::EnumAccess::variant::<__Field>(__data),
|
||||
|(__impossible, _)| match __impossible {},
|
||||
)
|
||||
}
|
||||
}
|
||||
const VARIANTS: &'static [&'static str] = &[];
|
||||
_serde::Deserializer::deserialize_enum(
|
||||
__deserializer,
|
||||
"Void",
|
||||
VARIANTS,
|
||||
__Visitor {
|
||||
marker: _serde::__private::PhantomData::<Void>,
|
||||
lifetime: _serde::__private::PhantomData,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
enum Void {}
|
||||
@@ -0,0 +1,8 @@
|
||||
#[cfg_attr(target_os = "emscripten", ignore)]
|
||||
#[cfg_attr(not(expandtest), ignore)]
|
||||
#[rustversion::attr(not(nightly), ignore)]
|
||||
#[allow(unused_attributes)]
|
||||
#[test]
|
||||
fn expandtest() {
|
||||
macrotest::expand("tests/expand/*.rs");
|
||||
}
|
||||
@@ -1,93 +1,77 @@
|
||||
use serde_test::Token;
|
||||
use std::iter;
|
||||
|
||||
macro_rules! btreeset {
|
||||
() => {
|
||||
BTreeSet::new()
|
||||
};
|
||||
($($value:expr),+) => {
|
||||
{
|
||||
let mut set = BTreeSet::new();
|
||||
$(set.insert($value);)+
|
||||
set
|
||||
}
|
||||
}
|
||||
($($value:expr),+) => {{
|
||||
let mut set = BTreeSet::new();
|
||||
$(set.insert($value);)+
|
||||
set
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! btreemap {
|
||||
() => {
|
||||
BTreeMap::new()
|
||||
};
|
||||
($($key:expr => $value:expr),+) => {
|
||||
{
|
||||
let mut map = BTreeMap::new();
|
||||
$(map.insert($key, $value);)+
|
||||
map
|
||||
}
|
||||
}
|
||||
($($key:expr => $value:expr),+) => {{
|
||||
let mut map = BTreeMap::new();
|
||||
$(map.insert($key, $value);)+
|
||||
map
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! hashset {
|
||||
() => {
|
||||
HashSet::new()
|
||||
};
|
||||
($($value:expr),+) => {
|
||||
{
|
||||
let mut set = HashSet::new();
|
||||
$(set.insert($value);)+
|
||||
set
|
||||
}
|
||||
};
|
||||
($hasher:ident @ $($value:expr),+) => {
|
||||
{
|
||||
use std::hash::BuildHasherDefault;
|
||||
let mut set = HashSet::with_hasher(BuildHasherDefault::<$hasher>::default());
|
||||
$(set.insert($value);)+
|
||||
set
|
||||
}
|
||||
}
|
||||
($($value:expr),+) => {{
|
||||
let mut set = HashSet::new();
|
||||
$(set.insert($value);)+
|
||||
set
|
||||
}};
|
||||
($hasher:ident @ $($value:expr),+) => {{
|
||||
use std::hash::BuildHasherDefault;
|
||||
let mut set = HashSet::with_hasher(BuildHasherDefault::<$hasher>::default());
|
||||
$(set.insert($value);)+
|
||||
set
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! hashmap {
|
||||
() => {
|
||||
HashMap::new()
|
||||
};
|
||||
($($key:expr => $value:expr),+) => {
|
||||
{
|
||||
let mut map = HashMap::new();
|
||||
$(map.insert($key, $value);)+
|
||||
map
|
||||
}
|
||||
};
|
||||
($hasher:ident @ $($key:expr => $value:expr),+) => {
|
||||
{
|
||||
use std::hash::BuildHasherDefault;
|
||||
let mut map = HashMap::with_hasher(BuildHasherDefault::<$hasher>::default());
|
||||
$(map.insert($key, $value);)+
|
||||
map
|
||||
}
|
||||
($($key:expr => $value:expr),+) => {{
|
||||
let mut map = HashMap::new();
|
||||
$(map.insert($key, $value);)+
|
||||
map
|
||||
}};
|
||||
($hasher:ident @ $($key:expr => $value:expr),+) => {{
|
||||
use std::hash::BuildHasherDefault;
|
||||
let mut map = HashMap::with_hasher(BuildHasherDefault::<$hasher>::default());
|
||||
$(map.insert($key, $value);)+
|
||||
map
|
||||
}};
|
||||
}
|
||||
|
||||
pub trait SingleTokenIntoIterator {
|
||||
fn into_iter(self) -> iter::Once<Token>;
|
||||
}
|
||||
|
||||
impl SingleTokenIntoIterator for Token {
|
||||
fn into_iter(self) -> iter::Once<Token> {
|
||||
iter::once(self)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! seq_impl {
|
||||
(seq $first:expr,) => {
|
||||
seq_impl!(seq $first)
|
||||
};
|
||||
($first:expr,) => {
|
||||
seq_impl!($first)
|
||||
};
|
||||
(seq $first:expr) => {
|
||||
$first.into_iter()
|
||||
};
|
||||
($first:expr) => {
|
||||
Some($first).into_iter()
|
||||
};
|
||||
(seq $first:expr , $( $elem: tt)*) => {
|
||||
$first.into_iter().chain(seq!( $($elem)* ))
|
||||
};
|
||||
($first:expr , $($elem: tt)*) => {
|
||||
Some($first).into_iter().chain(seq!( $($elem)* ))
|
||||
}
|
||||
}
|
||||
macro_rules! seq {
|
||||
($($tt: tt)*) => {
|
||||
seq_impl!($($tt)*).collect::<Vec<_>>()
|
||||
};
|
||||
($($elem:expr),* $(,)?) => {{
|
||||
use crate::macros::SingleTokenIntoIterator;
|
||||
let mut vec = Vec::new();
|
||||
$(<Vec<Token> as Extend<Token>>::extend(&mut vec, $elem.into_iter());)*
|
||||
vec
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(cast_lossless))]
|
||||
#![allow(
|
||||
clippy::cast_lossless,
|
||||
clippy::from_over_into,
|
||||
// Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7422
|
||||
clippy::nonstandard_macro_braces,
|
||||
clippy::too_many_lines,
|
||||
clippy::trivially_copy_pass_by_ref
|
||||
)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
extern crate serde;
|
||||
use self::serde::de::{self, MapAccess, Unexpected, Visitor};
|
||||
use self::serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use serde::de::{self, MapAccess, Unexpected, Visitor};
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
extern crate serde_test;
|
||||
use self::serde_test::{
|
||||
use serde_test::{
|
||||
assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_ser_tokens_error,
|
||||
assert_tokens, Token,
|
||||
};
|
||||
@@ -68,7 +70,7 @@ impl DeserializeWith for i32 {
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
if try!(Deserialize::deserialize(de)) {
|
||||
if Deserialize::deserialize(de)? {
|
||||
Ok(123)
|
||||
} else {
|
||||
Ok(2)
|
||||
@@ -93,6 +95,15 @@ where
|
||||
a5: E,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||
struct DefaultTupleStruct<A, B, C>(
|
||||
A,
|
||||
#[serde(default)] B,
|
||||
#[serde(default = "MyDefault::my_default")] C,
|
||||
)
|
||||
where
|
||||
C: MyDefault;
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||
struct CollectOther {
|
||||
a: u32,
|
||||
@@ -186,8 +197,37 @@ fn test_default_struct() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_tuple() {
|
||||
assert_de_tokens(
|
||||
&DefaultTupleStruct(1, 2, 3),
|
||||
&[
|
||||
Token::TupleStruct {
|
||||
name: "DefaultTupleStruct",
|
||||
len: 3,
|
||||
},
|
||||
Token::I32(1),
|
||||
Token::I32(2),
|
||||
Token::I32(3),
|
||||
Token::TupleStructEnd,
|
||||
],
|
||||
);
|
||||
|
||||
assert_de_tokens(
|
||||
&DefaultTupleStruct(1, 0, 123),
|
||||
&[
|
||||
Token::TupleStruct {
|
||||
name: "DefaultTupleStruct",
|
||||
len: 3,
|
||||
},
|
||||
Token::I32(1),
|
||||
Token::TupleStructEnd,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||
enum DefaultEnum<A, B, C, D, E>
|
||||
enum DefaultStructVariant<A, B, C, D, E>
|
||||
where
|
||||
C: MyDefault,
|
||||
E: MyDefault,
|
||||
@@ -205,10 +245,22 @@ where
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||
enum DefaultTupleVariant<A, B, C>
|
||||
where
|
||||
C: MyDefault,
|
||||
{
|
||||
Tuple(
|
||||
A,
|
||||
#[serde(default)] B,
|
||||
#[serde(default = "MyDefault::my_default")] C,
|
||||
),
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_enum() {
|
||||
fn test_default_struct_variant() {
|
||||
assert_de_tokens(
|
||||
&DefaultEnum::Struct {
|
||||
&DefaultStructVariant::Struct {
|
||||
a1: 1,
|
||||
a2: 2,
|
||||
a3: 3,
|
||||
@@ -217,7 +269,7 @@ fn test_default_enum() {
|
||||
},
|
||||
&[
|
||||
Token::StructVariant {
|
||||
name: "DefaultEnum",
|
||||
name: "DefaultStructVariant",
|
||||
variant: "Struct",
|
||||
len: 3,
|
||||
},
|
||||
@@ -236,7 +288,7 @@ fn test_default_enum() {
|
||||
);
|
||||
|
||||
assert_de_tokens(
|
||||
&DefaultEnum::Struct {
|
||||
&DefaultStructVariant::Struct {
|
||||
a1: 1,
|
||||
a2: 0,
|
||||
a3: 123,
|
||||
@@ -245,7 +297,7 @@ fn test_default_enum() {
|
||||
},
|
||||
&[
|
||||
Token::StructVariant {
|
||||
name: "DefaultEnum",
|
||||
name: "DefaultStructVariant",
|
||||
variant: "Struct",
|
||||
len: 3,
|
||||
},
|
||||
@@ -256,6 +308,37 @@ fn test_default_enum() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_tuple_variant() {
|
||||
assert_de_tokens(
|
||||
&DefaultTupleVariant::Tuple(1, 2, 3),
|
||||
&[
|
||||
Token::TupleVariant {
|
||||
name: "DefaultTupleVariant",
|
||||
variant: "Tuple",
|
||||
len: 3,
|
||||
},
|
||||
Token::I32(1),
|
||||
Token::I32(2),
|
||||
Token::I32(3),
|
||||
Token::TupleVariantEnd,
|
||||
],
|
||||
);
|
||||
|
||||
assert_de_tokens(
|
||||
&DefaultTupleVariant::Tuple(1, 0, 123),
|
||||
&[
|
||||
Token::TupleVariant {
|
||||
name: "DefaultTupleVariant",
|
||||
variant: "Tuple",
|
||||
len: 3,
|
||||
},
|
||||
Token::I32(1),
|
||||
Token::TupleVariantEnd,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
// Does not implement std::default::Default.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
struct NoStdDefault(i8);
|
||||
@@ -441,6 +524,16 @@ struct RenameStructSerializeDeserialize {
|
||||
a2: i32,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
struct AliasStruct {
|
||||
a1: i32,
|
||||
#[serde(alias = "a3")]
|
||||
a2: i32,
|
||||
#[serde(alias = "a5", rename = "a6")]
|
||||
a4: i32,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rename_struct() {
|
||||
assert_tokens(
|
||||
@@ -487,6 +580,67 @@ fn test_rename_struct() {
|
||||
Token::StructEnd,
|
||||
],
|
||||
);
|
||||
|
||||
assert_de_tokens(
|
||||
&AliasStruct {
|
||||
a1: 1,
|
||||
a2: 2,
|
||||
a4: 3,
|
||||
},
|
||||
&[
|
||||
Token::Struct {
|
||||
name: "AliasStruct",
|
||||
len: 3,
|
||||
},
|
||||
Token::Str("a1"),
|
||||
Token::I32(1),
|
||||
Token::Str("a2"),
|
||||
Token::I32(2),
|
||||
Token::Str("a5"),
|
||||
Token::I32(3),
|
||||
Token::StructEnd,
|
||||
],
|
||||
);
|
||||
|
||||
assert_de_tokens(
|
||||
&AliasStruct {
|
||||
a1: 1,
|
||||
a2: 2,
|
||||
a4: 3,
|
||||
},
|
||||
&[
|
||||
Token::Struct {
|
||||
name: "AliasStruct",
|
||||
len: 3,
|
||||
},
|
||||
Token::Str("a1"),
|
||||
Token::I32(1),
|
||||
Token::Str("a3"),
|
||||
Token::I32(2),
|
||||
Token::Str("a6"),
|
||||
Token::I32(3),
|
||||
Token::StructEnd,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unknown_field_rename_struct() {
|
||||
assert_de_tokens_error::<AliasStruct>(
|
||||
&[
|
||||
Token::Struct {
|
||||
name: "AliasStruct",
|
||||
len: 3,
|
||||
},
|
||||
Token::Str("a1"),
|
||||
Token::I32(1),
|
||||
Token::Str("a3"),
|
||||
Token::I32(2),
|
||||
Token::Str("a4"),
|
||||
Token::I32(3),
|
||||
],
|
||||
"unknown field `a4`, expected one of `a1`, `a2`, `a6`",
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||
@@ -517,6 +671,19 @@ enum RenameEnumSerializeDeserialize<A> {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
enum AliasEnum {
|
||||
#[serde(rename = "sailor_moon", alias = "usagi_tsukino")]
|
||||
SailorMoon {
|
||||
a: i8,
|
||||
#[serde(alias = "c")]
|
||||
b: i8,
|
||||
#[serde(alias = "e", rename = "f")]
|
||||
d: i8,
|
||||
},
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rename_enum() {
|
||||
assert_tokens(
|
||||
@@ -603,6 +770,71 @@ fn test_rename_enum() {
|
||||
Token::StructVariantEnd,
|
||||
],
|
||||
);
|
||||
|
||||
assert_de_tokens(
|
||||
&AliasEnum::SailorMoon { a: 0, b: 1, d: 2 },
|
||||
&[
|
||||
Token::StructVariant {
|
||||
name: "AliasEnum",
|
||||
variant: "sailor_moon",
|
||||
len: 3,
|
||||
},
|
||||
Token::Str("a"),
|
||||
Token::I8(0),
|
||||
Token::Str("b"),
|
||||
Token::I8(1),
|
||||
Token::Str("e"),
|
||||
Token::I8(2),
|
||||
Token::StructVariantEnd,
|
||||
],
|
||||
);
|
||||
|
||||
assert_de_tokens(
|
||||
&AliasEnum::SailorMoon { a: 0, b: 1, d: 2 },
|
||||
&[
|
||||
Token::StructVariant {
|
||||
name: "AliasEnum",
|
||||
variant: "usagi_tsukino",
|
||||
len: 3,
|
||||
},
|
||||
Token::Str("a"),
|
||||
Token::I8(0),
|
||||
Token::Str("c"),
|
||||
Token::I8(1),
|
||||
Token::Str("f"),
|
||||
Token::I8(2),
|
||||
Token::StructVariantEnd,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unknown_field_rename_enum() {
|
||||
assert_de_tokens_error::<AliasEnum>(
|
||||
&[Token::StructVariant {
|
||||
name: "AliasEnum",
|
||||
variant: "SailorMoon",
|
||||
len: 3,
|
||||
}],
|
||||
"unknown variant `SailorMoon`, expected `sailor_moon`",
|
||||
);
|
||||
|
||||
assert_de_tokens_error::<AliasEnum>(
|
||||
&[
|
||||
Token::StructVariant {
|
||||
name: "AliasEnum",
|
||||
variant: "usagi_tsukino",
|
||||
len: 3,
|
||||
},
|
||||
Token::Str("a"),
|
||||
Token::I8(0),
|
||||
Token::Str("c"),
|
||||
Token::I8(1),
|
||||
Token::Str("d"),
|
||||
Token::I8(2),
|
||||
],
|
||||
"unknown field `d`, expected one of `a`, `b`, `f`",
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize)]
|
||||
@@ -1364,14 +1596,35 @@ impl From<Option<u32>> for EnumToU32 {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq, Debug)]
|
||||
#[serde(try_from = "u32")]
|
||||
enum TryFromU32 {
|
||||
One,
|
||||
Two,
|
||||
}
|
||||
|
||||
impl TryFrom<u32> for TryFromU32 {
|
||||
type Error = String;
|
||||
|
||||
fn try_from(value: u32) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
1 => Ok(TryFromU32::One),
|
||||
2 => Ok(TryFromU32::Two),
|
||||
_ => Err("out of range".to_owned()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_into_traits() {
|
||||
assert_ser_tokens::<EnumToU32>(&EnumToU32::One, &[Token::Some, Token::U32(1)]);
|
||||
assert_ser_tokens::<EnumToU32>(&EnumToU32::Nothing, &[Token::None]);
|
||||
assert_de_tokens::<EnumToU32>(&EnumToU32::Two, &[Token::Some, Token::U32(2)]);
|
||||
assert_ser_tokens::<StructFromEnum>(&StructFromEnum(Some(5)), &[Token::None]);
|
||||
assert_ser_tokens::<StructFromEnum>(&StructFromEnum(None), &[Token::None]);
|
||||
assert_de_tokens::<StructFromEnum>(&StructFromEnum(Some(2)), &[Token::Some, Token::U32(2)]);
|
||||
assert_ser_tokens(&EnumToU32::One, &[Token::Some, Token::U32(1)]);
|
||||
assert_ser_tokens(&EnumToU32::Nothing, &[Token::None]);
|
||||
assert_de_tokens(&EnumToU32::Two, &[Token::Some, Token::U32(2)]);
|
||||
assert_ser_tokens(&StructFromEnum(Some(5)), &[Token::None]);
|
||||
assert_ser_tokens(&StructFromEnum(None), &[Token::None]);
|
||||
assert_de_tokens(&StructFromEnum(Some(2)), &[Token::Some, Token::U32(2)]);
|
||||
assert_de_tokens(&TryFromU32::Two, &[Token::U32(2)]);
|
||||
assert_de_tokens_error::<TryFromU32>(&[Token::U32(5)], "out of range");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1721,6 +1974,29 @@ fn test_flatten_map_twice() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_flatten_unit() {
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||
struct Response<T> {
|
||||
#[serde(flatten)]
|
||||
data: T,
|
||||
status: usize,
|
||||
}
|
||||
|
||||
assert_tokens(
|
||||
&Response {
|
||||
data: (),
|
||||
status: 0,
|
||||
},
|
||||
&[
|
||||
Token::Map { len: None },
|
||||
Token::Str("status"),
|
||||
Token::U64(0),
|
||||
Token::MapEnd,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_flatten_unsupported_type() {
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||
@@ -2364,3 +2640,171 @@ fn test_flatten_any_after_flatten_struct() {
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_expecting_message() {
|
||||
#[derive(Deserialize, PartialEq, Debug)]
|
||||
#[serde(expecting = "something strange...")]
|
||||
struct Unit;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(expecting = "something strange...")]
|
||||
struct Newtype(bool);
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(expecting = "something strange...")]
|
||||
struct Tuple(u32, bool);
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(expecting = "something strange...")]
|
||||
struct Struct {
|
||||
question: String,
|
||||
answer: u32,
|
||||
}
|
||||
|
||||
assert_de_tokens_error::<Unit>(
|
||||
&[Token::Str("Unit")],
|
||||
r#"invalid type: string "Unit", expected something strange..."#,
|
||||
);
|
||||
|
||||
assert_de_tokens_error::<Newtype>(
|
||||
&[Token::Str("Newtype")],
|
||||
r#"invalid type: string "Newtype", expected something strange..."#,
|
||||
);
|
||||
|
||||
assert_de_tokens_error::<Tuple>(
|
||||
&[Token::Str("Tuple")],
|
||||
r#"invalid type: string "Tuple", expected something strange..."#,
|
||||
);
|
||||
|
||||
assert_de_tokens_error::<Struct>(
|
||||
&[Token::Str("Struct")],
|
||||
r#"invalid type: string "Struct", expected something strange..."#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_expecting_message_externally_tagged_enum() {
|
||||
#[derive(Deserialize)]
|
||||
#[serde(expecting = "something strange...")]
|
||||
enum Enum {
|
||||
ExternallyTagged,
|
||||
}
|
||||
|
||||
assert_de_tokens_error::<Enum>(
|
||||
&[Token::Str("ExternallyTagged")],
|
||||
r#"invalid type: string "ExternallyTagged", expected something strange..."#,
|
||||
);
|
||||
|
||||
// Check that #[serde(expecting = "...")] doesn't affect variant identifier error message
|
||||
assert_de_tokens_error::<Enum>(
|
||||
&[Token::Enum { name: "Enum" }, Token::Unit],
|
||||
r#"invalid type: unit value, expected variant identifier"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_expecting_message_internally_tagged_enum() {
|
||||
#[derive(Deserialize)]
|
||||
#[serde(tag = "tag")]
|
||||
#[serde(expecting = "something strange...")]
|
||||
enum Enum {
|
||||
InternallyTagged,
|
||||
}
|
||||
|
||||
assert_de_tokens_error::<Enum>(
|
||||
&[Token::Str("InternallyTagged")],
|
||||
r#"invalid type: string "InternallyTagged", expected something strange..."#,
|
||||
);
|
||||
|
||||
// Check that #[serde(expecting = "...")] doesn't affect variant identifier error message
|
||||
assert_de_tokens_error::<Enum>(
|
||||
&[Token::Map { len: None }, Token::Str("tag"), Token::Unit],
|
||||
r#"invalid type: unit value, expected variant identifier"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_expecting_message_adjacently_tagged_enum() {
|
||||
#[derive(Deserialize)]
|
||||
#[serde(tag = "tag", content = "content")]
|
||||
#[serde(expecting = "something strange...")]
|
||||
enum Enum {
|
||||
AdjacentlyTagged,
|
||||
}
|
||||
|
||||
assert_de_tokens_error::<Enum>(
|
||||
&[Token::Str("AdjacentlyTagged")],
|
||||
r#"invalid type: string "AdjacentlyTagged", expected something strange..."#,
|
||||
);
|
||||
|
||||
assert_de_tokens_error::<Enum>(
|
||||
&[Token::Map { len: None }, Token::Unit],
|
||||
r#"invalid type: unit value, expected "tag", "content", or other ignored fields"#,
|
||||
);
|
||||
|
||||
// Check that #[serde(expecting = "...")] doesn't affect variant identifier error message
|
||||
assert_de_tokens_error::<Enum>(
|
||||
&[Token::Map { len: None }, Token::Str("tag"), Token::Unit],
|
||||
r#"invalid type: unit value, expected variant identifier"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_expecting_message_untagged_tagged_enum() {
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged)]
|
||||
#[serde(expecting = "something strange...")]
|
||||
enum Enum {
|
||||
Untagged,
|
||||
}
|
||||
|
||||
assert_de_tokens_error::<Enum>(&[Token::Str("Untagged")], r#"something strange..."#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_expecting_message_identifier_enum() {
|
||||
#[derive(Deserialize)]
|
||||
#[serde(field_identifier)]
|
||||
#[serde(expecting = "something strange...")]
|
||||
enum FieldEnum {
|
||||
Field,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(variant_identifier)]
|
||||
#[serde(expecting = "something strange...")]
|
||||
enum VariantEnum {
|
||||
Variant,
|
||||
}
|
||||
|
||||
assert_de_tokens_error::<FieldEnum>(
|
||||
&[Token::Unit],
|
||||
r#"invalid type: unit value, expected something strange..."#,
|
||||
);
|
||||
|
||||
assert_de_tokens_error::<FieldEnum>(
|
||||
&[
|
||||
Token::Enum { name: "FieldEnum" },
|
||||
Token::Str("Unknown"),
|
||||
Token::None,
|
||||
],
|
||||
r#"invalid type: map, expected something strange..."#,
|
||||
);
|
||||
|
||||
assert_de_tokens_error::<VariantEnum>(
|
||||
&[Token::Unit],
|
||||
r#"invalid type: unit value, expected something strange..."#,
|
||||
);
|
||||
|
||||
assert_de_tokens_error::<VariantEnum>(
|
||||
&[
|
||||
Token::Enum {
|
||||
name: "VariantEnum",
|
||||
},
|
||||
Token::Str("Unknown"),
|
||||
Token::None,
|
||||
],
|
||||
r#"invalid type: map, expected something strange..."#,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
#![allow(clippy::items_after_statements, clippy::used_underscore_binding)]
|
||||
|
||||
extern crate serde;
|
||||
use serde::{Deserialize, Deserializer};
|
||||
|
||||
extern crate serde_test;
|
||||
use serde_test::{assert_de_tokens, assert_de_tokens_error, Token};
|
||||
|
||||
use std::borrow::Cow;
|
||||
@@ -96,6 +92,30 @@ fn test_struct() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_field_identifier() {
|
||||
#[derive(Deserialize, Debug, PartialEq)]
|
||||
#[serde(field_identifier)]
|
||||
enum FieldStr<'a> {
|
||||
#[serde(borrow)]
|
||||
Str(&'a str),
|
||||
}
|
||||
|
||||
assert_de_tokens(&FieldStr::Str("value"), &[Token::BorrowedStr("value")]);
|
||||
|
||||
#[derive(Deserialize, Debug, PartialEq)]
|
||||
#[serde(field_identifier)]
|
||||
enum FieldBytes<'a> {
|
||||
#[serde(borrow)]
|
||||
Bytes(&'a [u8]),
|
||||
}
|
||||
|
||||
assert_de_tokens(
|
||||
&FieldBytes::Bytes(b"value"),
|
||||
&[Token::BorrowedBytes(b"value")],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cow() {
|
||||
#[derive(Deserialize)]
|
||||
|
||||
+1881
-935
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -3,14 +3,22 @@
|
||||
// types involved.
|
||||
|
||||
#![deny(warnings)]
|
||||
#![cfg_attr(feature = "unstable", feature(non_ascii_idents))]
|
||||
#![allow(
|
||||
unknown_lints,
|
||||
mixed_script_confusables,
|
||||
clippy::items_after_statements,
|
||||
clippy::missing_errors_doc,
|
||||
clippy::missing_panics_doc,
|
||||
clippy::must_use_candidate,
|
||||
// Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7422
|
||||
clippy::nonstandard_macro_braces,
|
||||
clippy::ptr_arg,
|
||||
clippy::too_many_lines,
|
||||
clippy::trivially_copy_pass_by_ref
|
||||
)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
extern crate serde;
|
||||
use self::serde::de::{DeserializeOwned, Deserializer};
|
||||
use self::serde::ser::{Serialize, Serializer};
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::marker::PhantomData;
|
||||
@@ -265,7 +273,6 @@ fn test_gen() {
|
||||
}
|
||||
assert::<EmptyEnumVariant>();
|
||||
|
||||
#[cfg(feature = "unstable")]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct NonAsciiIdents {
|
||||
σ: f64,
|
||||
@@ -384,6 +391,8 @@ fn test_gen() {
|
||||
}
|
||||
|
||||
mod vis {
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub struct S;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
@@ -523,6 +532,13 @@ fn test_gen() {
|
||||
}
|
||||
assert::<FlattenWith>();
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
struct FlattenDenyUnknown<T> {
|
||||
#[serde(flatten)]
|
||||
t: T,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct StaticStrStruct<'a> {
|
||||
a: &'a str,
|
||||
@@ -607,6 +623,8 @@ fn test_gen() {
|
||||
|
||||
mod restricted {
|
||||
mod inner {
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct Restricted {
|
||||
pub(super) a: usize,
|
||||
@@ -630,7 +648,7 @@ fn test_gen() {
|
||||
assert::<SkippedVariant<X>>();
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct ImpliciltyBorrowedOption<'a> {
|
||||
struct ImplicitlyBorrowedOption<'a> {
|
||||
option: std::option::Option<&'a str>,
|
||||
}
|
||||
|
||||
@@ -664,6 +682,71 @@ fn test_gen() {
|
||||
ty: &'a str,
|
||||
id: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct FlattenSkipSerializing<T> {
|
||||
#[serde(flatten, skip_serializing)]
|
||||
#[allow(dead_code)]
|
||||
flat: T,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct FlattenSkipSerializingIf<T> {
|
||||
#[serde(flatten, skip_serializing_if = "StdOption::is_none")]
|
||||
flat: StdOption<T>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct FlattenSkipDeserializing<T> {
|
||||
#[serde(flatten, skip_deserializing)]
|
||||
flat: T,
|
||||
}
|
||||
|
||||
// https://github.com/serde-rs/serde/issues/1804
|
||||
#[derive(Serialize, Deserialize)]
|
||||
enum Message {
|
||||
#[serde(skip)]
|
||||
#[allow(dead_code)]
|
||||
String(String),
|
||||
#[serde(other)]
|
||||
Unknown,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[repr(packed)]
|
||||
struct Packed {
|
||||
x: u8,
|
||||
y: u16,
|
||||
}
|
||||
|
||||
macro_rules! deriving {
|
||||
($field:ty) => {
|
||||
#[derive(Deserialize)]
|
||||
struct MacroRules<'a> {
|
||||
field: $field,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
deriving!(&'a str);
|
||||
|
||||
macro_rules! mac {
|
||||
($($tt:tt)*) => {
|
||||
$($tt)*
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct BorrowLifetimeInsideMacro<'a> {
|
||||
#[serde(borrow = "'a")]
|
||||
f: mac!(Cow<'a, str>),
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Struct {
|
||||
#[serde(serialize_with = "vec_first_element")]
|
||||
vec: Vec<Self>,
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -737,3 +820,72 @@ where
|
||||
pub fn is_zero(n: &u8) -> bool {
|
||||
*n == 0
|
||||
}
|
||||
|
||||
fn vec_first_element<T, S>(vec: &Vec<T>, serializer: S) -> StdResult<S::Ok, S::Error>
|
||||
where
|
||||
T: Serialize,
|
||||
S: Serializer,
|
||||
{
|
||||
vec.first().serialize(serializer)
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[serde(tag = "tag")]
|
||||
enum InternallyTagged {
|
||||
#[serde(deserialize_with = "deserialize_generic")]
|
||||
Unit,
|
||||
|
||||
#[serde(deserialize_with = "deserialize_generic")]
|
||||
Newtype(i32),
|
||||
|
||||
#[serde(deserialize_with = "deserialize_generic")]
|
||||
Struct { f1: String, f2: u8 },
|
||||
}
|
||||
|
||||
fn deserialize_generic<'de, T, D>(deserializer: D) -> StdResult<T, D::Error>
|
||||
where
|
||||
T: Deserialize<'de>,
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
T::deserialize(deserializer)
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[repr(packed)]
|
||||
pub struct RemotePacked {
|
||||
pub a: u16,
|
||||
pub b: u32,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[repr(packed)]
|
||||
#[serde(remote = "RemotePacked")]
|
||||
pub struct RemotePackedDef {
|
||||
a: u16,
|
||||
b: u32,
|
||||
}
|
||||
|
||||
impl Drop for RemotePackedDef {
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
#[repr(packed)]
|
||||
pub struct RemotePackedNonCopy {
|
||||
pub a: u16,
|
||||
pub b: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[repr(packed)]
|
||||
#[serde(remote = "RemotePackedNonCopy")]
|
||||
pub struct RemotePackedNonCopyDef {
|
||||
a: u16,
|
||||
b: String,
|
||||
}
|
||||
|
||||
impl Drop for RemotePackedNonCopyDef {
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
extern crate serde_test;
|
||||
//! Tests for `#[serde(field_identifier)]` and `#[serde(variant_identifier)]`
|
||||
use serde::Deserialize;
|
||||
use serde_test::{assert_de_tokens, Token};
|
||||
|
||||
#[test]
|
||||
@@ -30,6 +28,10 @@ fn test_field_identifier() {
|
||||
Bbb,
|
||||
}
|
||||
|
||||
assert_de_tokens(&F::Aaa, &[Token::U8(0)]);
|
||||
assert_de_tokens(&F::Aaa, &[Token::U16(0)]);
|
||||
assert_de_tokens(&F::Aaa, &[Token::U32(0)]);
|
||||
assert_de_tokens(&F::Aaa, &[Token::U64(0)]);
|
||||
assert_de_tokens(&F::Aaa, &[Token::Str("aaa")]);
|
||||
assert_de_tokens(&F::Aaa, &[Token::Bytes(b"aaa")]);
|
||||
}
|
||||
@@ -45,6 +47,10 @@ fn test_unit_fallthrough() {
|
||||
Other,
|
||||
}
|
||||
|
||||
assert_de_tokens(&F::Other, &[Token::U8(42)]);
|
||||
assert_de_tokens(&F::Other, &[Token::U16(42)]);
|
||||
assert_de_tokens(&F::Other, &[Token::U32(42)]);
|
||||
assert_de_tokens(&F::Other, &[Token::U64(42)]);
|
||||
assert_de_tokens(&F::Other, &[Token::Str("x")]);
|
||||
}
|
||||
|
||||
@@ -71,5 +77,9 @@ fn test_newtype_fallthrough_generic() {
|
||||
Other(T),
|
||||
}
|
||||
|
||||
assert_de_tokens(&F::Other(42u8), &[Token::U8(42)]);
|
||||
assert_de_tokens(&F::Other(42u16), &[Token::U16(42)]);
|
||||
assert_de_tokens(&F::Other(42u32), &[Token::U32(42)]);
|
||||
assert_de_tokens(&F::Other(42u64), &[Token::U64(42)]);
|
||||
assert_de_tokens(&F::Other("x".to_owned()), &[Token::Str("x")]);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
use serde::de::value::{Error, MapDeserializer, SeqDeserializer};
|
||||
use serde::de::{
|
||||
DeserializeSeed, EnumAccess, IgnoredAny, IntoDeserializer, VariantAccess, Visitor,
|
||||
};
|
||||
use serde::{forward_to_deserialize_any, Deserialize, Deserializer};
|
||||
|
||||
#[derive(PartialEq, Debug, Deserialize)]
|
||||
enum Target {
|
||||
Unit,
|
||||
Newtype(i32),
|
||||
Tuple(i32, i32),
|
||||
Struct { a: i32 },
|
||||
}
|
||||
|
||||
struct Enum(&'static str);
|
||||
|
||||
impl<'de> Deserializer<'de> for Enum {
|
||||
type Error = Error;
|
||||
|
||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
visitor.visit_enum(self)
|
||||
}
|
||||
|
||||
forward_to_deserialize_any! {
|
||||
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
|
||||
bytes byte_buf option unit unit_struct newtype_struct seq tuple
|
||||
tuple_struct map struct enum identifier ignored_any
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> EnumAccess<'de> for Enum {
|
||||
type Error = Error;
|
||||
type Variant = Self;
|
||||
|
||||
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
|
||||
where
|
||||
V: DeserializeSeed<'de>,
|
||||
{
|
||||
let v = seed.deserialize(self.0.into_deserializer())?;
|
||||
Ok((v, self))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> VariantAccess<'de> for Enum {
|
||||
type Error = Error;
|
||||
|
||||
fn unit_variant(self) -> Result<(), Self::Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
|
||||
where
|
||||
T: DeserializeSeed<'de>,
|
||||
{
|
||||
seed.deserialize(10i32.into_deserializer())
|
||||
}
|
||||
|
||||
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
let seq = SeqDeserializer::new(vec![1i32, 2].into_iter());
|
||||
visitor.visit_seq(seq)
|
||||
}
|
||||
|
||||
fn struct_variant<V>(
|
||||
self,
|
||||
_fields: &'static [&'static str],
|
||||
visitor: V,
|
||||
) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
let map = MapDeserializer::new(vec![("a", 10i32)].into_iter());
|
||||
visitor.visit_map(map)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_deserialize_enum() {
|
||||
// First just make sure the Deserializer impl works
|
||||
assert_eq!(Target::Unit, Target::deserialize(Enum("Unit")).unwrap());
|
||||
assert_eq!(
|
||||
Target::Newtype(10),
|
||||
Target::deserialize(Enum("Newtype")).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
Target::Tuple(1, 2),
|
||||
Target::deserialize(Enum("Tuple")).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
Target::Struct { a: 10 },
|
||||
Target::deserialize(Enum("Struct")).unwrap()
|
||||
);
|
||||
|
||||
// Now try IgnoredAny
|
||||
IgnoredAny::deserialize(Enum("Unit")).unwrap();
|
||||
IgnoredAny::deserialize(Enum("Newtype")).unwrap();
|
||||
IgnoredAny::deserialize(Enum("Tuple")).unwrap();
|
||||
IgnoredAny::deserialize(Enum("Struct")).unwrap();
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user