Compare commits

...

194 Commits

Author SHA1 Message Date
Erick Tryzelaar ac758ed3c8 Version bump 2015-07-16 11:28:18 -04:00
Erick Tryzelaar 236d40d73e Add Serializer hooks for sequence elements 2015-07-16 10:51:01 -04:00
Erick Tryzelaar 92029a05c6 Add Deserializer type hints
This allows file formats like bincode, which do not encode it's values
with a type tag, to deserialize values.
2015-07-16 10:50:54 -04:00
Erick Tryzelaar c7b9997dd1 Add all of the stdlib collection deserialization implementations 2015-07-16 10:42:34 -04:00
Erick Tryzelaar 48309bfdd0 Add all of the stdlib collection serialization implementations 2015-07-16 10:00:22 -04:00
Erick Tryzelaar f76d1ab10d Compile serde_macros tests with the nightly features 2015-07-16 10:00:22 -04:00
Erick Tryzelaar 45f552f006 Fix feature flag use for NonZero 2015-07-16 10:00:21 -04:00
Erick Tryzelaar 4d42cfea53 Fix warnings 2015-07-16 09:36:14 -04:00
Erick Tryzelaar 7109e2d379 Fix the tests 2015-07-16 09:35:09 -04:00
Erick Tryzelaar ff214643ce Merge remote-tracking branch 'remotes/origin/master' into nonzero
# Conflicts:
#	serde/src/de/impls.rs
2015-07-16 09:34:45 -04:00
Erick Tryzelaar 04918a52eb Merge pull request #105 from jnicholls/boolvisitor
Make BoolVisitor public so it is documented as being in existence
2015-07-16 07:41:49 -04:00
Erick Tryzelaar 5dd71600f7 Merge pull request #102 from pcwalton/result
Implement serialization for `Result`.
2015-07-16 07:29:28 -04:00
Patrick Walton ea9ed22e3e Implement serialization for NonZero values in nightly. 2015-07-14 12:00:46 -07:00
Jarred Nicholls 1611daf802 Make BoolVisitor public so it is documented as being in existence 2015-07-13 12:13:00 -04:00
Patrick Walton e24f52d3ae Implement serialization for Result.
Servo wants this.
2015-07-10 15:08:59 -07:00
Erick Tryzelaar bcc9e15b05 Merge pull request #94 from cmbrandenburg/master
Fix spelling in README.md
2015-07-01 10:38:13 -07:00
Craig M. Brandenburg af835a2699 Fix spelling in README.md 2015-06-29 07:18:48 -07:00
Erick Tryzelaar 5f2d306f9b Merge pull request #92 from SkylerLipthay/cow-impls
Add impls for Cow
2015-06-21 10:07:00 -07:00
Skyler Lipthay 36fb49b522 Add impls for Cow 2015-06-19 22:50:16 -07:00
Erick Tryzelaar ed5b4d7319 Fix serializing generic enums
This fixes generic enums with variants that don't use all lifetime
and typarams. Closes #88.
2015-06-18 08:45:03 -07:00
Erick Tryzelaar b09c0fc653 Fix an indent typo 2015-06-18 07:49:13 -07:00
Erick Tryzelaar ab3e40ca45 Version bump 2015-06-08 07:12:27 -07:00
Erick Tryzelaar 8f67e9c048 Switch exponent bounds checking back to using powi 2015-06-08 07:07:09 -07:00
Erick Tryzelaar 7dc1a64f03 Merge pull request #80 from ProtectedMode/master
Fix #77, integer overflow when parsing JSON scientific notation number.
2015-06-08 06:57:33 -07:00
Erick Tryzelaar ac3a3e922f Fix compilation with rust nightly (613e57b44) and syntex 0.7.0 2015-06-08 06:55:36 -07:00
Erick Tryzelaar 4e50c56542 Merge pull request #87 from Manishearth/patch-1
Use correct attribute syntax
2015-06-07 20:46:44 -07:00
Manish Goregaokar 26b1ed79c0 !!!!!! 2015-06-06 18:08:33 +05:30
ProtectedMode 2e8ef0f768 Add test for #77, integer overflow when parsing JSON scientific notation number. 2015-05-21 09:59:14 +02:00
Erick Tryzelaar c993414b92 serde_tests tests doesn't need the test crate 2015-05-20 22:57:19 -07:00
Erick Tryzelaar ed6ef4e149 Travis work 2015-05-20 22:44:50 -07:00
Erick Tryzelaar 859cdcc815 Remove unnecessary lifetime 2015-05-20 09:02:38 -07:00
ProtectedMode 745a95b607 Fix #77, integer overflow when parsing JSON scientific notation number. 2015-05-20 16:32:10 +02:00
Erick Tryzelaar 81d617bd93 The README is in a different location 2015-05-18 23:36:46 -07:00
Erick Tryzelaar 3396388222 Remove redundant import 2015-05-18 23:34:17 -07:00
Erick Tryzelaar ff8c3b3d51 Initial support for syntex 2015-05-18 23:34:17 -07:00
Erick Tryzelaar 3d0efd123f Minor cleanup 2015-05-18 22:49:50 -07:00
Erick Tryzelaar 8ca1b9ac3c default_value doesn't need to be public 2015-05-18 22:49:49 -07:00
Erick Tryzelaar 2c24be90d2 Switch to using MultiDecorator 2015-05-18 22:49:49 -07:00
Erick Tryzelaar 482f92af61 Add a single driver for tests and benchmarks 2015-05-18 22:47:36 -07:00
Erick Tryzelaar 24ac61f9f2 Pull codegen into it's own crate 2015-05-18 22:47:35 -07:00
Erick Tryzelaar 426394cd7b Version bump 2015-05-18 22:47:35 -07:00
Erick Tryzelaar 7c3e95a7c7 Ignore all target and Cargo.lock files 2015-05-18 22:47:35 -07:00
Erick Tryzelaar 9dd5f9dc7a Restructure directories to prep for syntex 2015-05-18 22:47:35 -07:00
Erick Tryzelaar e6776ffc37 Protect against json integer overflow
Closes #75
2015-05-18 22:40:29 -07:00
Erick Tryzelaar adae2bd3c5 Merge pull request #72 from borman/bytestrings
Improved support for byte strings
2015-05-18 22:28:37 -07:00
Erick Tryzelaar 14ca260c26 Merge pull request #70 from oli-obk/xml_requirements
changes needed for xml parsing
2015-05-18 22:25:15 -07:00
Erick Tryzelaar 64588f0cb6 Merge pull request #74 from tomprogrammer/array
Add serialization/deserialization for fixed size arrays
2015-05-18 22:21:59 -07:00
Erick Tryzelaar 50cac7f985 Rewrite Value::lookup to not require an allocation 2015-05-18 22:19:30 -07:00
Erick Tryzelaar 5fe85128c2 Merge pull request #76 from blaenk/json-lookup
implement lookup method for json::Value
2015-05-18 21:50:55 -07:00
Jorge Israel Peña bc236bde34 implement lookup method for json::Value 2015-05-17 21:24:00 -07:00
Thomas Bahn 15794a5ed6 Improve build time 2015-05-16 14:36:28 +02:00
Thomas Bahn 62058962de Add deserialiation implementations for fixed size arrays 2015-05-16 14:19:22 +02:00
Thomas Bahn 7d52366403 Add serialization implementations for fixed size arrays 2015-05-16 14:18:32 +02:00
Erick Tryzelaar ee45eb8340 Merge pull request #69 from hugoduncan/feature/format-specific-field-names
Adds serializer format specific field names
2015-05-14 21:59:05 -07:00
Hugo Duncan 801f37b305 Fix visitors for generic structs 2015-05-14 17:35:21 -04:00
Hugo Duncan bdec0b3e63 Update commas and blocks in match arms 2015-05-14 17:35:16 -04:00
Mikhail Borisov 5c631f3e58 WIP 2015-05-12 15:16:06 +03:00
Mikhail Borisov 5fd9daa865 WIP 2015-05-12 15:03:26 +03:00
Oliver Schneider 0485702a68 update benchmarks 2015-05-11 10:34:58 +02:00
Mikhail Borisov 875610044f Improved support for byte strings 2015-05-09 03:18:13 +03:00
Hugo Duncan ec483fc07d Add doc string for format method 2015-05-08 12:43:12 -04:00
Hugo Duncan 53e6e29571 Fix whitespace 2015-05-08 12:43:12 -04:00
Hugo Duncan c5eed99c6a Make forwarded trait name global 2015-05-08 12:43:12 -04:00
Hugo Duncan fe5176113b Add missing attr.rs file 2015-05-08 12:43:12 -04:00
Hugo Duncan 0f7c67efa7 Factor default attribute lookup into FieldAttrs 2015-05-08 12:43:12 -04:00
Hugo Duncan cd0ee64892 Add constructor functions for FieldAttrs 2015-05-08 12:43:12 -04:00
Hugo Duncan ec3af2cb6a Factor out attr module
Factors out field attribute code into the attr module.
2015-05-08 12:43:12 -04:00
Hugo Duncan 960b68937d Remove commented code and extra newline 2015-05-08 12:43:12 -04:00
Hugo Duncan a1e101b513 Make Value use the 'json' format string 2015-05-08 12:43:11 -04:00
Hugo Duncan c30311153c Rename fmt to format 2015-05-08 12:43:11 -04:00
Hugo Duncan a935ebe8b9 Adds serializer format specific field names
Allows different field names to be used for different external formats.

Field names are specified using the `rename` field attribute, e.g:

    #[serde(rename(xml= "a4", json="a5"))]

Reverts #62

Addresses #61
2015-05-08 12:43:11 -04:00
Oliver Schneider 83ee86122b address comments by erickt 2015-05-08 16:32:46 +02:00
Erick Tryzelaar af752ddcb5 Merge pull request #71 from lifthrasiir/json-split-branch
Replace a redundant `escape` variable with nested matches.
2015-05-07 10:51:57 -07:00
Kang Seonghoon 9550063275 Replace a redundant escape variable with nested matches.
This has a non-trivial performance effect due to the branch prediction,
but is expected to be no slower than the older code and, at least in
some cases, is slightly faster for a string-heavy JSON.
2015-05-08 01:53:24 +09:00
Oliver Schneider c117a680cf changes needed for xml parsing 2015-05-04 16:07:19 +02:00
Erick Tryzelaar 206e19edb4 Fix unquoting arms with latest quasi 2015-05-02 10:44:57 -07:00
Erick Tryzelaar f0c87fbd4c Format flats with Debug to properly print "-0.0". 2015-05-01 07:43:48 -07:00
Erick Tryzelaar c3fe6c9c67 Update the README to point at https://github.com/serde-rs 2015-04-26 18:37:18 -07:00
Erick Tryzelaar e5df4b6653 Simplify PrettyFormatter::new 2015-04-26 12:05:38 -07:00
Erick Tryzelaar 12cf2f0b0b Simplify the return types 2015-04-26 11:01:55 -07:00
Erick Tryzelaar 8d4de2b3db Rename Serializer::new_with_formatter to with_formatter 2015-04-26 10:29:28 -07:00
Erick Tryzelaar e509adcac5 Allow the pretty printer character to be changed
This unfortunately loses the simd-ish whitespace printer, but since
pretty printing shouldn't be on a hot path, this shouldn't really
matter.

Partially addresses #65.
2015-04-26 09:29:06 -07:00
Erick Tryzelaar eb9c860cb4 Rename iterator.rs to iter.rs and expose it. 2015-04-26 09:23:08 -07:00
Erick Tryzelaar cf38b8dae5 Add some docs to LineColIterator, expose the underlying iterator 2015-04-26 09:22:56 -07:00
Erick Tryzelaar 75af81234f LineColIterator doesn't need to be peekable. 2015-04-26 09:21:52 -07:00
Erick Tryzelaar 7cc319acca Bump version to 0.3.2. 2015-04-26 09:21:26 -07:00
Erick Tryzelaar 3b44792ff3 Merge pull request #64 from oli-obk/missing_renamed_field
missing field errors displayed original field name instead of renamed
2015-04-26 08:09:00 -07:00
Erick Tryzelaar 678bad241e Merge pull request #66 from daniellandau/fix/compilation
Fix compilation for latest nightly
2015-04-25 08:13:39 -07:00
Daniel Landau 5b1225cc87 Fix compilation for latest nightly 2015-04-24 22:35:56 +03:00
Oliver Schneider 1748831152 missing field errors displayed original field name instead of renamed
closes #63
2015-04-23 17:28:42 +02:00
Erick Tryzelaar ed1b476a22 Merge pull request #58 from oli-obk/separate_line_col
separate out the line/column counting from character iteration
2015-04-22 11:02:55 -07:00
Erick Tryzelaar 79c59ebae1 Merge pull request #62 from hugoduncan/add-ser-de-rename
Add serialize, deserialize specific rename
2015-04-22 11:01:38 -07:00
Hugo Duncan fd6462f8d1 Add serialize, deserialize specific rename
Adds the rename_serialize and rename_deserialize field attributes to
specify serialisation and deserialisation specific renames.
2015-04-21 17:58:18 -04:00
Oliver Schneider c37f67b0a1 separate out the line/column counting from character iteration 2015-04-16 16:31:56 +02:00
Erick Tryzelaar 195f7380b5 Merge pull request #56 from derhaskell/patch-1
fixes struct serialization example for rust 1.0.0-beta
2015-04-13 06:21:37 -07:00
derhaskell becb8c48e8 fixes typo in deserialization example 2015-04-13 13:37:06 +02:00
derhaskell aa16ecf4d3 Update README.md 2015-04-13 13:28:47 +02:00
derhaskell ddda360fec Update README.md
fixes struct serialization example for rust 1.0.0-beta
2015-04-13 13:27:15 +02:00
Erick Tryzelaar cca72f2dbc Merge pull request #55 from sfackler/master
Add doc link to Cargo.toml and doc attr
2015-04-12 22:22:25 -07:00
Steven Fackler 5013b37c09 Add doc link to Cargo.toml and doc attr
The attribute allows cross-crate rustdoc links.
2015-04-12 22:21:00 -07:00
Erick Tryzelaar c90dc9f48f bump version to 0.3.1 2015-04-12 11:43:35 -07:00
Erick Tryzelaar 67e8ca354c Remove core feature 2015-04-12 11:36:09 -07:00
Erick Tryzelaar 9a4ba047c4 Remove collections feature flag and disable VecMap, which is unstable 2015-04-12 10:48:32 -07:00
Erick Tryzelaar 7622255d6f Remove the std_misc feature flag 2015-04-12 10:43:29 -07:00
Erick Tryzelaar 8ba1e7aceb Remove the need for the unicode feature flag 2015-04-12 10:42:57 -07:00
Erick Tryzelaar 5f6838130d Update to Rust HEAD 2015-04-12 10:32:54 -07:00
Erick Tryzelaar e0eff942b1 Add Error::unknown_field_error 2015-04-12 10:32:54 -07:00
Erick Tryzelaar 1da47c0870 Change de::VariantVisitor to let deserializers know the variant kind
This allows formats like cbor that encode a unit variant as just a
string to work.

[breaking-change]
2015-04-12 10:32:54 -07:00
Erick Tryzelaar d36879f5ee Merge pull request #54 from apoelstra/no-impl-bytebuf
Remove `impl Into<Vec<u8>> for ByteBuf` since it causes a compile error
2015-04-12 10:32:36 -07:00
Andrew Poelstra f363cb435a Remove impl Into<Vec<u8>> for ByteBuf since it causes a compile error
As BurntSushi observes, there is an `impl<T, U> Into<U> for T where U: From<T>`
in libcore. We have `From<Vec<u8>>` for `ByteBuf` since we have implemented
`From<T> for ByteBuf where T: Into<Vec<u8>>`, so this is redundant anyway.
2015-04-11 17:51:31 -05:00
Erick Tryzelaar d8506e9a6d Update to rust HEAD 2015-04-05 13:20:33 -04:00
Erick Tryzelaar 87503d11e9 Merge pull request #49 from alexcrichton/tweak-some-impls
Tweak some Deserialize/Serialize impls
2015-04-03 12:04:50 -04:00
Erick Tryzelaar d0b49d9b89 Finish updating to rust HEAD 2015-04-02 19:13:25 -07:00
Erick Tryzelaar b30965ede4 Get serde to build, but tests are still failing 2015-04-02 13:27:57 -07:00
Alex Crichton ace6d9e442 Generalize some serialization impls
* Impl Serialize for bare `str`
* Expand `&T` and `&mut T` blanket impls to include `T: ?Sized`
* Expand `Box<T>` blanket impl to include `T: ?Sized`
2015-04-02 12:54:21 -07:00
Alex Crichton e150553d58 Add deserialize impls for smart pointers
This allows deserializing into a Box/Arc/Rc pointer
2015-04-02 12:53:51 -07:00
Erick Tryzelaar ed569bd3f6 Update to latest rust nightly 2015-04-01 22:51:02 -07:00
Erick Tryzelaar d00c1ad6d0 Remove the use of serde_macros from the doctests
This has been disabled in the upcoming beta.
2015-04-01 22:19:14 -07:00
Erick Tryzelaar 2cd49060fa Rename #[serde(alias)] to #[serde(rename)] and add tests
Closes #9 and #47.
2015-04-01 22:14:28 -07:00
Erick Tryzelaar 54a970e694 Remove an unnecessary import 2015-04-01 22:13:34 -07:00
Erick Tryzelaar d57f02884f Work on the README, add a json example 2015-04-01 21:59:37 -07:00
Erick Tryzelaar dcf7037792 Add some basic docs 2015-03-31 22:33:18 -07:00
Erick Tryzelaar 55eb390778 Update the readme 2015-03-31 22:16:15 -07:00
Erick Tryzelaar 99b9524201 Change the name of ValueDeserializer::{,into_}deserializer 2015-03-31 20:45:59 -07:00
Erick Tryzelaar 45bd239202 Release 0.3.0 2015-03-31 13:01:17 -07:00
Erick Tryzelaar 54009e0991 Factor out value deserializers 2015-03-31 12:56:17 -07:00
Erick Tryzelaar bfe7a04c4d Update the location of json errors coming from "Deserialize" 2015-03-30 19:50:41 -07:00
Erick Tryzelaar 3167da72d8 Minor whitespace cleanup 2015-03-28 15:40:56 -07:00
Erick Tryzelaar 0d725a63b0 Add some serialization docs 2015-03-26 08:11:43 -07:00
Erick Tryzelaar ee0cd4aba9 Pull the serialization impls into their own file 2015-03-26 08:05:29 -07:00
Erick Tryzelaar 1b1c605102 Pull deserialization impls into their own file 2015-03-26 07:58:26 -07:00
Erick Tryzelaar 44edfa5974 Add {,de}serializer for VecMap 2015-03-26 07:45:22 -07:00
Erick Tryzelaar aa8d13456a Add bytes type to enable {,de}serializing to a byte array 2015-03-25 23:03:01 -07:00
Erick Tryzelaar 4beb86ab7e Update to rust HEAD 2015-03-25 10:43:25 -07:00
Erick Tryzelaar c369010d3d Allow json::de to work with io::Read 2015-03-24 08:55:20 -07:00
Erick Tryzelaar 1618faed63 Add deserialization impls for {BTree,Hash}{Map,Set} 2015-03-23 19:02:20 -07:00
Erick Tryzelaar 9059b734aa Merge pull request #46 from oli-obk/no_rustc_serialize_propagation
require rustc-serialize only in tests and benchmarks
2015-03-23 17:59:55 -07:00
Erick Tryzelaar 89f463111e Merge pull request #42 from Byron/master
fix(macros): fully qualified usage of `Result`
2015-03-23 09:59:55 -07:00
Sebastian Thiel 2962287703 fix(macros): fully qualified usage of Result
Otherwise it was possible for the expanded macro to pickup a
user-defined `Result` type, which didn't fulfill the required type
bounds and cause compilation failure.
2015-03-23 17:04:23 +01:00
Oliver 'ker' Schneider aa3c55fd98 require rustc-serialize only in tests and benchmarks 2015-03-22 14:16:58 +01:00
Erick Tryzelaar 17c295680e Remove an unused variable 2015-03-20 08:47:48 -07:00
Erick Tryzelaar 09de237033 Allow Vecs, BTreeMaps, and HashMaps to be deserialized from a unit
Closes #36
2015-03-20 08:47:33 -07:00
Erick Tryzelaar d17846eff1 Add deserializer type hinting hooks
Formats like xml have trouble knowing if they should deserialize
tags into a sequence from the stream they are deserializing from.
This PR adds hooks so the deserializee can inform the deserializer
to provide them a sequence if possible.

Closes #38.
2015-03-20 08:32:33 -07:00
Erick Tryzelaar 5378d22708 Switch to the new custom_deserialize syntax 2015-03-19 20:19:49 -07:00
Erick Tryzelaar c8b2ad01b5 Update to rust HEAD 2015-03-19 20:19:49 -07:00
Erick Tryzelaar e778c7e25c Update to rust HEAD 2015-03-19 20:19:48 -07:00
Erick Tryzelaar f0d0dd2982 Merge pull request #41 from hugoduncan/feature/mark-field-attributes-used
Mark serde field attributes as used
2015-03-19 20:08:50 -07:00
Hugo Duncan 3e63d34c00 Mark serde field attributes as used
Prevents unused attribute warnings in code that marks fields with
field level #[serde] attributes.
2015-03-19 11:04:08 -04:00
Erick Tryzelaar 8821421357 Docs, json::Value::U64, and bring many of the rust-serialize fns to Value 2015-03-18 20:51:48 -07:00
Erick Tryzelaar eb4af09456 Simplify the variant deserializer visitor 2015-03-18 07:35:05 -07:00
Erick Tryzelaar 78137ee3a4 Rewrite enum deserialization to not require allocations 2015-03-16 22:42:04 -07:00
Erick Tryzelaar b40d8f7bac Remove the first argument from visit_{seq,map}_elt 2015-03-16 22:30:02 -07:00
Erick Tryzelaar a6ba251ef9 Enable a missing field test 2015-03-16 21:23:20 -07:00
Erick Tryzelaar c6cc2340c8 Rename a variable 2015-03-16 21:11:30 -07:00
Erick Tryzelaar a212ef11a9 Fix compiling bench_struct 2015-03-16 21:10:16 -07:00
Erick Tryzelaar 7bd4c6963b Merge pull request #37 from oli-obk/fix_seq_map_end
MapVisitor::end and SeqVisitor::end were mostly never called
2015-03-16 20:54:35 -07:00
Oliver Schneider f21cbb71e2 MapVisitor::end and SeqVisitor::end were mostly never called 2015-03-16 13:27:00 +01:00
Erick Tryzelaar f4f8194f46 More cleanup 2015-03-15 18:38:52 -07:00
Erick Tryzelaar 90e02206fe Cleanup, and move default::Default #[derive_deserialize] support to get called when missing 2015-03-15 18:37:26 -07:00
Erick Tryzelaar 9fc9d1b33a Get rid of syntax::ext::generic from #[derive_deserialize] 2015-03-15 17:47:25 -07:00
Erick Tryzelaar b9f5d22630 Spring cleaning 2015-03-15 15:31:31 -07:00
Erick Tryzelaar cbafc83af4 Cleanup palooza 2015-03-15 15:14:57 -07:00
Erick Tryzelaar b628446768 Cleanup train 2015-03-15 15:04:11 -07:00
Erick Tryzelaar aacc14ad7b More cleanup 2015-03-15 14:50:00 -07:00
Erick Tryzelaar 35eb234c41 More aster driven cleanup 2015-03-15 14:31:05 -07:00
Erick Tryzelaar 989c8ff809 Include running the benchmarks in travis 2015-03-15 13:12:21 -07:00
Erick Tryzelaar 49c2585a20 Try to fix travis 2015-03-15 13:08:08 -07:00
Erick Tryzelaar 9972478066 Fix #35 by not relying on the crate being import in the current module 2015-03-15 13:02:34 -07:00
Erick Tryzelaar 00287bd055 Cleanup 2015-03-14 21:47:23 -07:00
Erick Tryzelaar 11f47bd51f Minor cleanup 2015-03-14 15:20:00 -07:00
Erick Tryzelaar 5e98a83717 Remove redundant bounds 2015-03-14 15:03:41 -07:00
Erick Tryzelaar ec8b7c9b89 Update to rust HEAD 2015-03-14 14:57:13 -07:00
Erick Tryzelaar 008ce75ae5 Replace #[derive_serialize] syntax::ext::deriving::generic with aster 2015-03-14 14:57:05 -07:00
Erick Tryzelaar 5c62b7ed06 Split serde_macros into multiple files 2015-03-14 13:09:37 -07:00
Erick Tryzelaar 99f4efd313 Merge #[derive_serialize] for structs and struct variants 2015-03-14 12:53:53 -07:00
Erick Tryzelaar 87ff636c10 Fix some warnings 2015-03-14 12:03:53 -07:00
Erick Tryzelaar d2bd361d9c Merge #[derive_serialize] backend for serializing tuple structs and variants 2015-03-14 12:02:21 -07:00
Erick Tryzelaar 5a32d420cd More cleanup 2015-03-14 00:47:10 -07:00
Erick Tryzelaar a3b2f00c92 More cleanup 2015-03-14 00:08:23 -07:00
Erick Tryzelaar 13fcf1ad5b More cleanup 2015-03-14 00:04:25 -07:00
Erick Tryzelaar 8cb2ff6e2e Fix multiple unnamed enum seq/map variants
Closes #32.
2015-03-13 23:44:18 -07:00
Erick Tryzelaar c917941ec3 More cleanup 2015-03-13 23:43:21 -07:00
Erick Tryzelaar f699d29fb3 More cleanup 2015-03-13 23:38:12 -07:00
Erick Tryzelaar 6723097a3f More cleanup 2015-03-13 23:26:38 -07:00
Erick Tryzelaar 80e27344f1 More cleanup 2015-03-13 23:17:44 -07:00
Erick Tryzelaar f244e0f522 More cleanup 2015-03-13 23:11:05 -07:00
Erick Tryzelaar 61317f5935 Replace some aster with quasi in serde_macros 2015-03-13 22:46:21 -07:00
Erick Tryzelaar 9ca1e2a8f7 Bump aster and quasi 2015-03-13 19:37:01 -07:00
Erick Tryzelaar aedd5f57cf Split json compact and pretty serializer. Recover 20MB/s 2015-03-12 21:15:47 -07:00
Erick Tryzelaar dc87288f48 Allow json missing fields to be treated as a null
Closes #34.
2015-03-12 20:44:16 -07:00
Erick Tryzelaar 5dd53e7ea3 Change ser::{Seq,Map}Visitor to return an optional exact length
This is necessary for formats that serialize the length in the
format stream. Those formats need the exact length, so the
iterator-style size_hint has the wrong semantics.
2015-03-12 19:40:46 -07:00
Erick Tryzelaar 9e454a243a Rename Serialize::visit to Serialize::serialize 2015-03-12 07:33:34 -07:00
Erick Tryzelaar 3f62b6d2bf Merge ser::Serializer and ser::Visitor 2015-03-11 11:05:46 -07:00
Erick Tryzelaar fbd6d1974a Remove the unused Serializer::Value associated type 2015-03-11 10:15:27 -07:00
56 changed files with 9171 additions and 4373 deletions
+2 -2
View File
@@ -1,2 +1,2 @@
/target/
/Cargo.lock
target
Cargo.lock
+30 -9
View File
@@ -1,13 +1,34 @@
language: rust
rust:
- stable
- beta
- nightly
env:
global:
secure: HO41LMpMXkF2In9+1sxWVu7fgolL+y9+4Q5PI6wZX2L5pDwpPJCjxaQarQXCEnoIxED1PlP03JuF7ULNz0zw1ylYhAOfOSdkxFZRnE2wMZqq6qvXBHwyMiDrAociIzoPKSGv7JVrKPsjsnd+96K6xxueIodQZrmAdyq7N/M82Mc=
matrix:
- CRATE=serde_tests TARGET=test
matrix:
include:
- rust: nightly
env: CRATE=serde_macros TARGET=test
- rust: nightly
env: CRATE=serde_macros TARGET=bench
- rust: nightly
env: CRATE=serde_tests TARGET=bench
script:
- cargo build --verbose
- cargo test --verbose
- cargo bench --verbose
- cd serde2
- cargo build --verbose
- cargo test --verbose
- cargo bench --verbose
- (cd $CRATE && cargo $TARGET)
after_success: |
[ $TRAVIS_BRANCH = "master" ] &&
[ $TRAVIS_PULL_REQUEST = false ] &&
mkdir -p target/doc &&
(cd serde && cargo doc --no-deps) &&
(cd serde_codegen && cargo doc --no-deps) &&
(cd serde_macros && cargo doc --no-deps) &&
cp -r serde/target/doc target/doc/serde &&
cp -r serde_codegen/target/doc target/doc/serde_codegen &&
cp -r serde_macros/target/doc target/doc/serde_macros &&
echo "<meta http-equiv=refresh content=0;url=`echo $TRAVIS_REPO_SLUG | cut -d '/' -f 2`/index.html>" > target/doc/index.html &&
sudo pip install ghp-import &&
ghp-import -n target/doc &&
git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
-16
View File
@@ -1,16 +0,0 @@
[package]
name = "serde"
version = "0.2.1"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A serialization/deserialization framework"
repository = "https://github.com/erickt/rust-serde"
[lib]
name = "serde"
[dependencies]
rustc-serialize = "*"
[dev-dependencies]
serde_macros = "0.2.1"
+411 -21
View File
@@ -1,34 +1,424 @@
Experimental Rust Serialization Library.
Serde Rust Serialization Framework
==================================
[![Build Status](https://travis-ci.org/erickt/rust-serde.png?branch=master)](https://travis-ci.org/erickt/rust-serde)
[![Build Status](https://api.travis-ci.org/serde-rs/serde.png?branch=master)](https://travis-ci.org/serde-rs/serde)
[![Latest Version](https://img.shields.io/crates/v/serde.svg)](https://crates.io/crates/serde)
This is an experiment to modernize rust's `libserialize` library. It is designed to implement https://github.com/rust-lang/rfcs/pull/22. `rust-serde` is an attempt to address a major shortcoming in `libserialize`. For normal structures, when you say you want to deserialize into:
Serde is a powerful framework that enables serialization libraries to
generically serialize Rust data structures without the overhead of runtime type
information. In many situations, the handshake protocol between serializers and
serializees can be completely optimized away, leaving Serde to perform roughly
the same speed as a hand written serializer for a specific type.
Documentation is available at http://serde-rs.github.io/serde/serde
Making a Type Serializable
==========================
The simplest way to make a type serializable is to use the `serde_macros`
syntax extension, which comes with a `#[derive(Serialize, Deserialize)]`
annotation, which automatically generates implementations of
[Serialize](http://serde-rs.github.io/serde/serde/ser/trait.Serialize.html)
and
[Deserialize](http://serde-rs.github.io/serde/serde/de/trait.Deserialize.html)
for the annotated type:
```rust
struct Foo {
x: int,
y: int,
#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]
extern crate serde;
...
#[derive(Serialize, Deserialize)]
struct Point {
x: i32,
y: i32,
}
```
`libserialize`'s deserializer essentially asks for:
Serde bundles a high performance JSON serializer and deserializer,
[serde::json](http://serde-rs.github.io/serde/serde/json/index.html),
which comes with the helper functions
[to_string](http://serde-rs.github.io/serde/serde/json/ser/fn.to_string.html)
and
[from_str](http://serde-rs.github.io/serde/serde/json/de/fn.from_str.html)
that make it easy to go to and from JSON:
* Is the next value a struct named "Foo"? If not, error.
* Is the next field named "x"? If not, error.
* Is the next value an "int"? If not, error.
* Is the next field named "y"? If not, error.
* Is the next value an "int"? If not, error.
* Is the struct finished? If not, error.
```rust
use serde::json;
While this works for user defined structures, it cannot support deserializing into a value like `json::Json`, which is an enum that can represent every JSON value. In order to support that, it needs to be able to do some lookahead:
...
* What is the next value type?
* If a struct, parse a struct.
* If an integer, parse an integer.
* ...
let point = Point { x: 1, y: 2 };
let serialized_point = json::to_string(&point).unwrap();
More formally, `libserialize` implements a LL(0) grammar, whereas `json::Json` requires a LL(1) grammar. `rust-serde` provides this by implementing a serializer and deserializer that produces a tagged token stream of values. This enables a `Deserializable` for `json::Json` to look at the next token before deciding on how to parse the value.
println!("{}", serialized_point); // prints: {"x":1,"y":2}
---
let deserialize_point: Point = json::from_str(&serialized_point).unwrap();
```
There is now also a new library variation called `serde2`. This removes the need for tagged values and replaces them with a `Visitor` pattern. This pattern is very similar to the `Iterator` pattern, but it threads some custom state through visiting each type. This gets many of the benefits of the `serde` library without needing to always pay for tagging the variants.
[serde::json](http://serde-rs.github.io/serde/serde/json/index.html) also
supports a generic
[Value](http://serde-rs.github.io/serde/serde/json/value/enum.Value.html)
type, which can represent any JSON value. Also, any
[Serialize](http://serde-rs.github.io/serde/serde/ser/trait.Serialize.html)
and
[Deserialize](http://serde-rs.github.io/serde/serde/de/trait.Deserialize.html)
can be converted into a
[Value](http://serde-rs.github.io/serde/serde/json/value/enum.Value.html)
with the methods
[to_value](http://serde-rs.github.io/serde/serde/json/value/fn.to_value.html)
and
[from_value](http://serde-rs.github.io/serde/serde/json/value/fn.from_value.html):
```rust
let point = Point { x: 1, y: 2 };
let point_value = json::to_value(&point).unwrap();
println!("{}", point_value.find("x")); // prints: Some(1)
let deserialize_point: Point = json::from_value(point_value).unwrap();
```
Serialization without Macros
============================
Under the covers, Serde extensively uses the Visitor pattern to thread state
between the
[Serializer](http://serde-rs.github.io/serde/serde/ser/trait.Serializer.html)
and
[Serialize](http://serde-rs.github.io/serde/serde/ser/trait.Serialize.html)
without the two having specific information about each other's concrete type.
This has many of the same benefits as frameworks that use runtime type
information without the overhead. In fact, when compiling with optimizations,
Rust is able to remove most or all the visitor state, and generate code that's
nearly as fast as a hand written serializer format for a specific type.
To see it in action, lets look at how a simple type like `i32` is serialized.
The
[Serializer](http://serde-rs.github.io/serde/serde/ser/trait.Serializer.html)
is threaded through the type:
```rust
impl serde::Serialize for i32 {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: serde::Serializer,
{
serializer.visit_i32(*self)
}
}
```
As you can see it's pretty simple. More complex types like `BTreeMap` need to
pass a
[MapVisitor](http://serde-rs.github.io/serde/serde/ser/trait.MapVisitor.html)
to the
[Serializer](http://serde-rs.github.io/serde/serde/ser/trait.Serializer.html)
in order to walk through the type:
```rust
impl<K, V> Serialize for BTreeMap<K, V>
where K: Serialize + Ord,
V: Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.visit_map(MapIteratorVisitor::new(self.iter(), Some(self.len())))
}
}
pub struct MapIteratorVisitor<Iter> {
iter: Iter,
len: Option<usize>,
}
impl<K, V, Iter> MapIteratorVisitor<Iter>
where Iter: Iterator<Item=(K, V)>
{
#[inline]
pub fn new(iter: Iter, len: Option<usize>) -> MapIteratorVisitor<Iter> {
MapIteratorVisitor {
iter: iter,
len: len,
}
}
}
impl<K, V, I> MapVisitor for MapIteratorVisitor<I>
where K: Serialize,
V: Serialize,
I: Iterator<Item=(K, V)>,
{
#[inline]
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer,
{
match self.iter.next() {
Some((key, value)) => {
let value = try!(serializer.visit_map_elt(key, value));
Ok(Some(value))
}
None => Ok(None)
}
}
#[inline]
fn len(&self) -> Option<usize> {
self.len
}
}
```
Serializing structs follow this same pattern. In fact, structs are represented
as a named map. Its visitor uses a simple state machine to iterate through all
the fields:
```rust
struct Point {
x: i32,
y: i32,
}
impl serde::Serialize for Point {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: serde::Serializer
{
serializer.visit_named_map("Point", PointMapVisitor {
value: self,
state: 0,
})
}
}
struct PointMapVisitor<'a> {
value: &'a Point,
state: u8,
}
impl<'a> serde::ser::MapVisitor for PointMapVisitor<'a> {
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: serde::Serializer
{
match self.state {
0 => {
self.state += 1;
Ok(Some(try!(serializer.visit_map_elt("x", &self.value.x))))
}
1 => {
self.state += 1;
Ok(Some(try!(serializer.visit_map_elt("y", &self.value.y))))
}
_ => {
Ok(None)
}
}
}
}
```
Deserialization without Macros
==============================
Deserialization is a little more complicated since there's a bit more error
handling that needs to occur. Let's start with the simple `i32`
[Deserialize](http://serde-rs.github.io/serde/serde/de/trait.Deserialize.html)
implementation. It passes a
[Visitor](http://serde-rs.github.io/serde/serde/de/trait.Visitor.html) to the
[Deserializer](http://serde-rs.github.io/serde/serde/de/trait.Deserializer.html).
The [Visitor](http://serde-rs.github.io/serde/serde/de/trait.Visitor.html)
can create the `i32` from a variety of different types:
```rust
impl Deserialize for i32 {
fn deserialize<D>(deserializer: &mut D) -> Result<i32, D::Error>
where D: serde::Deserializer,
{
deserializer.visit(I32Visitor)
}
}
struct I32Visitor;
impl serde::de::Visitor for I32Visitor {
type Value = i32;
fn visit_i16<E>(&mut self, value: i16) -> Result<i16, E>
where E: Error,
{
self.visit_i32(value as i32)
}
fn visit_i32<E>(&mut self, value: i32) -> Result<i32, E>
where E: Error,
{
Ok(value)
}
...
```
Since it's possible for this type to get passed an unexpected type, we need a
way to error out. This is done by way of the
[Error](http://serde-rs.github.io/serde/serde/de/trait.Error.html) trait,
which allows a
[Deserialize](http://serde-rs.github.io/serde/serde/de/trait.Deserialize.html)
to generate an error for a few common error conditions. Here's how it could be used:
```rust
...
fn visit_string<E>(&mut self, _: String) -> Result<i32, E>
where E: Error,
{
Err(serde::de::Error::syntax_error())
}
...
```
Maps follow a similar pattern as before, and use a
[MapVisitor](http://serde-rs.github.io/serde/serde/de/trait.MapVisitor.html)
to walk through the values generated by the
[Deserializer](http://serde-rs.github.io/serde/serde/de/trait.Deserializer.html).
```rust
impl<K, V> serde::Deserialize for BTreeMap<K, V>
where K: serde::Deserialize + Eq + Ord,
V: serde::Deserialize,
{
fn deserialize<D>(deserializer: &mut D) -> Result<BTreeMap<K, V>, D::Error>
where D: serde::Deserializer,
{
deserializer.visit(BTreeMapVisitor::new())
}
}
pub struct BTreeMapVisitor<K, V> {
marker: PhantomData<BTreeMap<K, V>>,
}
impl<K, V> BTreeMapVisitor<K, V> {
pub fn new() -> Self {
BTreeMapVisitor {
marker: PhantomData,
}
}
}
impl<K, V> serde::de::Visitor for BTreeMapVisitor<K, V>
where K: serde::de::Deserialize + Ord,
V: serde::de::Deserialize
{
type Value = BTreeMap<K, V>;
fn visit_unit<E>(&mut self) -> Result<BTreeMap<K, V>, E>
where E: Error,
{
Ok(BTreeMap::new())
}
fn visit_map<V_>(&mut self, mut visitor: V_) -> Result<BTreeMap<K, V>, V_::Error>
where V_: MapVisitor,
{
let mut values = BTreeMap::new();
while let Some((key, value)) = try!(visitor.visit()) {
values.insert(key, value);
}
try!(visitor.end());
Ok(values)
}
}
```
Deserializing structs goes a step further in order to support not allocating a
`String` to hold the field names. This is done by custom field enum that
deserializes an enum variant from a string. So for our `Point` example from
before, we need to generate:
```rust
enum PointField {
X,
Y,
}
impl serde::Deserialize for PointField {
fn deserialize<D>(deserializer: &mut D) -> Result<PointField, D::Error>
where D: serde::de::Deserializer
{
struct FieldVisitor;
impl serde::de::Visitor for FieldVisitor {
type Value = Field;
fn visit_str<E>(&mut self, value: &str) -> Result<PointField, E>
where E: serde::de::Error
{
match value {
"x" => Ok(Field::X),
"y" => Ok(Field::Y),
_ => Err(serde::de::Error::syntax_error()),
}
}
}
deserializer.visit(FieldVisitor)
}
}
```
This is then used in our actual deserializer:
```rust
impl serde::Deserialize for Point {
fn deserialize<D>(deserializer: &mut D) -> Result<Point, D::Error>
where D: serde::de::Deserializer
{
deserializer.visit_named_map("Point", PointVisitor)
}
}
struct PointVisitor;
impl serde::de::Visitor for PointVisitor {
type Value = Point;
fn visit_map<V>(&mut self, mut visitor: V) -> Result<Point, V::Error>
where V: serde::de::MapVisitor
{
let mut x = None;
let mut y = None;
loop {
match try!(visitor.visit_key()) {
Some(Field::X) => { x = Some(try!(visitor.visit_value())); }
Some(Field::Y) => { y = Some(try!(visitor.visit_value())); }
None => { break; }
}
}
let x = match x {
Some(x) => x,
None => try!(visitor.missing_field("x")),
};
let y = match y {
Some(y) => y,
None => try!(visitor.missing_field("y")),
};
try!(visitor.end());
Ok(Point{ x: x, y: y })
}
}
```
+17
View File
@@ -0,0 +1,17 @@
[package]
name = "serde"
version = "0.4.3"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework"
repository = "https://github.com/serde-rs/serde"
documentation = "http://serde-rs.github.io/serde/serde"
readme = "../README.md"
keywords = ["serialization"]
[dependencies]
num = "*"
[features]
nightly = []
+94
View File
@@ -0,0 +1,94 @@
use std::cmp;
use std::io;
use std::slice;
trait IntoBufRead {
type IntoBuf: io::BufRead + BufReadExt;
fn into_buf_read(self) -> Self::IntoBuf;
}
trait BufReadExt {
fn get_buf(&self) -> &[u8];
fn read_u8(&mut self) -> io::Result<Option<u8>>;
}
struct SliceReader<'a> {
buf: &'a [u8],
}
impl<'a> io::Read for SliceReader<'a> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let amt = cmp::min(buf.len(), self.buf.len());
let (a, b) = self.buf.split_at(amt);
slice::bytes::copy_memory(buf, a);
*self.buf = b;
Ok(amt)
}
}
impl<'a> io::BufRead for SliceReader<'a> {
fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(*self) }
fn consume(&mut self, amt: usize) { *self.buf = &self.buf[amt..]; }
}
impl<'a> BufReadExt for SliceReader<'a> {
fn get_buf(&self) -> &[u8] { self.buf }
fn read_u8(&mut self) -> io::Result<Option<u8>> {
let byte = self.buf.get(0);
*self.buf = &self.buf[1..];
byte
}
}
struct BufReader<R> {
inner: R,
buf: io::Cursor<Vec<u8>>,
}
impl<R> BufReader<R> where R: io::Read {
fn new(inner: R) -> Self {
BufferedReader::with_capacity(io::DEFAULT_BUF_SIZE, inner)
}
fn new(cap: usize, inner: R) -> Self {
BufferedReader {
inner: inner,
buf: io::Cursor::new(Vec::with_capacity(cap)),
}
}
fn into_inner(self) -> R {
self.inner
}
}
impl<R> Read for BufReader<R> where R: io::Read {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
// If we don't have any buffered data and we're doing a massive read
// (larger than our internal buffer), bypass our internal buffer
// entirely.
if self.buf.get_ref().len() == self.buf.position() as usize &&
buf.len() >= self.buf.get_ref().capacity() {
return self.inner.read(buf);
}
try!(self.fill_buf());
self.buf.read(buf)
}
}
impl<R> BufReadExt for BufReader<R> {
fn get_buf(&self) -> &[u8] {
self.buf.get_ref()
}
fn read_u8(&mut self) -> io::Result<Option<u8>> {
if self.buf.get_ref().len() == self.buf.position() as usize {
}
let byte = self.buf.get(0);
*self.buf = &self.buf[1..];
byte
}
}
+213
View File
@@ -0,0 +1,213 @@
//! Helper module to enable serializing bytes more efficiently
use std::ops;
use std::fmt;
use std::ascii;
use ser;
use de;
///////////////////////////////////////////////////////////////////////////////
/// `Bytes` wraps a `&[u8]` in order to serialize into a byte array.
#[derive(Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct Bytes<'a> {
bytes: &'a [u8],
}
impl<'a> fmt::Debug for Bytes<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "b\"{}\"", escape_bytestring(self.bytes))
}
}
impl<'a> From<&'a [u8]> for Bytes<'a> {
fn from(bytes: &'a [u8]) -> Self {
Bytes {
bytes: bytes,
}
}
}
impl<'a> From<&'a Vec<u8>> for Bytes<'a> {
fn from(bytes: &'a Vec<u8>) -> Self {
Bytes {
bytes: &bytes,
}
}
}
impl<'a> Into<&'a [u8]> for Bytes<'a> {
fn into(self) -> &'a [u8] {
self.bytes
}
}
impl<'a> ops::Deref for Bytes<'a> {
type Target = [u8];
fn deref(&self) -> &[u8] { self.bytes }
}
impl<'a> ser::Serialize for Bytes<'a> {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer
{
serializer.visit_bytes(self.bytes)
}
}
///////////////////////////////////////////////////////////////////////////////
/// `ByteBuf` wraps a `Vec<u8>` in order to hook into serialize and from deserialize a byte array.
#[derive(Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct ByteBuf {
bytes: Vec<u8>,
}
impl ByteBuf {
pub fn new() -> Self {
ByteBuf {
bytes: Vec::new(),
}
}
pub fn with_capacity(cap: usize) -> Self {
ByteBuf {
bytes: Vec::with_capacity(cap)
}
}
}
impl fmt::Debug for ByteBuf {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "b\"{}\"", escape_bytestring(self.bytes.as_ref()))
}
}
impl Into<Vec<u8>> for ByteBuf {
fn into(self) -> Vec<u8> {
self.bytes
}
}
impl From<Vec<u8>> for ByteBuf {
fn from(bytes: Vec<u8>) -> Self {
ByteBuf {
bytes: bytes,
}
}
}
impl AsRef<Vec<u8>> for ByteBuf {
fn as_ref(&self) -> &Vec<u8> {
&self.bytes
}
}
impl AsRef<[u8]> for ByteBuf {
fn as_ref(&self) -> &[u8] {
&self.bytes
}
}
impl AsMut<Vec<u8>> for ByteBuf {
fn as_mut(&mut self) -> &mut Vec<u8> {
&mut self.bytes
}
}
impl AsMut<[u8]> for ByteBuf {
fn as_mut(&mut self) -> &mut [u8] {
&mut self.bytes
}
}
impl ops::Deref for ByteBuf {
type Target = [u8];
fn deref(&self) -> &[u8] { &self.bytes[..] }
}
impl ops::DerefMut for ByteBuf {
fn deref_mut(&mut self) -> &mut [u8] { &mut self.bytes[..] }
}
impl ser::Serialize for ByteBuf {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer
{
serializer.visit_bytes(&self)
}
}
pub struct ByteBufVisitor;
impl de::Visitor for ByteBufVisitor {
type Value = ByteBuf;
#[inline]
fn visit_unit<E>(&mut self) -> Result<ByteBuf, E>
where E: de::Error,
{
Ok(ByteBuf {
bytes: Vec::new(),
})
}
#[inline]
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<ByteBuf, V::Error>
where V: de::SeqVisitor,
{
let (len, _) = visitor.size_hint();
let mut values = Vec::with_capacity(len);
while let Some(value) = try!(visitor.visit()) {
values.push(value);
}
try!(visitor.end());
Ok(ByteBuf {
bytes: values,
})
}
#[inline]
fn visit_bytes<E>(&mut self, v: &[u8]) -> Result<ByteBuf, E>
where E: de::Error,
{
self.visit_byte_buf(v.to_vec())
}
#[inline]
fn visit_byte_buf<E>(&mut self, v: Vec<u8>) -> Result<ByteBuf, E>
where E: de::Error,
{
Ok(ByteBuf {
bytes: v,
})
}
}
impl de::Deserialize for ByteBuf {
#[inline]
fn deserialize<D>(deserializer: &mut D) -> Result<ByteBuf, D::Error>
where D: de::Deserializer
{
deserializer.visit_bytes(ByteBufVisitor)
}
}
///////////////////////////////////////////////////////////////////////////////
fn escape_bytestring(bytes: &[u8]) -> String {
let mut result = String::new();
for &b in bytes {
for esc in ascii::escape_default(b) {
result.push(esc as char);
}
}
result
}
+974
View File
@@ -0,0 +1,974 @@
use std::borrow::Cow;
use std::collections::{
BinaryHeap,
BTreeMap,
BTreeSet,
LinkedList,
HashMap,
HashSet,
VecDeque,
};
#[cfg(feature = "nightly")]
use collections::enum_set::{CLike, EnumSet};
#[cfg(feature = "nightly")]
use collections::vec_map::VecMap;
use std::hash::Hash;
use std::marker::PhantomData;
use std::path;
use std::rc::Rc;
use std::str;
use std::sync::Arc;
use num::FromPrimitive;
#[cfg(feature = "nightly")]
use core::nonzero::{NonZero, Zeroable};
#[cfg(feature = "nightly")]
use std::num::Zero;
use de::{
Deserialize,
Deserializer,
EnumVisitor,
Error,
MapVisitor,
SeqVisitor,
VariantVisitor,
Visitor,
};
///////////////////////////////////////////////////////////////////////////////
pub struct UnitVisitor;
impl Visitor for UnitVisitor {
type Value = ();
fn visit_unit<E>(&mut self) -> Result<(), E>
where E: Error,
{
Ok(())
}
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<(), V::Error>
where V: SeqVisitor,
{
visitor.end()
}
}
impl Deserialize for () {
fn deserialize<D>(deserializer: &mut D) -> Result<(), D::Error>
where D: Deserializer,
{
deserializer.visit_unit(UnitVisitor)
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct BoolVisitor;
impl Visitor for BoolVisitor {
type Value = bool;
fn visit_bool<E>(&mut self, v: bool) -> Result<bool, E>
where E: Error,
{
Ok(v)
}
fn visit_str<E>(&mut self, s: &str) -> Result<bool, E>
where E: Error,
{
match s.trim() {
"true" => Ok(true),
"false" => Ok(false),
_ => Err(Error::syntax_error()),
}
}
}
impl Deserialize for bool {
fn deserialize<D>(deserializer: &mut D) -> Result<bool, D::Error>
where D: Deserializer,
{
deserializer.visit_bool(BoolVisitor)
}
}
///////////////////////////////////////////////////////////////////////////////
macro_rules! impl_deserialize_num_method {
($src_ty:ty, $method:ident, $from_method:ident) => {
#[inline]
fn $method<E>(&mut self, v: $src_ty) -> Result<T, E>
where E: Error,
{
match FromPrimitive::$from_method(v) {
Some(v) => Ok(v),
None => Err(Error::syntax_error()),
}
}
}
}
pub struct PrimitiveVisitor<T> {
marker: PhantomData<T>,
}
impl<T> PrimitiveVisitor<T> {
#[inline]
pub fn new() -> Self {
PrimitiveVisitor {
marker: PhantomData,
}
}
}
impl<
T: Deserialize + FromPrimitive + str::FromStr
> Visitor for PrimitiveVisitor<T> {
type Value = T;
impl_deserialize_num_method!(isize, visit_isize, from_isize);
impl_deserialize_num_method!(i8, visit_i8, from_i8);
impl_deserialize_num_method!(i16, visit_i16, from_i16);
impl_deserialize_num_method!(i32, visit_i32, from_i32);
impl_deserialize_num_method!(i64, visit_i64, from_i64);
impl_deserialize_num_method!(usize, visit_usize, from_usize);
impl_deserialize_num_method!(u8, visit_u8, from_u8);
impl_deserialize_num_method!(u16, visit_u16, from_u16);
impl_deserialize_num_method!(u32, visit_u32, from_u32);
impl_deserialize_num_method!(u64, visit_u64, from_u64);
impl_deserialize_num_method!(f32, visit_f32, from_f32);
impl_deserialize_num_method!(f64, visit_f64, from_f64);
#[inline]
fn visit_str<E>(&mut self, v: &str) -> Result<T, E>
where E: Error,
{
str::FromStr::from_str(v.trim()).or(Err(Error::syntax_error()))
}
}
macro_rules! impl_deserialize_num {
($ty:ty, $method:ident) => {
impl Deserialize for $ty {
#[inline]
fn deserialize<D>(deserializer: &mut D) -> Result<$ty, D::Error>
where D: Deserializer,
{
deserializer.$method(PrimitiveVisitor::new())
}
}
}
}
impl_deserialize_num!(isize, visit_isize);
impl_deserialize_num!(i8, visit_i8);
impl_deserialize_num!(i16, visit_i16);
impl_deserialize_num!(i32, visit_i32);
impl_deserialize_num!(i64, visit_i64);
impl_deserialize_num!(usize, visit_usize);
impl_deserialize_num!(u8, visit_u8);
impl_deserialize_num!(u16, visit_u16);
impl_deserialize_num!(u32, visit_u32);
impl_deserialize_num!(u64, visit_u64);
impl_deserialize_num!(f32, visit_f32);
impl_deserialize_num!(f64, visit_f64);
///////////////////////////////////////////////////////////////////////////////
struct CharVisitor;
impl Visitor for CharVisitor {
type Value = char;
#[inline]
fn visit_char<E>(&mut self, v: char) -> Result<char, E>
where E: Error,
{
Ok(v)
}
#[inline]
fn visit_str<E>(&mut self, v: &str) -> Result<char, E>
where E: Error,
{
let mut iter = v.chars();
if let Some(v) = iter.next() {
if iter.next().is_some() {
Err(Error::syntax_error())
} else {
Ok(v)
}
} else {
Err(Error::end_of_stream_error())
}
}
}
impl Deserialize for char {
#[inline]
fn deserialize<D>(deserializer: &mut D) -> Result<char, D::Error>
where D: Deserializer,
{
deserializer.visit_char(CharVisitor)
}
}
///////////////////////////////////////////////////////////////////////////////
struct StringVisitor;
impl Visitor for StringVisitor {
type Value = String;
fn visit_str<E>(&mut self, v: &str) -> Result<String, E>
where E: Error,
{
Ok(v.to_string())
}
fn visit_string<E>(&mut self, v: String) -> Result<String, E>
where E: Error,
{
Ok(v)
}
fn visit_bytes<E>(&mut self, v: &[u8]) -> Result<String, E>
where E: Error,
{
match str::from_utf8(v) {
Ok(s) => Ok(s.to_string()),
Err(_) => Err(Error::syntax_error()),
}
}
fn visit_byte_buf<'a, E>(&mut self, v: Vec<u8>) -> Result<String, E>
where E: Error,
{
match String::from_utf8(v) {
Ok(s) => Ok(s),
Err(_) => Err(Error::syntax_error()),
}
}
}
impl Deserialize for String {
fn deserialize<D>(deserializer: &mut D) -> Result<String, D::Error>
where D: Deserializer,
{
deserializer.visit_string(StringVisitor)
}
}
///////////////////////////////////////////////////////////////////////////////
struct OptionVisitor<T> {
marker: PhantomData<T>,
}
impl<
T: Deserialize,
> Visitor for OptionVisitor<T> {
type Value = Option<T>;
#[inline]
fn visit_none<E>(&mut self) -> Result<Option<T>, E>
where E: Error,
{
Ok(None)
}
#[inline]
fn visit_some<D>(&mut self, deserializer: &mut D) -> Result<Option<T>, D::Error>
where D: Deserializer,
{
Ok(Some(try!(Deserialize::deserialize(deserializer))))
}
}
impl<T> Deserialize for Option<T> where T: Deserialize {
fn deserialize<D>(deserializer: &mut D) -> Result<Option<T>, D::Error>
where D: Deserializer,
{
deserializer.visit_option(OptionVisitor { marker: PhantomData })
}
}
///////////////////////////////////////////////////////////////////////////////
macro_rules! set_impl {
(
$ty:ty,
< $($constraints:ident),* >,
$visitor_name:ident,
$visitor:ident,
$ctor:expr,
$with_capacity:expr,
$insert:expr
) => {
pub struct $visitor_name<T> {
marker: PhantomData<T>,
}
impl<T> $visitor_name<T> {
pub fn new() -> Self {
$visitor_name {
marker: PhantomData,
}
}
}
impl<T> Visitor for $visitor_name<T>
where T: $($constraints +)*,
{
type Value = $ty;
#[inline]
fn visit_unit<E>(&mut self) -> Result<$ty, E>
where E: Error,
{
Ok($ctor)
}
#[inline]
fn visit_seq<V>(&mut self, mut $visitor: V) -> Result<$ty, V::Error>
where V: SeqVisitor,
{
let mut values = $with_capacity;
while let Some(value) = try!($visitor.visit()) {
$insert(&mut values, value);
}
try!($visitor.end());
Ok(values)
}
}
impl<T> Deserialize for $ty
where T: $($constraints +)*,
{
fn deserialize<D>(deserializer: &mut D) -> Result<$ty, D::Error>
where D: Deserializer,
{
deserializer.visit_seq($visitor_name::new())
}
}
}
}
set_impl!(
BinaryHeap<T>,
<Deserialize, Ord>,
BinaryHeapVisitor,
visitor,
BinaryHeap::new(),
BinaryHeap::with_capacity(visitor.size_hint().0),
BinaryHeap::push);
set_impl!(
BTreeSet<T>,
<Deserialize, Eq, Ord>,
BTreeSetVisitor,
visitor,
BTreeSet::new(),
BTreeSet::new(),
BTreeSet::insert);
#[cfg(feature = "nightly")]
set_impl!(
EnumSet<T>,
<Deserialize, CLike>,
EnumSetVisitor,
visitor,
EnumSet::new(),
EnumSet::new(),
EnumSet::insert);
set_impl!(
LinkedList<T>,
<Deserialize>,
LinkedListVisitor,
visitor,
LinkedList::new(),
LinkedList::new(),
LinkedList::push_back);
set_impl!(
HashSet<T>,
<Deserialize, Eq, Hash>,
HashSetVisitor,
visitor,
HashSet::new(),
HashSet::with_capacity(visitor.size_hint().0),
HashSet::insert);
set_impl!(
Vec<T>,
<Deserialize>,
VecVisitor,
visitor,
Vec::new(),
Vec::with_capacity(visitor.size_hint().0),
Vec::push);
set_impl!(
VecDeque<T>,
<Deserialize>,
VecDequeVisitor,
visitor,
VecDeque::new(),
VecDeque::with_capacity(visitor.size_hint().0),
VecDeque::push_back);
///////////////////////////////////////////////////////////////////////////////
struct ArrayVisitor0<T> {
marker: PhantomData<T>,
}
impl<T> ArrayVisitor0<T> {
pub fn new() -> Self {
ArrayVisitor0 {
marker: PhantomData,
}
}
}
impl<T> Visitor for ArrayVisitor0<T> where T: Deserialize + Default {
type Value = [T; 0];
#[inline]
fn visit_unit<E>(&mut self) -> Result<[T; 0], E>
where E: Error,
{
Ok([T::default(); 0])
}
#[inline]
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<[T; 0], V::Error>
where V: SeqVisitor,
{
try!(visitor.end());
Ok([T::default(); 0])
}
}
impl<T> Deserialize for [T; 0]
where T: Deserialize + Default
{
fn deserialize<D>(deserializer: &mut D) -> Result<[T; 0], D::Error>
where D: Deserializer,
{
deserializer.visit_seq(ArrayVisitor0::new())
}
}
macro_rules! array_impls {
($($visitor:ident, $len:expr => ($($name:ident),+),)+) => {
$(
struct $visitor<T> {
marker: PhantomData<T>,
}
impl<T> $visitor<T> {
pub fn new() -> Self {
$visitor {
marker: PhantomData
}
}
}
impl<T> Visitor for $visitor<T> where T: Deserialize {
type Value = [T; $len];
#[inline]
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<[T; $len], V::Error>
where V: SeqVisitor,
{
$(
let $name = match try!(visitor.visit()) {
Some(val) => val,
None => { return Err(Error::end_of_stream_error()); }
};
)+;
try!(visitor.end());
Ok([$($name,)+])
}
}
impl<T> Deserialize for [T; $len]
where T: Deserialize,
{
fn deserialize<D>(deserializer: &mut D) -> Result<[T; $len], D::Error>
where D: Deserializer,
{
deserializer.visit_seq($visitor::new())
}
}
)+
}
}
array_impls! {
ArrayVisitor1, 1 => (a),
ArrayVisitor2, 2 => (a, b),
ArrayVisitor3, 3 => (a, b, c),
ArrayVisitor4, 4 => (a, b, c, d),
ArrayVisitor5, 5 => (a, b, c, d, e),
ArrayVisitor6, 6 => (a, b, c, d, e, f),
ArrayVisitor7, 7 => (a, b, c, d, e, f, g),
ArrayVisitor8, 8 => (a, b, c, d, e, f, g, h),
ArrayVisitor9, 9 => (a, b, c, d, e, f, g, h, i),
ArrayVisitor10, 10 => (a, b, c, d, e, f, g, h, i, j),
ArrayVisitor11, 11 => (a, b, c, d, e, f, g, h, i, j, k),
ArrayVisitor12, 12 => (a, b, c, d, e, f, g, h, i, j, k, l),
ArrayVisitor13, 13 => (a, b, c, d, e, f, g, h, i, j, k, l, m),
ArrayVisitor14, 14 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n),
ArrayVisitor15, 15 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o),
ArrayVisitor16, 16 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p),
ArrayVisitor17, 17 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q),
ArrayVisitor18, 18 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r),
ArrayVisitor19, 19 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s),
ArrayVisitor20, 20 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s ,t),
ArrayVisitor21, 21 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u),
ArrayVisitor22, 22 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v),
ArrayVisitor23, 23 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w),
ArrayVisitor24, 24 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x),
ArrayVisitor25, 25 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x,
y),
ArrayVisitor26, 26 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x,
y, z),
ArrayVisitor27, 27 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x,
y, z, aa),
ArrayVisitor28, 28 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x,
y, z, aa, ab),
ArrayVisitor29, 29 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x,
y, z, aa, ab, ac),
ArrayVisitor30, 30 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x,
y, z, aa, ab, ac, ad),
ArrayVisitor31, 31 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x,
y, z, aa, ab, ac, ad, ae),
ArrayVisitor32, 32 => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x,
y, z, aa, ab, ac, ad, ae, af),
}
///////////////////////////////////////////////////////////////////////////////
macro_rules! tuple_impls {
() => {};
($($visitor:ident => ($($name:ident),+),)+) => {
$(
struct $visitor<$($name,)+> {
marker: PhantomData<($($name,)+)>,
}
impl<
$($name: Deserialize,)+
> Visitor for $visitor<$($name,)+> {
type Value = ($($name,)+);
#[inline]
#[allow(non_snake_case)]
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<($($name,)+), V::Error>
where V: SeqVisitor,
{
$(
let $name = match try!(visitor.visit()) {
Some(value) => value,
None => { return Err(Error::end_of_stream_error()); }
};
)+;
try!(visitor.end());
Ok(($($name,)+))
}
}
impl<
$($name: Deserialize),+
> Deserialize for ($($name,)+) {
#[inline]
fn deserialize<D>(deserializer: &mut D) -> Result<($($name,)+), D::Error>
where D: Deserializer,
{
deserializer.visit_tuple($visitor { marker: PhantomData })
}
}
)+
}
}
tuple_impls! {
TupleVisitor1 => (T0),
TupleVisitor2 => (T0, T1),
TupleVisitor3 => (T0, T1, T2),
TupleVisitor4 => (T0, T1, T2, T3),
TupleVisitor5 => (T0, T1, T2, T3, T4),
TupleVisitor6 => (T0, T1, T2, T3, T4, T5),
TupleVisitor7 => (T0, T1, T2, T3, T4, T5, T6),
TupleVisitor8 => (T0, T1, T2, T3, T4, T5, T6, T7),
TupleVisitor9 => (T0, T1, T2, T3, T4, T5, T6, T7, T8),
TupleVisitor10 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9),
TupleVisitor11 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10),
TupleVisitor12 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11),
}
///////////////////////////////////////////////////////////////////////////////
macro_rules! map_impl {
(
$ty:ty,
< $($constraints:ident),* >,
$visitor_name:ident,
$visitor:ident,
$ctor:expr,
$with_capacity:expr,
$insert:expr
) => {
pub struct $visitor_name<K, V> {
marker: PhantomData<$ty>,
}
impl<K, V> $visitor_name<K, V> {
pub fn new() -> Self {
$visitor_name {
marker: PhantomData,
}
}
}
impl<K, V> Visitor for $visitor_name<K, V>
where K: $($constraints +)*,
V: Deserialize,
{
type Value = $ty;
#[inline]
fn visit_unit<E>(&mut self) -> Result<$ty, E>
where E: Error,
{
Ok($ctor)
}
#[inline]
fn visit_map<Visitor>(&mut self, mut $visitor: Visitor) -> Result<$ty, Visitor::Error>
where Visitor: MapVisitor,
{
let mut values = $with_capacity;
while let Some((key, value)) = try!($visitor.visit()) {
$insert(&mut values, key, value);
}
try!($visitor.end());
Ok(values)
}
}
impl<K, V> Deserialize for $ty
where K: $($constraints +)*,
V: Deserialize,
{
fn deserialize<D>(deserializer: &mut D) -> Result<$ty, D::Error>
where D: Deserializer,
{
deserializer.visit_map($visitor_name::new())
}
}
}
}
map_impl!(
BTreeMap<K, V>,
<Deserialize, Eq, Ord>,
BTreeMapVisitor,
visitor,
BTreeMap::new(),
BTreeMap::new(),
BTreeMap::insert);
map_impl!(
HashMap<K, V>,
<Deserialize, Eq, Hash>,
HashMapVisitor,
visitor,
HashMap::new(),
HashMap::with_capacity(visitor.size_hint().0),
HashMap::insert);
///////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "nightly")]
pub struct VecMapVisitor<V> {
marker: PhantomData<VecMap<V>>,
}
#[cfg(feature = "nightly")]
impl<V> VecMapVisitor<V> {
#[inline]
pub fn new() -> Self {
VecMapVisitor {
marker: PhantomData,
}
}
}
#[cfg(feature = "nightly")]
impl<V> Visitor for VecMapVisitor<V>
where V: Deserialize,
{
type Value = VecMap<V>;
#[inline]
fn visit_unit<E>(&mut self) -> Result<VecMap<V>, E>
where E: Error,
{
Ok(VecMap::new())
}
#[inline]
fn visit_map<V_>(&mut self, mut visitor: V_) -> Result<VecMap<V>, V_::Error>
where V_: MapVisitor,
{
let (len, _) = visitor.size_hint();
let mut values = VecMap::with_capacity(len);
while let Some((key, value)) = try!(visitor.visit()) {
values.insert(key, value);
}
try!(visitor.end());
Ok(values)
}
}
#[cfg(feature = "nightly")]
impl<V> Deserialize for VecMap<V>
where V: Deserialize,
{
fn deserialize<D>(deserializer: &mut D) -> Result<VecMap<V>, D::Error>
where D: Deserializer,
{
deserializer.visit_map(VecMapVisitor::new())
}
}
///////////////////////////////////////////////////////////////////////////////
struct PathBufVisitor;
impl Visitor for PathBufVisitor {
type Value = path::PathBuf;
fn visit_str<E>(&mut self, v: &str) -> Result<path::PathBuf, E>
where E: Error,
{
Ok(From::from(v))
}
fn visit_string<E>(&mut self, v: String) -> Result<path::PathBuf, E>
where E: Error,
{
self.visit_str(&v)
}
}
impl Deserialize for path::PathBuf {
fn deserialize<D>(deserializer: &mut D) -> Result<path::PathBuf, D::Error>
where D: Deserializer,
{
deserializer.visit(PathBufVisitor)
}
}
///////////////////////////////////////////////////////////////////////////////
impl<T: Deserialize> Deserialize for Box<T> {
fn deserialize<D>(deserializer: &mut D) -> Result<Box<T>, D::Error>
where D: Deserializer,
{
let val = try!(Deserialize::deserialize(deserializer));
Ok(Box::new(val))
}
}
impl<T: Deserialize> Deserialize for Arc<T> {
fn deserialize<D>(deserializer: &mut D) -> Result<Arc<T>, D::Error>
where D: Deserializer,
{
let val = try!(Deserialize::deserialize(deserializer));
Ok(Arc::new(val))
}
}
impl<T: Deserialize> Deserialize for Rc<T> {
fn deserialize<D>(deserializer: &mut D) -> Result<Rc<T>, D::Error>
where D: Deserializer,
{
let val = try!(Deserialize::deserialize(deserializer));
Ok(Rc::new(val))
}
}
impl<'a, T: ?Sized> Deserialize for Cow<'a, T> where T: ToOwned, T::Owned: Deserialize, {
#[inline]
fn deserialize<D>(deserializer: &mut D) -> Result<Cow<'a, T>, D::Error>
where D: Deserializer,
{
let val = try!(Deserialize::deserialize(deserializer));
Ok(Cow::Owned(val))
}
}
///////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "nightly")]
impl<T> Deserialize for NonZero<T> where T: Deserialize + PartialEq + Zeroable + Zero {
fn deserialize<D>(deserializer: &mut D) -> Result<NonZero<T>, D::Error> where D: Deserializer {
let value = try!(Deserialize::deserialize(deserializer));
if value == Zero::zero() {
return Err(Error::syntax_error())
}
unsafe {
Ok(NonZero::new(value))
}
}
}
///////////////////////////////////////////////////////////////////////////////
impl<T, E> Deserialize for Result<T, E> where T: Deserialize, E: Deserialize {
fn deserialize<D>(deserializer: &mut D) -> Result<Result<T, E>, D::Error>
where D: Deserializer {
enum Field {
Field0,
Field1,
}
impl Deserialize for Field {
#[inline]
fn deserialize<D>(deserializer: &mut D) -> Result<Field, D::Error>
where D: Deserializer {
struct FieldVisitor<D> {
phantom: PhantomData<D>,
}
impl<D> ::de::Visitor for FieldVisitor<D> where D: Deserializer {
type Value = Field;
fn visit_str<E>(&mut self, value: &str) -> Result<Field, E> where E: Error {
match value {
"Ok" => Ok(Field::Field0),
"Err" => Ok(Field::Field1),
_ => Err(Error::unknown_field_error(value)),
}
}
fn visit_bytes<E>(&mut self, value: &[u8]) -> Result<Field, E> where E: Error {
match str::from_utf8(value) {
Ok(s) => self.visit_str(s),
_ => Err(Error::syntax_error()),
}
}
}
deserializer.visit(FieldVisitor::<D> {
phantom: PhantomData,
})
}
}
struct Visitor<D, T, E>(PhantomData<D>, PhantomData<T>, PhantomData<E>)
where D: Deserializer, T: Deserialize, E: Deserialize;
impl<D, T, E> EnumVisitor for Visitor<D, T, E> where D: Deserializer,
T: Deserialize,
E: Deserialize {
type Value = Result<T, E>;
fn visit<V>(&mut self, mut visitor: V) -> Result<Result<T, E>, V::Error>
where V: VariantVisitor {
match match visitor.visit_variant() {
Ok(val) => val,
Err(err) => return Err(From::from(err)),
} {
Field::Field0 => {
struct Visitor<D, T, E>(PhantomData<D>, PhantomData<T>, PhantomData<E>)
where D: Deserializer,
T: Deserialize,
E: Deserialize;
impl <D, T, E> ::de::Visitor for Visitor<D, T, E> where D: Deserializer,
T: Deserialize,
E: Deserialize {
type Value = Result<T, E>;
fn visit_seq<V>(&mut self, mut visitor: V)
-> Result<Result<T, E>, V::Error> where V: SeqVisitor {
let field0 = match match visitor.visit() {
Ok(val) => val,
Err(err) => return Err(From::from(err)),
} {
Some(value) => value,
None => return Err(Error::end_of_stream_error()),
};
match visitor.end() {
Ok(val) => val,
Err(err) => return Err(From::from(err)),
};
Ok(Result::Ok(field0))
}
}
visitor.visit_seq(Visitor::<D, T, E>(PhantomData,
PhantomData,
PhantomData))
}
Field::Field1 => {
struct Visitor<D, T, E>(PhantomData<D>, PhantomData<T>, PhantomData<E>)
where D: Deserializer,
T: Deserialize,
E: Deserialize;
impl <D, T, E> ::de::Visitor for Visitor<D, T, E> where D: Deserializer,
T: Deserialize,
E: Deserialize {
type Value = Result<T, E>;
fn visit_seq<V>(&mut self, mut visitor: V)
-> Result<Result<T, E>, V::Error> where V: SeqVisitor {
let field0 = match match visitor.visit() {
Ok(val) => val,
Err(err) => return Err(From::from(err)),
} {
Some(value) => value,
None => return Err(Error::end_of_stream_error()),
};
match visitor.end() {
Ok(val) => val,
Err(err) => return Err(From::from(err)),
};
Ok(Result::Err(field0))
}
}
visitor.visit_seq(Visitor::<D, T, E>(PhantomData,
PhantomData,
PhantomData))
}
}
}
}
deserializer.visit_enum("Result",
Visitor::<D, T, E>(PhantomData, PhantomData, PhantomData))
}
}
+628
View File
@@ -0,0 +1,628 @@
//! Generic deserialization framework.
pub mod impls;
pub mod value;
///////////////////////////////////////////////////////////////////////////////
pub trait Error {
fn syntax_error() -> Self;
fn end_of_stream_error() -> Self;
fn unknown_field_error(field: &str) -> Self;
fn missing_field_error(field: &'static str) -> Self;
}
///////////////////////////////////////////////////////////////////////////////
pub trait Deserialize {
/// Deserialize this value given this `Deserializer`.
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
where D: Deserializer;
}
///////////////////////////////////////////////////////////////////////////////
/// `Deserializer` is a trait that can deserialize values by threading a `Visitor` trait through a
/// value. It supports two entry point styles which enables different kinds of deserialization.
///
/// 1) The `visit` method. File formats like JSON embed the type of it's construct in it's file
/// format. This allows the `Deserializer` to deserialize into a generic type like
/// `json::Value`, which can represent all JSON types.
///
/// 2) The `visit_*` methods. File formats like bincode do not embed in it's format how to decode
/// it's values. It relies instead on the `Deserialize` type to hint to the `Deserializer` with
/// the `visit_*` methods how it should parse the next value. One downside though to only
/// supporting the `visit_*` types is that it does not allow for deserializing into a generic
/// `json::Value`-esque type.
pub trait Deserializer {
type Error: Error;
/// This method walks a visitor through a value as it is being deserialized.
fn visit<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor;
/// This method hints that the `Deserialize` type is expecting a `bool` value.
#[inline]
fn visit_bool<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `usize` value.
#[inline]
fn visit_usize<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `u8` value.
#[inline]
fn visit_u8<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `u16` value.
#[inline]
fn visit_u16<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `u32` value.
#[inline]
fn visit_u32<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `u64` value.
#[inline]
fn visit_u64<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `isize` value.
#[inline]
fn visit_isize<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `i8` value.
#[inline]
fn visit_i8<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `i16` value.
#[inline]
fn visit_i16<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `i32` value.
#[inline]
fn visit_i32<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `i64` value.
#[inline]
fn visit_i64<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting a `f32` value.
#[inline]
fn visit_f32<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting a `f64` value.
#[inline]
fn visit_f64<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting a `char` value.
#[inline]
fn visit_char<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting a `&str` value.
#[inline]
fn visit_str<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting a `String` value.
#[inline]
fn visit_string<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit_str(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `unit` value.
#[inline]
fn visit_unit<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `Option` value. This allows
/// deserializers that encode an optional value as a nullable value to convert the null value
/// into a `None`, and a regular value as `Some(value)`.
#[inline]
fn visit_option<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting a sequence value. This allows
/// deserializers to parse sequences that aren't tagged as sequences.
#[inline]
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting a map of values. This allows
/// deserializers to parse sequences that aren't tagged as maps.
#[inline]
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting a named unit. This allows
/// deserializers to a named unit that aren't tagged as a named unit.
#[inline]
fn visit_named_unit<V>(&mut self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting a named sequence.
/// This allows deserializers to parse sequences that aren't tagged as sequences.
#[inline]
fn visit_named_seq<V>(&mut self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit_seq(visitor)
}
/// This method hints that the `Deserialize` type is expecting a named map. This allows
/// deserializers to parse sequences that aren't tagged as maps.
#[inline]
fn visit_named_map<V>(&mut self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit_map(visitor)
}
/// This method hints that the `Deserialize` type is expecting a tuple value. This allows
/// deserializers that provide a custom tuple serialization to properly deserialize the type.
#[inline]
fn visit_tuple<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting an enum value. This allows
/// deserializers that provide a custom enumeration serialization to properly deserialize the
/// type.
#[inline]
fn visit_enum<V>(&mut self, _enum: &str, _visitor: V) -> Result<V::Value, Self::Error>
where V: EnumVisitor,
{
Err(Error::syntax_error())
}
/// This method hints that the `Deserialize` type is expecting a `Vec<u8>`. This allows
/// deserializers that provide a custom byte vector serialization to properly deserialize the
/// type.
#[inline]
fn visit_bytes<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// Specify a format string for the deserializer.
///
/// The deserializer format is used to determine which format
/// specific field attributes should be used with the
/// deserializer.
fn format() -> &'static str {
""
}
}
///////////////////////////////////////////////////////////////////////////////
pub trait Visitor {
type Value: Deserialize;
fn visit_bool<E>(&mut self, _v: bool) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
fn visit_isize<E>(&mut self, v: isize) -> Result<Self::Value, E>
where E: Error,
{
self.visit_i64(v as i64)
}
fn visit_i8<E>(&mut self, v: i8) -> Result<Self::Value, E>
where E: Error,
{
self.visit_i64(v as i64)
}
fn visit_i16<E>(&mut self, v: i16) -> Result<Self::Value, E>
where E: Error,
{
self.visit_i64(v as i64)
}
fn visit_i32<E>(&mut self, v: i32) -> Result<Self::Value, E>
where E: Error,
{
self.visit_i64(v as i64)
}
fn visit_i64<E>(&mut self, _v: i64) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
fn visit_usize<E>(&mut self, v: usize) -> Result<Self::Value, E>
where E: Error,
{
self.visit_u64(v as u64)
}
fn visit_u8<E>(&mut self, v: u8) -> Result<Self::Value, E>
where E: Error,
{
self.visit_u64(v as u64)
}
fn visit_u16<E>(&mut self, v: u16) -> Result<Self::Value, E>
where E: Error,
{
self.visit_u64(v as u64)
}
fn visit_u32<E>(&mut self, v: u32) -> Result<Self::Value, E>
where E: Error,
{
self.visit_u64(v as u64)
}
fn visit_u64<E>(&mut self, _v: u64) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
fn visit_f32<E>(&mut self, v: f32) -> Result<Self::Value, E>
where E: Error,
{
self.visit_f64(v as f64)
}
fn visit_f64<E>(&mut self, _v: f64) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
#[inline]
fn visit_char<E>(&mut self, v: char) -> Result<Self::Value, E>
where E: Error,
{
// FIXME: this allocation is required in order to be compatible with stable rust, which
// doesn't support encoding a `char` into a stack buffer.
self.visit_string(v.to_string())
}
fn visit_str<E>(&mut self, _v: &str) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
#[inline]
fn visit_string<E>(&mut self, v: String) -> Result<Self::Value, E>
where E: Error,
{
self.visit_str(&v)
}
fn visit_unit<E>(&mut self) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
#[inline]
fn visit_named_unit<E>(&mut self, _name: &str) -> Result<Self::Value, E>
where E: Error,
{
self.visit_unit()
}
fn visit_none<E>(&mut self) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
fn visit_some<D>(&mut self, _deserializer: &mut D) -> Result<Self::Value, D::Error>
where D: Deserializer,
{
Err(Error::syntax_error())
}
fn visit_seq<V>(&mut self, _visitor: V) -> Result<Self::Value, V::Error>
where V: SeqVisitor,
{
Err(Error::syntax_error())
}
fn visit_map<V>(&mut self, _visitor: V) -> Result<Self::Value, V::Error>
where V: MapVisitor,
{
Err(Error::syntax_error())
}
fn visit_bytes<E>(&mut self, _v: &[u8]) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
fn visit_byte_buf<E>(&mut self, v: Vec<u8>) -> Result<Self::Value, E>
where E: Error,
{
self.visit_bytes(&v)
}
}
///////////////////////////////////////////////////////////////////////////////
pub trait SeqVisitor {
type Error: Error;
fn visit<T>(&mut self) -> Result<Option<T>, Self::Error>
where T: Deserialize;
fn end(&mut self) -> Result<(), Self::Error>;
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
}
impl<'a, V> SeqVisitor for &'a mut V where V: SeqVisitor {
type Error = V::Error;
#[inline]
fn visit<T>(&mut self) -> Result<Option<T>, V::Error>
where T: Deserialize
{
(**self).visit()
}
#[inline]
fn end(&mut self) -> Result<(), V::Error> {
(**self).end()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(**self).size_hint()
}
}
///////////////////////////////////////////////////////////////////////////////
pub trait MapVisitor {
type Error: Error;
#[inline]
fn visit<K, V>(&mut self) -> Result<Option<(K, V)>, Self::Error>
where K: Deserialize,
V: Deserialize,
{
match try!(self.visit_key()) {
Some(key) => {
let value = try!(self.visit_value());
Ok(Some((key, value)))
}
None => Ok(None)
}
}
fn visit_key<K>(&mut self) -> Result<Option<K>, Self::Error>
where K: Deserialize;
fn visit_value<V>(&mut self) -> Result<V, Self::Error>
where V: Deserialize;
fn end(&mut self) -> Result<(), Self::Error>;
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
fn missing_field<V>(&mut self, field: &'static str) -> Result<V, Self::Error>
where V: Deserialize,
{
Err(Error::missing_field_error(field))
}
}
impl<'a, V_> MapVisitor for &'a mut V_ where V_: MapVisitor {
type Error = V_::Error;
#[inline]
fn visit<K, V>(&mut self) -> Result<Option<(K, V)>, V_::Error>
where K: Deserialize,
V: Deserialize,
{
(**self).visit()
}
#[inline]
fn visit_key<K>(&mut self) -> Result<Option<K>, V_::Error>
where K: Deserialize
{
(**self).visit_key()
}
#[inline]
fn visit_value<V>(&mut self) -> Result<V, V_::Error>
where V: Deserialize
{
(**self).visit_value()
}
#[inline]
fn end(&mut self) -> Result<(), V_::Error> {
(**self).end()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(**self).size_hint()
}
}
///////////////////////////////////////////////////////////////////////////////
/// `EnumVisitor` is a visitor that is created by the `Deserialize` and passed to the
/// `Deserializer` in order to deserialize enums.
pub trait EnumVisitor {
type Value;
fn visit<V>(&mut self, visitor: V) -> Result<Self::Value, V::Error>
where V: VariantVisitor;
}
///////////////////////////////////////////////////////////////////////////////
/// `VariantVisitor` is a visitor that is created by the `Deserializer` and passed to the
/// `Deserialize` in order to deserialize a specific enum variant.
pub trait VariantVisitor {
type Error: Error;
/// `visit_variant` is called to identify which variant to deserialize.
fn visit_variant<V>(&mut self) -> Result<V, Self::Error>
where V: Deserialize;
/// `visit_unit` is called when deserializing a variant with no values.
fn visit_unit(&mut self) -> Result<(), Self::Error> {
Err(Error::syntax_error())
}
/// `visit_seq` is called when deserializing a tuple-like variant.
fn visit_seq<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor
{
Err(Error::syntax_error())
}
/// `visit_map` is called when deserializing a struct-like variant.
fn visit_map<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor
{
Err(Error::syntax_error())
}
}
impl<'a, T> VariantVisitor for &'a mut T where T: VariantVisitor {
type Error = T::Error;
fn visit_variant<V>(&mut self) -> Result<V, T::Error>
where V: Deserialize
{
(**self).visit_variant()
}
fn visit_unit(&mut self) -> Result<(), T::Error> {
(**self).visit_unit()
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, T::Error>
where V: Visitor,
{
(**self).visit_seq(visitor)
}
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, T::Error>
where V: Visitor,
{
(**self).visit_map(visitor)
}
}
///////////////////////////////////////////////////////////////////////////////
pub trait EnumSeqVisitor {
type Value;
fn visit<V>(&mut self, visitor: V) -> Result<Self::Value, V::Error>
where V: SeqVisitor;
}
///////////////////////////////////////////////////////////////////////////////
pub trait EnumMapVisitor {
type Value;
fn visit<V>(&mut self, visitor: V) -> Result<Self::Value, V::Error>
where V: MapVisitor;
}
+465
View File
@@ -0,0 +1,465 @@
use std::collections::{
BTreeMap,
BTreeSet,
HashMap,
HashSet,
btree_map,
btree_set,
hash_map,
hash_set,
};
use std::hash::Hash;
use std::vec;
use de;
use bytes;
///////////////////////////////////////////////////////////////////////////////
pub enum Error {
SyntaxError,
EndOfStreamError,
UnknownFieldError(String),
MissingFieldError(&'static str),
}
impl de::Error for Error {
fn syntax_error() -> Self { Error::SyntaxError }
fn end_of_stream_error() -> Self { Error::EndOfStreamError }
fn unknown_field_error(field: &str) -> Self { Error::UnknownFieldError(field.to_string()) }
fn missing_field_error(field: &'static str) -> Self { Error::MissingFieldError(field) }
}
///////////////////////////////////////////////////////////////////////////////
pub trait ValueDeserializer {
type Deserializer: de::Deserializer<Error=Error>;
fn into_deserializer(self) -> Self::Deserializer;
}
///////////////////////////////////////////////////////////////////////////////
impl ValueDeserializer for () {
type Deserializer = UnitDeserializer;
fn into_deserializer(self) -> UnitDeserializer {
UnitDeserializer
}
}
/// A helper deserializer that deserializes a `()`.
pub struct UnitDeserializer;
impl de::Deserializer for UnitDeserializer {
type Error = Error;
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
visitor.visit_unit()
}
fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
visitor.visit_none()
}
}
///////////////////////////////////////////////////////////////////////////////
macro_rules! primitive_deserializer {
($ty:ty, $name:ident, $method:ident) => {
pub struct $name(Option<$ty>);
impl ValueDeserializer for $ty {
type Deserializer = $name;
fn into_deserializer(self) -> $name {
$name(Some(self))
}
}
impl de::Deserializer for $name {
type Error = Error;
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.0.take() {
Some(v) => visitor.$method(v),
None => Err(de::Error::end_of_stream_error()),
}
}
}
}
}
primitive_deserializer!(bool, BoolDeserializer, visit_bool);
primitive_deserializer!(i8, I8Deserializer, visit_i8);
primitive_deserializer!(i16, I16Deserializer, visit_i16);
primitive_deserializer!(i32, I32Deserializer, visit_i32);
primitive_deserializer!(i64, I64Deserializer, visit_i64);
primitive_deserializer!(isize, IsizeDeserializer, visit_isize);
primitive_deserializer!(u8, U8Deserializer, visit_u8);
primitive_deserializer!(u16, U16Deserializer, visit_u16);
primitive_deserializer!(u32, U32Deserializer, visit_u32);
primitive_deserializer!(u64, U64Deserializer, visit_u64);
primitive_deserializer!(usize, UsizeDeserializer, visit_usize);
primitive_deserializer!(f32, F32Deserializer, visit_f32);
primitive_deserializer!(f64, F64Deserializer, visit_f64);
primitive_deserializer!(char, CharDeserializer, visit_char);
///////////////////////////////////////////////////////////////////////////////
/// A helper deserializer that deserializes a `&str`.
pub struct StrDeserializer<'a>(Option<&'a str>);
impl<'a> ValueDeserializer for &'a str {
type Deserializer = StrDeserializer<'a>;
fn into_deserializer(self) -> StrDeserializer<'a> {
StrDeserializer(Some(self))
}
}
impl<'a> de::Deserializer for StrDeserializer<'a> {
type Error = Error;
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.0.take() {
Some(v) => visitor.visit_str(v),
None => Err(de::Error::end_of_stream_error()),
}
}
fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
visitor.visit(self)
}
}
impl<'a> de::VariantVisitor for StrDeserializer<'a> {
type Error = Error;
fn visit_variant<T>(&mut self) -> Result<T, Error>
where T: de::Deserialize,
{
de::Deserialize::deserialize(self)
}
fn visit_unit(&mut self) -> Result<(), Error> {
Ok(())
}
}
///////////////////////////////////////////////////////////////////////////////
/// A helper deserializer that deserializes a `String`.
pub struct StringDeserializer(Option<String>);
impl ValueDeserializer for String {
type Deserializer = StringDeserializer;
fn into_deserializer(self) -> StringDeserializer {
StringDeserializer(Some(self))
}
}
impl de::Deserializer for StringDeserializer {
type Error = Error;
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.0.take() {
Some(string) => visitor.visit_string(string),
None => Err(de::Error::end_of_stream_error()),
}
}
fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
visitor.visit(self)
}
}
impl<'a> de::VariantVisitor for StringDeserializer {
type Error = Error;
fn visit_variant<T>(&mut self) -> Result<T, Error>
where T: de::Deserialize,
{
de::Deserialize::deserialize(self)
}
fn visit_unit(&mut self) -> Result<(), Error> {
Ok(())
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct SeqDeserializer<I> {
iter: I,
len: usize,
}
impl<I> SeqDeserializer<I> {
pub fn new(iter: I, len: usize) -> Self {
SeqDeserializer {
iter: iter,
len: len,
}
}
}
impl<I, T> de::Deserializer for SeqDeserializer<I>
where I: Iterator<Item=T>,
T: ValueDeserializer,
{
type Error = Error;
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
visitor.visit_seq(self)
}
}
impl<I, T> de::SeqVisitor for SeqDeserializer<I>
where I: Iterator<Item=T>,
T: ValueDeserializer,
{
type Error = Error;
fn visit<V>(&mut self) -> Result<Option<V>, Error>
where V: de::Deserialize
{
match self.iter.next() {
Some(value) => {
self.len -= 1;
let mut de = value.into_deserializer();
Ok(Some(try!(de::Deserialize::deserialize(&mut de))))
}
None => Ok(None),
}
}
fn end(&mut self) -> Result<(), Error> {
if self.len == 0 {
Ok(())
} else {
Err(de::Error::end_of_stream_error())
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len, Some(self.len))
}
}
///////////////////////////////////////////////////////////////////////////////
impl<T> ValueDeserializer for Vec<T>
where T: ValueDeserializer,
{
type Deserializer = SeqDeserializer<vec::IntoIter<T>>;
fn into_deserializer(self) -> SeqDeserializer<vec::IntoIter<T>> {
let len = self.len();
SeqDeserializer::new(self.into_iter(), len)
}
}
impl<T> ValueDeserializer for BTreeSet<T>
where T: ValueDeserializer + Eq + Ord,
{
type Deserializer = SeqDeserializer<btree_set::IntoIter<T>>;
fn into_deserializer(self) -> SeqDeserializer<btree_set::IntoIter<T>> {
let len = self.len();
SeqDeserializer::new(self.into_iter(), len)
}
}
impl<T> ValueDeserializer for HashSet<T>
where T: ValueDeserializer + Eq + Hash,
{
type Deserializer = SeqDeserializer<hash_set::IntoIter<T>>;
fn into_deserializer(self) -> SeqDeserializer<hash_set::IntoIter<T>> {
let len = self.len();
SeqDeserializer::new(self.into_iter(), len)
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct MapDeserializer<I, K, V>
where I: Iterator<Item=(K, V)>,
K: ValueDeserializer,
V: ValueDeserializer,
{
iter: I,
value: Option<V>,
len: usize,
}
impl<I, K, V> MapDeserializer<I, K, V>
where I: Iterator<Item=(K, V)>,
K: ValueDeserializer,
V: ValueDeserializer,
{
pub fn new(iter: I, len: usize) -> Self {
MapDeserializer {
iter: iter,
value: None,
len: len,
}
}
}
impl<I, K, V> de::Deserializer for MapDeserializer<I, K, V>
where I: Iterator<Item=(K, V)>,
K: ValueDeserializer,
V: ValueDeserializer,
{
type Error = Error;
fn visit<V_>(&mut self, mut visitor: V_) -> Result<V_::Value, Error>
where V_: de::Visitor,
{
visitor.visit_map(self)
}
}
impl<I, K, V> de::MapVisitor for MapDeserializer<I, K, V>
where I: Iterator<Item=(K, V)>,
K: ValueDeserializer,
V: ValueDeserializer,
{
type Error = Error;
fn visit_key<T>(&mut self) -> Result<Option<T>, Error>
where T: de::Deserialize,
{
match self.iter.next() {
Some((key, value)) => {
self.len -= 1;
self.value = Some(value);
let mut de = key.into_deserializer();
Ok(Some(try!(de::Deserialize::deserialize(&mut de))))
}
None => Ok(None),
}
}
fn visit_value<T>(&mut self) -> Result<T, Error>
where T: de::Deserialize,
{
match self.value.take() {
Some(value) => {
let mut de = value.into_deserializer();
de::Deserialize::deserialize(&mut de)
}
None => Err(de::Error::syntax_error())
}
}
fn end(&mut self) -> Result<(), Error> {
if self.len == 0 {
Ok(())
} else {
Err(de::Error::end_of_stream_error())
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len, Some(self.len))
}
}
///////////////////////////////////////////////////////////////////////////////
impl<K, V> ValueDeserializer for BTreeMap<K, V>
where K: ValueDeserializer + Eq + Ord,
V: ValueDeserializer,
{
type Deserializer = MapDeserializer<btree_map::IntoIter<K, V>, K, V>;
fn into_deserializer(self) -> MapDeserializer<btree_map::IntoIter<K, V>, K, V> {
let len = self.len();
MapDeserializer::new(self.into_iter(), len)
}
}
impl<K, V> ValueDeserializer for HashMap<K, V>
where K: ValueDeserializer + Eq + Hash,
V: ValueDeserializer,
{
type Deserializer = MapDeserializer<hash_map::IntoIter<K, V>, K, V>;
fn into_deserializer(self) -> MapDeserializer<hash_map::IntoIter<K, V>, K, V> {
let len = self.len();
MapDeserializer::new(self.into_iter(), len)
}
}
///////////////////////////////////////////////////////////////////////////////
impl<'a> ValueDeserializer for bytes::Bytes<'a>
{
type Deserializer = BytesDeserializer<'a>;
fn into_deserializer(self) -> BytesDeserializer<'a> {
BytesDeserializer(Some(self.into()))
}
}
pub struct BytesDeserializer<'a> (Option<&'a [u8]>);
impl<'a> de::Deserializer for BytesDeserializer<'a> {
type Error = Error;
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.0.take() {
Some(bytes) => visitor.visit_bytes(bytes),
None => Err(de::Error::end_of_stream_error()),
}
}
}
///////////////////////////////////////////////////////////////////////////////
impl ValueDeserializer for bytes::ByteBuf
{
type Deserializer = ByteBufDeserializer;
fn into_deserializer(self) -> Self::Deserializer {
ByteBufDeserializer(Some(self.into()))
}
}
pub struct ByteBufDeserializer(Option<Vec<u8>>);
impl de::Deserializer for ByteBufDeserializer {
type Error = Error;
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.0.take() {
Some(bytes) => visitor.visit_byte_buf(bytes),
None => Err(de::Error::end_of_stream_error()),
}
}
}
+57
View File
@@ -0,0 +1,57 @@
use std::io;
use std::iter::Peekable;
pub struct LineColIterator<Iter: Iterator<Item=io::Result<u8>>> {
iter: Iter,
line: usize,
col: usize,
}
impl<Iter: Iterator<Item=io::Result<u8>>> LineColIterator<Iter> {
pub fn new(iter: Iter) -> LineColIterator<Iter> {
LineColIterator {
iter: iter,
line: 1,
col: 0,
}
}
/// Report the current line inside the iterator.
pub fn line(&self) -> usize { self.line }
/// Report the current column inside the iterator.
pub fn col(&self) -> usize { self.col }
/// Gets a reference to the underlying iterator.
pub fn get_ref(&self) -> &Iter { &self.iter }
/// Gets a mutable reference to the underlying iterator.
pub fn get_mut(&mut self) -> &mut Iter { &mut self.iter }
/// Unwraps this `LineColIterator`, returning the underlying iterator.
pub fn into_inner(self) -> Iter { self.iter }
}
impl<Iter: Iterator<Item=io::Result<u8>>> LineColIterator<Peekable<Iter>> {
/// peeks at the next value
pub fn peek(&mut self) -> Option<&io::Result<u8>> { self.iter.peek() }
}
impl<Iter: Iterator<Item=io::Result<u8>>> Iterator for LineColIterator<Iter> {
type Item = io::Result<u8>;
fn next(&mut self) -> Option<io::Result<u8>> {
match self.iter.next() {
None => None,
Some(Ok(b'\n')) => {
self.line += 1;
self.col = 0;
Some(Ok(b'\n'))
},
Some(Ok(c)) => {
self.col += 1;
Some(Ok(c))
},
Some(Err(e)) => Some(Err(e)),
}
}
}
+258 -200
View File
@@ -1,39 +1,48 @@
use std::char;
use std::num::Float;
use unicode::str::Utf16Item;
use std::i32;
use std::io;
use std::str;
use de;
use iter::LineColIterator;
use super::error::{Error, ErrorCode};
pub struct Deserializer<Iter> {
rdr: Iter,
pub struct Deserializer<Iter: Iterator<Item=io::Result<u8>>> {
rdr: LineColIterator<Iter>,
ch: Option<u8>,
line: usize,
col: usize,
buf: Vec<u8>,
str_buf: Vec<u8>,
}
macro_rules! try_or_invalid {
($self_:expr, $e:expr) => {
match $e {
Some(v) => v,
None => { return Err($self_.error(ErrorCode::InvalidNumber)); }
}
}
}
impl<Iter> Deserializer<Iter>
where Iter: Iterator<Item=u8>,
where Iter: Iterator<Item=io::Result<u8>>,
{
/// Creates the JSON parser.
/// Creates the JSON parser from an `std::iter::Iterator`.
#[inline]
pub fn new(rdr: Iter) -> Deserializer<Iter> {
let mut p = Deserializer {
rdr: rdr,
ch: Some(b'\x00'),
line: 1,
col: 0,
buf: Vec::with_capacity(128),
pub fn new(rdr: Iter) -> Result<Deserializer<Iter>, Error> {
let mut deserializer = Deserializer {
rdr: LineColIterator::new(rdr),
ch: None,
str_buf: Vec::with_capacity(128),
};
p.bump();
return p;
try!(deserializer.bump());
Ok(deserializer)
}
#[inline]
pub fn end(&mut self) -> Result<(), Error> {
self.parse_whitespace();
try!(self.parse_whitespace());
if self.eof() {
Ok(())
} else {
@@ -45,20 +54,19 @@ impl<Iter> Deserializer<Iter>
fn ch_or_null(&self) -> u8 { self.ch.unwrap_or(b'\x00') }
fn bump(&mut self) {
self.ch = self.rdr.next();
fn bump(&mut self) -> Result<(), Error> {
self.ch = match self.rdr.next() {
Some(Err(err)) => { return Err(Error::IoError(err)); }
Some(Ok(ch)) => Some(ch),
None => None,
};
if self.ch_is(b'\n') {
self.line += 1;
self.col = 1;
} else {
self.col += 1;
}
Ok(())
}
fn next_char(&mut self) -> Option<u8> {
self.bump();
self.ch
fn next_char(&mut self) -> Result<Option<u8>, Error> {
try!(self.bump());
Ok(self.ch)
}
fn ch_is(&self, c: u8) -> bool {
@@ -66,26 +74,28 @@ impl<Iter> Deserializer<Iter>
}
fn error(&mut self, reason: ErrorCode) -> Error {
Error::SyntaxError(reason, self.line, self.col)
Error::SyntaxError(reason, self.rdr.line(), self.rdr.col())
}
fn parse_whitespace(&mut self) {
fn parse_whitespace(&mut self) -> Result<(), Error> {
while self.ch_is(b' ') ||
self.ch_is(b'\n') ||
self.ch_is(b'\t') ||
self.ch_is(b'\r') { self.bump(); }
self.ch_is(b'\r') { try!(self.bump()); }
Ok(())
}
fn parse_value<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
self.parse_whitespace();
try!(self.parse_whitespace());
if self.eof() {
return Err(self.error(ErrorCode::EOFWhileParsingValue));
}
match self.ch_or_null() {
let value = match self.ch_or_null() {
b'n' => {
try!(self.parse_ident(b"ull"));
visitor.visit_unit()
@@ -101,46 +111,53 @@ impl<Iter> Deserializer<Iter>
b'0' ... b'9' | b'-' => self.parse_number(visitor),
b'"' => {
try!(self.parse_string());
let s = str::from_utf8(&self.buf).unwrap();
let s = str::from_utf8(&self.str_buf).unwrap();
visitor.visit_str(s)
}
b'[' => {
self.bump();
try!(self.bump());
visitor.visit_seq(SeqVisitor::new(self))
}
b'{' => {
self.bump();
try!(self.bump());
visitor.visit_map(MapVisitor::new(self))
}
_ => {
Err(self.error(ErrorCode::ExpectedSomeValue))
}
};
match value {
Ok(value) => Ok(value),
Err(Error::SyntaxError(code, _, _)) => Err(self.error(code)),
Err(err) => Err(err),
}
}
fn parse_ident(&mut self, ident: &[u8]) -> Result<(), Error> {
if ident.iter().all(|c| Some(*c) == self.next_char()) {
self.bump();
Ok(())
} else {
Err(self.error(ErrorCode::ExpectedSomeIdent))
for c in ident {
if Some(*c) != try!(self.next_char()) {
return Err(self.error(ErrorCode::ExpectedSomeIdent));
}
}
try!(self.bump());
Ok(())
}
fn parse_number<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
let mut neg = 1;
let mut neg = false;
if self.ch_is(b'-') {
self.bump();
neg = -1;
try!(self.bump());
neg = true;
}
let res = try!(self.parse_integer());
if self.ch_is(b'.') || self.ch_is(b'e') || self.ch_is(b'E') {
let neg = neg as f64;
let mut res = res as f64;
if self.ch_is(b'.') {
@@ -151,18 +168,33 @@ impl<Iter> Deserializer<Iter>
res = try!(self.parse_exponent(res));
}
visitor.visit_f64(neg * res)
if neg {
visitor.visit_f64(-res)
} else {
visitor.visit_f64(res)
}
} else {
visitor.visit_i64(neg * res)
if neg {
let res = -(res as i64);
// Make sure we didn't underflow.
if res > 0 {
Err(self.error(ErrorCode::InvalidNumber))
} else {
visitor.visit_i64(res)
}
} else {
visitor.visit_u64(res)
}
}
}
fn parse_integer(&mut self) -> Result<i64, Error> {
let mut res = 0;
fn parse_integer(&mut self) -> Result<u64, Error> {
let mut accum: u64 = 0;
match self.ch_or_null() {
b'0' => {
self.bump();
try!(self.bump());
// There can be only one leading '0'.
match self.ch_or_null() {
@@ -176,9 +208,10 @@ impl<Iter> Deserializer<Iter>
while !self.eof() {
match self.ch_or_null() {
c @ b'0' ... b'9' => {
res *= 10;
res += (c as i64) - (b'0' as i64);
self.bump();
accum = try_or_invalid!(self, accum.checked_mul(10));
accum = try_or_invalid!(self, accum.checked_add((c as u64) - ('0' as u64)));
try!(self.bump());
}
_ => break,
}
@@ -187,11 +220,11 @@ impl<Iter> Deserializer<Iter>
_ => { return Err(self.error(ErrorCode::InvalidNumber)); }
}
Ok(res)
Ok(accum)
}
fn parse_decimal(&mut self, res: f64) -> Result<f64, Error> {
self.bump();
try!(self.bump());
// Make sure a digit follows the decimal place.
match self.ch_or_null() {
@@ -206,7 +239,7 @@ impl<Iter> Deserializer<Iter>
c @ b'0' ... b'9' => {
dec /= 10.0;
res += (((c as u64) - (b'0' as u64)) as f64) * dec;
self.bump();
try!(self.bump());
}
_ => break,
}
@@ -216,15 +249,15 @@ impl<Iter> Deserializer<Iter>
}
fn parse_exponent(&mut self, mut res: f64) -> Result<f64, Error> {
self.bump();
try!(self.bump());
let mut exp = 0;
let mut exp: u64 = 0;
let mut neg_exp = false;
if self.ch_is(b'+') {
self.bump();
try!(self.bump());
} else if self.ch_is(b'-') {
self.bump();
try!(self.bump());
neg_exp = true;
}
@@ -236,16 +269,21 @@ impl<Iter> Deserializer<Iter>
while !self.eof() {
match self.ch_or_null() {
c @ b'0' ... b'9' => {
exp *= 10;
exp += (c as i32) - (b'0' as i32);
exp = try_or_invalid!(self, exp.checked_mul(10));
exp = try_or_invalid!(self, exp.checked_add((c as u64) - (b'0' as u64)));
self.bump();
try!(self.bump());
}
_ => break
}
}
let exp: f64 = 10_f64.powi(exp);
let exp = if exp <= i32::MAX as u64 {
10_f64.powi(exp as i32)
} else {
return Err(self.error(ErrorCode::InvalidNumber));
};
if neg_exp {
res /= exp;
} else {
@@ -259,7 +297,7 @@ impl<Iter> Deserializer<Iter>
let mut i = 0;
let mut n = 0u16;
while i < 4 && !self.eof() {
self.bump();
try!(self.bump());
n = match self.ch_or_null() {
c @ b'0' ... b'9' => n * 16_u16 + ((c as u16) - (b'0' as u16)),
b'a' | b'A' => n * 16_u16 + 10_u16,
@@ -283,92 +321,99 @@ impl<Iter> Deserializer<Iter>
}
fn parse_string(&mut self) -> Result<(), Error> {
self.buf.clear();
let mut escape = false;
self.str_buf.clear();
loop {
let ch = match self.next_char() {
let ch = match try!(self.next_char()) {
Some(ch) => ch,
None => { return Err(self.error(ErrorCode::EOFWhileParsingString)); }
};
if escape {
match ch {
b'"' => self.buf.push(b'"'),
b'\\' => self.buf.push(b'\\'),
b'/' => self.buf.push(b'/'),
b'b' => self.buf.push(b'\x08'),
b'f' => self.buf.push(b'\x0c'),
b'n' => self.buf.push(b'\n'),
b'r' => self.buf.push(b'\r'),
b't' => self.buf.push(b'\t'),
b'u' => {
let c = match try!(self.decode_hex_escape()) {
0xDC00 ... 0xDFFF => {
return Err(self.error(ErrorCode::LoneLeadingSurrogateInHexEscape));
}
match ch {
b'"' => {
try!(self.bump());
return Ok(());
}
b'\\' => {
let ch = match try!(self.next_char()) {
Some(ch) => ch,
None => { return Err(self.error(ErrorCode::EOFWhileParsingString)); }
};
// Non-BMP characters are encoded as a sequence of
// two hex escapes, representing UTF-16 surrogates.
n1 @ 0xD800 ... 0xDBFF => {
let c1 = self.next_char();
let c2 = self.next_char();
match (c1, c2) {
(Some(b'\\'), Some(b'u')) => (),
_ => {
return Err(self.error(ErrorCode::UnexpectedEndOfHexEscape));
}
match ch {
b'"' => self.str_buf.push(b'"'),
b'\\' => self.str_buf.push(b'\\'),
b'/' => self.str_buf.push(b'/'),
b'b' => self.str_buf.push(b'\x08'),
b'f' => self.str_buf.push(b'\x0c'),
b'n' => self.str_buf.push(b'\n'),
b'r' => self.str_buf.push(b'\r'),
b't' => self.str_buf.push(b'\t'),
b'u' => {
let c = match try!(self.decode_hex_escape()) {
0xDC00 ... 0xDFFF => {
return Err(self.error(ErrorCode::LoneLeadingSurrogateInHexEscape));
}
let buf = &[n1, try!(self.decode_hex_escape())];
match ::unicode::str::utf16_items(buf).next() {
Some(Utf16Item::ScalarValue(c)) => c,
_ => {
// Non-BMP characters are encoded as a sequence of
// two hex escapes, representing UTF-16 surrogates.
n1 @ 0xD800 ... 0xDBFF => {
match (try!(self.next_char()), try!(self.next_char())) {
(Some(b'\\'), Some(b'u')) => (),
_ => {
return Err(self.error(ErrorCode::UnexpectedEndOfHexEscape));
}
}
let n2 = try!(self.decode_hex_escape());
if n2 < 0xDC00 || n2 > 0xDFFF {
return Err(self.error(ErrorCode::LoneLeadingSurrogateInHexEscape));
}
}
}
n => match char::from_u32(n as u32) {
Some(c) => c,
None => {
return Err(self.error(ErrorCode::InvalidUnicodeCodePoint));
}
}
};
let n = (((n1 - 0xD800) as u32) << 10 |
(n2 - 0xDC00) as u32) + 0x1_0000;
let buf = &mut [0; 4];
let len = c.encode_utf8(buf).unwrap_or(0);
self.buf.extend(buf[..len].iter().map(|b| *b));
}
_ => {
return Err(self.error(ErrorCode::InvalidEscape));
match char::from_u32(n as u32) {
Some(c) => c,
None => {
return Err(self.error(ErrorCode::InvalidUnicodeCodePoint));
}
}
}
n => {
match char::from_u32(n as u32) {
Some(c) => c,
None => {
return Err(self.error(ErrorCode::InvalidUnicodeCodePoint));
}
}
}
};
// FIXME: this allocation is required in order to be compatible with stable
// rust, which doesn't support encoding a `char` into a stack buffer.
let buf = c.to_string();
self.str_buf.extend(buf.bytes());
}
_ => {
return Err(self.error(ErrorCode::InvalidEscape));
}
}
}
escape = false;
} else {
match ch {
b'"' => {
self.bump();
return Ok(());
}
b'\\' => {
escape = true;
}
ch => {
self.buf.push(ch);
}
ch => {
self.str_buf.push(ch);
}
}
}
}
fn parse_object_colon(&mut self) -> Result<(), Error> {
self.parse_whitespace();
try!(self.parse_whitespace());
if self.ch_is(b':') {
self.bump();
try!(self.bump());
Ok(())
} else if self.eof() {
Err(self.error(ErrorCode::EOFWhileParsingObject))
@@ -379,7 +424,7 @@ impl<Iter> Deserializer<Iter>
}
impl<Iter> de::Deserializer for Deserializer<Iter>
where Iter: Iterator<Item=u8>,
where Iter: Iterator<Item=io::Result<u8>>,
{
type Error = Error;
@@ -394,7 +439,7 @@ impl<Iter> de::Deserializer for Deserializer<Iter>
fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
self.parse_whitespace();
try!(self.parse_whitespace());
if self.eof() {
return Err(self.error(ErrorCode::EOFWhileParsingValue));
@@ -409,44 +454,44 @@ impl<Iter> de::Deserializer for Deserializer<Iter>
}
#[inline]
fn visit_enum<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
self.parse_whitespace();
try!(self.parse_whitespace());
if self.ch_is(b'{') {
self.bump();
self.parse_whitespace();
try!(self.bump());
try!(self.parse_whitespace());
try!(self.parse_string());
try!(self.parse_object_colon());
let value = {
try!(visitor.visit(&mut *self))
};
let variant = str::from_utf8(&self.buf).unwrap().to_string();
let value = try!(visitor.visit_variant(&variant, EnumVisitor {
de: self,
}));
self.parse_whitespace();
try!(self.parse_whitespace());
if self.ch_is(b'}') {
self.bump();
try!(self.bump());
Ok(value)
} else {
return Err(self.error(ErrorCode::ExpectedSomeValue));
Err(self.error(ErrorCode::ExpectedSomeValue))
}
} else {
Err(self.error(ErrorCode::ExpectedSomeValue))
}
}
#[inline]
fn format() -> &'static str {
"json"
}
}
struct SeqVisitor<'a, Iter: 'a> {
struct SeqVisitor<'a, Iter: 'a + Iterator<Item=io::Result<u8>>> {
de: &'a mut Deserializer<Iter>,
first: bool,
}
impl<'a, Iter> SeqVisitor<'a, Iter> {
impl<'a, Iter: Iterator<Item=io::Result<u8>>> SeqVisitor<'a, Iter> {
fn new(de: &'a mut Deserializer<Iter>) -> Self {
SeqVisitor {
de: de,
@@ -456,17 +501,16 @@ impl<'a, Iter> SeqVisitor<'a, Iter> {
}
impl<'a, Iter> de::SeqVisitor for SeqVisitor<'a, Iter>
where Iter: Iterator<Item=u8>
where Iter: Iterator<Item=io::Result<u8>>,
{
type Error = Error;
fn visit<T>(&mut self) -> Result<Option<T>, Error>
where T: de::Deserialize,
{
self.de.parse_whitespace();
try!(self.de.parse_whitespace());
if self.de.ch_is(b']') {
self.de.bump();
return Ok(None);
}
@@ -474,7 +518,7 @@ impl<'a, Iter> de::SeqVisitor for SeqVisitor<'a, Iter>
self.first = false;
} else {
if self.de.ch_is(b',') {
self.de.bump();
try!(self.de.bump());
} else if self.de.eof() {
return Err(self.de.error(ErrorCode::EOFWhileParsingList));
} else {
@@ -487,11 +531,10 @@ impl<'a, Iter> de::SeqVisitor for SeqVisitor<'a, Iter>
}
fn end(&mut self) -> Result<(), Error> {
self.de.parse_whitespace();
try!(self.de.parse_whitespace());
if self.de.ch_is(b']') {
self.de.bump();
Ok(())
self.de.bump()
} else if self.de.eof() {
Err(self.de.error(ErrorCode::EOFWhileParsingList))
} else {
@@ -500,12 +543,12 @@ impl<'a, Iter> de::SeqVisitor for SeqVisitor<'a, Iter>
}
}
struct MapVisitor<'a, Iter: 'a> {
struct MapVisitor<'a, Iter: 'a + Iterator<Item=io::Result<u8>>> {
de: &'a mut Deserializer<Iter>,
first: bool,
}
impl<'a, Iter> MapVisitor<'a, Iter> {
impl<'a, Iter: Iterator<Item=io::Result<u8>>> MapVisitor<'a, Iter> {
fn new(de: &'a mut Deserializer<Iter>) -> Self {
MapVisitor {
de: de,
@@ -515,17 +558,16 @@ impl<'a, Iter> MapVisitor<'a, Iter> {
}
impl<'a, Iter> de::MapVisitor for MapVisitor<'a, Iter>
where Iter: Iterator<Item=u8>
where Iter: Iterator<Item=io::Result<u8>>
{
type Error = Error;
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
where K: de::Deserialize,
{
self.de.parse_whitespace();
try!(self.de.parse_whitespace());
if self.de.ch_is(b'}') {
self.de.bump();
return Ok(None);
}
@@ -533,8 +575,8 @@ impl<'a, Iter> de::MapVisitor for MapVisitor<'a, Iter>
self.first = false;
} else {
if self.de.ch_is(b',') {
self.de.bump();
self.de.parse_whitespace();
try!(self.de.bump());
try!(self.de.parse_whitespace());
} else if self.de.eof() {
return Err(self.de.error(ErrorCode::EOFWhileParsingObject));
} else {
@@ -562,65 +604,66 @@ impl<'a, Iter> de::MapVisitor for MapVisitor<'a, Iter>
}
fn end(&mut self) -> Result<(), Error> {
self.de.parse_whitespace();
try!(self.de.parse_whitespace());
if self.de.ch_is(b']') {
self.de.bump();
if self.de.ch_is(b'}') {
try!(self.de.bump());
Ok(())
} else if self.de.eof() {
Err(self.de.error(ErrorCode::EOFWhileParsingList))
Err(self.de.error(ErrorCode::EOFWhileParsingObject))
} else {
Err(self.de.error(ErrorCode::TrailingCharacters))
}
}
fn missing_field<V>(&mut self, _field: &'static str) -> Result<V, Error>
where V: de::Deserialize,
{
let mut de = de::value::ValueDeserializer::into_deserializer(());
Ok(try!(de::Deserialize::deserialize(&mut de)))
}
}
struct EnumVisitor<'a, Iter: 'a> {
de: &'a mut Deserializer<Iter>,
}
impl<'a, Iter> de::EnumVisitor for EnumVisitor<'a, Iter>
where Iter: Iterator<Item=u8>,
impl<Iter> de::VariantVisitor for Deserializer<Iter>
where Iter: Iterator<Item=io::Result<u8>>,
{
type Error = Error;
fn visit_variant<V>(&mut self) -> Result<V, Error>
where V: de::Deserialize
{
de::Deserialize::deserialize(self)
}
fn visit_unit(&mut self) -> Result<(), Error> {
de::Deserialize::deserialize(self.de)
try!(self.parse_object_colon());
de::Deserialize::deserialize(self)
}
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumSeqVisitor,
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
self.de.parse_whitespace();
try!(self.parse_object_colon());
if self.de.ch_is(b'[') {
self.de.bump();
visitor.visit(SeqVisitor::new(self.de))
} else {
Err(self.de.error(ErrorCode::ExpectedSomeValue))
}
de::Deserializer::visit(self, visitor)
}
fn visit_map<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumMapVisitor,
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
self.de.parse_whitespace();
try!(self.parse_object_colon());
if self.de.ch_is(b'{') {
self.de.bump();
visitor.visit(MapVisitor::new(self.de))
} else {
Err(self.de.error(ErrorCode::ExpectedSomeValue))
}
de::Deserializer::visit(self, visitor)
}
}
/// Decodes a json value from an `Iterator<u8>`.
/// Decodes a json value from a `std::io::Read`.
pub fn from_iter<I, T>(iter: I) -> Result<T, Error>
where I: Iterator<Item=u8>,
T: de::Deserialize
where I: Iterator<Item=io::Result<u8>>,
T: de::Deserialize,
{
let mut de = Deserializer::new(iter);
let mut de = try!(Deserializer::new(iter));
let value = try!(de::Deserialize::deserialize(&mut de));
// Make sure the whole stream has been consumed.
@@ -628,9 +671,24 @@ pub fn from_iter<I, T>(iter: I) -> Result<T, Error>
Ok(value)
}
/// Decodes a json value from a string
pub fn from_str<'a, T>(s: &'a str) -> Result<T, Error>
/// Decodes a json value from a `std::io::Read`.
pub fn from_reader<R, T>(rdr: R) -> Result<T, Error>
where R: io::Read,
T: de::Deserialize,
{
from_iter(rdr.bytes())
}
/// Decodes a json value from a `&str`.
pub fn from_slice<T>(v: &[u8]) -> Result<T, Error>
where T: de::Deserialize
{
from_iter(s.bytes())
from_iter(v.iter().map(|byte| Ok(*byte)))
}
/// Decodes a json value from a `&str`.
pub fn from_str<T>(s: &str) -> Result<T, Error>
where T: de::Deserialize
{
from_slice(s.as_bytes())
}
+30 -5
View File
@@ -5,7 +5,7 @@ use std::io;
use de;
/// The errors that can arise while parsing a JSON stream.
#[derive(Copy, Clone, PartialEq)]
#[derive(Clone, PartialEq)]
pub enum ErrorCode {
EOFWhileParsingList,
EOFWhileParsingObject,
@@ -28,6 +28,7 @@ pub enum ErrorCode {
InvalidUnicodeCodePoint,
KeyMustBeAString,
LoneLeadingSurrogateInHexEscape,
UnknownField(String),
MissingField(&'static str),
NotFourDigit,
NotUtf8,
@@ -65,6 +66,7 @@ impl fmt::Debug for ErrorCode {
ErrorCode::InvalidUnicodeCodePoint => "invalid unicode code point".fmt(f),
ErrorCode::KeyMustBeAString => "key must be a string".fmt(f),
ErrorCode::LoneLeadingSurrogateInHexEscape => "lone leading surrogate in hex escape".fmt(f),
ErrorCode::UnknownField(ref field) => write!(f, "unknown field \"{}\"", field),
ErrorCode::MissingField(ref field) => write!(f, "missing field \"{}\"", field),
ErrorCode::NotFourDigit => "invalid \\u escape (not four digits)".fmt(f),
ErrorCode::NotUtf8 => "contents not utf-8".fmt(f),
@@ -77,7 +79,7 @@ impl fmt::Debug for ErrorCode {
}
}
#[derive(Clone, PartialEq, Debug)]
#[derive(Debug)]
pub enum Error {
/// msg, line, col
SyntaxError(ErrorCode, usize, usize),
@@ -95,7 +97,7 @@ impl error::Error for Error {
fn description(&self) -> &str {
match *self {
Error::SyntaxError(..) => "syntax error",
Error::IoError(ref error) => error.description(),
Error::IoError(ref error) => error::Error::description(error),
/*
Error::ExpectedError(ref expected, _) => &expected,
*/
@@ -139,12 +141,31 @@ impl fmt::Display for Error {
}
}
impl error::FromError<io::Error> for Error {
fn from_error(error: io::Error) -> Error {
impl From<io::Error> for Error {
fn from(error: io::Error) -> Error {
Error::IoError(error)
}
}
impl From<de::value::Error> for Error {
fn from(error: de::value::Error) -> Error {
match error {
de::value::Error::SyntaxError => {
de::Error::syntax_error()
}
de::value::Error::EndOfStreamError => {
de::Error::end_of_stream_error()
}
de::value::Error::UnknownFieldError(field) => {
Error::SyntaxError(ErrorCode::UnknownField(field), 0, 0)
}
de::value::Error::MissingFieldError(field) => {
de::Error::missing_field_error(field)
}
}
}
}
impl de::Error for Error {
fn syntax_error() -> Error {
Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)
@@ -154,6 +175,10 @@ impl de::Error for Error {
Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 0, 0)
}
fn unknown_field_error(field: &str) -> Error {
Error::SyntaxError(ErrorCode::UnknownField(field.to_string()), 0, 0)
}
fn missing_field_error(field: &'static str) -> Error {
Error::MissingFieldError(field)
}
+113
View File
@@ -0,0 +1,113 @@
//! JSON and serialization
//!
//! # What is JSON?
//!
//! JSON (JavaScript Object Notation) is a way to write data in JavaScript. Like XML, it allows to
//! encode structured data in a text format that can be easily read by humans. Its simple syntax
//! and native compatibility with JavaScript have made it a widely used format.
//!
//! Data types that can be encoded are JavaScript types (see the `serde::json:Value` enum for more
//! details):
//!
//! * `Boolean`: equivalent to rust's `bool`
//! * `I64`: equivalent to rust's `i64`
//! * `U64`: equivalent to rust's `u64`
//! * `F64`: equivalent to rust's `i64`
//! * `String`: equivalent to rust's `String`
//! * `Array`: equivalent to rust's `Vec<T>`, but also allowing objects of different types in the
//! same array
//! * `Object`: equivalent to rust's `BTreeMap<String, serde::json::Value>`
//! * `Null`
//!
//! An object is a series of string keys mapping to values, in `"key": value` format. Arrays are
//! enclosed in square brackets ([ ... ]) and objects in curly brackets ({ ... }). A simple JSON
//! document encoding a person, his/her age, address and phone numbers could look like
//!
//! ```ignore
//! {
//! "FirstName": "John",
//! "LastName": "Doe",
//! "Age": 43,
//! "Address": {
//! "Street": "Downing Street 10",
//! "City": "London",
//! "Country": "Great Britain"
//! },
//! "PhoneNumbers": [
//! "+44 1234567",
//! "+44 2345678"
//! ]
//! }
//! ```
//!
//! # Type-based Serialization and Deserialization
//!
//! Serde provides a mechanism for low boilerplate serialization & deserialization of values to and
//! from JSON via the serialization API. To be able to serialize a piece of data, it must implement
//! the `serde::Serialize` trait. To be able to deserialize a piece of data, it must implement the
//! `serde::Deserialize` trait. Serde provides provides an annotation to automatically generate
//! the code for these traits: `#[derive(Serialize, Deserialize)]`.
//!
//! The JSON API also provides an enum `serde::json::Value` and a method `to_value` to serialize
//! objects. A `serde::json::Value` value can be serialized as a string or buffer using the
//! functions described above. You can also use the `json::Serializer` object, which implements the
//! `Serializer` trait.
//!
//! # Examples of use
//!
//! ## Parsing a `str` to `Value` and reading the result
//!
//! ```rust
//! //#![feature(custom_derive, plugin)]
//! //#![plugin(serde_macros)]
//!
//! extern crate serde;
//!
//! use serde::json::{self, Value};
//!
//! fn main() {
//! let data: Value = json::from_str("{\"foo\": 13, \"bar\": \"baz\"}").unwrap();
//! println!("data: {:?}", data);
//! // data: {"bar":"baz","foo":13}
//! println!("object? {}", data.is_object());
//! // object? true
//!
//! let obj = data.as_object().unwrap();
//! let foo = obj.get("foo").unwrap();
//!
//! println!("array? {:?}", foo.as_array());
//! // array? None
//! println!("u64? {:?}", foo.as_u64());
//! // u64? Some(13u64)
//!
//! for (key, value) in obj.iter() {
//! println!("{}: {}", key, match *value {
//! Value::U64(v) => format!("{} (u64)", v),
//! Value::String(ref v) => format!("{} (string)", v),
//! _ => format!("other")
//! });
//! }
//! // bar: baz (string)
//! // foo: 13 (u64)
//! }
//! ```
pub use self::de::{Deserializer, from_str};
pub use self::error::{Error, ErrorCode};
pub use self::ser::{
Serializer,
to_writer,
to_writer_pretty,
to_vec,
to_vec_pretty,
to_string,
to_string_pretty,
escape_str,
};
pub use self::value::{Value, to_value, from_value};
pub mod builder;
pub mod de;
pub mod error;
pub mod ser;
pub mod value;
+524
View File
@@ -0,0 +1,524 @@
use std::io;
use std::num::FpCategory;
use std::string::FromUtf8Error;
use ser;
/// A structure for implementing serialization to JSON.
pub struct Serializer<W, F=CompactFormatter> {
writer: W,
formatter: F,
/// `first` is used to signify if we should print a comma when we are walking through a
/// sequence.
first: bool,
}
impl<W> Serializer<W>
where W: io::Write,
{
/// Creates a new JSON serializer.
#[inline]
pub fn new(writer: W) -> Self {
Serializer::with_formatter(writer, CompactFormatter)
}
}
impl<'a, W> Serializer<W, PrettyFormatter<'a>>
where W: io::Write,
{
/// Creates a new JSON pretty print serializer.
#[inline]
pub fn pretty(writer: W) -> Self {
Serializer::with_formatter(writer, PrettyFormatter::new())
}
}
impl<W, F> Serializer<W, F>
where W: io::Write,
F: Formatter,
{
/// Creates a new JSON visitor whose output will be written to the writer
/// specified.
#[inline]
pub fn with_formatter(writer: W, formatter: F) -> Self {
Serializer {
writer: writer,
formatter: formatter,
first: false,
}
}
/// Unwrap the `Writer` from the `Serializer`.
#[inline]
pub fn into_inner(self) -> W {
self.writer
}
}
impl<W, F> ser::Serializer for Serializer<W, F>
where W: io::Write,
F: Formatter,
{
type Error = io::Error;
#[inline]
fn visit_bool(&mut self, value: bool) -> io::Result<()> {
if value {
self.writer.write_all(b"true")
} else {
self.writer.write_all(b"false")
}
}
#[inline]
fn visit_isize(&mut self, value: isize) -> io::Result<()> {
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_i8(&mut self, value: i8) -> io::Result<()> {
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_i16(&mut self, value: i16) -> io::Result<()> {
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_i32(&mut self, value: i32) -> io::Result<()> {
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_i64(&mut self, value: i64) -> io::Result<()> {
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_usize(&mut self, value: usize) -> io::Result<()> {
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_u8(&mut self, value: u8) -> io::Result<()> {
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_u16(&mut self, value: u16) -> io::Result<()> {
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_u32(&mut self, value: u32) -> io::Result<()> {
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_u64(&mut self, value: u64) -> io::Result<()> {
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_f32(&mut self, value: f32) -> io::Result<()> {
fmt_f32_or_null(&mut self.writer, value)
}
#[inline]
fn visit_f64(&mut self, value: f64) -> io::Result<()> {
fmt_f64_or_null(&mut self.writer, value)
}
#[inline]
fn visit_char(&mut self, value: char) -> io::Result<()> {
escape_char(&mut self.writer, value)
}
#[inline]
fn visit_str(&mut self, value: &str) -> io::Result<()> {
escape_str(&mut self.writer, value)
}
#[inline]
fn visit_none(&mut self) -> io::Result<()> {
self.visit_unit()
}
#[inline]
fn visit_some<V>(&mut self, value: V) -> io::Result<()>
where V: ser::Serialize
{
value.serialize(self)
}
#[inline]
fn visit_unit(&mut self) -> io::Result<()> {
self.writer.write_all(b"null")
}
#[inline]
fn visit_enum_unit(&mut self, _name: &str, variant: &str) -> io::Result<()> {
try!(self.formatter.open(&mut self.writer, b'{'));
try!(self.formatter.comma(&mut self.writer, true));
try!(self.visit_str(variant));
try!(self.formatter.colon(&mut self.writer));
try!(self.writer.write_all(b"[]"));
self.formatter.close(&mut self.writer, b'}')
}
#[inline]
fn visit_seq<V>(&mut self, mut visitor: V) -> io::Result<()>
where V: ser::SeqVisitor,
{
match visitor.len() {
Some(len) if len == 0 => {
self.writer.write_all(b"[]")
}
_ => {
try!(self.formatter.open(&mut self.writer, b'['));
self.first = true;
while let Some(()) = try!(visitor.visit(self)) { }
self.formatter.close(&mut self.writer, b']')
}
}
}
#[inline]
fn visit_enum_seq<V>(&mut self, _name: &str, variant: &str, visitor: V) -> io::Result<()>
where V: ser::SeqVisitor,
{
try!(self.formatter.open(&mut self.writer, b'{'));
try!(self.formatter.comma(&mut self.writer, true));
try!(self.visit_str(variant));
try!(self.formatter.colon(&mut self.writer));
try!(self.visit_seq(visitor));
self.formatter.close(&mut self.writer, b'}')
}
#[inline]
fn visit_seq_elt<T>(&mut self, value: T) -> io::Result<()>
where T: ser::Serialize,
{
try!(self.formatter.comma(&mut self.writer, self.first));
self.first = false;
value.serialize(self)
}
#[inline]
fn visit_map<V>(&mut self, mut visitor: V) -> io::Result<()>
where V: ser::MapVisitor,
{
match visitor.len() {
Some(len) if len == 0 => {
self.writer.write_all(b"{}")
}
_ => {
try!(self.formatter.open(&mut self.writer, b'{'));
self.first = true;
while let Some(()) = try!(visitor.visit(self)) { }
self.formatter.close(&mut self.writer, b'}')
}
}
}
#[inline]
fn visit_enum_map<V>(&mut self, _name: &str, variant: &str, visitor: V) -> io::Result<()>
where V: ser::MapVisitor,
{
try!(self.formatter.open(&mut self.writer, b'{'));
try!(self.formatter.comma(&mut self.writer, true));
try!(self.visit_str(variant));
try!(self.formatter.colon(&mut self.writer));
try!(self.visit_map(visitor));
self.formatter.close(&mut self.writer, b'}')
}
#[inline]
fn visit_map_elt<K, V>(&mut self, key: K, value: V) -> io::Result<()>
where K: ser::Serialize,
V: ser::Serialize,
{
try!(self.formatter.comma(&mut self.writer, self.first));
self.first = false;
try!(key.serialize(self));
try!(self.formatter.colon(&mut self.writer));
value.serialize(self)
}
#[inline]
fn format() -> &'static str {
"json"
}
}
pub trait Formatter {
fn open<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
where W: io::Write;
fn comma<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
where W: io::Write;
fn colon<W>(&mut self, writer: &mut W) -> io::Result<()>
where W: io::Write;
fn close<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
where W: io::Write;
}
pub struct CompactFormatter;
impl Formatter for CompactFormatter {
fn open<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
where W: io::Write,
{
writer.write_all(&[ch])
}
fn comma<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
where W: io::Write,
{
if first {
Ok(())
} else {
writer.write_all(b",")
}
}
fn colon<W>(&mut self, writer: &mut W) -> io::Result<()>
where W: io::Write,
{
writer.write_all(b":")
}
fn close<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
where W: io::Write,
{
writer.write_all(&[ch])
}
}
pub struct PrettyFormatter<'a> {
current_indent: usize,
indent: &'a [u8],
}
impl<'a> PrettyFormatter<'a> {
fn new() -> Self {
PrettyFormatter::with_indent(b" ")
}
fn with_indent(indent: &'a [u8]) -> Self {
PrettyFormatter {
current_indent: 0,
indent: indent,
}
}
}
impl<'a> Formatter for PrettyFormatter<'a> {
fn open<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
where W: io::Write,
{
self.current_indent += 1;
writer.write_all(&[ch])
}
fn comma<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
where W: io::Write,
{
if first {
try!(writer.write_all(b"\n"));
} else {
try!(writer.write_all(b",\n"));
}
indent(writer, self.current_indent, self.indent)
}
fn colon<W>(&mut self, writer: &mut W) -> io::Result<()>
where W: io::Write,
{
writer.write_all(b": ")
}
fn close<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
where W: io::Write,
{
self.current_indent -= 1;
try!(writer.write(b"\n"));
try!(indent(writer, self.current_indent, self.indent));
writer.write_all(&[ch])
}
}
#[inline]
pub fn escape_bytes<W>(wr: &mut W, bytes: &[u8]) -> io::Result<()>
where W: io::Write
{
try!(wr.write_all(b"\""));
let mut start = 0;
for (i, byte) in bytes.iter().enumerate() {
let escaped = match *byte {
b'"' => b"\\\"",
b'\\' => b"\\\\",
b'\x08' => b"\\b",
b'\x0c' => b"\\f",
b'\n' => b"\\n",
b'\r' => b"\\r",
b'\t' => b"\\t",
_ => { continue; }
};
if start < i {
try!(wr.write_all(&bytes[start..i]));
}
try!(wr.write_all(escaped));
start = i + 1;
}
if start != bytes.len() {
try!(wr.write_all(&bytes[start..]));
}
try!(wr.write_all(b"\""));
Ok(())
}
#[inline]
pub fn escape_str<W>(wr: &mut W, value: &str) -> io::Result<()>
where W: io::Write
{
escape_bytes(wr, value.as_bytes())
}
#[inline]
fn escape_char<W>(wr: &mut W, value: char) -> io::Result<()>
where W: io::Write
{
// FIXME: this allocation is required in order to be compatible with stable
// rust, which doesn't support encoding a `char` into a stack buffer.
escape_bytes(wr, value.to_string().as_bytes())
}
fn fmt_f32_or_null<W>(wr: &mut W, value: f32) -> io::Result<()>
where W: io::Write
{
match value.classify() {
FpCategory::Nan | FpCategory::Infinite => wr.write_all(b"null"),
_ => {
let s = format!("{:?}", value);
try!(wr.write_all(s.as_bytes()));
if !s.contains('.') {
try!(wr.write_all(b".0"))
}
Ok(())
}
}
}
fn fmt_f64_or_null<W>(wr: &mut W, value: f64) -> io::Result<()>
where W: io::Write
{
match value.classify() {
FpCategory::Nan | FpCategory::Infinite => wr.write_all(b"null"),
_ => {
let s = format!("{:?}", value);
try!(wr.write_all(s.as_bytes()));
if !s.contains('.') {
try!(wr.write_all(b".0"))
}
Ok(())
}
}
}
/// Encode the specified struct into a json `[u8]` writer.
#[inline]
pub fn to_writer<W, T>(writer: &mut W, value: &T) -> io::Result<()>
where W: io::Write,
T: ser::Serialize,
{
let mut ser = Serializer::new(writer);
try!(value.serialize(&mut ser));
Ok(())
}
/// Encode the specified struct into a json `[u8]` writer.
#[inline]
pub fn to_writer_pretty<W, T>(writer: &mut W, value: &T) -> io::Result<()>
where W: io::Write,
T: ser::Serialize,
{
let mut ser = Serializer::pretty(writer);
try!(value.serialize(&mut ser));
Ok(())
}
/// Encode the specified struct into a json `[u8]` buffer.
#[inline]
pub fn to_vec<T>(value: &T) -> Vec<u8>
where T: ser::Serialize,
{
// We are writing to a Vec, which doesn't fail. So we can ignore
// the error.
let mut writer = Vec::with_capacity(128);
to_writer(&mut writer, value).unwrap();
writer
}
/// Encode the specified struct into a json `[u8]` buffer.
#[inline]
pub fn to_vec_pretty<T>(value: &T) -> Vec<u8>
where T: ser::Serialize,
{
// We are writing to a Vec, which doesn't fail. So we can ignore
// the error.
let mut writer = Vec::with_capacity(128);
to_writer_pretty(&mut writer, value).unwrap();
writer
}
/// Encode the specified struct into a json `String` buffer.
#[inline]
pub fn to_string<T>(value: &T) -> Result<String, FromUtf8Error>
where T: ser::Serialize
{
let vec = to_vec(value);
String::from_utf8(vec)
}
/// Encode the specified struct into a json `String` buffer.
#[inline]
pub fn to_string_pretty<T>(value: &T) -> Result<String, FromUtf8Error>
where T: ser::Serialize
{
let vec = to_vec_pretty(value);
String::from_utf8(vec)
}
fn indent<W>(wr: &mut W, n: usize, s: &[u8]) -> io::Result<()>
where W: io::Write,
{
for _ in 0 .. n {
try!(wr.write_all(s));
}
Ok(())
}
+370 -59
View File
@@ -4,6 +4,8 @@ use std::io;
use std::str;
use std::vec;
use num::NumCast;
use de;
use ser;
use super::error::Error;
@@ -13,25 +15,248 @@ pub enum Value {
Null,
Bool(bool),
I64(i64),
U64(u64),
F64(f64),
String(String),
Array(Vec<Value>),
Object(BTreeMap<String, Value>),
}
impl Value {
/// If the `Value` is an Object, returns the value associated with the provided key.
/// Otherwise, returns None.
pub fn find<'a>(&'a self, key: &str) -> Option<&'a Value>{
match self {
&Value::Object(ref map) => map.get(key),
_ => None
}
}
/// Attempts to get a nested Value Object for each key in `keys`.
/// If any key is found not to exist, find_path will return None.
/// Otherwise, it will return the `Value` associated with the final key.
pub fn find_path<'a>(&'a self, keys: &[&str]) -> Option<&'a Value>{
let mut target = self;
for key in keys {
match target.find(key) {
Some(t) => { target = t; },
None => return None
}
}
Some(target)
}
/// Looks up a value by path.
///
/// This is a convenience method that splits the path by `'.'`
/// and then feeds the sequence of keys into the `find_path`
/// method.
///
/// ``` ignore
/// let obj: Value = json::from_str(r#"{"x": {"a": 1}}"#).unwrap();
///
/// assert!(obj.lookup("x.a").unwrap() == &Value::U64(1));
/// ```
pub fn lookup<'a>(&'a self, path: &str) -> Option<&'a Value> {
let mut target = self;
for key in path.split('.') {
match target.find(key) {
Some(t) => { target = t; },
None => return None
}
}
Some(target)
}
/// If the `Value` is an Object, performs a depth-first search until
/// a value associated with the provided key is found. If no value is found
/// or the `Value` is not an Object, returns None.
pub fn search<'a>(&'a self, key: &str) -> Option<&'a Value> {
match self {
&Value::Object(ref map) => {
match map.get(key) {
Some(json_value) => Some(json_value),
None => {
for (_, v) in map.iter() {
match v.search(key) {
x if x.is_some() => return x,
_ => ()
}
}
None
}
}
},
_ => None
}
}
/// Returns true if the `Value` is an Object. Returns false otherwise.
pub fn is_object<'a>(&'a self) -> bool {
self.as_object().is_some()
}
/// If the `Value` is an Object, returns the associated BTreeMap.
/// Returns None otherwise.
pub fn as_object<'a>(&'a self) -> Option<&'a BTreeMap<String, Value>> {
match self {
&Value::Object(ref map) => Some(map),
_ => None
}
}
/// If the `Value` is an Object, returns the associated mutable BTreeMap.
/// Returns None otherwise.
pub fn as_object_mut<'a>(&'a mut self) -> Option<&'a mut BTreeMap<String, Value>> {
match self {
&mut Value::Object(ref mut map) => Some(map),
_ => None
}
}
/// Returns true if the `Value` is an Array. Returns false otherwise.
pub fn is_array<'a>(&'a self) -> bool {
self.as_array().is_some()
}
/// If the `Value` is an Array, returns the associated vector.
/// Returns None otherwise.
pub fn as_array<'a>(&'a self) -> Option<&'a Vec<Value>> {
match self {
&Value::Array(ref array) => Some(&*array),
_ => None
}
}
/// If the `Value` is an Array, returns the associated mutable vector.
/// Returns None otherwise.
pub fn as_array_mut<'a>(&'a mut self) -> Option<&'a mut Vec<Value>> {
match self {
&mut Value::Array(ref mut list) => Some(list),
_ => None
}
}
/// Returns true if the `Value` is a String. Returns false otherwise.
pub fn is_string<'a>(&'a self) -> bool {
self.as_string().is_some()
}
/// If the `Value` is a String, returns the associated str.
/// Returns None otherwise.
pub fn as_string<'a>(&'a self) -> Option<&'a str> {
match *self {
Value::String(ref s) => Some(&s),
_ => None
}
}
/// Returns true if the `Value` is a Number. Returns false otherwise.
pub fn is_number(&self) -> bool {
match *self {
Value::I64(_) | Value::U64(_) | Value::F64(_) => true,
_ => false,
}
}
/// Returns true if the `Value` is a i64. Returns false otherwise.
pub fn is_i64(&self) -> bool {
match *self {
Value::I64(_) => true,
_ => false,
}
}
/// Returns true if the `Value` is a u64. Returns false otherwise.
pub fn is_u64(&self) -> bool {
match *self {
Value::U64(_) => true,
_ => false,
}
}
/// Returns true if the `Value` is a f64. Returns false otherwise.
pub fn is_f64(&self) -> bool {
match *self {
Value::F64(_) => true,
_ => false,
}
}
/// If the `Value` is a number, return or cast it to a i64.
/// Returns None otherwise.
pub fn as_i64(&self) -> Option<i64> {
match *self {
Value::I64(n) => Some(n),
Value::U64(n) => NumCast::from(n),
_ => None
}
}
/// If the `Value` is a number, return or cast it to a u64.
/// Returns None otherwise.
pub fn as_u64(&self) -> Option<u64> {
match *self {
Value::I64(n) => NumCast::from(n),
Value::U64(n) => Some(n),
_ => None
}
}
/// If the `Value` is a number, return or cast it to a f64.
/// Returns None otherwise.
pub fn as_f64(&self) -> Option<f64> {
match *self {
Value::I64(n) => NumCast::from(n),
Value::U64(n) => NumCast::from(n),
Value::F64(n) => Some(n),
_ => None
}
}
/// Returns true if the `Value` is a Boolean. Returns false otherwise.
pub fn is_boolean(&self) -> bool {
self.as_boolean().is_some()
}
/// If the `Value` is a Boolean, returns the associated bool.
/// Returns None otherwise.
pub fn as_boolean(&self) -> Option<bool> {
match self {
&Value::Bool(b) => Some(b),
_ => None
}
}
/// Returns true if the `Value` is a Null. Returns false otherwise.
pub fn is_null(&self) -> bool {
self.as_null().is_some()
}
/// If the `Value` is a Null, returns ().
/// Returns None otherwise.
pub fn as_null(&self) -> Option<()> {
match self {
&Value::Null => Some(()),
_ => None
}
}
}
impl ser::Serialize for Value {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: ser::Visitor,
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer,
{
match *self {
Value::Null => visitor.visit_unit(),
Value::Bool(v) => visitor.visit_bool(v),
Value::I64(v) => visitor.visit_i64(v),
Value::F64(v) => visitor.visit_f64(v),
Value::String(ref v) => visitor.visit_str(&v),
Value::Array(ref v) => v.visit(visitor),
Value::Object(ref v) => v.visit(visitor),
Value::Null => serializer.visit_unit(),
Value::Bool(v) => serializer.visit_bool(v),
Value::I64(v) => serializer.visit_i64(v),
Value::U64(v) => serializer.visit_u64(v),
Value::F64(v) => serializer.visit_f64(v),
Value::String(ref v) => serializer.visit_str(&v),
Value::Array(ref v) => v.serialize(serializer),
Value::Object(ref v) => v.serialize(serializer),
}
}
}
@@ -53,7 +278,16 @@ impl de::Deserialize for Value {
#[inline]
fn visit_i64<E>(&mut self, value: i64) -> Result<Value, E> {
Ok(Value::I64(value))
if value < 0 {
Ok(Value::I64(value))
} else {
Ok(Value::U64(value as u64))
}
}
#[inline]
fn visit_u64<E>(&mut self, value: u64) -> Result<Value, E> {
Ok(Value::U64(value))
}
#[inline]
@@ -94,7 +328,7 @@ impl de::Deserialize for Value {
fn visit_seq<V>(&mut self, visitor: V) -> Result<Value, V::Error>
where V: de::SeqVisitor,
{
let values = try!(de::VecVisitor::new().visit_seq(visitor));
let values = try!(de::impls::VecVisitor::new().visit_seq(visitor));
Ok(Value::Array(values))
}
@@ -102,7 +336,7 @@ impl de::Deserialize for Value {
fn visit_map<V>(&mut self, visitor: V) -> Result<Value, V::Error>
where V: de::MapVisitor,
{
let values = try!(de::BTreeMapVisitor::new().visit_map(visitor));
let values = try!(de::impls::BTreeMapVisitor::new().visit_map(visitor));
Ok(Value::Object(values))
}
}
@@ -163,20 +397,6 @@ impl Serializer {
}
impl ser::Serializer for Serializer {
type Value = ();
type Error = ();
#[inline]
fn visit<T>(&mut self, value: &T) -> Result<(), ()>
where T: ser::Serialize,
{
try!(value.visit(self));
Ok(())
}
}
impl ser::Visitor for Serializer {
type Value = ();
type Error = ();
#[inline]
@@ -187,13 +407,17 @@ impl ser::Visitor for Serializer {
#[inline]
fn visit_i64(&mut self, value: i64) -> Result<(), ()> {
self.state.push(State::Value(Value::I64(value)));
if value < 0 {
self.state.push(State::Value(Value::I64(value)));
} else {
self.state.push(State::Value(Value::U64(value as u64)));
}
Ok(())
}
#[inline]
fn visit_u64(&mut self, value: u64) -> Result<(), ()> {
self.state.push(State::Value(Value::I64(value as i64)));
self.state.push(State::Value(Value::U64(value)));
Ok(())
}
@@ -224,7 +448,7 @@ impl ser::Visitor for Serializer {
fn visit_some<V>(&mut self, value: V) -> Result<(), ()>
where V: ser::Serialize,
{
value.visit(self)
value.serialize(self)
}
#[inline]
@@ -247,11 +471,7 @@ impl ser::Visitor for Serializer {
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<(), ()>
where V: ser::SeqVisitor,
{
let len = match visitor.size_hint() {
(_, Some(len)) => len,
(len, None) => len,
};
let len = visitor.len().unwrap_or(0);
let values = Vec::with_capacity(len);
self.state.push(State::Array(values));
@@ -289,10 +509,10 @@ impl ser::Visitor for Serializer {
}
#[inline]
fn visit_seq_elt<T>(&mut self, _first: bool, value: T) -> Result<(), ()>
fn visit_seq_elt<T>(&mut self, value: T) -> Result<(), ()>
where T: ser::Serialize,
{
try!(value.visit(self));
try!(value.serialize(self));
let value = match self.state.pop().unwrap() {
State::Value(value) => value,
@@ -348,18 +568,18 @@ impl ser::Visitor for Serializer {
}
#[inline]
fn visit_map_elt<K, V>(&mut self, _first: bool, key: K, value: V) -> Result<(), ()>
fn visit_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), ()>
where K: ser::Serialize,
V: ser::Serialize,
{
try!(key.visit(self));
try!(key.serialize(self));
let key = match self.state.pop().unwrap() {
State::Value(Value::String(value)) => value,
state => panic!("expected key, found {:?}", state),
};
try!(value.visit(self));
try!(value.serialize(self));
let value = match self.state.pop().unwrap() {
State::Value(value) => value,
@@ -373,6 +593,11 @@ impl ser::Visitor for Serializer {
Ok(())
}
#[inline]
fn format() -> &'static str {
"json"
}
}
pub struct Deserializer {
@@ -404,6 +629,7 @@ impl de::Deserializer for Deserializer {
Value::Null => visitor.visit_unit(),
Value::Bool(v) => visitor.visit_bool(v),
Value::I64(v) => visitor.visit_i64(v),
Value::U64(v) => visitor.visit_u64(v),
Value::F64(v) => visitor.visit_f64(v),
Value::String(v) => visitor.visit_string(v),
Value::Array(v) => {
@@ -438,8 +664,8 @@ impl de::Deserializer for Deserializer {
}
#[inline]
fn visit_enum<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
let value = match self.value.take() {
Some(Value::Object(value)) => value,
@@ -451,8 +677,10 @@ impl de::Deserializer for Deserializer {
let value = match iter.next() {
Some((variant, Value::Array(fields))) => {
self.value = Some(Value::String(variant));
let len = fields.len();
try!(visitor.visit_variant(&variant, SeqDeserializer {
try!(visitor.visit(SeqDeserializer {
de: self,
iter: fields.into_iter(),
len: len,
@@ -460,10 +688,10 @@ impl de::Deserializer for Deserializer {
}
Some((variant, Value::Object(fields))) => {
let len = fields.len();
try!(visitor.visit_variant(&variant, MapDeserializer {
try!(visitor.visit(MapDeserializer {
de: self,
iter: fields.into_iter(),
value: None,
value: Some(Value::String(variant)),
len: len,
}))
}
@@ -476,6 +704,11 @@ impl de::Deserializer for Deserializer {
None => Ok(value)
}
}
#[inline]
fn format() -> &'static str {
"json"
}
}
struct SeqDeserializer<'a> {
@@ -484,6 +717,21 @@ struct SeqDeserializer<'a> {
len: usize,
}
impl<'a> de::Deserializer for SeqDeserializer<'a> {
type Error = Error;
#[inline]
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
if self.len == 0 {
visitor.visit_unit()
} else {
visitor.visit_seq(self)
}
}
}
impl<'a> de::SeqVisitor for SeqDeserializer<'a> {
type Error = Error;
@@ -513,21 +761,30 @@ impl<'a> de::SeqVisitor for SeqDeserializer<'a> {
}
}
impl<'a> de::EnumVisitor for SeqDeserializer<'a> {
impl<'a> de::VariantVisitor for SeqDeserializer<'a> {
type Error = Error;
fn visit_unit(&mut self) -> Result<(), Error> {
if self.len == 0 {
Ok(())
} else {
Err(de::Error::syntax_error())
}
fn visit_variant<V>(&mut self) -> Result<V, Error>
where V: de::Deserialize,
{
de::Deserialize::deserialize(self.de)
}
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumSeqVisitor,
fn visit_unit(&mut self) -> Result<(), Error>
{
visitor.visit(self)
de::Deserialize::deserialize(self)
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
de::Deserializer::visit(self, visitor)
}
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
de::Deserializer::visit(self, visitor)
}
}
@@ -571,18 +828,72 @@ impl<'a> de::MapVisitor for MapDeserializer<'a> {
}
}
fn missing_field<V>(&mut self, _field: &'static str) -> Result<V, Error>
where V: de::Deserialize,
{
// See if the type can deserialize from a unit.
struct UnitDeserializer;
impl de::Deserializer for UnitDeserializer {
type Error = Error;
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
visitor.visit_unit()
}
fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
visitor.visit_none()
}
}
Ok(try!(de::Deserialize::deserialize(&mut UnitDeserializer)))
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len, Some(self.len))
}
}
impl<'a> de::EnumVisitor for MapDeserializer<'a> {
impl<'a> de::Deserializer for MapDeserializer<'a> {
type Error = Error;
fn visit_map<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumMapVisitor,
#[inline]
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
visitor.visit(self)
println!("MapDeserializer!");
visitor.visit_map(self)
}
}
impl<'a> de::VariantVisitor for MapDeserializer<'a> {
type Error = Error;
fn visit_variant<V>(&mut self) -> Result<V, Error>
where V: de::Deserialize,
{
self.de.value = self.value.take();
de::Deserialize::deserialize(self.de)
}
fn visit_unit(&mut self) -> Result<(), Error> {
de::Deserialize::deserialize(self)
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
de::Deserializer::visit(self, visitor)
}
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
de::Deserializer::visit(self, visitor)
}
}
@@ -591,7 +902,7 @@ pub fn to_value<T>(value: &T) -> Value
where T: ser::Serialize
{
let mut ser = Serializer::new();
ser::Serializer::visit(&mut ser, value).ok().unwrap();
value.serialize(&mut ser).ok().unwrap();
ser.unwrap()
}
+26
View File
@@ -0,0 +1,26 @@
//! Serde Serialization Framework
//!
//! Serde is a powerful framework that enables serialization libraries to generically serialize
//! Rust data structures without the overhead of runtime type information. In many situations, the
//! handshake protocol between serializers and serializees can be completely optimized away,
//! leaving serde to perform roughly the same speed as a hand written serializer for a specific
//! type.
#![doc(html_root_url="http://erickt.github.io/rust-serde")]
#![cfg_attr(feature = "nightly", feature(collections, core, enumset, nonzero, step_trait, vecmap, zero_one))]
extern crate num;
#[cfg(feature = "nightly")]
extern crate collections;
#[cfg(feature = "nightly")]
extern crate core;
pub use ser::{Serialize, Serializer};
pub use de::{Deserialize, Deserializer, Error};
pub mod bytes;
pub mod de;
pub mod iter;
pub mod json;
pub mod ser;
+722
View File
@@ -0,0 +1,722 @@
use std::borrow::Cow;
use std::collections::{
BinaryHeap,
BTreeMap,
BTreeSet,
LinkedList,
HashMap,
HashSet,
VecDeque,
};
#[cfg(feature = "nightly")]
use collections::enum_set::{CLike, EnumSet};
#[cfg(feature = "nightly")]
use std::collections::vec_map::VecMap;
use std::hash::Hash;
#[cfg(feature = "nightly")]
use std::iter;
use std::marker::PhantomData;
#[cfg(feature = "nightly")]
use std::num;
#[cfg(feature = "nightly")]
use std::ops;
use std::path;
use std::rc::Rc;
use std::sync::Arc;
#[cfg(feature = "nightly")]
use core::nonzero::{NonZero, Zeroable};
use super::{
Serialize,
Serializer,
SeqVisitor,
MapVisitor,
};
///////////////////////////////////////////////////////////////////////////////
macro_rules! impl_visit {
($ty:ty, $method:ident) => {
impl Serialize for $ty {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.$method(*self)
}
}
}
}
impl_visit!(bool, visit_bool);
impl_visit!(isize, visit_isize);
impl_visit!(i8, visit_i8);
impl_visit!(i16, visit_i16);
impl_visit!(i32, visit_i32);
impl_visit!(i64, visit_i64);
impl_visit!(usize, visit_usize);
impl_visit!(u8, visit_u8);
impl_visit!(u16, visit_u16);
impl_visit!(u32, visit_u32);
impl_visit!(u64, visit_u64);
impl_visit!(f32, visit_f32);
impl_visit!(f64, visit_f64);
impl_visit!(char, visit_char);
///////////////////////////////////////////////////////////////////////////////
impl Serialize for str {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.visit_str(self)
}
}
impl Serialize for String {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
(&self[..]).serialize(serializer)
}
}
///////////////////////////////////////////////////////////////////////////////
impl<T> Serialize for Option<T> where T: Serialize {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
match *self {
Some(ref value) => serializer.visit_some(value),
None => serializer.visit_none(),
}
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct SeqIteratorVisitor<Iter> {
iter: Iter,
len: Option<usize>,
}
impl<T, Iter> SeqIteratorVisitor<Iter>
where Iter: Iterator<Item=T>
{
#[inline]
pub fn new(iter: Iter, len: Option<usize>) -> SeqIteratorVisitor<Iter> {
SeqIteratorVisitor {
iter: iter,
len: len,
}
}
}
impl<T, Iter> SeqVisitor for SeqIteratorVisitor<Iter>
where T: Serialize,
Iter: Iterator<Item=T>,
{
#[inline]
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer,
{
match self.iter.next() {
Some(value) => {
let value = try!(serializer.visit_seq_elt(value));
Ok(Some(value))
}
None => Ok(None),
}
}
#[inline]
fn len(&self) -> Option<usize> {
self.len
}
}
///////////////////////////////////////////////////////////////////////////////
impl<T> Serialize for [T]
where T: Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
}
}
macro_rules! array_impls {
($len:expr) => {
impl<T> Serialize for [T; $len] where T: Serialize {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some($len)))
}
}
}
}
array_impls!(0);
array_impls!(1);
array_impls!(2);
array_impls!(3);
array_impls!(4);
array_impls!(5);
array_impls!(6);
array_impls!(7);
array_impls!(8);
array_impls!(9);
array_impls!(10);
array_impls!(11);
array_impls!(12);
array_impls!(13);
array_impls!(14);
array_impls!(15);
array_impls!(16);
array_impls!(17);
array_impls!(18);
array_impls!(19);
array_impls!(20);
array_impls!(21);
array_impls!(22);
array_impls!(23);
array_impls!(24);
array_impls!(25);
array_impls!(26);
array_impls!(27);
array_impls!(28);
array_impls!(29);
array_impls!(30);
array_impls!(31);
array_impls!(32);
///////////////////////////////////////////////////////////////////////////////
impl<T> Serialize for BinaryHeap<T>
where T: Serialize + Ord
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
}
}
impl<T> Serialize for BTreeSet<T>
where T: Serialize + Ord,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
}
}
#[cfg(feature = "nightly")]
impl<T> Serialize for EnumSet<T>
where T: Serialize + CLike
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
}
}
impl<T> Serialize for HashSet<T>
where T: Serialize + Eq + Hash,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
}
}
impl<T> Serialize for LinkedList<T>
where T: Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
}
}
#[cfg(feature = "nightly")]
impl<A> Serialize for ops::Range<A>
where A: Serialize + Clone + iter::Step + num::One,
for<'a> &'a A: ops::Add<&'a A, Output = A>,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
let len = iter::Step::steps_between(&self.start, &self.end, &A::one());
serializer.visit_seq(SeqIteratorVisitor::new(self.clone(), len))
}
}
impl<T> Serialize for Vec<T> where T: Serialize {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
(&self[..]).serialize(serializer)
}
}
impl<T> Serialize for VecDeque<T> where T: Serialize {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
}
}
///////////////////////////////////////////////////////////////////////////////
impl Serialize for () {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.visit_unit()
}
}
///////////////////////////////////////////////////////////////////////////////
// FIXME(rust #19630) Remove this work-around
macro_rules! e {
($e:expr) => { $e }
}
macro_rules! tuple_impls {
($(
$TupleVisitor:ident ($len:expr, $($T:ident),+) {
$($state:pat => $idx:tt,)+
}
)+) => {
$(
pub struct $TupleVisitor<'a, $($T: 'a),+> {
tuple: &'a ($($T,)+),
state: u8,
}
impl<'a, $($T: 'a),+> $TupleVisitor<'a, $($T),+> {
pub fn new(tuple: &'a ($($T,)+)) -> $TupleVisitor<'a, $($T),+> {
$TupleVisitor {
tuple: tuple,
state: 0,
}
}
}
impl<'a, $($T),+> SeqVisitor for $TupleVisitor<'a, $($T),+>
where $($T: Serialize),+
{
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer,
{
match self.state {
$(
$state => {
self.state += 1;
Ok(Some(try!(serializer.visit_tuple_elt(&e!(self.tuple.$idx)))))
}
)+
_ => {
Ok(None)
}
}
}
fn len(&self) -> Option<usize> {
Some($len)
}
}
impl<$($T),+> Serialize for ($($T,)+)
where $($T: Serialize),+
{
#[inline]
fn serialize<S: Serializer>(&self, serializer: &mut S) -> Result<(), S::Error> {
serializer.visit_tuple($TupleVisitor::new(self))
}
}
)+
}
}
tuple_impls! {
TupleVisitor1 (1, T0) {
0 => 0,
}
TupleVisitor2 (2, T0, T1) {
0 => 0,
1 => 1,
}
TupleVisitor3 (3, T0, T1, T2) {
0 => 0,
1 => 1,
2 => 2,
}
TupleVisitor4 (4, T0, T1, T2, T3) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
}
TupleVisitor5 (5, T0, T1, T2, T3, T4) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
}
TupleVisitor6 (6, T0, T1, T2, T3, T4, T5) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
}
TupleVisitor7 (7, T0, T1, T2, T3, T4, T5, T6) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
}
TupleVisitor8 (8, T0, T1, T2, T3, T4, T5, T6, T7) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
}
TupleVisitor9 (9, T0, T1, T2, T3, T4, T5, T6, T7, T8) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
}
TupleVisitor10 (10, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
}
TupleVisitor11 (11, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
10 => 10,
}
TupleVisitor12 (12, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
10 => 10,
11 => 11,
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct MapIteratorVisitor<Iter> {
iter: Iter,
len: Option<usize>,
}
impl<K, V, Iter> MapIteratorVisitor<Iter>
where Iter: Iterator<Item=(K, V)>
{
#[inline]
pub fn new(iter: Iter, len: Option<usize>) -> MapIteratorVisitor<Iter> {
MapIteratorVisitor {
iter: iter,
len: len,
}
}
}
impl<K, V, I> MapVisitor for MapIteratorVisitor<I>
where K: Serialize,
V: Serialize,
I: Iterator<Item=(K, V)>,
{
#[inline]
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer,
{
match self.iter.next() {
Some((key, value)) => {
let value = try!(serializer.visit_map_elt(key, value));
Ok(Some(value))
}
None => Ok(None)
}
}
#[inline]
fn len(&self) -> Option<usize> {
self.len
}
}
///////////////////////////////////////////////////////////////////////////////
impl<K, V> Serialize for BTreeMap<K, V>
where K: Serialize + Ord,
V: Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.visit_map(MapIteratorVisitor::new(self.iter(), Some(self.len())))
}
}
impl<K, V> Serialize for HashMap<K, V>
where K: Serialize + Eq + Hash,
V: Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.visit_map(MapIteratorVisitor::new(self.iter(), Some(self.len())))
}
}
#[cfg(feature = "nightly")]
impl<V> Serialize for VecMap<V>
where V: Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.visit_map(MapIteratorVisitor::new(self.iter(), Some(self.len())))
}
}
///////////////////////////////////////////////////////////////////////////////
impl<'a, T: ?Sized> Serialize for &'a T where T: Serialize {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
(**self).serialize(serializer)
}
}
impl<'a, T: ?Sized> Serialize for &'a mut T where T: Serialize {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
(**self).serialize(serializer)
}
}
impl<T: ?Sized> Serialize for Box<T> where T: Serialize {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
(**self).serialize(serializer)
}
}
impl<T> Serialize for Rc<T> where T: Serialize, {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
(**self).serialize(serializer)
}
}
impl<T> Serialize for Arc<T> where T: Serialize, {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
(**self).serialize(serializer)
}
}
impl<'a, T: ?Sized> Serialize for Cow<'a, T> where T: Serialize + ToOwned, {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
(**self).serialize(serializer)
}
}
///////////////////////////////////////////////////////////////////////////////
impl<T, E> Serialize for Result<T, E> where T: Serialize, E: Serialize {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
match *self {
Result::Ok(ref field0) => {
struct Visitor<'a, T, E> where T: Serialize + 'a, E: Serialize + 'a {
state: usize,
value: (&'a T,),
_structure_ty: PhantomData<&'a Result<T, E>>,
}
impl<'a, T, E> SeqVisitor for Visitor<'a, T, E> where T: Serialize + 'a,
E: Serialize + 'a {
#[inline]
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer {
match self.state {
0 => {
self.state += 1;
let v = match serializer.visit_seq_elt(&self.value.0) {
Ok(val) => val,
Err(err) => return Err(From::from(err)),
};
Ok(Some(v))
}
_ => Ok(None),
}
}
#[inline]
fn len(&self) -> Option<usize> {
Some(1)
}
}
let field0: &T = field0;
let data: PhantomData<&Result<&T,E>> = PhantomData;
let visitor = Visitor {
value: (&field0,),
state: 0,
_structure_ty: data
};
serializer.visit_enum_seq("Result", "Ok", visitor)
}
Result::Err(ref field0) => {
struct Visitor<'a, T, E> where T: Serialize + 'a, E: Serialize + 'a {
state: usize,
value: (&'a E,),
_structure_ty: PhantomData<&'a Result<T, E>>,
}
impl<'a, T, E> SeqVisitor for Visitor<'a, T, E> where T: Serialize + 'a,
E: Serialize + 'a {
#[inline]
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer {
match self.state {
0 => {
self.state += 1;
let v = match serializer.visit_seq_elt(&self.value.0) {
Ok(val) => val,
Err(err) => return Err(From::from(err)),
};
Ok(Some(v))
}
_ => Ok(None),
}
}
#[inline]
fn len(&self) -> Option<usize> {
Some(1)
}
}
let field0: &E = field0;
let data: PhantomData<&Result<T,&E>> = PhantomData;
let visitor = Visitor {
value: (&field0,),
state: 0,
_structure_ty: data
};
serializer.visit_enum_seq("Result", "Err", visitor)
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
impl Serialize for path::Path {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
self.to_str().unwrap().serialize(serializer)
}
}
impl Serialize for path::PathBuf {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
self.to_str().unwrap().serialize(serializer)
}
}
#[cfg(feature = "nightly")]
impl<T> Serialize for NonZero<T> where T: Serialize + Zeroable {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
(**self).serialize(serializer)
}
}
+256
View File
@@ -0,0 +1,256 @@
//! Generic serialization framework.
pub mod impls;
///////////////////////////////////////////////////////////////////////////////
pub trait Serialize {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer;
}
///////////////////////////////////////////////////////////////////////////////
pub trait Serializer {
type Error;
/// `visit_bool` serializes a `bool` value.
fn visit_bool(&mut self, v: bool) -> Result<(), Self::Error>;
/// `visit_isize` serializes a `isize` value. By default it casts the value to a `i64` and
/// passes it to the `visit_i64` method.
#[inline]
fn visit_isize(&mut self, v: isize) -> Result<(), Self::Error> {
self.visit_i64(v as i64)
}
/// `visit_i8` serializes a `i8` value. By default it casts the value to a `i64` and
/// passes it to the `visit_i64` method.
#[inline]
fn visit_i8(&mut self, v: i8) -> Result<(), Self::Error> {
self.visit_i64(v as i64)
}
/// `visit_i16` serializes a `i16` value. By default it casts the value to a `i64` and
/// passes it to the `visit_i64` method.
#[inline]
fn visit_i16(&mut self, v: i16) -> Result<(), Self::Error> {
self.visit_i64(v as i64)
}
/// `visit_i32` serializes a `i32` value. By default it casts the value to a `i64` and
/// passes it to the `visit_i64` method.
#[inline]
fn visit_i32(&mut self, v: i32) -> Result<(), Self::Error> {
self.visit_i64(v as i64)
}
/// `visit_i64` serializes a `i64` value.
#[inline]
fn visit_i64(&mut self, v: i64) -> Result<(), Self::Error>;
/// `visit_usize` serializes a `usize` value. By default it casts the value to a `u64` and
/// passes it to the `visit_u64` method.
#[inline]
fn visit_usize(&mut self, v: usize) -> Result<(), Self::Error> {
self.visit_u64(v as u64)
}
/// `visit_u8` serializes a `u8` value. By default it casts the value to a `u64` and passes
/// it to the `visit_u64` method.
#[inline]
fn visit_u8(&mut self, v: u8) -> Result<(), Self::Error> {
self.visit_u64(v as u64)
}
/// `visit_u32` serializes a `u32` value. By default it casts the value to a `u64` and passes
/// it to the `visit_u64` method.
#[inline]
fn visit_u16(&mut self, v: u16) -> Result<(), Self::Error> {
self.visit_u64(v as u64)
}
/// `visit_u32` serializes a `u32` value. By default it casts the value to a `u64` and passes
/// it to the `visit_u64` method.
#[inline]
fn visit_u32(&mut self, v: u32) -> Result<(), Self::Error> {
self.visit_u64(v as u64)
}
/// `visit_u64` serializes a `u64` value.
#[inline]
fn visit_u64(&mut self, v: u64) -> Result<(), Self::Error>;
/// `visit_f32` serializes a `f32` value. By default it casts the value to a `f64` and passes
/// it to the `visit_f64` method.
#[inline]
fn visit_f32(&mut self, v: f32) -> Result<(), Self::Error> {
self.visit_f64(v as f64)
}
/// `visit_f64` serializes a `f64` value.
fn visit_f64(&mut self, v: f64) -> Result<(), Self::Error>;
/// `visit_char` serializes a character. By default it serializes it as a `&str` containing a
/// single character.
#[inline]
fn visit_char(&mut self, v: char) -> Result<(), Self::Error> {
// FIXME: this allocation is required in order to be compatible with stable rust, which
// doesn't support encoding a `char` into a stack buffer.
self.visit_str(&v.to_string())
}
/// `visit_str` serializes a `&str`.
fn visit_str(&mut self, value: &str) -> Result<(), Self::Error>;
/// `visit_bytes` is a hook that enables those serialization formats that support serializing
/// byte slices separately from generic arrays. By default it serializes as a regular array.
#[inline]
fn visit_bytes(&mut self, value: &[u8]) -> Result<(), Self::Error> {
self.visit_seq(impls::SeqIteratorVisitor::new(value.iter(), Some(value.len())))
}
fn visit_unit(&mut self) -> Result<(), Self::Error>;
#[inline]
fn visit_named_unit(&mut self, _name: &str) -> Result<(), Self::Error> {
self.visit_unit()
}
#[inline]
fn visit_enum_unit(&mut self,
_name: &str,
_variant: &str) -> Result<(), Self::Error> {
self.visit_unit()
}
fn visit_none(&mut self) -> Result<(), Self::Error>;
fn visit_some<V>(&mut self, value: V) -> Result<(), Self::Error>
where V: Serialize;
fn visit_seq<V>(&mut self, visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor;
fn visit_seq_elt<T>(&mut self, value: T) -> Result<(), Self::Error>
where T: Serialize;
#[inline]
fn visit_tuple<V>(&mut self, visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor,
{
self.visit_seq(visitor)
}
#[inline]
fn visit_tuple_elt<T>(&mut self, value: T) -> Result<(), Self::Error>
where T: Serialize
{
self.visit_seq_elt(value)
}
#[inline]
fn visit_named_seq<V>(&mut self,
_name: &'static str,
visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor,
{
self.visit_tuple(visitor)
}
#[inline]
fn visit_named_seq_elt<T>(&mut self, value: T) -> Result<(), Self::Error>
where T: Serialize
{
self.visit_tuple_elt(value)
}
#[inline]
fn visit_enum_seq<V>(&mut self,
_name: &'static str,
_variant: &'static str,
visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor,
{
self.visit_tuple(visitor)
}
#[inline]
fn visit_enum_seq_elt<T>(&mut self, value: T) -> Result<(), Self::Error>
where T: Serialize
{
self.visit_tuple_elt(value)
}
fn visit_map<V>(&mut self, visitor: V) -> Result<(), Self::Error>
where V: MapVisitor;
fn visit_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), Self::Error>
where K: Serialize,
V: Serialize;
#[inline]
fn visit_named_map<V>(&mut self,
_name: &'static str,
visitor: V) -> Result<(), Self::Error>
where V: MapVisitor,
{
self.visit_map(visitor)
}
#[inline]
fn visit_named_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), Self::Error>
where K: Serialize,
V: Serialize,
{
self.visit_map_elt(key, value)
}
#[inline]
fn visit_enum_map<V>(&mut self,
_name: &'static str,
variant: &'static str,
visitor: V) -> Result<(), Self::Error>
where V: MapVisitor,
{
self.visit_named_map(variant, visitor)
}
#[inline]
fn visit_enum_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), Self::Error>
where K: Serialize,
V: Serialize,
{
self.visit_named_map_elt(key, value)
}
/// Specify a format string for the serializer.
///
/// The serializer format is used to determine which format
/// specific field attributes should be used with the serializer.
fn format() -> &'static str {
""
}
}
pub trait SeqVisitor {
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer;
/// Return the length of the sequence if known.
#[inline]
fn len(&self) -> Option<usize> {
None
}
}
pub trait MapVisitor {
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer;
/// Return the length of the map if known.
#[inline]
fn len(&self) -> Option<usize> {
None
}
}
+24
View File
@@ -0,0 +1,24 @@
[package]
name = "serde_codegen"
version = "0.4.3"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Macros to auto-generate implementations for the serde framework"
repository = "https://github.com/erickt/rust-serde"
build = "build.rs"
[features]
default = ["with-syntex"]
nightly = ["quasi_macros"]
with-syntex = ["quasi/with-syntex", "quasi_codegen/with-syntex", "syntex", "syntex_syntax"]
[build-dependencies]
quasi_codegen = { verision = "*", optional = true }
syntex = { version = "*", optional = true }
[dependencies]
aster = { version = "*", default-features = false }
quasi = { verision = "*", default-features = false }
quasi_macros = { version = "*", optional = true }
syntex = { version = "*", optional = true }
syntex_syntax = { version = "*", optional = true }
+28
View File
@@ -0,0 +1,28 @@
#[cfg(feature = "with-syntex")]
mod inner {
extern crate syntex;
extern crate quasi_codegen;
use std::env;
use std::path::Path;
pub fn main() {
let out_dir = env::var_os("OUT_DIR").unwrap();
let mut registry = syntex::Registry::new();
quasi_codegen::register(&mut registry);
let src = Path::new("src/lib.rs.in");
let dst = Path::new(&out_dir).join("lib.rs");
registry.expand("", &src, &dst).unwrap();
}
}
#[cfg(not(feature = "with-syntex"))]
mod inner {
pub fn main() {}
}
fn main() {
inner::main();
}
+108
View File
@@ -0,0 +1,108 @@
use std::collections::HashMap;
use std::collections::HashSet;
use syntax::ast;
use syntax::ext::base::ExtCtxt;
use syntax::ptr::P;
/// Represents field name information
pub enum FieldNames {
Global(P<ast::Expr>),
Format{
formats: HashMap<P<ast::Expr>, P<ast::Expr>>,
default: P<ast::Expr>,
}
}
/// Represents field attribute information
pub struct FieldAttrs {
names: FieldNames,
use_default: bool,
}
impl FieldAttrs {
/// Create a FieldAttr with a single default field name
pub fn new(default_value: bool, name: P<ast::Expr>) -> FieldAttrs {
FieldAttrs {
names: FieldNames::Global(name),
use_default: default_value,
}
}
/// Create a FieldAttr with format specific field names
pub fn new_with_formats(
default_value: bool,
default_name: P<ast::Expr>,
formats: HashMap<P<ast::Expr>, P<ast::Expr>>,
) -> FieldAttrs {
FieldAttrs {
names: FieldNames::Format {
formats: formats,
default: default_name,
},
use_default: default_value,
}
}
/// Return a set of formats that the field has attributes for.
pub fn formats(&self) -> HashSet<P<ast::Expr>> {
match self.names {
FieldNames::Format{ref formats, default: _} => {
let mut set = HashSet::new();
for (fmt, _) in formats.iter() {
set.insert(fmt.clone());
};
set
},
_ => HashSet::new()
}
}
/// Return an expression for the field key name for serialisation.
///
/// The resulting expression assumes that `S` refers to a type
/// that implements `Serializer`.
pub fn serializer_key_expr(self, cx: &ExtCtxt) -> P<ast::Expr> {
match self.names {
FieldNames::Global(x) => x,
FieldNames::Format{formats, default} => {
let arms = formats.iter()
.map(|(fmt, lit)| {
quote_arm!(cx, $fmt => { $lit })
})
.collect::<Vec<_>>();
quote_expr!(cx,
{
match S::format() {
$arms
_ => { $default }
}
})
},
}
}
/// Return the default field name for the field.
pub fn default_key_expr(&self) -> &P<ast::Expr> {
match self.names {
FieldNames::Global(ref expr) => expr,
FieldNames::Format{formats: _, ref default} => default
}
}
/// Return the field name for the field in the specified format.
pub fn key_expr(&self, format: &P<ast::Expr>) -> &P<ast::Expr> {
match self.names {
FieldNames::Global(ref expr) =>
expr,
FieldNames::Format{ref formats, ref default} =>
formats.get(format).unwrap_or(default)
}
}
/// Predicate for using a field's default value
pub fn use_default(&self) -> bool {
self.use_default
}
}
+833
View File
@@ -0,0 +1,833 @@
use std::collections::HashSet;
use aster;
use syntax::ast::{
self,
Ident,
MetaItem,
Item,
Expr,
StructDef,
EnumDef,
};
use syntax::codemap::Span;
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
use syntax::owned_slice::OwnedSlice;
use syntax::ptr::P;
use attr;
use field;
pub fn expand_derive_deserialize(
cx: &mut ExtCtxt,
span: Span,
meta_item: &MetaItem,
annotatable: &Annotatable,
push: &mut FnMut(Annotatable)
) {
let item = match *annotatable {
Annotatable::Item(ref item) => item,
_ => {
cx.span_err(
meta_item.span,
"`derive` may only be applied to structs and enums");
return;
}
};
let builder = aster::AstBuilder::new().span(span);
let generics = match item.node {
ast::ItemStruct(_, ref generics) => generics,
ast::ItemEnum(_, ref generics) => generics,
_ => cx.bug("expected ItemStruct or ItemEnum in #[derive(Deserialize)]")
};
let impl_generics = builder.from_generics(generics.clone())
.add_ty_param_bound(
builder.path().global().ids(&["serde", "de", "Deserialize"]).build()
)
.build();
let ty = builder.ty().path()
.segment(item.ident).with_generics(impl_generics.clone()).build()
.build();
let body = deserialize_body(
cx,
&builder,
&item,
&impl_generics,
ty.clone(),
);
let where_clause = &impl_generics.where_clause;
let impl_item = quote_item!(cx,
#[automatically_derived]
impl $impl_generics ::serde::de::Deserialize for $ty $where_clause {
fn deserialize<__D>(deserializer: &mut __D) -> ::std::result::Result<$ty, __D::Error>
where __D: ::serde::de::Deserializer,
{
$body
}
}
).unwrap();
push(Annotatable::Item(impl_item))
}
fn deserialize_body(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
item: &Item,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
) -> P<ast::Expr> {
match item.node {
ast::ItemStruct(ref struct_def, _) => {
deserialize_item_struct(
cx,
builder,
item,
impl_generics,
ty,
struct_def,
)
}
ast::ItemEnum(ref enum_def, _) => {
deserialize_item_enum(
cx,
builder,
item.ident,
impl_generics,
ty,
enum_def,
)
}
_ => cx.bug("expected ItemStruct or ItemEnum in #[derive(Deserialize)]")
}
}
fn deserialize_item_struct(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
item: &Item,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
struct_def: &ast::StructDef,
) -> P<ast::Expr> {
let mut named_fields = vec![];
let mut unnamed_fields = 0;
for field in struct_def.fields.iter() {
match field.node.kind {
ast::NamedField(name, _) => { named_fields.push(name); }
ast::UnnamedField(_) => { unnamed_fields += 1; }
}
}
match (named_fields.is_empty(), unnamed_fields == 0) {
(true, true) => {
deserialize_unit_struct(
cx,
&builder,
item.ident,
)
}
(true, false) => {
deserialize_tuple_struct(
cx,
&builder,
item.ident,
impl_generics,
ty,
unnamed_fields,
)
}
(false, true) => {
deserialize_struct(
cx,
&builder,
item.ident,
impl_generics,
ty,
struct_def,
)
}
(false, false) => {
cx.bug("struct has named and unnamed fields")
}
}
}
// Build `__Visitor<A, B, ...>(PhantomData<A>, PhantomData<B>, ...)`
fn deserialize_visitor(
builder: &aster::AstBuilder,
trait_generics: &ast::Generics,
forward_ty_params: Vec<ast::TyParam>,
forward_tys: Vec<P<ast::Ty>>
) -> (P<ast::Item>, P<ast::Ty>, P<ast::Expr>, ast::Generics) {
if trait_generics.ty_params.is_empty() && forward_tys.is_empty() {
(
builder.item().tuple_struct("__Visitor").build(),
builder.ty().id("__Visitor"),
builder.expr().id("__Visitor"),
trait_generics.clone(),
)
} else {
let placeholders : Vec<_> = trait_generics.ty_params.iter()
.map(|t| builder.ty().id(t.ident))
.collect();
let mut trait_generics = trait_generics.clone();
let mut ty_params = forward_ty_params.clone();
ty_params.extend(trait_generics.ty_params.into_vec());
trait_generics.ty_params = OwnedSlice::from_vec(ty_params);
(
builder.item().tuple_struct("__Visitor")
.generics().with(trait_generics.clone()).build()
.with_tys(
trait_generics.ty_params.iter().map(|ty_param| {
builder.ty().phantom_data().id(ty_param.ident)
})
)
.build(),
builder.ty().path()
.segment("__Visitor").with_generics(trait_generics.clone()).build()
.build(),
builder.expr().call()
.path().segment("__Visitor")
.with_tys(forward_tys)
.with_tys(placeholders)
.build().build()
.with_args(
trait_generics.ty_params.iter().map(|_| {
builder.expr().phantom_data()
})
)
.build(),
trait_generics,
)
}
}
fn deserializer_ty_param(builder: &aster::AstBuilder) -> ast::TyParam {
builder.ty_param("__D")
.trait_bound(builder.path()
.global()
.segment("serde").build()
.segment("de").build()
.id("Deserializer")
.build())
.build()
.build()
}
fn deserializer_ty_arg(builder: &aster::AstBuilder) -> P<ast::Ty>{
builder.ty().id("__D")
}
fn deserialize_unit_struct(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: Ident,
) -> P<ast::Expr> {
let type_name = builder.expr().str(type_ident);
quote_expr!(cx, {
struct __Visitor;
impl ::serde::de::Visitor for __Visitor {
type Value = $type_ident;
#[inline]
fn visit_unit<E>(&mut self) -> ::std::result::Result<$type_ident, E>
where E: ::serde::de::Error,
{
Ok($type_ident)
}
#[inline]
fn visit_seq<V>(&mut self, mut visitor: V) -> ::std::result::Result<$type_ident, V::Error>
where V: ::serde::de::SeqVisitor,
{
try!(visitor.end());
self.visit_unit()
}
}
deserializer.visit_named_unit($type_name, __Visitor)
})
}
fn deserialize_tuple_struct(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: Ident,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
fields: usize,
) -> P<ast::Expr> {
let where_clause = &impl_generics.where_clause;
let (visitor_item, visitor_ty, visitor_expr, visitor_generics) =
deserialize_visitor(
builder,
impl_generics,
vec![deserializer_ty_param(builder)],
vec![deserializer_ty_arg(builder)],
);
let visit_seq_expr = deserialize_seq(
cx,
builder,
builder.path().id(type_ident).build(),
fields,
);
let type_name = builder.expr().str(type_ident);
quote_expr!(cx, {
$visitor_item
impl $visitor_generics ::serde::de::Visitor for $visitor_ty $where_clause {
type Value = $ty;
fn visit_seq<__V>(&mut self, mut visitor: __V) -> ::std::result::Result<$ty, __V::Error>
where __V: ::serde::de::SeqVisitor,
{
$visit_seq_expr
}
}
deserializer.visit_named_seq($type_name, $visitor_expr)
})
}
fn deserialize_seq(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
struct_path: ast::Path,
fields: usize,
) -> P<ast::Expr> {
let let_values: Vec<P<ast::Stmt>> = (0 .. fields)
.map(|i| {
let name = builder.id(format!("__field{}", i));
quote_stmt!(cx,
let $name = match try!(visitor.visit()) {
Some(value) => { value },
None => {
return Err(::serde::de::Error::end_of_stream_error());
}
};
).unwrap()
})
.collect();
let result = builder.expr().call()
.build_path(struct_path)
.with_args((0 .. fields).map(|i| builder.expr().id(format!("__field{}", i))))
.build();
quote_expr!(cx, {
$let_values
try!(visitor.end());
Ok($result)
})
}
fn deserialize_struct(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: Ident,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
struct_def: &StructDef,
) -> P<ast::Expr> {
let where_clause = &impl_generics.where_clause;
let (visitor_item, visitor_ty, visitor_expr, visitor_generics) =
deserialize_visitor(
builder,
&impl_generics,
vec![deserializer_ty_param(builder)],
vec![deserializer_ty_arg(builder)],
);
let (field_visitor, visit_map_expr) = deserialize_struct_visitor(
cx,
builder,
struct_def,
builder.path().id(type_ident).build(),
);
let type_name = builder.expr().str(type_ident);
quote_expr!(cx, {
$field_visitor
$visitor_item
impl $visitor_generics ::serde::de::Visitor for $visitor_ty $where_clause {
type Value = $ty;
#[inline]
fn visit_map<__V>(&mut self, mut visitor: __V) -> ::std::result::Result<$ty, __V::Error>
where __V: ::serde::de::MapVisitor,
{
$visit_map_expr
}
}
deserializer.visit_named_map($type_name, $visitor_expr)
})
}
fn deserialize_item_enum(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: Ident,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
enum_def: &EnumDef,
) -> P<ast::Expr> {
let where_clause = &impl_generics.where_clause;
let type_name = builder.expr().str(type_ident);
let variant_visitor = deserialize_field_visitor(
cx,
builder,
enum_def.variants.iter()
.map(|variant|
attr::FieldAttrs::new(
true,
builder.expr().str(variant.node.name)))
.collect()
);
// Match arms to extract a variant from a string
let variant_arms: Vec<_> = enum_def.variants.iter()
.enumerate()
.map(|(i, variant)| {
let variant_name = builder.pat().enum_()
.id("__Field").id(format!("__field{}", i)).build()
.build();
let expr = deserialize_variant(
cx,
builder,
type_ident,
impl_generics,
ty.clone(),
variant,
);
quote_arm!(cx, $variant_name => { $expr })
})
.collect();
let (visitor_item, visitor_ty, visitor_expr, visitor_generics) =
deserialize_visitor(
builder,
impl_generics,
vec![deserializer_ty_param(builder)],
vec![deserializer_ty_arg(builder)],
);
quote_expr!(cx, {
$variant_visitor
$visitor_item
impl $visitor_generics ::serde::de::EnumVisitor for $visitor_ty $where_clause {
type Value = $ty;
fn visit<__V>(&mut self, mut visitor: __V) -> ::std::result::Result<$ty, __V::Error>
where __V: ::serde::de::VariantVisitor,
{
match try!(visitor.visit_variant()) {
$variant_arms
}
}
}
deserializer.visit_enum($type_name, $visitor_expr)
})
}
fn deserialize_variant(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: Ident,
generics: &ast::Generics,
ty: P<ast::Ty>,
variant: &ast::Variant,
) -> P<ast::Expr> {
let variant_ident = variant.node.name;
match variant.node.kind {
ast::TupleVariantKind(ref args) if args.is_empty() => {
quote_expr!(cx, {
try!(visitor.visit_unit());
Ok($type_ident::$variant_ident)
})
}
ast::TupleVariantKind(ref args) => {
deserialize_tuple_variant(
cx,
builder,
type_ident,
variant_ident,
generics,
ty,
args.len(),
)
}
ast::StructVariantKind(ref struct_def) => {
deserialize_struct_variant(
cx,
builder,
type_ident,
variant_ident,
generics,
ty,
struct_def,
)
}
}
}
fn deserialize_tuple_variant(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: ast::Ident,
variant_ident: ast::Ident,
generics: &ast::Generics,
ty: P<ast::Ty>,
fields: usize,
) -> P<ast::Expr> {
let where_clause = &generics.where_clause;
let (visitor_item, visitor_ty, visitor_expr, visitor_generics) =
deserialize_visitor(
builder,
generics,
vec![deserializer_ty_param(builder)],
vec![deserializer_ty_arg(builder)],
);
let visit_seq_expr = deserialize_seq(
cx,
builder,
builder.path().id(type_ident).id(variant_ident).build(),
fields,
);
quote_expr!(cx, {
$visitor_item
impl $visitor_generics ::serde::de::Visitor for $visitor_ty $where_clause {
type Value = $ty;
fn visit_seq<__V>(&mut self, mut visitor: __V) -> ::std::result::Result<$ty, __V::Error>
where __V: ::serde::de::SeqVisitor,
{
$visit_seq_expr
}
}
visitor.visit_seq($visitor_expr)
})
}
fn deserialize_struct_variant(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: ast::Ident,
variant_ident: ast::Ident,
generics: &ast::Generics,
ty: P<ast::Ty>,
struct_def: &ast::StructDef,
) -> P<ast::Expr> {
let where_clause = &generics.where_clause;
let (field_visitor, field_expr) = deserialize_struct_visitor(
cx,
builder,
struct_def,
builder.path().id(type_ident).id(variant_ident).build(),
);
let (visitor_item, visitor_ty, visitor_expr, visitor_generics) =
deserialize_visitor(
builder,
generics,
vec![deserializer_ty_param(builder)],
vec![deserializer_ty_arg(builder)],
);
quote_expr!(cx, {
$field_visitor
$visitor_item
impl $visitor_generics ::serde::de::Visitor for $visitor_ty $where_clause {
type Value = $ty;
fn visit_map<__V>(&mut self, mut visitor: __V) -> ::std::result::Result<$ty, __V::Error>
where __V: ::serde::de::MapVisitor,
{
$field_expr
}
}
visitor.visit_map($visitor_expr)
})
}
fn deserialize_field_visitor(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
field_attrs: Vec<attr::FieldAttrs>,
) -> Vec<P<ast::Item>> {
// Create the field names for the fields.
let field_idents: Vec<ast::Ident> = (0 .. field_attrs.len())
.map(|i| builder.id(format!("__field{}", i)))
.collect();
let field_enum = builder.item()
.attr().allow(&["non_camel_case_types"])
.enum_("__Field")
.with_variants(
field_idents.iter().map(|field_ident| {
builder.variant(field_ident).tuple().build()
})
)
.build();
// A set of all the formats that have specialized field attributes
let formats = field_attrs.iter()
.fold(HashSet::new(), |mut set, field_expr| {
set.extend(field_expr.formats());
set
});
// Match arms to extract a field from a string
let default_field_arms: Vec<_> = field_idents.iter()
.zip(field_attrs.iter())
.map(|(field_ident, field_expr)| {
let expr = field_expr.default_key_expr();
quote_arm!(cx, $expr => { Ok(__Field::$field_ident) })
})
.collect();
let body = if formats.is_empty() {
// No formats specific attributes, so no match on format required
quote_expr!(cx,
match value {
$default_field_arms
_ => { Err(::serde::de::Error::unknown_field_error(value)) }
})
} else {
let field_arms : Vec<_> = formats.iter()
.map(|fmt| {
field_idents.iter()
.zip(field_attrs.iter())
.map(|(field_ident, field_expr)| {
let expr = field_expr.key_expr(fmt);
quote_arm!(cx, $expr => { Ok(__Field::$field_ident) })
})
.collect::<Vec<_>>()
})
.collect();
let fmt_matches : Vec<_> = formats.iter()
.zip(field_arms.iter())
.map(|(ref fmt, ref arms)| {
quote_arm!(cx, $fmt => {
match value {
$arms
_ => {
Err(::serde::de::Error::unknown_field_error(value))
}
}})
})
.collect();
quote_expr!(cx,
match __D::format() {
$fmt_matches
_ => match value {
$default_field_arms
_ => { Err(::serde::de::Error::unknown_field_error(value)) }
}
})
};
let impl_item = quote_item!(cx,
impl ::serde::de::Deserialize for __Field {
#[inline]
fn deserialize<D>(deserializer: &mut D) -> ::std::result::Result<__Field, D::Error>
where D: ::serde::de::Deserializer,
{
use std::marker::PhantomData;
struct __FieldVisitor<D> {
phantom: PhantomData<D>
}
impl<__D> ::serde::de::Visitor for __FieldVisitor<__D>
where __D: ::serde::de::Deserializer
{
type Value = __Field;
fn visit_str<E>(&mut self, value: &str) -> ::std::result::Result<__Field, E>
where E: ::serde::de::Error,
{
$body
}
fn visit_bytes<E>(&mut self, value: &[u8]) -> ::std::result::Result<__Field, E>
where E: ::serde::de::Error,
{
// TODO: would be better to generate a byte string literal match
match ::std::str::from_utf8(value) {
Ok(s) => self.visit_str(s),
_ => Err(::serde::de::Error::syntax_error()),
}
}
}
deserializer.visit(
__FieldVisitor::<D>{ phantom: PhantomData })
}
}
).unwrap();
vec![field_enum, impl_item]
}
fn deserialize_struct_visitor(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
struct_def: &ast::StructDef,
struct_path: ast::Path,
) -> (Vec<P<ast::Item>>, P<ast::Expr>) {
let field_visitor = deserialize_field_visitor(
cx,
builder,
field::struct_field_attrs(cx, builder, struct_def),
);
let visit_map_expr = deserialize_map(
cx,
builder,
struct_path,
struct_def,
);
(field_visitor, visit_map_expr)
}
fn deserialize_map(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
struct_path: ast::Path,
struct_def: &StructDef,
) -> P<ast::Expr> {
// Create the field names for the fields.
let field_names: Vec<ast::Ident> = (0 .. struct_def.fields.len())
.map(|i| builder.id(format!("__field{}", i)))
.collect();
// Declare each field.
let let_values: Vec<P<ast::Stmt>> = field_names.iter()
.map(|field_name| quote_stmt!(cx, let mut $field_name = None;).unwrap())
.collect();
// Match arms to extract a value for a field.
let value_arms: Vec<ast::Arm> = field_names.iter()
.map(|field_name| {
quote_arm!(cx,
__Field::$field_name => {
$field_name = Some(try!(visitor.visit_value()));
}
)
})
.collect();
let extract_values: Vec<P<ast::Stmt>> = field_names.iter()
.zip(field::struct_field_attrs(cx, builder, struct_def).iter())
.map(|(field_name, field_attr)| {
let missing_expr = if field_attr.use_default() {
quote_expr!(cx, ::std::default::Default::default())
} else {
let formats = field_attr.formats();
let arms : Vec<_> = formats.iter()
.map(|format| {
let key_expr = field_attr.key_expr(format);
quote_arm!(cx, $format => { $key_expr })
})
.collect();
let default = field_attr.default_key_expr();
if arms.is_empty() {
quote_expr!(cx, try!(visitor.missing_field($default)))
} else {
quote_expr!(
cx,
try!(visitor.missing_field(
match __D::format() {
$arms
_ => { $default }
})))
}
};
quote_stmt!(cx,
let $field_name = match $field_name {
Some($field_name) => $field_name,
None => $missing_expr
};
).unwrap()
})
.collect();
let result = builder.expr().struct_path(struct_path)
.with_id_exprs(
struct_def.fields.iter()
.zip(field_names.iter())
.map(|(field, field_name)| {
(
match field.node.kind {
ast::NamedField(name, _) => name.clone(),
ast::UnnamedField(_) => panic!("struct contains unnamed fields"),
},
builder.expr().id(field_name),
)
})
)
.build();
quote_expr!(cx, {
$let_values
while let Some(key) = try!(visitor.visit_key()) {
match key {
$value_arms
}
}
$extract_values
try!(visitor.end());
Ok($result)
})
}
+133
View File
@@ -0,0 +1,133 @@
use std::collections::HashMap;
use aster;
use syntax::ast;
use syntax::attr;
use syntax::ext::base::ExtCtxt;
use syntax::ptr::P;
use attr::FieldAttrs;
enum Rename<'a> {
None,
Global(&'a ast::Lit),
Format(HashMap<P<ast::Expr>, &'a ast::Lit>)
}
fn rename<'a>(
builder: &aster::AstBuilder,
mi: &'a ast::MetaItem,
) -> Option<Rename<'a>>
{
match mi.node {
ast::MetaNameValue(ref n, ref lit) => {
if n == &"rename" {
Some(Rename::Global(lit))
} else {
None
}
},
ast::MetaList(ref n, ref items) => {
if n == &"rename" {
let mut m = HashMap::new();
m.extend(
items.iter()
.filter_map(
|item|
match item.node {
ast::MetaNameValue(ref n, ref lit) =>
Some((builder.expr().str(n),
lit)),
_ => None
}));
Some(Rename::Format(m))
} else {
None
}
},
_ => None
}
}
fn default_value(mi: &ast::MetaItem) -> bool {
if let ast::MetaItem_::MetaWord(ref n) = mi.node {
n == &"default"
} else {
false
}
}
fn field_attrs<'a>(
builder: &aster::AstBuilder,
field: &'a ast::StructField,
) -> (Rename<'a>, bool) {
field.node.attrs.iter()
.find(|sa| {
if let ast::MetaList(ref n, _) = sa.node.value.node {
n == &"serde"
} else {
false
}
})
.and_then(|sa| {
if let ast::MetaList(_, ref vals) = sa.node.value.node {
attr::mark_used(&sa);
Some((vals.iter()
.fold(None, |v, mi| v.or(rename(builder, mi)))
.unwrap_or(Rename::None),
vals.iter().any(|mi| default_value(mi))))
} else {
Some((Rename::None, false))
}
})
.unwrap_or((Rename::None, false))
}
pub fn struct_field_attrs(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
struct_def: &ast::StructDef,
) -> Vec<FieldAttrs> {
struct_def.fields.iter()
.map(|field| {
match field_attrs(builder, field) {
(Rename::Global(rename), default_value) =>
FieldAttrs::new(
default_value,
builder.expr().build_lit(P(rename.clone()))),
(Rename::Format(renames), default_value) => {
let mut res = HashMap::new();
res.extend(
renames.into_iter()
.map(|(k,v)|
(k, builder.expr().build_lit(P(v.clone())))));
FieldAttrs::new_with_formats(
default_value,
default_field_name(cx, builder, field.node.kind),
res)
},
(Rename::None, default_value) => {
FieldAttrs::new(
default_value,
default_field_name(cx, builder, field.node.kind))
}
}
})
.collect()
}
fn default_field_name(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
kind: ast::StructFieldKind,
) -> P<ast::Expr> {
match kind {
ast::NamedField(name, _) => {
builder.expr().str(name)
}
ast::UnnamedField(_) => {
cx.bug("struct has named and unnamed fields")
}
}
}
+73
View File
@@ -0,0 +1,73 @@
#![cfg_attr(not(feature = "with-syntex"), feature(rustc_private, plugin))]
#![cfg_attr(not(feature = "with-syntex"), plugin(quasi_macros))]
extern crate aster;
extern crate quasi;
#[cfg(feature = "with-syntex")]
extern crate syntex;
#[cfg(feature = "with-syntex")]
extern crate syntex_syntax as syntax;
#[cfg(not(feature = "with-syntex"))]
extern crate syntax;
#[cfg(not(feature = "with-syntex"))]
extern crate rustc;
#[cfg(feature = "with-syntex")]
include!(concat!(env!("OUT_DIR"), "/lib.rs"));
#[cfg(not(feature = "with-syntex"))]
include!("lib.rs.in");
#[cfg(feature = "with-syntex")]
pub fn register(reg: &mut syntex::Registry) {
use syntax::{ast, fold};
reg.add_attr("feature(custom_derive)");
reg.add_attr("feature(custom_attribute)");
reg.add_decorator("derive_Serialize", ser::expand_derive_serialize);
reg.add_decorator("derive_Deserialize", de::expand_derive_deserialize);
reg.add_post_expansion_pass(strip_attributes);
/// Strip the serde attributes from the crate.
#[cfg(feature = "with-syntex")]
fn strip_attributes(krate: ast::Crate) -> ast::Crate {
/// Helper folder that strips the serde attributes after the extensions have been expanded.
struct StripAttributeFolder;
impl fold::Folder for StripAttributeFolder {
fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
match attr.node.value.node {
ast::MetaList(ref n, _) if n == &"serde" => { return None; }
_ => {}
}
Some(attr)
}
fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
fold::noop_fold_mac(mac, self)
}
}
fold::Folder::fold_crate(&mut StripAttributeFolder, krate)
}
}
#[cfg(not(feature = "with-syntex"))]
pub fn register(reg: &mut rustc::plugin::Registry) {
reg.register_syntax_extension(
syntax::parse::token::intern("derive_Serialize"),
syntax::ext::base::MultiDecorator(
Box::new(ser::expand_derive_serialize)));
reg.register_syntax_extension(
syntax::parse::token::intern("derive_Deserialize"),
syntax::ext::base::MultiDecorator(
Box::new(de::expand_derive_deserialize)));
}
+4
View File
@@ -0,0 +1,4 @@
mod attr;
mod de;
mod field;
mod ser;
+623
View File
@@ -0,0 +1,623 @@
use aster;
use syntax::ast::{
Ident,
MetaItem,
Item,
Expr,
StructDef,
};
use syntax::ast;
use syntax::codemap::Span;
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
use syntax::ptr::P;
use field::struct_field_attrs;
pub fn expand_derive_serialize(
cx: &mut ExtCtxt,
span: Span,
meta_item: &MetaItem,
annotatable: &Annotatable,
push: &mut FnMut(Annotatable)
) {
let item = match *annotatable {
Annotatable::Item(ref item) => item,
_ => {
cx.span_err(
meta_item.span,
"`derive` may only be applied to structs and enums");
return;
}
};
let builder = aster::AstBuilder::new().span(span);
let generics = match item.node {
ast::ItemStruct(_, ref generics) => generics,
ast::ItemEnum(_, ref generics) => generics,
_ => cx.bug("expected ItemStruct or ItemEnum in #[derive(Serialize)]")
};
let impl_generics = builder.from_generics(generics.clone())
.add_ty_param_bound(
builder.path().global().ids(&["serde", "ser", "Serialize"]).build()
)
.build();
let ty = builder.ty().path()
.segment(item.ident).with_generics(impl_generics.clone()).build()
.build();
let body = serialize_body(
cx,
&builder,
&item,
&impl_generics,
builder.ty()
.ref_()
.lifetime("'__a")
.build_ty(ty.clone()),
);
let where_clause = &impl_generics.where_clause;
let impl_item = quote_item!(cx,
#[automatically_derived]
impl $impl_generics ::serde::ser::Serialize for $ty $where_clause {
fn serialize<__S>(&self, serializer: &mut __S) -> ::std::result::Result<(), __S::Error>
where __S: ::serde::ser::Serializer,
{
$body
}
}
).unwrap();
push(Annotatable::Item(impl_item))
}
fn serialize_body(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
item: &Item,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
) -> P<ast::Expr> {
match item.node {
ast::ItemStruct(ref struct_def, _) => {
serialize_item_struct(
cx,
builder,
item,
impl_generics,
ty,
struct_def,
)
}
ast::ItemEnum(ref enum_def, _) => {
serialize_item_enum(
cx,
builder,
item.ident,
impl_generics,
ty,
enum_def,
)
}
_ => cx.bug("expected ItemStruct or ItemEnum in #[derive(Serialize)]")
}
}
fn serialize_item_struct(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
item: &Item,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
struct_def: &ast::StructDef,
) -> P<ast::Expr> {
let mut named_fields = vec![];
let mut unnamed_fields = 0;
for field in struct_def.fields.iter() {
match field.node.kind {
ast::NamedField(name, _) => { named_fields.push(name); }
ast::UnnamedField(_) => { unnamed_fields += 1; }
}
}
match (named_fields.is_empty(), unnamed_fields == 0) {
(true, true) => {
serialize_unit_struct(
cx,
&builder,
item.ident,
)
}
(true, false) => {
serialize_tuple_struct(
cx,
&builder,
item.ident,
impl_generics,
ty,
unnamed_fields,
)
}
(false, true) => {
serialize_struct(
cx,
&builder,
item.ident,
impl_generics,
ty,
struct_def,
named_fields,
)
}
(false, false) => {
cx.bug("struct has named and unnamed fields")
}
}
}
fn serialize_unit_struct(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: Ident
) -> P<ast::Expr> {
let type_name = builder.expr().str(type_ident);
quote_expr!(cx, serializer.visit_named_unit($type_name))
}
fn serialize_tuple_struct(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: Ident,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
fields: usize,
) -> P<ast::Expr> {
let (visitor_struct, visitor_impl) = serialize_tuple_struct_visitor(
cx,
builder,
ty.clone(),
ty,
fields,
impl_generics,
);
let type_name = builder.expr().str(type_ident);
quote_expr!(cx, {
$visitor_struct
$visitor_impl
serializer.visit_named_seq($type_name, Visitor {
value: self,
state: 0,
_structure_ty: ::std::marker::PhantomData,
})
})
}
fn serialize_struct(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: Ident,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
struct_def: &StructDef,
fields: Vec<Ident>,
) -> P<ast::Expr> {
let (visitor_struct, visitor_impl) = serialize_struct_visitor(
cx,
builder,
ty.clone(),
ty,
struct_def,
impl_generics,
fields.iter().map(|field| quote_expr!(cx, &self.value.$field)),
);
let type_name = builder.expr().str(type_ident);
quote_expr!(cx, {
$visitor_struct
$visitor_impl
serializer.visit_named_map($type_name, Visitor {
value: self,
state: 0,
_structure_ty: ::std::marker::PhantomData,
})
})
}
fn serialize_item_enum(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: Ident,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
enum_def: &ast::EnumDef,
) -> P<ast::Expr> {
let arms: Vec<ast::Arm> = enum_def.variants.iter()
.map(|variant| {
serialize_variant(
cx,
builder,
type_ident,
impl_generics,
ty.clone(),
variant,
)
})
.collect();
quote_expr!(cx,
match *self {
$arms
}
)
}
fn serialize_variant(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: Ident,
generics: &ast::Generics,
ty: P<ast::Ty>,
variant: &ast::Variant,
) -> ast::Arm {
let type_name = builder.expr().str(type_ident);
let variant_ident = variant.node.name;
let variant_name = builder.expr().str(variant_ident);
match variant.node.kind {
ast::TupleVariantKind(ref args) if args.is_empty() => {
let pat = builder.pat().enum_()
.id(type_ident).id(variant_ident).build()
.build();
quote_arm!(cx,
$pat => {
::serde::ser::Serializer::visit_enum_unit(
serializer,
$type_name,
$variant_name,
)
}
)
}
ast::TupleVariantKind(ref args) => {
let fields: Vec<ast::Ident> = (0 .. args.len())
.map(|i| builder.id(format!("__field{}", i)))
.collect();
let pat = builder.pat().enum_()
.id(type_ident).id(variant_ident).build()
.with_pats(fields.iter().map(|field| builder.pat().ref_id(field)))
.build();
let expr = serialize_tuple_variant(
cx,
builder,
type_name,
variant_name,
generics,
ty,
args,
fields,
);
quote_arm!(cx, $pat => { $expr })
}
ast::StructVariantKind(ref struct_def) => {
let fields: Vec<_> = (0 .. struct_def.fields.len())
.map(|i| builder.id(format!("__field{}", i)))
.collect();
let pat = builder.pat().struct_()
.id(type_ident).id(variant_ident).build()
.with_pats(
fields.iter()
.zip(struct_def.fields.iter())
.map(|(id, field)| {
let name = match field.node.kind {
ast::NamedField(name, _) => name,
ast::UnnamedField(_) => {
cx.bug("struct variant has unnamed fields")
}
};
(name, builder.pat().ref_id(id))
})
)
.build();
let expr = serialize_struct_variant(
cx,
builder,
type_name,
variant_name,
generics,
ty,
struct_def,
fields,
);
quote_arm!(cx, $pat => { $expr })
}
}
}
fn serialize_tuple_variant(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_name: P<ast::Expr>,
variant_name: P<ast::Expr>,
generics: &ast::Generics,
structure_ty: P<ast::Ty>,
args: &[ast::VariantArg],
fields: Vec<Ident>,
) -> P<ast::Expr> {
let variant_ty = builder.ty().tuple()
.with_tys(
args.iter().map(|arg| {
builder.ty()
.ref_()
.lifetime("'__a")
.build_ty(arg.ty.clone())
})
)
.build();
let (visitor_struct, visitor_impl) = serialize_tuple_struct_visitor(
cx,
builder,
structure_ty,
variant_ty,
args.len(),
generics,
);
let value_expr = builder.expr().tuple()
.with_exprs(
fields.iter().map(|field| {
builder.expr()
.addr_of()
.id(field)
})
)
.build();
quote_expr!(cx, {
$visitor_struct
$visitor_impl
serializer.visit_enum_seq($type_name, $variant_name, Visitor {
value: $value_expr,
state: 0,
_structure_ty: ::std::marker::PhantomData,
})
})
}
fn serialize_struct_variant(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_name: P<ast::Expr>,
variant_name: P<ast::Expr>,
generics: &ast::Generics,
structure_ty: P<ast::Ty>,
struct_def: &ast::StructDef,
fields: Vec<Ident>,
) -> P<ast::Expr> {
let value_ty = builder.ty().tuple()
.with_tys(
struct_def.fields.iter().map(|field| {
builder.ty()
.ref_()
.lifetime("'__a")
.build_ty(field.node.ty.clone())
})
)
.build();
let value_expr = builder.expr().tuple()
.with_exprs(
fields.iter().map(|field| {
builder.expr()
.addr_of()
.id(field)
})
)
.build();
let (visitor_struct, visitor_impl) = serialize_struct_visitor(
cx,
builder,
structure_ty,
value_ty,
struct_def,
generics,
(0 .. fields.len()).map(|i| {
builder.expr()
.tup_field(i)
.field("value").self_()
})
);
quote_expr!(cx, {
$visitor_struct
$visitor_impl
serializer.visit_enum_map($type_name, $variant_name, Visitor {
value: $value_expr,
state: 0,
_structure_ty: ::std::marker::PhantomData,
})
})
}
fn serialize_tuple_struct_visitor(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
structure_ty: P<ast::Ty>,
variant_ty: P<ast::Ty>,
fields: usize,
generics: &ast::Generics
) -> (P<ast::Item>, P<ast::Item>) {
let arms: Vec<ast::Arm> = (0 .. fields)
.map(|i| {
let expr = builder.expr()
.tup_field(i)
.field("value").self_();
quote_arm!(cx,
$i => {
self.state += 1;
let v = try!(serializer.visit_named_seq_elt(&$expr));
Ok(Some(v))
}
)
})
.collect();
let visitor_impl_generics = builder.from_generics(generics.clone())
.add_lifetime_bound("'__a")
.lifetime_name("'__a")
.build();
let where_clause = &visitor_impl_generics.where_clause;
let visitor_generics = builder.from_generics(visitor_impl_generics.clone())
.strip_bounds()
.build();
// Variants don't necessarily reference all generic lifetimes and type parameters,
// so to avoid a compilation failure, we'll just add a phantom type to capture these
// unused values.
let structure_ty = builder.ty()
.phantom_data()
.build(structure_ty);
(
quote_item!(cx,
struct Visitor $visitor_impl_generics $where_clause {
state: usize,
value: $variant_ty,
_structure_ty: $structure_ty,
}
).unwrap(),
quote_item!(cx,
impl $visitor_impl_generics ::serde::ser::SeqVisitor
for Visitor $visitor_generics
$where_clause {
#[inline]
fn visit<S>(&mut self, serializer: &mut S) -> ::std::result::Result<Option<()>, S::Error>
where S: ::serde::ser::Serializer
{
match self.state {
$arms
_ => Ok(None)
}
}
#[inline]
fn len(&self) -> Option<usize> {
Some($fields)
}
}
).unwrap(),
)
}
fn serialize_struct_visitor<I>(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
structure_ty: P<ast::Ty>,
variant_ty: P<ast::Ty>,
struct_def: &StructDef,
generics: &ast::Generics,
value_exprs: I,
) -> (P<ast::Item>, P<ast::Item>)
where I: Iterator<Item=P<ast::Expr>>,
{
let len = struct_def.fields.len();
let field_attrs = struct_field_attrs(cx, builder, struct_def);
let arms: Vec<ast::Arm> = field_attrs.into_iter()
.zip(value_exprs)
.enumerate()
.map(|(i, (field, value_expr))| {
let key_expr = field.serializer_key_expr(cx);
quote_arm!(cx,
$i => {
self.state += 1;
Ok(
Some(
try!(
serializer.visit_named_map_elt(
$key_expr,
$value_expr,
)
)
)
)
}
)
})
.collect();
let visitor_impl_generics = builder.from_generics(generics.clone())
.add_lifetime_bound("'__a")
.lifetime_name("'__a")
.build();
let where_clause = &visitor_impl_generics.where_clause;
let visitor_generics = builder.from_generics(visitor_impl_generics.clone())
.strip_bounds()
.build();
// Variants don't necessarily reference all generic lifetimes and type parameters,
// so to avoid a compilation failure, we'll just add a phantom type to capture these
// unused values.
let structure_ty = builder.ty()
.phantom_data()
.build(structure_ty);
(
quote_item!(cx,
struct Visitor $visitor_impl_generics $where_clause {
state: usize,
value: $variant_ty,
_structure_ty: $structure_ty,
}
).unwrap(),
quote_item!(cx,
impl $visitor_impl_generics
::serde::ser::MapVisitor
for Visitor $visitor_generics
$where_clause {
#[inline]
fn visit<S>(&mut self, serializer: &mut S) -> ::std::result::Result<Option<()>, S::Error>
where S: ::serde::ser::Serializer,
{
match self.state {
$arms
_ => Ok(None)
}
}
#[inline]
fn len(&self) -> Option<usize> {
Some($len)
}
}
).unwrap(),
)
}
+10 -4
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_macros"
version = "0.2.1"
version = "0.4.3"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Macros to auto-generate implementations for the serde framework"
@@ -10,7 +10,13 @@ repository = "https://github.com/erickt/rust-serde"
name = "serde_macros"
plugin = true
[features]
default = ["serde/nightly"]
[dependencies]
quasi = "0.1.3"
quasi_macros = "0.1.3"
aster = "0.1.3"
serde_codegen = { version = "*", path = "../serde_codegen", default-features = false, features = ["nightly"] }
[dev-dependencies]
num = "*"
rustc-serialize = "*"
serde = { version = "*", path = "../serde" }
+9
View File
@@ -0,0 +1,9 @@
#![feature(custom_attribute, custom_derive, plugin, test)]
#![plugin(serde_macros)]
extern crate num;
extern crate rustc_serialize;
extern crate serde;
extern crate test;
include!("../../serde_tests/benches/bench.rs.in");
+64
View File
@@ -0,0 +1,64 @@
#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]
extern crate serde;
use std::collections::BTreeMap;
use serde::json;
// Creating serializable types with serde is quite simple with `serde_macros`. It implements a
// syntax extension that automatically generates the necessary serde trait implementations.
#[derive(Debug, Serialize, Deserialize)]
struct Point {
x: i32,
y: i32,
}
fn main() {
let point = Point { x: 5, y: 6 };
// Serializing to JSON is pretty simple by using the `to_string` method:
let serialized_point = json::to_string(&point).unwrap();
println!("{}", serialized_point);
// prints:
//
// {"x":5,"y":6}
// There is also support for pretty printing using `to_string_pretty`:
let serialized_point = json::to_string_pretty(&point).unwrap();
println!("{}", serialized_point);
// prints:
//
// {
// "x":5,
// "y":6
// }
// Values can also be deserialized with the same style using `from_str`:
let deserialized_point: Point = json::from_str(&serialized_point).unwrap();
println!("{:?}", deserialized_point);
// prints:
//
// Point { x: 5, y: 6 }
// `Point`s aren't the only type that can be serialized to. Because `Point` members have the
// same type, they can be also serialized into a map. Also,
let deserialized_map: BTreeMap<String, i64> = json::from_str(&serialized_point).unwrap();
println!("{:?}", deserialized_map);
// prints:
//
// {"x": 5, "y": 6}
// If you need to accept arbitrary data, you can also deserialize into `json::Value`, which
// can represent all JSON values.
let deserialized_value: json::Value = json::from_str(&serialized_point).unwrap();
println!("{:?}", deserialized_value);
// prints:
//
// {"x":5,"y":6}
}
+4 -1437
View File
File diff suppressed because it is too large Load Diff
+7
View File
@@ -0,0 +1,7 @@
#![feature(test, custom_attribute, custom_derive, plugin)]
#![plugin(serde_macros)]
extern crate serde;
extern crate test;
include!("../../serde_tests/tests/test.rs.in");
+30
View File
@@ -0,0 +1,30 @@
[package]
name = "serde_tests"
version = "0.4.3"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework"
repository = "https://github.com/serde-rs/serde"
documentation = "http://serde-rs.github.io/serde/serde"
readme = "README.md"
keywords = ["serialization"]
build = "build.rs"
[build-dependencies]
syntex = { version = "*", optional = true }
syntex_syntax = { version = "*" }
serde_codegen = { version = "*", path = "../serde_codegen", features = ["with-syntex"] }
[dev-dependencies]
num = "*"
rustc-serialize = "*"
serde = { version = "*", path = "../serde" }
syntex = "*"
[[test]]
name = "test"
path = "tests/test.rs"
[[bench]]
name = "bench"
path = "benches/bench.rs"
+8
View File
@@ -0,0 +1,8 @@
#![feature(test)]
extern crate num;
extern crate rustc_serialize;
extern crate serde;
extern crate test;
include!(concat!(env!("OUT_DIR"), "/bench.rs"));
+5
View File
@@ -0,0 +1,5 @@
mod bench_enum;
mod bench_log;
mod bench_map;
mod bench_struct;
mod bench_vec;
@@ -1,23 +1,12 @@
#![feature(custom_derive, plugin, test)]
#![plugin(serde_macros)]
extern crate serde;
extern crate "rustc-serialize" as rustc_serialize;
extern crate test;
use test::Bencher;
use rustc_serialize::{Decoder, Decodable};
use serde;
use serde::de::{Deserializer, Deserialize};
use Animal::{Dog, Frog};
//////////////////////////////////////////////////////////////////////////////
#[derive(Clone, PartialEq, Debug, RustcDecodable)]
#[derive_deserialize]
enum Animal {
#[derive(Clone, PartialEq, Debug, RustcDecodable, Deserialize)]
pub enum Animal {
Dog,
Frog(String, isize)
}
@@ -35,6 +24,8 @@ impl serde::de::Error for Error {
fn end_of_stream_error() -> Error { Error::EndOfStreamError }
fn unknown_field_error(_: &str) -> Error { Error::SyntaxError }
fn missing_field_error(_: &'static str) -> Error { Error::SyntaxError }
}
@@ -245,9 +236,11 @@ mod deserializer {
use serde::de;
#[derive(Debug)]
enum State {
AnimalState(Animal),
IsizeState(isize),
StrState(&'static str),
StringState(String),
UnitState,
}
@@ -273,29 +266,51 @@ mod deserializer {
where V: de::Visitor,
{
match self.stack.pop() {
Some(State::AnimalState(Animal::Dog)) => {
self.stack.push(State::UnitState);
visitor.visit_enum("Animal", "Dog", DogVisitor {
de: self,
})
}
Some(State::AnimalState(Animal::Frog(x0, x1))) => {
self.stack.push(State::IsizeState(x1));
self.stack.push(State::StringState(x0));
visitor.visit_enum("Animal", "Frog", FrogVisitor {
de: self,
state: 0,
})
}
Some(State::IsizeState(value)) => {
visitor.visit_isize(value)
}
Some(State::StringState(value)) => {
visitor.visit_string(value)
}
Some(State::StrState(value)) => {
visitor.visit_str(value)
}
Some(State::UnitState) => {
visitor.visit_unit()
}
Some(_) => {
Err(Error::SyntaxError)
}
None => {
Err(Error::EndOfStreamError)
}
}
}
#[inline]
fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
match self.stack.pop() {
Some(State::AnimalState(Animal::Dog)) => {
self.stack.push(State::UnitState);
self.stack.push(State::StrState("Dog"));
visitor.visit(DogVisitor {
de: self,
})
}
Some(State::AnimalState(Animal::Frog(x0, x1))) => {
self.stack.push(State::IsizeState(x1));
self.stack.push(State::StringState(x0));
self.stack.push(State::StrState("Frog"));
visitor.visit(FrogVisitor {
de: self,
state: 0,
})
}
Some(_) => {
Err(Error::SyntaxError)
}
None => {
Err(Error::EndOfStreamError)
}
@@ -307,9 +322,15 @@ mod deserializer {
de: &'a mut AnimalDeserializer,
}
impl<'a> de::EnumVisitor for DogVisitor<'a> {
impl<'a> de::VariantVisitor for DogVisitor<'a> {
type Error = Error;
fn visit_variant<V>(&mut self) -> Result<V, Error>
where V: de::Deserialize
{
de::Deserialize::deserialize(self.de)
}
fn visit_unit(&mut self) -> Result<(), Error> {
de::Deserialize::deserialize(self.de)
}
@@ -320,13 +341,19 @@ mod deserializer {
state: usize,
}
impl<'a> de::EnumVisitor for FrogVisitor<'a> {
impl<'a> de::VariantVisitor for FrogVisitor<'a> {
type Error = Error;
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumSeqVisitor,
fn visit_variant<V>(&mut self) -> Result<V, Error>
where V: de::Deserialize
{
visitor.visit(self)
de::Deserialize::deserialize(self.de)
}
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
visitor.visit_seq(self)
}
}
@@ -371,7 +398,7 @@ mod deserializer {
#[bench]
fn bench_decoder_dog(b: &mut Bencher) {
b.iter(|| {
let animal = Dog;
let animal = Animal::Dog;
let mut d = decoder::AnimalDecoder::new(animal.clone());
let value: Animal = Decodable::decode(&mut d).unwrap();
@@ -383,7 +410,7 @@ fn bench_decoder_dog(b: &mut Bencher) {
#[bench]
fn bench_decoder_frog(b: &mut Bencher) {
b.iter(|| {
let animal = Frog("Henry".to_string(), 349);
let animal = Animal::Frog("Henry".to_string(), 349);
let mut d = decoder::AnimalDecoder::new(animal.clone());
let value: Animal = Decodable::decode(&mut d).unwrap();
@@ -395,7 +422,7 @@ fn bench_decoder_frog(b: &mut Bencher) {
#[bench]
fn bench_deserializer_dog(b: &mut Bencher) {
b.iter(|| {
let animal = Dog;
let animal = Animal::Dog;
let mut d = deserializer::AnimalDeserializer::new(animal.clone());
let value: Animal = Deserialize::deserialize(&mut d).unwrap();
@@ -407,7 +434,7 @@ fn bench_deserializer_dog(b: &mut Bencher) {
#[bench]
fn bench_deserializer_frog(b: &mut Bencher) {
b.iter(|| {
let animal = Frog("Henry".to_string(), 349);
let animal = Animal::Frog("Henry".to_string(), 349);
let mut d = deserializer::AnimalDeserializer::new(animal.clone());
let value: Animal = Deserialize::deserialize(&mut d).unwrap();
@@ -1,25 +1,18 @@
#![feature(custom_derive, collections, core, io, plugin, test)]
#![allow(non_camel_case_types)]
#![plugin(serde_macros)]
extern crate serde;
extern crate "rustc-serialize" as rustc_serialize;
extern crate test;
use std::io::{self, ReadExt, WriteExt};
use std::num::FromPrimitive;
use std::io::{self, Read, Write};
use num::FromPrimitive;
use test::Bencher;
use rustc_serialize;
use serde::de::{self, Deserialize, Deserializer};
use serde::json::ser::escape_str;
use serde::json;
use serde::ser::{self, Serialize, Serializer};
use std::str::FromStr;
use rustc_serialize::Encodable;
#[derive(Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive_serialize]
#[derive_deserialize]
#[derive(Debug, PartialEq, RustcEncodable, RustcDecodable, Serialize, Deserialize)]
struct Http {
protocol: HttpProtocol,
status: u32,
@@ -32,7 +25,8 @@ struct Http {
request_uri: String,
}
#[derive(Copy, Debug, PartialEq, FromPrimitive)]
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, PartialEq)]
enum HttpProtocol {
HTTP_PROTOCOL_UNKNOWN,
HTTP10,
@@ -54,12 +48,32 @@ impl rustc_serialize::Decodable for HttpProtocol {
}
}
impl FromStr for HttpProtocol {
type Err = ();
fn from_str(_s: &str) -> Result<HttpProtocol, ()> { unimplemented!() }
}
impl FromPrimitive for HttpProtocol {
fn from_i64(i: i64) -> Option<HttpProtocol> {
FromPrimitive::from_u64(i as u64)
}
fn from_u64(n: u64) -> Option<HttpProtocol> {
match n {
0 => Some(HttpProtocol::HTTP_PROTOCOL_UNKNOWN),
1 => Some(HttpProtocol::HTTP10),
2 => Some(HttpProtocol::HTTP11),
_ => None,
}
}
}
impl ser::Serialize for HttpProtocol {
#[inline]
fn visit<
V: ser::Visitor,
>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
visitor.visit_u8(*self as u8)
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer,
{
serializer.visit_u8(*self as u8)
}
}
@@ -68,11 +82,12 @@ impl de::Deserialize for HttpProtocol {
fn deserialize<
S: Deserializer,
>(state: &mut S) -> Result<HttpProtocol, S::Error> {
state.visit(de::PrimitiveVisitor::new())
state.visit(de::impls::PrimitiveVisitor::new())
}
}
#[derive(Copy, Debug, PartialEq, FromPrimitive)]
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, PartialEq)]
enum HttpMethod {
METHOD_UNKNOWN,
GET,
@@ -87,6 +102,34 @@ enum HttpMethod {
PATCH,
}
impl FromStr for HttpMethod {
type Err = ();
fn from_str(_s: &str) -> Result<HttpMethod, ()> { unimplemented!() }
}
impl FromPrimitive for HttpMethod {
fn from_i64(i: i64) -> Option<HttpMethod> {
FromPrimitive::from_u64(i as u64)
}
fn from_u64(n: u64) -> Option<HttpMethod> {
match n {
0 => Some(HttpMethod::METHOD_UNKNOWN),
1 => Some(HttpMethod::GET),
2 => Some(HttpMethod::POST),
3 => Some(HttpMethod::DELETE),
4 => Some(HttpMethod::PUT),
5 => Some(HttpMethod::HEAD),
6 => Some(HttpMethod::PURGE),
7 => Some(HttpMethod::OPTIONS),
8 => Some(HttpMethod::PROPFIND),
9 => Some(HttpMethod::MKCOL),
10 => Some(HttpMethod::PATCH),
_ => None,
}
}
}
impl rustc_serialize::Encodable for HttpMethod {
fn encode<S: rustc_serialize::Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
(*self as usize).encode(s)
@@ -104,10 +147,10 @@ impl rustc_serialize::Decodable for HttpMethod {
impl ser::Serialize for HttpMethod {
#[inline]
fn visit<
V: ser::Visitor,
>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
visitor.visit_u8(*self as u8)
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer,
{
serializer.visit_u8(*self as u8)
}
}
@@ -116,11 +159,12 @@ impl de::Deserialize for HttpMethod {
fn deserialize<
S: de::Deserializer,
>(state: &mut S) -> Result<HttpMethod, S::Error> {
state.visit(de::PrimitiveVisitor::new())
state.visit(de::impls::PrimitiveVisitor::new())
}
}
#[derive(Copy, Debug, PartialEq, FromPrimitive)]
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, PartialEq)]
enum CacheStatus {
CACHESTATUS_UNKNOWN,
Miss,
@@ -128,6 +172,27 @@ enum CacheStatus {
Hit,
}
impl FromStr for CacheStatus {
type Err = ();
fn from_str(_s: &str) -> Result<CacheStatus, ()> { unimplemented!() }
}
impl FromPrimitive for CacheStatus {
fn from_i64(i: i64) -> Option<CacheStatus> {
FromPrimitive::from_u64(i as u64)
}
fn from_u64(n: u64) -> Option<CacheStatus> {
match n {
0 => Some(CacheStatus::CACHESTATUS_UNKNOWN),
1 => Some(CacheStatus::Miss),
2 => Some(CacheStatus::Expired),
3 => Some(CacheStatus::Hit),
_ => None,
}
}
}
impl rustc_serialize::Encodable for CacheStatus {
fn encode<S: rustc_serialize::Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
(*self as u8).encode(s)
@@ -145,10 +210,10 @@ impl rustc_serialize::Decodable for CacheStatus {
impl ser::Serialize for CacheStatus {
#[inline]
fn visit<
V: ser::Visitor,
>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
visitor.visit_u8(*self as u8)
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer,
{
serializer.visit_u8(*self as u8)
}
}
@@ -157,13 +222,11 @@ impl de::Deserialize for CacheStatus {
fn deserialize<
S: de::Deserializer,
>(state: &mut S) -> Result<CacheStatus, S::Error> {
state.visit(de::PrimitiveVisitor::new())
state.visit(de::impls::PrimitiveVisitor::new())
}
}
#[derive(Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive_serialize]
#[derive_deserialize]
#[derive(Debug, PartialEq, RustcEncodable, RustcDecodable, Serialize, Deserialize)]
struct Origin {
ip: String,
port: u32,
@@ -171,13 +234,34 @@ struct Origin {
protocol: OriginProtocol,
}
#[derive(Copy, Debug, PartialEq, FromPrimitive)]
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, PartialEq)]
enum OriginProtocol {
ORIGIN_PROTOCOL_UNKNOWN,
HTTP,
HTTPS,
}
impl FromStr for OriginProtocol {
type Err = ();
fn from_str(_s: &str) -> Result<OriginProtocol, ()> { unimplemented!() }
}
impl FromPrimitive for OriginProtocol {
fn from_i64(i: i64) -> Option<OriginProtocol> {
FromPrimitive::from_u64(i as u64)
}
fn from_u64(n: u64) -> Option<OriginProtocol> {
match n {
0 => Some(OriginProtocol::ORIGIN_PROTOCOL_UNKNOWN),
1 => Some(OriginProtocol::HTTP),
2 => Some(OriginProtocol::HTTPS),
_ => None,
}
}
}
impl rustc_serialize::Encodable for OriginProtocol {
fn encode<S: rustc_serialize::Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
(*self as u8).encode(s)
@@ -195,10 +279,10 @@ impl rustc_serialize::Decodable for OriginProtocol {
impl ser::Serialize for OriginProtocol {
#[inline]
fn visit<
V: ser::Visitor,
>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
visitor.visit_u8(*self as u8)
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer,
{
serializer.visit_u8(*self as u8)
}
}
@@ -207,11 +291,12 @@ impl de::Deserialize for OriginProtocol {
fn deserialize<
S: de::Deserializer,
>(state: &mut S) -> Result<OriginProtocol, S::Error> {
state.visit(de::PrimitiveVisitor::new())
state.visit(de::impls::PrimitiveVisitor::new())
}
}
#[derive(Copy, Debug, PartialEq, FromPrimitive)]
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, PartialEq)]
enum ZonePlan {
ZONEPLAN_UNKNOWN,
FREE,
@@ -220,6 +305,28 @@ enum ZonePlan {
ENT,
}
impl FromStr for ZonePlan {
type Err = ();
fn from_str(_s: &str) -> Result<ZonePlan, ()> { unimplemented!() }
}
impl FromPrimitive for ZonePlan {
fn from_i64(i: i64) -> Option<ZonePlan> {
FromPrimitive::from_u64(i as u64)
}
fn from_u64(n: u64) -> Option<ZonePlan> {
match n {
0 => Some(ZonePlan::ZONEPLAN_UNKNOWN),
1 => Some(ZonePlan::FREE),
2 => Some(ZonePlan::PRO),
3 => Some(ZonePlan::BIZ),
4 => Some(ZonePlan::ENT),
_ => None,
}
}
}
impl rustc_serialize::Encodable for ZonePlan {
fn encode<S: rustc_serialize::Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
(*self as u8).encode(s)
@@ -237,10 +344,10 @@ impl rustc_serialize::Decodable for ZonePlan {
impl ser::Serialize for ZonePlan {
#[inline]
fn visit<
V: ser::Visitor,
>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
visitor.visit_u8(*self as u8)
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer,
{
serializer.visit_u8(*self as u8)
}
}
@@ -249,11 +356,11 @@ impl de::Deserialize for ZonePlan {
fn deserialize<
S: de::Deserializer,
>(state: &mut S) -> Result<ZonePlan, S::Error> {
state.visit(de::PrimitiveVisitor::new())
state.visit(de::impls::PrimitiveVisitor::new())
}
}
#[derive(Copy, Debug, PartialEq, FromPrimitive)]
#[derive(Copy, Clone, Debug, PartialEq)]
enum Country {
UNKNOWN,
A1,
@@ -513,6 +620,279 @@ enum Country {
ZW,
}
impl FromStr for Country {
type Err = ();
fn from_str(_s: &str) -> Result<Country, ()> { unimplemented!() }
}
impl FromPrimitive for Country {
fn from_i64(i: i64) -> Option<Country> {
FromPrimitive::from_u64(i as u64)
}
fn from_u64(n: u64) -> Option<Country> {
match n {
0 => Some(Country::UNKNOWN),
1 => Some(Country::A1),
2 => Some(Country::A2),
3 => Some(Country::O1),
4 => Some(Country::AD),
5 => Some(Country::AE),
6 => Some(Country::AF),
7 => Some(Country::AG),
8 => Some(Country::AI),
9 => Some(Country::AL),
10 => Some(Country::AM),
11 => Some(Country::AO),
12 => Some(Country::AP),
13 => Some(Country::AQ),
14 => Some(Country::AR),
15 => Some(Country::AS),
16 => Some(Country::AT),
17 => Some(Country::AU),
18 => Some(Country::AW),
19 => Some(Country::AX),
20 => Some(Country::AZ),
21 => Some(Country::BA),
22 => Some(Country::BB),
23 => Some(Country::BD),
24 => Some(Country::BE),
25 => Some(Country::BF),
26 => Some(Country::BG),
27 => Some(Country::BH),
28 => Some(Country::BI),
29 => Some(Country::BJ),
30 => Some(Country::BL),
31 => Some(Country::BM),
32 => Some(Country::BN),
33 => Some(Country::BO),
34 => Some(Country::BQ),
35 => Some(Country::BR),
36 => Some(Country::BS),
37 => Some(Country::BT),
38 => Some(Country::BV),
39 => Some(Country::BW),
40 => Some(Country::BY),
41 => Some(Country::BZ),
42 => Some(Country::CA),
43 => Some(Country::CC),
44 => Some(Country::CD),
45 => Some(Country::CF),
46 => Some(Country::CG),
47 => Some(Country::CH),
48 => Some(Country::CI),
49 => Some(Country::CK),
50 => Some(Country::CL),
51 => Some(Country::CM),
52 => Some(Country::CN),
53 => Some(Country::CO),
54 => Some(Country::CR),
55 => Some(Country::CU),
56 => Some(Country::CV),
57 => Some(Country::CW),
58 => Some(Country::CX),
59 => Some(Country::CY),
60 => Some(Country::CZ),
61 => Some(Country::DE),
62 => Some(Country::DJ),
63 => Some(Country::DK),
64 => Some(Country::DM),
65 => Some(Country::DO),
66 => Some(Country::DZ),
67 => Some(Country::EC),
68 => Some(Country::EE),
69 => Some(Country::EG),
70 => Some(Country::EH),
71 => Some(Country::ER),
72 => Some(Country::ES),
73 => Some(Country::ET),
74 => Some(Country::EU),
75 => Some(Country::FI),
76 => Some(Country::FJ),
77 => Some(Country::FK),
78 => Some(Country::FM),
79 => Some(Country::FO),
80 => Some(Country::FR),
81 => Some(Country::GA),
82 => Some(Country::GB),
83 => Some(Country::GD),
84 => Some(Country::GE),
85 => Some(Country::GF),
86 => Some(Country::GG),
87 => Some(Country::GH),
88 => Some(Country::GI),
89 => Some(Country::GL),
90 => Some(Country::GM),
91 => Some(Country::GN),
92 => Some(Country::GP),
93 => Some(Country::GQ),
94 => Some(Country::GR),
95 => Some(Country::GS),
96 => Some(Country::GT),
97 => Some(Country::GU),
98 => Some(Country::GW),
99 => Some(Country::GY),
100 => Some(Country::HK),
101 => Some(Country::HM),
102 => Some(Country::HN),
103 => Some(Country::HR),
104 => Some(Country::HT),
105 => Some(Country::HU),
106 => Some(Country::ID),
107 => Some(Country::IE),
108 => Some(Country::IL),
109 => Some(Country::IM),
110 => Some(Country::IN),
111 => Some(Country::IO),
112 => Some(Country::IQ),
113 => Some(Country::IR),
114 => Some(Country::IS),
115 => Some(Country::IT),
116 => Some(Country::JE),
117 => Some(Country::JM),
118 => Some(Country::JO),
119 => Some(Country::JP),
120 => Some(Country::KE),
121 => Some(Country::KG),
122 => Some(Country::KH),
123 => Some(Country::KI),
124 => Some(Country::KM),
125 => Some(Country::KN),
126 => Some(Country::KP),
127 => Some(Country::KR),
128 => Some(Country::KW),
129 => Some(Country::KY),
130 => Some(Country::KZ),
131 => Some(Country::LA),
132 => Some(Country::LB),
133 => Some(Country::LC),
134 => Some(Country::LI),
135 => Some(Country::LK),
136 => Some(Country::LR),
137 => Some(Country::LS),
138 => Some(Country::LT),
139 => Some(Country::LU),
140 => Some(Country::LV),
141 => Some(Country::LY),
142 => Some(Country::MA),
143 => Some(Country::MC),
144 => Some(Country::MD),
145 => Some(Country::ME),
146 => Some(Country::MF),
147 => Some(Country::MG),
148 => Some(Country::MH),
149 => Some(Country::MK),
150 => Some(Country::ML),
151 => Some(Country::MM),
152 => Some(Country::MN),
153 => Some(Country::MO),
154 => Some(Country::MP),
155 => Some(Country::MQ),
156 => Some(Country::MR),
157 => Some(Country::MS),
158 => Some(Country::MT),
159 => Some(Country::MU),
160 => Some(Country::MV),
161 => Some(Country::MW),
162 => Some(Country::MX),
163 => Some(Country::MY),
164 => Some(Country::MZ),
165 => Some(Country::NA),
166 => Some(Country::NC),
167 => Some(Country::NE),
168 => Some(Country::NF),
169 => Some(Country::NG),
170 => Some(Country::NI),
171 => Some(Country::NL),
172 => Some(Country::NO),
173 => Some(Country::NP),
174 => Some(Country::NR),
175 => Some(Country::NU),
176 => Some(Country::NZ),
177 => Some(Country::OM),
178 => Some(Country::PA),
179 => Some(Country::PE),
180 => Some(Country::PF),
181 => Some(Country::PG),
182 => Some(Country::PH),
183 => Some(Country::PK),
184 => Some(Country::PL),
185 => Some(Country::PM),
186 => Some(Country::PN),
187 => Some(Country::PR),
188 => Some(Country::PS),
189 => Some(Country::PT),
190 => Some(Country::PW),
191 => Some(Country::PY),
192 => Some(Country::QA),
193 => Some(Country::RE),
194 => Some(Country::RO),
195 => Some(Country::RS),
196 => Some(Country::RU),
197 => Some(Country::RW),
198 => Some(Country::SA),
199 => Some(Country::SB),
200 => Some(Country::SC),
201 => Some(Country::SD),
202 => Some(Country::SE),
203 => Some(Country::SG),
204 => Some(Country::SH),
205 => Some(Country::SI),
206 => Some(Country::SJ),
207 => Some(Country::SK),
208 => Some(Country::SL),
209 => Some(Country::SM),
210 => Some(Country::SN),
211 => Some(Country::SO),
212 => Some(Country::SR),
213 => Some(Country::SS),
214 => Some(Country::ST),
215 => Some(Country::SV),
216 => Some(Country::SX),
217 => Some(Country::SY),
218 => Some(Country::SZ),
219 => Some(Country::TC),
220 => Some(Country::TD),
221 => Some(Country::TF),
222 => Some(Country::TG),
223 => Some(Country::TH),
224 => Some(Country::TJ),
225 => Some(Country::TK),
226 => Some(Country::TL),
227 => Some(Country::TM),
228 => Some(Country::TN),
229 => Some(Country::TO),
230 => Some(Country::TR),
231 => Some(Country::TT),
232 => Some(Country::TV),
233 => Some(Country::TW),
234 => Some(Country::TZ),
235 => Some(Country::UA),
236 => Some(Country::UG),
237 => Some(Country::UM),
238 => Some(Country::US),
239 => Some(Country::UY),
240 => Some(Country::UZ),
241 => Some(Country::VA),
242 => Some(Country::VC),
243 => Some(Country::VE),
244 => Some(Country::VG),
245 => Some(Country::VI),
246 => Some(Country::VN),
247 => Some(Country::VU),
248 => Some(Country::WF),
249 => Some(Country::WS),
250 => Some(Country::XX),
251 => Some(Country::YE),
252 => Some(Country::YT),
253 => Some(Country::ZA),
254 => Some(Country::ZM),
255 => Some(Country::ZW),
_ => None,
}
}
}
impl rustc_serialize::Encodable for Country {
fn encode<S: rustc_serialize::Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
(*self as u8).encode(s)
@@ -530,10 +910,10 @@ impl rustc_serialize::Decodable for Country {
impl ser::Serialize for Country {
#[inline]
fn visit<
V: ser::Visitor,
>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
visitor.visit_u8(*self as u8)
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer,
{
serializer.visit_u8(*self as u8)
}
}
@@ -542,13 +922,11 @@ impl de::Deserialize for Country {
fn deserialize<
S: de::Deserializer,
>(state: &mut S) -> Result<Country, S::Error> {
state.visit(de::PrimitiveVisitor::new())
state.visit(de::impls::PrimitiveVisitor::new())
}
}
#[derive(Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive_serialize]
#[derive_deserialize]
#[derive(Debug, PartialEq, RustcEncodable, RustcDecodable, Serialize, Deserialize)]
struct Log {
timestamp: i64,
zone_id: u32,
@@ -637,13 +1015,21 @@ impl MyMemWriter0 {
}
impl io::Write for MyMemWriter0 {
impl Write for MyMemWriter0 {
#[cfg(feature = "nightly")]
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.buf.push_all(buf);
Ok(buf.len())
}
#[cfg(not(feature = "nightly"))]
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.buf.extend(buf.iter().cloned());
Ok(buf.len())
}
#[inline]
fn flush(&mut self) -> io::Result<()> {
Ok(())
@@ -676,13 +1062,13 @@ fn push_all_bytes(dst: &mut Vec<u8>, src: &[u8]) {
dst.set_len(dst_len + src_len);
::std::ptr::copy_nonoverlapping(
dst.as_mut_ptr().offset(dst_len as isize),
src.as_ptr(),
dst.as_mut_ptr().offset(dst_len as isize),
src_len);
}
}
impl io::Write for MyMemWriter1 {
impl Write for MyMemWriter1 {
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
push_all_bytes(&mut self.buf, buf);
@@ -757,7 +1143,7 @@ fn test_serializer_vec() {
let log = Log::new();
let wr = Vec::with_capacity(1024);
let mut serializer = json::Serializer::new(wr);
serializer.visit(&log).unwrap();
log.serialize(&mut serializer).unwrap();
let json = serializer.into_inner();
assert_eq!(&json, &JSON_STR.as_bytes());
@@ -775,7 +1161,7 @@ fn bench_serializer_vec(b: &mut Bencher) {
wr.clear();
let mut serializer = json::Serializer::new(wr.by_ref());
serializer.visit(&log).unwrap();
log.serialize(&mut serializer).unwrap();
let _json = serializer.into_inner();
});
}
@@ -793,7 +1179,7 @@ fn bench_serializer_slice(b: &mut Bencher) {
let mut wr = &mut buf[..];
let mut serializer = json::Serializer::new(wr.by_ref());
serializer.visit(&log).unwrap();
log.serialize(&mut serializer).unwrap();
let _json = serializer.into_inner();
});
}
@@ -806,7 +1192,7 @@ fn test_serializer_my_mem_writer0() {
{
let mut serializer = json::Serializer::new(wr.by_ref());
serializer.visit(&log).unwrap();
log.serialize(&mut serializer).unwrap();
let _json = serializer.into_inner();
}
@@ -825,7 +1211,7 @@ fn bench_serializer_my_mem_writer0(b: &mut Bencher) {
wr.buf.clear();
let mut serializer = json::Serializer::new(wr.by_ref());
serializer.visit(&log).unwrap();
log.serialize(&mut serializer).unwrap();
let _json = serializer.into_inner();
});
}
@@ -838,7 +1224,7 @@ fn test_serializer_my_mem_writer1() {
{
let mut serializer = json::Serializer::new(wr.by_ref());
serializer.visit(&log).unwrap();
log.serialize(&mut serializer).unwrap();
let _json = serializer.into_inner();
}
@@ -857,7 +1243,7 @@ fn bench_serializer_my_mem_writer1(b: &mut Bencher) {
wr.buf.clear();
let mut serializer = json::Serializer::new(wr.by_ref());
serializer.visit(&log).unwrap();
log.serialize(&mut serializer).unwrap();
let _json = serializer.into_inner();
});
}
@@ -872,7 +1258,7 @@ fn bench_copy(b: &mut Bencher) {
});
}
fn manual_serialize_no_escape<W: io::Write>(wr: &mut W, log: &Log) {
fn manual_serialize_no_escape<W: Write>(wr: &mut W, log: &Log) {
wr.write(b"{\"timestamp\":").unwrap();
(write!(wr, "{}", log.timestamp)).unwrap();
wr.write(b",\"zone_id\":").unwrap();
@@ -929,7 +1315,7 @@ fn manual_serialize_no_escape<W: io::Write>(wr: &mut W, log: &Log) {
wr.write(b"}").unwrap();
}
fn manual_serialize_escape<W: io::Write>(wr: &mut W, log: &Log) {
fn manual_serialize_escape<W: Write>(wr: &mut W, log: &Log) {
wr.write_all(b"{").unwrap();
escape_str(wr, "timestamp").unwrap();
wr.write_all(b":").unwrap();
@@ -1,16 +1,10 @@
#![feature(custom_derive, core, plugin, test)]
#![plugin(serde_macros)]
extern crate serde;
extern crate "rustc-serialize" as rustc_serialize;
extern crate test;
use std::fmt::Debug;
use std::collections::HashMap;
use test::Bencher;
use rustc_serialize::{Decoder, Decodable};
use serde;
use serde::de::{Deserializer, Deserialize};
//////////////////////////////////////////////////////////////////////////////
@@ -27,6 +21,8 @@ impl serde::de::Error for Error {
fn end_of_stream_error() -> Error { Error::EndOfStream }
fn unknown_field_error(_: &str) -> Error { Error::SyntaxError }
fn missing_field_error(_: &'static str) -> Error {
Error::MissingField
}
@@ -403,7 +399,7 @@ fn bench_decoder_000(b: &mut Bencher) {
fn bench_decoder_003(b: &mut Bencher) {
b.iter(|| {
let mut m: HashMap<String, isize> = HashMap::new();
for i in range(0, 3) {
for i in (0 .. 3) {
m.insert(i.to_string(), i);
}
run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
@@ -414,7 +410,7 @@ fn bench_decoder_003(b: &mut Bencher) {
fn bench_decoder_100(b: &mut Bencher) {
b.iter(|| {
let mut m: HashMap<String, isize> = HashMap::new();
for i in range(0, 100) {
for i in (0 .. 100) {
m.insert(i.to_string(), i);
}
run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
@@ -443,7 +439,7 @@ fn bench_deserializer_000(b: &mut Bencher) {
fn bench_deserializer_003(b: &mut Bencher) {
b.iter(|| {
let mut m: HashMap<String, isize> = HashMap::new();
for i in range(0, 3) {
for i in (0 .. 3) {
m.insert(i.to_string(), i);
}
run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
@@ -454,7 +450,7 @@ fn bench_deserializer_003(b: &mut Bencher) {
fn bench_deserializer_100(b: &mut Bencher) {
b.iter(|| {
let mut m: HashMap<String, isize> = HashMap::new();
for i in range(0, 100) {
for i in (0 .. 100) {
m.insert(i.to_string(), i);
}
run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
@@ -1,22 +1,15 @@
#![feature(custom_derive, plugin, test)]
#![plugin(serde_macros)]
extern crate serde;
extern crate "rustc-serialize" as rustc_serialize;
extern crate test;
use std::collections::HashMap;
use test::Bencher;
use rustc_serialize::{Decoder, Decodable};
use serde;
use serde::de::{Deserializer, Deserialize};
//////////////////////////////////////////////////////////////////////////////
#[derive(Clone, PartialEq, Debug, RustcDecodable)]
#[derive_deserialize]
struct Inner {
#[derive(Clone, PartialEq, Debug, RustcDecodable, Deserialize)]
pub struct Inner {
a: (),
b: usize,
c: HashMap<String, Option<char>>,
@@ -24,20 +17,17 @@ struct Inner {
//////////////////////////////////////////////////////////////////////////////
#[derive(Clone, PartialEq, Debug, RustcDecodable)]
#[derive_deserialize]
struct Outer {
#[derive(Clone, PartialEq, Debug, RustcDecodable, Deserialize)]
pub struct Outer {
inner: Vec<Inner>,
}
//////////////////////////////////////////////////////////////////////////////
#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub enum Error {
EndOfStream,
SyntaxError,
UnexpectedName,
ConversionError,
MissingField,
OtherError,
}
@@ -47,6 +37,8 @@ impl serde::de::Error for Error {
fn end_of_stream_error() -> Error { Error::EndOfStream }
fn unknown_field_error(_: &str) -> Error { Error::SyntaxError }
fn missing_field_error(_: &'static str) -> Error {
Error::MissingField
}
@@ -368,30 +360,6 @@ mod deserializer {
where V: de::Visitor,
{
match self.stack.pop() {
Some(State::OuterState(Outer { inner })) => {
self.stack.push(State::VecState(inner));
self.stack.push(State::StrState("inner"));
visitor.visit_named_map("Outer", OuterMapVisitor {
de: self,
state: 0,
})
}
Some(State::InnerState(Inner { a: (), b, c })) => {
self.stack.push(State::MapState(c));
self.stack.push(State::StrState("c"));
self.stack.push(State::UsizeState(b));
self.stack.push(State::StrState("b"));
self.stack.push(State::NullState);
self.stack.push(State::StrState("a"));
visitor.visit_named_map("Inner", InnerMapVisitor {
de: self,
state: 0,
})
}
Some(State::VecState(value)) => {
visitor.visit_seq(OuterSeqVisitor {
de: self,
@@ -425,9 +393,52 @@ mod deserializer {
Some(State::OptionState(true)) => {
visitor.visit_some(self)
}
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStream),
}
}
fn visit_named_map<V>(&mut self, name: &str, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.stack.pop() {
Some(State::OuterState(Outer { inner })) => {
if name != "Outer" {
return Err(Error::SyntaxError);
}
self.stack.push(State::VecState(inner));
self.stack.push(State::StrState("inner"));
visitor.visit_map(OuterMapVisitor {
de: self,
state: 0,
})
}
Some(State::InnerState(Inner { a: (), b, c })) => {
if name != "Inner" {
return Err(Error::SyntaxError);
}
self.stack.push(State::MapState(c));
self.stack.push(State::StrState("c"));
self.stack.push(State::UsizeState(b));
self.stack.push(State::StrState("b"));
self.stack.push(State::NullState);
self.stack.push(State::StrState("a"));
visitor.visit_map(InnerMapVisitor {
de: self,
state: 0,
})
}
_ => {
Err(Error::SyntaxError)
}
}
}
}
struct OuterMapVisitor<'a> {
@@ -535,7 +546,7 @@ mod deserializer {
}
fn end(&mut self) -> Result<(), Error> {
if self.state == 1 {
if self.state == 3 {
Ok(())
} else {
Err(Error::SyntaxError)
@@ -607,9 +618,9 @@ fn bench_decoder_0_0(b: &mut Bencher) {
};
let mut d = decoder::OuterDecoder::new(outer.clone());
let value: Outer = Decodable::decode(&mut d).unwrap();
let value: Result<Outer, Error> = Decodable::decode(&mut d);
assert_eq!(value, outer);
assert_eq!(value, Ok(outer));
})
}
@@ -629,9 +640,9 @@ fn bench_decoder_1_0(b: &mut Bencher) {
};
let mut d = decoder::OuterDecoder::new(outer.clone());
let value: Outer = Decodable::decode(&mut d).unwrap();
let value: Result<Outer, Error> = Decodable::decode(&mut d);
assert_eq!(value, outer);
assert_eq!(value, Ok(outer));
})
}
@@ -656,9 +667,9 @@ fn bench_decoder_1_5(b: &mut Bencher) {
};
let mut d = decoder::OuterDecoder::new(outer.clone());
let value: Outer = Decodable::decode(&mut d).unwrap();
let value: Result<Outer, Error> = Decodable::decode(&mut d);
assert_eq!(value, outer);
assert_eq!(value, Ok(outer));
})
}
@@ -670,9 +681,9 @@ fn bench_deserializer_0_0(b: &mut Bencher) {
};
let mut d = deserializer::OuterDeserializer::new(outer.clone());
let value: Outer = Deserialize::deserialize(&mut d).unwrap();
let value: Result<Outer, Error> = Deserialize::deserialize(&mut d);
assert_eq!(value, outer);
assert_eq!(value, Ok(outer));
})
}
@@ -692,9 +703,9 @@ fn bench_deserializer_1_0(b: &mut Bencher) {
};
let mut d = deserializer::OuterDeserializer::new(outer.clone());
let value: Outer = Deserialize::deserialize(&mut d).unwrap();
let value: Result<Outer, Error> = Deserialize::deserialize(&mut d);
assert_eq!(value, outer);
assert_eq!(value, Ok(outer));
})
}
@@ -719,8 +730,8 @@ fn bench_deserializer_1_5(b: &mut Bencher) {
};
let mut d = deserializer::OuterDeserializer::new(outer.clone());
let value: Outer = Deserialize::deserialize(&mut d).unwrap();
let value: Result<Outer, Error> = Deserialize::deserialize(&mut d);
assert_eq!(value, outer);
assert_eq!(value, Ok(outer));
})
}
@@ -1,15 +1,9 @@
#![feature(core, plugin, test)]
#![plugin(serde_macros)]
extern crate serde;
extern crate "rustc-serialize" as rustc_serialize;
extern crate test;
use std::fmt::Debug;
use test::Bencher;
use rustc_serialize::{Decoder, Decodable};
use serde;
use serde::de::{Deserializer, Deserialize};
//////////////////////////////////////////////////////////////////////////////
@@ -25,6 +19,8 @@ impl serde::de::Error for Error {
fn end_of_stream_error() -> Error { Error::EndOfStreamError }
fn unknown_field_error(_: &str) -> Error { Error::SyntaxError }
fn missing_field_error(_: &'static str) -> Error { Error::SyntaxError }
}
@@ -537,7 +533,7 @@ fn bench_decoder_usize_003(b: &mut Bencher) {
#[bench]
fn bench_decoder_usize_100(b: &mut Bencher) {
b.iter(|| {
let v: Vec<usize> = range(0, 100).collect();
let v: Vec<usize> = (0 .. 100).collect();
run_decoder(decoder::UsizeDecoder::new(v.clone()), v)
})
}
@@ -561,7 +557,7 @@ fn bench_decoder_u8_003(b: &mut Bencher) {
#[bench]
fn bench_decoder_u8_100(b: &mut Bencher) {
b.iter(|| {
let v: Vec<u8> = range(0u8, 100).collect();
let v: Vec<u8> = (0 .. 100).collect();
run_decoder(decoder::U8Decoder::new(v.clone()), v)
})
}
@@ -585,7 +581,7 @@ fn bench_deserializer_usize_003(b: &mut Bencher) {
#[bench]
fn bench_deserializer_usize_100(b: &mut Bencher) {
b.iter(|| {
let v: Vec<usize> = range(0, 100).collect();
let v: Vec<usize> = (0 .. 100).collect();
run_deserializer(deserializer::Deserializer::new(v.clone()), v)
})
}
@@ -609,7 +605,7 @@ fn bench_deserializer_u8_003(b: &mut Bencher) {
#[bench]
fn bench_deserializer_u8_100(b: &mut Bencher) {
b.iter(|| {
let v: Vec<u8> = range(0u8, 100).collect();
let v: Vec<u8> = (0 .. 100).collect();
run_deserializer(deserializer::Deserializer::new(v.clone()), v)
})
}
+22
View File
@@ -0,0 +1,22 @@
extern crate syntex;
extern crate serde_codegen;
use std::env;
use std::path::Path;
fn main() {
let out_dir = env::var_os("OUT_DIR").unwrap();
for &(src, dst) in &[
("tests/test.rs.in", "test.rs"),
("benches/bench.rs.in", "bench.rs"),
] {
let src = Path::new(src);
let dst = Path::new(&out_dir).join(dst);
let mut registry = syntex::Registry::new();
serde_codegen::register(&mut registry);
registry.expand("", &src, &dst).unwrap();
}
}
+3
View File
@@ -0,0 +1,3 @@
extern crate serde;
include!(concat!(env!("OUT_DIR"), "/test.rs"));
+7
View File
@@ -0,0 +1,7 @@
mod test_annotations;
mod test_bytes;
mod test_de;
mod test_json;
mod test_json_builder;
mod test_macros;
mod test_ser;
+73
View File
@@ -0,0 +1,73 @@
use serde::json;
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Default {
a1: i32,
#[serde(default)]
a2: i32,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Rename {
a1: i32,
#[serde(rename="a3")]
a2: i32,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct FormatRename {
a1: i32,
#[serde(rename(xml= "a4", json="a5"))]
a2: i32,
}
#[derive(Debug, PartialEq, Deserialize, Serialize)]
enum SerEnum<A> {
Map {
a: i8,
#[serde(rename(xml= "c", json="d"))]
b: A,
},
}
#[test]
fn test_default() {
let deserialized_value: Default = json::from_str(&"{\"a1\":1,\"a2\":2}").unwrap();
assert_eq!(deserialized_value, Default { a1: 1, a2: 2 });
let deserialized_value: Default = json::from_str(&"{\"a1\":1}").unwrap();
assert_eq!(deserialized_value, Default { a1: 1, a2: 0 });
}
#[test]
fn test_rename() {
let value = Rename { a1: 1, a2: 2 };
let serialized_value = json::to_string(&value).unwrap();
assert_eq!(serialized_value, "{\"a1\":1,\"a3\":2}");
let deserialized_value: Rename = json::from_str(&serialized_value).unwrap();
assert_eq!(value, deserialized_value);
}
#[test]
fn test_format_rename() {
let value = FormatRename { a1: 1, a2: 2 };
let serialized_value = json::to_string(&value).unwrap();
assert_eq!(serialized_value, "{\"a1\":1,\"a5\":2}");
let deserialized_value = json::from_str("{\"a1\":1,\"a5\":2}").unwrap();
assert_eq!(value, deserialized_value);
}
#[test]
fn test_enum_format_rename() {
let s1 = String::new();
let value = SerEnum::Map { a: 0i8, b: s1 };
let serialized_value = json::to_string(&value).unwrap();
let ans = "{\"Map\":{\"a\":0,\"d\":\"\"}}";
assert_eq!(serialized_value, ans);
let deserialized_value = json::from_str(ans).unwrap();
assert_eq!(value, deserialized_value);
}
+209
View File
@@ -0,0 +1,209 @@
use serde;
use serde::Serialize;
use serde::bytes::{ByteBuf, Bytes};
use serde::json;
///////////////////////////////////////////////////////////////////////////////
#[derive(Debug, PartialEq)]
struct Error;
impl serde::de::Error for Error {
fn syntax_error() -> Error { Error }
fn end_of_stream_error() -> Error { Error }
fn unknown_field_error(_field: &str) -> Error { Error }
fn missing_field_error(_field: &'static str) -> Error { Error }
}
///////////////////////////////////////////////////////////////////////////////
struct BytesSerializer {
bytes: Vec<u8>,
}
impl BytesSerializer {
fn new(bytes: Vec<u8>) -> Self {
BytesSerializer {
bytes: bytes,
}
}
}
impl serde::Serializer for BytesSerializer {
type Error = Error;
fn visit_unit(&mut self) -> Result<(), Error> {
Err(Error)
}
fn visit_bool(&mut self, _v: bool) -> Result<(), Error> {
Err(Error)
}
fn visit_i64(&mut self, _v: i64) -> Result<(), Error> {
Err(Error)
}
fn visit_u64(&mut self, _v: u64) -> Result<(), Error> {
Err(Error)
}
fn visit_f32(&mut self, _v: f32) -> Result<(), Error> {
Err(Error)
}
fn visit_f64(&mut self, _v: f64) -> Result<(), Error> {
Err(Error)
}
fn visit_char(&mut self, _v: char) -> Result<(), Error> {
Err(Error)
}
fn visit_str(&mut self, _v: &str) -> Result<(), Error> {
Err(Error)
}
fn visit_none(&mut self) -> Result<(), Error> {
Err(Error)
}
fn visit_some<V>(&mut self, _value: V) -> Result<(), Error>
where V: serde::Serialize,
{
Err(Error)
}
fn visit_seq<V>(&mut self, _visitor: V) -> Result<(), Error>
where V: serde::ser::SeqVisitor,
{
Err(Error)
}
fn visit_seq_elt<T>(&mut self, _value: T) -> Result<(), Error>
where T: serde::Serialize
{
Err(Error)
}
fn visit_map<V>(&mut self, _visitor: V) -> Result<(), Error>
where V: serde::ser::MapVisitor,
{
Err(Error)
}
fn visit_map_elt<K, V>(&mut self, _key: K, _value: V) -> Result<(), Error>
where K: serde::Serialize,
V: serde::Serialize,
{
Err(Error)
}
fn visit_bytes(&mut self, bytes: &[u8]) -> Result<(), Error> {
assert_eq!(self.bytes, bytes);
Ok(())
}
}
///////////////////////////////////////////////////////////////////////////////
struct BytesDeserializer {
bytes: Option<Vec<u8>>,
}
impl BytesDeserializer {
fn new(bytes: Vec<u8>) -> Self {
BytesDeserializer {
bytes: Some(bytes),
}
}
}
impl serde::Deserializer for BytesDeserializer {
type Error = Error;
fn visit<V>(&mut self, _visitor: V) -> Result<V::Value, Error>
where V: serde::de::Visitor,
{
Err(Error)
}
fn visit_bytes<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: serde::de::Visitor,
{
visitor.visit_byte_buf(self.bytes.take().unwrap())
}
}
///////////////////////////////////////////////////////////////////////////////
#[test]
fn test_bytes_ser_json() {
let buf = vec![];
let bytes = Bytes::from(&buf);
assert_eq!(json::to_string(&bytes).unwrap(), "[]".to_string());
let buf = vec![1, 2, 3];
let bytes = Bytes::from(&buf);
assert_eq!(json::to_string(&bytes).unwrap(), "[1,2,3]".to_string());
}
#[test]
fn test_bytes_ser_bytes() {
let buf = vec![];
let bytes = Bytes::from(&buf);
let mut ser = BytesSerializer::new(vec![]);
bytes.serialize(&mut ser).unwrap();
let buf = vec![1, 2, 3];
let bytes = Bytes::from(&buf);
let mut ser = BytesSerializer::new(vec![1, 2, 3]);
bytes.serialize(&mut ser).unwrap();
}
#[test]
fn test_byte_buf_ser_json() {
let bytes = ByteBuf::new();
assert_eq!(json::to_string(&bytes).unwrap(), "[]".to_string());
let bytes = ByteBuf::from(vec![1, 2, 3]);
assert_eq!(json::to_string(&bytes).unwrap(), "[1,2,3]".to_string());
}
#[test]
fn test_byte_buf_ser_bytes() {
let bytes = ByteBuf::new();
let mut ser = BytesSerializer::new(vec![]);
bytes.serialize(&mut ser).unwrap();
let bytes = ByteBuf::from(vec![1, 2, 3]);
let mut ser = BytesSerializer::new(vec![1, 2, 3]);
bytes.serialize(&mut ser).unwrap();
}
///////////////////////////////////////////////////////////////////////////////
#[test]
fn test_byte_buf_de_json() {
let bytes = ByteBuf::new();
let v: ByteBuf = json::from_str("[]").unwrap();
assert_eq!(v, bytes);
let bytes = ByteBuf::from(vec![1, 2, 3]);
let v: ByteBuf = json::from_str("[1, 2, 3]").unwrap();
assert_eq!(v, bytes);
}
#[test]
fn test_byte_buf_de_bytes() {
let mut de = BytesDeserializer::new(vec![]);
let bytes = serde::Deserialize::deserialize(&mut de);
assert_eq!(bytes, Ok(ByteBuf::new()));
let mut de = BytesDeserializer::new(vec![1, 2, 3]);
let bytes = serde::Deserialize::deserialize(&mut de);
assert_eq!(bytes, Ok(ByteBuf::from(vec![1, 2, 3])));
}
+412 -164
View File
@@ -1,17 +1,11 @@
#![feature(custom_derive, plugin, test)]
#![plugin(serde_macros)]
extern crate test;
extern crate serde;
use std::collections::BTreeMap;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::iter;
use std::vec;
use serde::de::{self, Deserialize, Deserializer, Visitor};
#[derive(Debug)]
enum Token<'a> {
enum Token {
Bool(bool),
Isize(isize),
I8(i8),
@@ -26,45 +20,46 @@ enum Token<'a> {
F32(f32),
F64(f64),
Char(char),
Str(&'a str),
Str(&'static str),
String(String),
Option(bool),
Name(&'static str),
Unit,
NamedUnit(&'a str),
SeqStart(usize),
NamedSeqStart(&'a str, usize),
SeqSep(bool),
SeqSep,
SeqEnd,
MapStart(usize),
NamedMapStart(&'a str, usize),
MapSep(bool),
MapSep,
MapEnd,
EnumStart(&'a str, &'a str),
EnumStart(&'static str),
EnumEnd,
}
struct TokenDeserializer<'a> {
tokens: iter::Peekable<vec::IntoIter<Token<'a>>>,
struct TokenDeserializer {
tokens: iter::Peekable<vec::IntoIter<Token>>,
}
impl<'a> TokenDeserializer<'a> {
fn new(tokens: Vec<Token<'a>>) -> TokenDeserializer<'a> {
impl<'a> TokenDeserializer {
fn new(tokens: Vec<Token>) -> TokenDeserializer {
TokenDeserializer {
tokens: tokens.into_iter().peekable(),
}
}
}
#[derive(Copy, PartialEq, Debug)]
#[derive(Clone, PartialEq, Debug)]
enum Error {
SyntaxError,
EndOfStreamError,
UnknownFieldError(String),
MissingFieldError(&'static str),
InvalidName(&'static str),
}
impl de::Error for Error {
@@ -72,12 +67,16 @@ impl de::Error for Error {
fn end_of_stream_error() -> Error { Error::EndOfStreamError }
fn unknown_field_error(field: &str) -> Error {
Error::UnknownFieldError(field.to_string())
}
fn missing_field_error(field: &'static str) -> Error {
Error::MissingFieldError(field)
}
}
impl<'a> Deserializer for TokenDeserializer<'a> {
impl Deserializer for TokenDeserializer {
type Error = Error;
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
@@ -103,40 +102,19 @@ impl<'a> Deserializer for TokenDeserializer<'a> {
Some(Token::Option(false)) => visitor.visit_none(),
Some(Token::Option(true)) => visitor.visit_some(self),
Some(Token::Unit) => visitor.visit_unit(),
Some(Token::NamedUnit(name)) => visitor.visit_named_unit(name),
Some(Token::SeqStart(len)) => {
visitor.visit_seq(TokenDeserializerSeqVisitor {
de: self,
len: len,
first: true,
})
}
Some(Token::NamedSeqStart(name, len)) => {
visitor.visit_named_seq(name, TokenDeserializerSeqVisitor {
de: self,
len: len,
first: true,
})
}
Some(Token::MapStart(len)) => {
visitor.visit_map(TokenDeserializerMapVisitor {
de: self,
len: len,
first: true,
})
}
Some(Token::NamedMapStart(name, len)) => {
visitor.visit_named_map(name, TokenDeserializerMapVisitor {
de: self,
len: len,
first: true,
})
}
Some(Token::EnumStart(name, variant)) => {
visitor.visit_enum(name, variant, TokenDeserializerEnumVisitor {
de: self,
})
}
Some(Token::Name(_)) => self.visit(visitor),
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
@@ -144,7 +122,6 @@ impl<'a> Deserializer for TokenDeserializer<'a> {
/// Hook into `Option` deserializing so we can treat `Unit` as a
/// `None`, or a regular value as `Some(value)`.
#[inline]
fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: Visitor,
{
@@ -165,31 +142,97 @@ impl<'a> Deserializer for TokenDeserializer<'a> {
None => Err(Error::EndOfStreamError),
}
}
fn visit_enum<V>(&mut self, name: &str, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
match self.tokens.next() {
Some(Token::EnumStart(n)) => {
if name == n {
visitor.visit(TokenDeserializerVariantVisitor {
de: self,
})
} else {
Err(Error::SyntaxError)
}
}
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
}
fn visit_named_unit<V>(&mut self, name: &str, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.tokens.peek() {
Some(&Token::Name(n)) => {
if name == n {
self.tokens.next();
self.visit_seq(visitor)
} else {
Err(Error::InvalidName(n))
}
}
Some(_) => self.visit(visitor),
None => Err(Error::EndOfStreamError),
}
}
fn visit_named_seq<V>(&mut self, name: &str, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.tokens.peek() {
Some(&Token::Name(n)) => {
if name == n {
self.tokens.next();
self.visit_seq(visitor)
} else {
Err(Error::InvalidName(n))
}
}
Some(_) => self.visit_seq(visitor),
None => Err(Error::EndOfStreamError),
}
}
fn visit_named_map<V>(&mut self, name: &str, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.tokens.peek() {
Some(&Token::Name(n)) => {
if name == n {
self.tokens.next();
self.visit_map(visitor)
} else {
Err(Error::InvalidName(n))
}
}
Some(_) => self.visit_map(visitor),
None => Err(Error::EndOfStreamError),
}
}
}
//////////////////////////////////////////////////////////////////////////
struct TokenDeserializerSeqVisitor<'a, 'b: 'a> {
de: &'a mut TokenDeserializer<'b>,
struct TokenDeserializerSeqVisitor<'a> {
de: &'a mut TokenDeserializer,
len: usize,
first: bool,
}
impl<'a, 'b> de::SeqVisitor for TokenDeserializerSeqVisitor<'a, 'b> {
impl<'a> de::SeqVisitor for TokenDeserializerSeqVisitor<'a> {
type Error = Error;
fn visit<T>(&mut self) -> Result<Option<T>, Error>
where T: Deserialize,
{
let first = self.first;
self.first = false;
match self.de.tokens.next() {
Some(Token::SeqSep(first_)) if first_ == first => {
match self.de.tokens.peek() {
Some(&Token::SeqSep) => {
self.len -= 1;
self.de.tokens.next();
Ok(Some(try!(Deserialize::deserialize(self.de))))
}
Some(Token::SeqEnd) => Ok(None),
Some(&Token::SeqEnd) => Ok(None),
Some(_) => {
Err(Error::SyntaxError)
}
@@ -198,6 +241,7 @@ impl<'a, 'b> de::SeqVisitor for TokenDeserializerSeqVisitor<'a, 'b> {
}
fn end(&mut self) -> Result<(), Error> {
assert_eq!(self.len, 0);
match self.de.tokens.next() {
Some(Token::SeqEnd) => Ok(()),
Some(_) => Err(Error::SyntaxError),
@@ -212,26 +256,24 @@ impl<'a, 'b> de::SeqVisitor for TokenDeserializerSeqVisitor<'a, 'b> {
//////////////////////////////////////////////////////////////////////////
struct TokenDeserializerMapVisitor<'a, 'b: 'a> {
de: &'a mut TokenDeserializer<'b>,
struct TokenDeserializerMapVisitor<'a> {
de: &'a mut TokenDeserializer,
len: usize,
first: bool,
}
impl<'a, 'b> de::MapVisitor for TokenDeserializerMapVisitor<'a, 'b> {
impl<'a> de::MapVisitor for TokenDeserializerMapVisitor<'a> {
type Error = Error;
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
where K: Deserialize,
{
let first = self.first;
self.first = false;
match self.de.tokens.next() {
Some(Token::MapSep(first_)) if first_ == first => {
match self.de.tokens.peek() {
Some(&Token::MapSep) => {
self.de.tokens.next();
self.len -= 1;
Ok(Some(try!(Deserialize::deserialize(self.de))))
}
Some(Token::MapEnd) => Ok(None),
Some(&Token::MapEnd) => Ok(None),
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
@@ -244,6 +286,7 @@ impl<'a, 'b> de::MapVisitor for TokenDeserializerMapVisitor<'a, 'b> {
}
fn end(&mut self) -> Result<(), Error> {
assert_eq!(self.len, 0);
match self.de.tokens.next() {
Some(Token::MapEnd) => Ok(()),
Some(_) => Err(Error::SyntaxError),
@@ -258,89 +301,52 @@ impl<'a, 'b> de::MapVisitor for TokenDeserializerMapVisitor<'a, 'b> {
//////////////////////////////////////////////////////////////////////////
struct TokenDeserializerEnumVisitor<'a, 'b: 'a> {
de: &'a mut TokenDeserializer<'b>,
struct TokenDeserializerVariantVisitor<'a> {
de: &'a mut TokenDeserializer,
}
impl<'a, 'b> de::EnumVisitor for TokenDeserializerEnumVisitor<'a, 'b> {
impl<'a> de::VariantVisitor for TokenDeserializerVariantVisitor<'a> {
type Error = Error;
fn visit_variant<V>(&mut self) -> Result<V, Error>
where V: de::Deserialize,
{
de::Deserialize::deserialize(self.de)
}
fn visit_unit(&mut self) -> Result<(), Error> {
let value = try!(Deserialize::deserialize(self.de));
match self.de.tokens.next() {
Some(Token::EnumEnd) => Ok(value),
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
de::Deserialize::deserialize(self.de)
}
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumSeqVisitor,
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
let token = self.de.tokens.next();
match token {
Some(Token::SeqStart(len)) => {
let value = try!(visitor.visit(TokenDeserializerSeqVisitor {
de: self.de,
len: len,
first: true,
}));
match self.de.tokens.next() {
Some(Token::EnumEnd) => Ok(value),
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
}
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
de::Deserializer::visit(self.de, visitor)
}
fn visit_map<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumMapVisitor,
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.de.tokens.next() {
Some(Token::MapStart(len)) => {
let value = try!(visitor.visit(TokenDeserializerMapVisitor {
de: self.de,
len: len,
first: true,
}));
match self.de.tokens.next() {
Some(Token::EnumEnd) => Ok(value),
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
}
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
de::Deserializer::visit(self.de, visitor)
}
}
//////////////////////////////////////////////////////////////////////////
#[derive(Copy, PartialEq, Debug)]
#[derive_deserialize]
#[derive(Copy, Clone, PartialEq, Debug, Deserialize)]
struct NamedUnit;
#[derive(PartialEq, Debug)]
#[derive_deserialize]
#[derive(PartialEq, Debug, Deserialize)]
struct NamedSeq(i32, i32, i32);
#[derive(PartialEq, Debug)]
#[derive_deserialize]
#[derive(PartialEq, Debug, Deserialize)]
struct NamedMap {
a: i32,
b: i32,
c: i32,
}
#[derive(PartialEq, Debug)]
#[derive_deserialize]
#[derive(PartialEq, Debug, Deserialize)]
enum Enum {
Unit,
Seq(i32, i32, i32),
@@ -349,6 +355,19 @@ enum Enum {
//////////////////////////////////////////////////////////////////////////
macro_rules! btreeset {
() => {
BTreeSet::new()
};
($($value:expr),+) => {
{
let mut set = BTreeSet::new();
$(set.insert($value);)+
set
}
}
}
macro_rules! btreemap {
() => {
BTreeMap::new()
@@ -362,6 +381,32 @@ macro_rules! btreemap {
}
}
macro_rules! hashset {
() => {
HashSet::new()
};
($($value:expr),+) => {
{
let mut set = HashSet::new();
$(set.insert($value);)+
set
}
}
}
macro_rules! hashmap {
() => {
HashMap::new()
};
($($key:expr => $value:expr),+) => {
{
let mut map = HashMap::new();
$(map.insert($key, $value);)+
map
}
}
}
macro_rules! declare_test {
($name:ident { $($value:expr => $tokens:expr,)+ }) => {
#[test]
@@ -448,13 +493,17 @@ declare_tests! {
Token::SeqEnd,
],
() => vec![
Token::NamedSeqStart("Anything", 0),
Token::Name("Anything"),
Token::SeqStart(0),
Token::SeqEnd,
],
}
test_named_unit {
NamedUnit => vec![Token::Unit],
NamedUnit => vec![Token::NamedUnit("NamedUnit")],
NamedUnit => vec![
Token::Name("NamedUnit"),
Token::Unit,
],
NamedUnit => vec![
Token::SeqStart(0),
Token::SeqEnd,
@@ -463,167 +512,365 @@ declare_tests! {
test_named_seq {
NamedSeq(1, 2, 3) => vec![
Token::SeqStart(3),
Token::SeqSep(true),
Token::SeqSep,
Token::I32(1),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(2),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
],
NamedSeq(1, 2, 3) => vec![
Token::NamedSeqStart("NamedSeq", 3),
Token::SeqSep(true),
Token::Name("NamedSeq"),
Token::SeqStart(3),
Token::SeqSep,
Token::I32(1),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(2),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
],
}
test_btreeset {
BTreeSet::<isize>::new() => vec![
Token::Unit,
],
BTreeSet::<isize>::new() => vec![
Token::SeqStart(0),
Token::SeqEnd,
],
btreeset![btreeset![], btreeset![1], btreeset![2, 3]] => vec![
Token::SeqStart(3),
Token::SeqSep,
Token::SeqStart(0),
Token::SeqEnd,
Token::SeqSep,
Token::SeqStart(1),
Token::SeqSep,
Token::I32(1),
Token::SeqEnd,
Token::SeqSep,
Token::SeqStart(2),
Token::SeqSep,
Token::I32(2),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
Token::SeqEnd,
],
BTreeSet::<isize>::new() => vec![
Token::Name("Anything"),
Token::Unit,
],
BTreeSet::<isize>::new() => vec![
Token::Name("Anything"),
Token::SeqStart(0),
Token::SeqEnd,
],
}
test_hashset {
HashSet::<isize>::new() => vec![
Token::Unit,
],
HashSet::<isize>::new() => vec![
Token::SeqStart(0),
Token::SeqEnd,
],
hashset![1, 2, 3] => vec![
Token::SeqStart(3),
Token::SeqSep,
Token::I32(1),
Token::SeqSep,
Token::I32(2),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
],
HashSet::<isize>::new() => vec![
Token::Name("Anything"),
Token::Unit,
],
HashSet::<isize>::new() => vec![
Token::Name("Anything"),
Token::SeqStart(0),
Token::SeqEnd,
],
}
test_vec {
Vec::<isize>::new() => vec![
Token::Unit,
],
Vec::<isize>::new() => vec![
Token::SeqStart(0),
Token::SeqEnd,
],
vec![vec![], vec![1], vec![2, 3]] => vec![
Token::SeqStart(3),
Token::SeqSep(true),
Token::SeqSep,
Token::SeqStart(0),
Token::SeqEnd,
Token::SeqSep(false),
Token::SeqSep,
Token::SeqStart(1),
Token::SeqSep(true),
Token::SeqSep,
Token::I32(1),
Token::SeqEnd,
Token::SeqSep(false),
Token::SeqSep,
Token::SeqStart(2),
Token::SeqSep(true),
Token::SeqSep,
Token::I32(2),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
Token::SeqEnd,
],
Vec::<isize>::new() => vec![
Token::Name("Anything"),
Token::Unit,
],
Vec::<isize>::new() => vec![
Token::Name("Anything"),
Token::SeqStart(0),
Token::SeqEnd,
],
}
test_array {
[0; 0] => vec![
Token::Unit,
],
[0; 0] => vec![
Token::SeqStart(0),
Token::SeqEnd,
],
([0; 0], [1], [2, 3]) => vec![
Token::SeqStart(3),
Token::SeqSep,
Token::SeqStart(0),
Token::SeqEnd,
Token::SeqSep,
Token::SeqStart(1),
Token::SeqSep,
Token::I32(1),
Token::SeqEnd,
Token::SeqSep,
Token::SeqStart(2),
Token::SeqSep,
Token::I32(2),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
Token::SeqEnd,
],
[0; 0] => vec![
Token::Name("Anything"),
Token::Unit,
],
[0; 0] => vec![
Token::Name("Anything"),
Token::SeqStart(0),
Token::SeqEnd,
],
}
test_tuple {
(1,) => vec![
Token::SeqStart(1),
Token::SeqSep(true),
Token::SeqSep,
Token::I32(1),
Token::SeqEnd,
],
(1, 2, 3) => vec![
Token::SeqStart(3),
Token::SeqSep(true),
Token::SeqSep,
Token::I32(1),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(2),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
],
}
test_btreemap {
BTreeMap::<isize, isize>::new() => vec![
Token::Unit,
],
BTreeMap::<isize, isize>::new() => vec![
Token::MapStart(0),
Token::MapEnd,
],
btreemap![1 => 2] => vec![
Token::MapStart(1),
Token::MapSep(true),
Token::MapSep,
Token::I32(1),
Token::I32(2),
Token::MapEnd,
],
btreemap![1 => 2, 3 => 4] => vec![
Token::MapStart(2),
Token::MapSep(true),
Token::MapSep,
Token::I32(1),
Token::I32(2),
Token::MapSep(false),
Token::MapSep,
Token::I32(3),
Token::I32(4),
Token::MapEnd,
],
btreemap![1 => btreemap![], 2 => btreemap![3 => 4, 5 => 6]] => vec![
Token::MapStart(2),
Token::MapSep(true),
Token::MapSep,
Token::I32(1),
Token::MapStart(0),
Token::MapEnd,
Token::MapSep(false),
Token::MapSep,
Token::I32(2),
Token::MapStart(2),
Token::MapSep(true),
Token::MapSep,
Token::I32(3),
Token::I32(4),
Token::MapSep(false),
Token::MapSep,
Token::I32(5),
Token::I32(6),
Token::MapEnd,
Token::MapEnd,
],
BTreeMap::<isize, isize>::new() => vec![
Token::Name("Anything"),
Token::Unit,
],
BTreeMap::<isize, isize>::new() => vec![
Token::Name("Anything"),
Token::MapStart(0),
Token::MapEnd,
],
}
test_hashmap {
HashMap::<isize, isize>::new() => vec![
Token::Unit,
],
HashMap::<isize, isize>::new() => vec![
Token::MapStart(0),
Token::MapEnd,
],
hashmap![1 => 2] => vec![
Token::MapStart(1),
Token::MapSep,
Token::I32(1),
Token::I32(2),
Token::MapEnd,
],
hashmap![1 => 2, 3 => 4] => vec![
Token::MapStart(2),
Token::MapSep,
Token::I32(1),
Token::I32(2),
Token::MapSep,
Token::I32(3),
Token::I32(4),
Token::MapEnd,
],
hashmap![1 => hashmap![], 2 => hashmap![3 => 4, 5 => 6]] => vec![
Token::MapStart(2),
Token::MapSep,
Token::I32(1),
Token::MapStart(0),
Token::MapEnd,
Token::MapSep,
Token::I32(2),
Token::MapStart(2),
Token::MapSep,
Token::I32(3),
Token::I32(4),
Token::MapSep,
Token::I32(5),
Token::I32(6),
Token::MapEnd,
Token::MapEnd,
],
HashMap::<isize, isize>::new() => vec![
Token::Name("Anything"),
Token::Unit,
],
HashMap::<isize, isize>::new() => vec![
Token::Name("Anything"),
Token::MapStart(0),
Token::MapEnd,
],
}
test_named_map {
NamedMap { a: 1, b: 2, c: 3 } => vec![
Token::MapStart(3),
Token::MapSep(true),
Token::MapSep,
Token::Str("a"),
Token::I32(1),
Token::MapSep(false),
Token::MapSep,
Token::Str("b"),
Token::I32(2),
Token::MapSep(false),
Token::MapSep,
Token::Str("c"),
Token::I32(3),
Token::MapEnd,
],
NamedMap { a: 1, b: 2, c: 3 } => vec![
Token::NamedMapStart("NamedMap", 3),
Token::MapSep(true),
Token::Name("NamedMap"),
Token::MapStart(3),
Token::MapSep,
Token::Str("a"),
Token::I32(1),
Token::MapSep(false),
Token::MapSep,
Token::Str("b"),
Token::I32(2),
Token::MapSep(false),
Token::MapSep,
Token::Str("c"),
Token::I32(3),
Token::MapEnd,
],
}
test_enum {
test_enum_unit {
Enum::Unit => vec![
Token::EnumStart("Enum", "Unit"),
Token::EnumStart("Enum"),
Token::Str("Unit"),
Token::Unit,
Token::EnumEnd,
],
}
test_enum_seq {
Enum::Seq(1, 2, 3) => vec![
Token::EnumStart("Enum", "Seq"),
Token::EnumStart("Enum"),
Token::Str("Seq"),
Token::SeqStart(3),
Token::SeqSep(true),
Token::SeqSep,
Token::I32(1),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(2),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
Token::EnumEnd,
@@ -631,17 +878,18 @@ declare_tests! {
}
test_enum_map {
Enum::Map { a: 1, b: 2, c: 3 } => vec![
Token::EnumStart("Enum", "Map"),
Token::EnumStart("Enum"),
Token::Str("Map"),
Token::MapStart(3),
Token::MapSep(true),
Token::MapSep,
Token::Str("a"),
Token::I32(1),
Token::MapSep(false),
Token::MapSep,
Token::Str("b"),
Token::I32(2),
Token::MapSep(false),
Token::MapSep,
Token::Str("c"),
Token::I32(3),
Token::MapEnd,
@@ -1,9 +1,3 @@
#![feature(custom_derive, plugin, test)]
#![plugin(serde_macros)]
extern crate test;
extern crate serde;
use std::fmt::Debug;
use std::collections::BTreeMap;
@@ -28,9 +22,7 @@ macro_rules! treemap {
})
}
#[derive(PartialEq, Debug)]
#[derive_serialize]
#[derive_deserialize]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
enum Animal {
Dog,
Frog(String, Vec<isize>),
@@ -38,18 +30,14 @@ enum Animal {
}
#[derive(PartialEq, Debug)]
#[derive_serialize]
#[derive_deserialize]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
struct Inner {
a: (),
b: usize,
c: Vec<String>,
}
#[derive(PartialEq, Debug)]
#[derive_serialize]
#[derive_deserialize]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
struct Outer {
inner: Vec<Inner>,
}
@@ -107,7 +95,7 @@ fn test_write_i64() {
#[test]
fn test_write_f64() {
let tests = &[
(3.0, "3"),
(3.0, "3.0"),
(3.1, "3.1"),
(-1.5, "-1.5"),
(0.5, "0.5"),
@@ -144,6 +132,68 @@ fn test_write_list() {
(vec![true, false], "[true,false]"),
]);
test_encode_ok(&[
(vec![vec![], vec![], vec![]], "[[],[],[]]"),
(vec![vec![1, 2, 3], vec![], vec![]], "[[1,2,3],[],[]]"),
(vec![vec![], vec![1, 2, 3], vec![]], "[[],[1,2,3],[]]"),
(vec![vec![], vec![], vec![1, 2, 3]], "[[],[],[1,2,3]]"),
]);
test_pretty_encode_ok(&[
(
vec![vec![], vec![], vec![]],
concat!(
"[\n",
" [],\n",
" [],\n",
" []\n",
"]"
),
),
(
vec![vec![1, 2, 3], vec![], vec![]],
concat!(
"[\n",
" [\n",
" 1,\n",
" 2,\n",
" 3\n",
" ],\n",
" [],\n",
" []\n",
"]"
),
),
(
vec![vec![], vec![1, 2, 3], vec![]],
concat!(
"[\n",
" [],\n",
" [\n",
" 1,\n",
" 2,\n",
" 3\n",
" ],\n",
" []\n",
"]"
),
),
(
vec![vec![], vec![], vec![1, 2, 3]],
concat!(
"[\n",
" [],\n",
" [],\n",
" [\n",
" 1,\n",
" 2,\n",
" 3\n",
" ]\n",
"]"
),
),
]);
test_pretty_encode_ok(&[
(vec![], "[]"),
(
@@ -207,6 +257,154 @@ fn test_write_object() {
"{\"a\":true,\"b\":false}"),
]);
test_encode_ok(&[
(
treemap![
"a".to_string() => treemap![],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
"{\"a\":{},\"b\":{},\"c\":{}}",
),
(
treemap![
"a".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
"{\"a\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}},\"b\":{},\"c\":{}}",
),
(
treemap![
"a".to_string() => treemap![],
"b".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
"c".to_string() => treemap![]
],
"{\"a\":{},\"b\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}},\"c\":{}}",
),
(
treemap![
"a".to_string() => treemap![],
"b".to_string() => treemap![],
"c".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
]
],
"{\"a\":{},\"b\":{},\"c\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}}}",
),
]);
test_pretty_encode_ok(&[
(
treemap![
"a".to_string() => treemap![],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
concat!(
"{\n",
" \"a\": {},\n",
" \"b\": {},\n",
" \"c\": {}\n",
"}",
),
),
(
treemap![
"a".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
concat!(
"{\n",
" \"a\": {\n",
" \"a\": {\n",
" \"a\": [\n",
" 1,\n",
" 2,\n",
" 3\n",
" ]\n",
" },\n",
" \"b\": {},\n",
" \"c\": {}\n",
" },\n",
" \"b\": {},\n",
" \"c\": {}\n",
"}"
),
),
(
treemap![
"a".to_string() => treemap![],
"b".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
"c".to_string() => treemap![]
],
concat!(
"{\n",
" \"a\": {},\n",
" \"b\": {\n",
" \"a\": {\n",
" \"a\": [\n",
" 1,\n",
" 2,\n",
" 3\n",
" ]\n",
" },\n",
" \"b\": {},\n",
" \"c\": {}\n",
" },\n",
" \"c\": {}\n",
"}"
),
),
(
treemap![
"a".to_string() => treemap![],
"b".to_string() => treemap![],
"c".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
]
],
concat!(
"{\n",
" \"a\": {},\n",
" \"b\": {},\n",
" \"c\": {\n",
" \"a\": {\n",
" \"a\": [\n",
" 1,\n",
" 2,\n",
" 3\n",
" ]\n",
" },\n",
" \"b\": {},\n",
" \"c\": {}\n",
" }\n",
"}"
),
),
]);
test_pretty_encode_ok(&[
(treemap!(), "{}"),
(
@@ -418,12 +616,12 @@ fn test_write_option() {
]);
}
fn test_parse_ok<'a, T>(errors: &[(&'a str, T)])
where T: PartialEq + Debug + ser::Serialize + de::Deserialize,
fn test_parse_ok<T>(errors: Vec<(&'static str, T)>)
where T: Clone + Debug + PartialEq + ser::Serialize + de::Deserialize,
{
for &(s, ref value) in errors {
for (s, value) in errors {
let v: T = from_str(s).unwrap();
assert_eq!(v, *value);
assert_eq!(v, value.clone());
// Make sure we can deserialize into a `Value`.
let json_value: Value = from_str(s).unwrap();
@@ -431,49 +629,61 @@ fn test_parse_ok<'a, T>(errors: &[(&'a str, T)])
// Make sure we can deserialize from a `Value`.
let v: T = from_value(json_value.clone()).unwrap();
assert_eq!(v, *value);
assert_eq!(v, value);
// Make sure we can round trip back to `Value`.
let json_value2: Value = from_value(json_value.clone()).unwrap();
assert_eq!(json_value, json_value2);
assert_eq!(json_value2, json_value);
}
}
// FIXME (#5527): these could be merged once UFCS is finished.
fn test_parse_err<'a, T>(errors: &[(&'a str, Error)])
where T: Debug + de::Deserialize,
fn test_parse_err<T>(errors: Vec<(&'static str, Error)>)
where T: Debug + PartialEq + de::Deserialize,
{
for &(s, ref err) in errors {
let v: Result<T, Error> = from_str(s);
assert_eq!(v.unwrap_err(), *err);
for (s, err) in errors {
match (err, from_str::<T>(s).unwrap_err()) {
(
Error::SyntaxError(expected_code, expected_line, expected_col),
Error::SyntaxError(actual_code, actual_line, actual_col),
) => {
assert_eq!(
(expected_code, expected_line, expected_col),
(actual_code, actual_line, actual_col)
)
}
(expected_err, actual_err) => {
panic!("unexpected errors {} != {}", expected_err, actual_err)
}
}
}
}
#[test]
fn test_parse_null() {
test_parse_err::<()>(&[
("n", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)),
("nul", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 4)),
test_parse_err::<()>(vec![
("n", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 1)),
("nul", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 3)),
("nulla", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 5)),
]);
test_parse_ok(&[
test_parse_ok(vec![
("null", ()),
]);
}
#[test]
fn test_parse_bool() {
test_parse_err::<bool>(&[
("t", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)),
test_parse_err::<bool>(vec![
("t", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 1)),
("truz", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 4)),
("f", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)),
("f", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 1)),
("faz", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 3)),
("truea", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 5)),
("falsea", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)),
]);
test_parse_ok(&[
test_parse_ok(vec![
("true", true),
(" true ", true),
("false", false),
@@ -483,31 +693,40 @@ fn test_parse_bool() {
#[test]
fn test_parse_number_errors() {
test_parse_err::<f64>(&[
test_parse_err::<f64>(vec![
("+", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)),
(".", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)),
("-", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)),
("-", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 1)),
("00", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)),
("1.", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)),
("1e", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)),
("1e+", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 4)),
("1.", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)),
("1e", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)),
("1e+", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)),
("1a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 2)),
("777777777777777777777777777", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 20)),
("1e777777777777777777777777777", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 22)),
]);
}
#[test]
fn test_parse_i64() {
test_parse_ok(&[
("3", 3),
test_parse_ok(vec![
("-2", -2),
("-1234", -1234),
(" -1234 ", -1234),
]);
}
#[test]
fn test_parse_u64() {
test_parse_ok(vec![
("3", 3u64),
("1234", 1234),
]);
}
#[test]
fn test_parse_f64() {
test_parse_ok(&[
test_parse_ok(vec![
("3.0", 3.0f64),
("3.1", 3.1),
("-1.2", -1.2),
@@ -521,13 +740,13 @@ fn test_parse_f64() {
#[test]
fn test_parse_string() {
test_parse_err::<String>(&[
("\"", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 2)),
("\"lol", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 5)),
test_parse_err::<String>(vec![
("\"", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 1)),
("\"lol", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 4)),
("\"lol\"a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)),
]);
test_parse_ok(&[
test_parse_ok(vec![
("\"\"", "".to_string()),
("\"foo\"", "foo".to_string()),
(" \"foo\" ", "foo".to_string()),
@@ -543,50 +762,50 @@ fn test_parse_string() {
#[test]
fn test_parse_list() {
test_parse_err::<Vec<f64>>(&[
("[", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
("[ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)),
("[1", Error::SyntaxError(ErrorCode::EOFWhileParsingList, 1, 3)),
("[1,", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 4)),
test_parse_err::<Vec<f64>>(vec![
("[", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 1)),
("[ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
("[1", Error::SyntaxError(ErrorCode::EOFWhileParsingList, 1, 2)),
("[1,", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)),
("[1,]", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 4)),
("[1 2]", Error::SyntaxError(ErrorCode::ExpectedListCommaOrEnd, 1, 4)),
("[]a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)),
]);
test_parse_ok(&[
test_parse_ok(vec![
("[]", vec![]),
("[ ]", vec![]),
("[null]", vec![()]),
(" [ null ] ", vec![()]),
]);
test_parse_ok(&[
test_parse_ok(vec![
("[true]", vec![true]),
]);
test_parse_ok(&[
("[3,1]", vec![3, 1]),
test_parse_ok(vec![
("[3,1]", vec![3u64, 1]),
(" [ 3 , 1 ] ", vec![3, 1]),
]);
test_parse_ok(&[
("[[3], [1, 2]]", vec![vec![3], vec![1, 2]]),
test_parse_ok(vec![
("[[3], [1, 2]]", vec![vec![3u64], vec![1, 2]]),
]);
test_parse_ok(&[
("[1]", (1,)),
test_parse_ok(vec![
("[1]", (1u64,)),
]);
test_parse_ok(&[
("[1, 2]", (1, 2)),
test_parse_ok(vec![
("[1, 2]", (1u64, 2u64)),
]);
test_parse_ok(&[
("[1, 2, 3]", (1, 2, 3)),
test_parse_ok(vec![
("[1, 2, 3]", (1u64, 2u64, 3u64)),
]);
test_parse_ok(&[
("[1, [2, 3]]", (1, (2, 3))),
test_parse_ok(vec![
("[1, [2, 3]]", (1u64, (2u64, 3u64))),
]);
let v: () = from_str("[]").unwrap();
@@ -595,27 +814,27 @@ fn test_parse_list() {
#[test]
fn test_parse_object() {
test_parse_err::<BTreeMap<String, u32>>(&[
("{", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
("{ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)),
test_parse_err::<BTreeMap<String, u32>>(vec![
("{", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 1)),
("{ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
("{1", Error::SyntaxError(ErrorCode::KeyMustBeAString, 1, 2)),
("{ \"a\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 6)),
("{\"a\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 5)),
("{\"a\" ", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 6)),
("{ \"a\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 5)),
("{\"a\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 4)),
("{\"a\" ", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 5)),
("{\"a\" 1", Error::SyntaxError(ErrorCode::ExpectedColon, 1, 6)),
("{\"a\":", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 6)),
("{\"a\":1", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 7)),
("{\"a\":", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 5)),
("{\"a\":1", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 6)),
("{\"a\":1 1", Error::SyntaxError(ErrorCode::ExpectedObjectCommaOrEnd, 1, 8)),
("{\"a\":1,", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 8)),
("{\"a\":1,", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 7)),
("{}a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)),
]);
test_parse_ok(&[
test_parse_ok(vec![
("{}", treemap!()),
("{ }", treemap!()),
(
"{\"a\":3}",
treemap!("a".to_string() => 3)
treemap!("a".to_string() => 3u64)
),
(
"{ \"a\" : 3 }",
@@ -631,23 +850,28 @@ fn test_parse_object() {
),
]);
test_parse_ok(&[
test_parse_ok(vec![
(
"{\"a\": {\"b\": 3, \"c\": 4}}",
treemap!("a".to_string() => treemap!("b".to_string() => 3, "c".to_string() => 4)),
treemap!(
"a".to_string() => treemap!(
"b".to_string() => 3u64,
"c".to_string() => 4
)
),
),
]);
}
#[test]
fn test_parse_struct() {
test_parse_err::<Outer>(&[
("[]", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)),
("{}", Error::MissingFieldError("inner")),
("{\"inner\": true}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)),
test_parse_err::<Outer>(vec![
("5", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)),
("\"hello\"", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 7)),
("{\"inner\": true}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 15)),
]);
test_parse_ok(&[
test_parse_ok(vec![
(
"{
\"inner\": []
@@ -669,44 +893,54 @@ fn test_parse_struct() {
},
)
]);
let v: Outer = from_str("{}").unwrap();
assert_eq!(
v,
Outer {
inner: vec![],
}
);
}
#[test]
fn test_parse_option() {
test_parse_ok(&[
test_parse_ok(vec![
("null", None::<String>),
("\"jodhpurs\"", Some("jodhpurs".to_string())),
]);
#[derive(PartialEq, Debug)]
#[derive_serialize]
#[derive_deserialize]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
struct Foo {
x: Option<isize>,
}
/*
let value: Foo = from_str("{}").unwrap();
assert_eq!(value, Foo { x: None });
*/
test_parse_ok(&[
test_parse_ok(vec![
("{\"x\": null}", Foo { x: None }),
("{\"x\": 5}", Foo { x: Some(5) }),
]);
}
#[test]
fn test_parse_enum() {
test_parse_err::<Animal>(&[
("{}", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 3)),
("{\"unknown\":[]}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)),
("{\"Dog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)),
("{\"Frog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 9)),
("{\"Cat\":[]}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 8)),
fn test_parse_enum_errors() {
test_parse_err::<Animal>(vec![
("{}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 2)),
("{\"Dog\":", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 7)),
("{\"Dog\":}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 8)),
("{\"unknown\":[]}", Error::SyntaxError(ErrorCode::UnknownField("unknown".to_string()), 1, 11)),
("{\"Dog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 9)),
("{\"Frog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 10)),
("{\"Cat\":[]}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 9)),
]);
}
test_parse_ok(&[
#[test]
fn test_parse_enum() {
test_parse_ok(vec![
("{\"Dog\":[]}", Animal::Dog),
(" { \"Dog\" : [ ] } ", Animal::Dog),
(
@@ -727,7 +961,7 @@ fn test_parse_enum() {
),
]);
test_parse_ok(&[
test_parse_ok(vec![
(
concat!(
"{",
@@ -745,8 +979,8 @@ fn test_parse_enum() {
#[test]
fn test_parse_trailing_whitespace() {
test_parse_ok(&[
("[1, 2] ", vec![1, 2]),
test_parse_ok(vec![
("[1, 2] ", vec![1u64, 2]),
("[1, 2]\n", vec![1, 2]),
("[1, 2]\t", vec![1, 2]),
("[1, 2]\t \n", vec![1, 2]),
@@ -755,7 +989,93 @@ fn test_parse_trailing_whitespace() {
#[test]
fn test_multiline_errors() {
test_parse_err::<BTreeMap<String, String>>(&[
("{\n \"foo\":\n \"bar\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 3, 8)),
test_parse_err::<BTreeMap<String, String>>(vec![
("{\n \"foo\":\n \"bar\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 3, 6)),
]);
}
#[test]
fn test_missing_field() {
#[derive(Debug, PartialEq, Deserialize)]
struct Foo {
x: Option<u32>,
}
let value: Foo = from_str("{}").unwrap();
assert_eq!(value, Foo { x: None });
let value: Foo = from_str("{\"x\": 5}").unwrap();
assert_eq!(value, Foo { x: Some(5) });
let value: Foo = from_value(Value::Object(treemap!())).unwrap();
assert_eq!(value, Foo { x: None });
let value: Foo = from_value(Value::Object(treemap!(
"x".to_string() => Value::I64(5)
))).unwrap();
assert_eq!(value, Foo { x: Some(5) });
}
#[test]
fn test_missing_renamed_field() {
#[derive(Debug, PartialEq, Deserialize)]
struct Foo {
#[serde(rename="y")]
x: Option<u32>,
}
let value: Foo = from_str("{}").unwrap();
assert_eq!(value, Foo { x: None });
let value: Foo = from_str("{\"y\": 5}").unwrap();
assert_eq!(value, Foo { x: Some(5) });
let value: Foo = from_value(Value::Object(treemap!())).unwrap();
assert_eq!(value, Foo { x: None });
let value: Foo = from_value(Value::Object(treemap!(
"y".to_string() => Value::I64(5)
))).unwrap();
assert_eq!(value, Foo { x: Some(5) });
}
#[test]
fn test_missing_fmt_renamed_field() {
#[derive(Debug, PartialEq, Deserialize)]
struct Foo {
#[serde(rename(json="y"))]
x: Option<u32>,
}
let value: Foo = from_str("{}").unwrap();
assert_eq!(value, Foo { x: None });
let value: Foo = from_str("{\"y\": 5}").unwrap();
assert_eq!(value, Foo { x: Some(5) });
let value: Foo = from_value(Value::Object(treemap!())).unwrap();
assert_eq!(value, Foo { x: None });
let value : Foo = from_value(Value::Object(treemap!(
"y".to_string() => Value::I64(5)
))).unwrap();
assert_eq!(value, Foo { x: Some(5) });
}
#[test]
fn test_find_path() {
let obj: Value = json::from_str(r#"{"x": {"a": 1}, "y": 2}"#).unwrap();
assert!(obj.find_path(&["x", "a"]).unwrap() == &Value::U64(1));
assert!(obj.find_path(&["y"]).unwrap() == &Value::U64(2));
assert!(obj.find_path(&["z"]).is_none());
}
#[test]
fn test_lookup() {
let obj: Value = json::from_str(r#"{"x": {"a": 1}, "y": 2}"#).unwrap();
assert!(obj.lookup("x.a").unwrap() == &Value::U64(1));
assert!(obj.lookup("y").unwrap() == &Value::U64(2));
assert!(obj.lookup("z").is_none());
}
@@ -1,5 +1,3 @@
extern crate serde;
use std::collections::BTreeMap;
use serde::json::value::Value;
@@ -15,12 +13,12 @@ fn test_array_builder() {
.push(2)
.push(3)
.unwrap();
assert_eq!(value, Value::Array(vec!(Value::I64(1), Value::I64(2), Value::I64(3))));
assert_eq!(value, Value::Array(vec!(Value::U64(1), Value::U64(2), Value::U64(3))));
let value = ArrayBuilder::new()
.push_array(|bld| bld.push(1).push(2).push(3))
.unwrap();
assert_eq!(value, Value::Array(vec!(Value::Array(vec!(Value::I64(1), Value::I64(2), Value::I64(3))))));
assert_eq!(value, Value::Array(vec!(Value::Array(vec!(Value::U64(1), Value::U64(2), Value::U64(3))))));
let value = ArrayBuilder::new()
.push_object(|bld|
@@ -30,8 +28,8 @@ fn test_array_builder() {
.unwrap();
let mut map = BTreeMap::new();
map.insert("a".to_string(), Value::I64(1));
map.insert("b".to_string(), Value::I64(2));
map.insert("a".to_string(), Value::U64(1));
map.insert("b".to_string(), Value::U64(2));
assert_eq!(value, Value::Array(vec!(Value::Object(map))));
}
@@ -46,7 +44,7 @@ fn test_object_builder() {
.unwrap();
let mut map = BTreeMap::new();
map.insert("a".to_string(), Value::I64(1));
map.insert("b".to_string(), Value::I64(2));
map.insert("a".to_string(), Value::U64(1));
map.insert("b".to_string(), Value::U64(2));
assert_eq!(value, Value::Object(map));
}
@@ -1,8 +1,3 @@
#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]
extern crate serde;
use std::collections::BTreeMap;
use serde::json::{self, Value};
@@ -25,13 +20,30 @@ trait Trait {
}
*/
#[derive(Debug, PartialEq)]
#[derive_serialize]
#[derive_deserialize]
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct NamedUnit;
#[derive(Debug, PartialEq)]
#[derive_serialize]
#[derive(Debug, PartialEq, Serialize)]
struct SerNamedTuple<'a, 'b, A: 'a, B: 'b, C>(&'a A, &'b mut B, C);
#[derive(Debug, PartialEq, Deserialize)]
struct DeNamedTuple<A, B, C>(A, B, C);
#[derive(Debug, PartialEq, Serialize)]
struct SerNamedMap<'a, 'b, A: 'a, B: 'b, C> {
a: &'a A,
b: &'b mut B,
c: C,
}
#[derive(Debug, PartialEq, Deserialize)]
struct DeNamedMap<A, B, C> {
a: A,
b: B,
c: C,
}
#[derive(Debug, PartialEq, Serialize)]
enum SerEnum<'a, B: 'a, C: /* Trait + */ 'a, D> where D: /* Trait + */ 'a {
Unit,
Seq(
@@ -50,10 +62,28 @@ enum SerEnum<'a, B: 'a, C: /* Trait + */ 'a, D> where D: /* Trait + */ 'a {
e: &'a mut D,
//f: <D as Trait>::Type,
},
// Make sure we can support more than one variant.
_Unit2,
_Seq2(
i8,
B,
&'a C,
//C::Type,
&'a mut D,
//<D as Trait>::Type,
),
_Map2 {
a: i8,
b: B,
c: &'a C,
//d: C::Type,
e: &'a mut D,
//f: <D as Trait>::Type,
},
}
#[derive(Debug, PartialEq)]
#[derive_deserialize]
#[derive(Debug, PartialEq, Deserialize)]
enum DeEnum<B, C: /* Trait */, D> /* where D: Trait */ {
Unit,
Seq(
@@ -72,6 +102,33 @@ enum DeEnum<B, C: /* Trait */, D> /* where D: Trait */ {
e: D,
//f: <D as Trait>::Type,
},
// Make sure we can support more than one variant.
_Unit2,
_Seq2(
i8,
B,
C,
//C::Type,
D,
//<D as Trait>::Type,
),
_Map2 {
a: i8,
b: B,
c: C,
//d: C::Type,
e: D,
//f: <D as Trait>::Type,
},
}
#[derive(Serialize)]
enum Lifetimes<'a> {
LifetimeSeq(&'a i32),
NoLifetimeSeq(i32),
LifetimeMap { a: &'a i32 },
NoLifetimeMap { a: i32 },
}
#[test]
@@ -88,23 +145,19 @@ fn test_named_unit() {
Value::Null
);
let v = json::from_str("null").unwrap();
let v: NamedUnit = json::from_str("null").unwrap();
assert_eq!(v, named_unit);
let v = json::from_value(Value::Null).unwrap();
let v: NamedUnit = json::from_value(Value::Null).unwrap();
assert_eq!(v, named_unit);
}
#[test]
fn test_ser_named_tuple() {
#[derive(Debug, PartialEq)]
#[derive_serialize]
struct NamedTuple<'a, 'b, A: 'a, B: 'b, C>(&'a A, &'b mut B, C);
let a = 5;
let mut b = 6;
let c = 7;
let named_tuple = NamedTuple(&a, &mut b, c);
let named_tuple = SerNamedTuple(&a, &mut b, c);
assert_eq!(
json::to_string(&named_tuple).unwrap(),
@@ -113,45 +166,35 @@ fn test_ser_named_tuple() {
assert_eq!(
json::to_value(&named_tuple),
Value::Array(vec![Value::I64(5), Value::I64(6), Value::I64(7)])
Value::Array(vec![Value::U64(5), Value::U64(6), Value::U64(7)])
);
}
#[test]
fn test_de_named_tuple() {
#[derive(Debug, PartialEq)]
#[derive_deserialize]
struct NamedTuple<A, B, C>(A, B, C);
let v: DeNamedTuple<i32, i32, i32> = json::from_str("[1,2,3]").unwrap();
assert_eq!(
json::from_str("[1,2,3]").unwrap(),
NamedTuple(1, 2, 3)
v,
DeNamedTuple(1, 2, 3)
);
let v: Value = json::from_str("[1,2,3]").unwrap();
assert_eq!(
json::from_str("[1,2,3]").unwrap(),
v,
Value::Array(vec![
Value::I64(1),
Value::I64(2),
Value::I64(3),
Value::U64(1),
Value::U64(2),
Value::U64(3),
])
);
}
#[test]
fn test_ser_named_map() {
#[derive(Debug, PartialEq)]
#[derive_serialize]
struct NamedMap<'a, 'b, A: 'a, B: 'b, C> {
a: &'a A,
b: &'b mut B,
c: C,
}
let a = 5;
let mut b = 6;
let c = 7;
let named_map = NamedMap {
let named_map = SerNamedMap {
a: &a,
b: &mut b,
c: c,
@@ -165,42 +208,32 @@ fn test_ser_named_map() {
assert_eq!(
json::to_value(&named_map),
Value::Object(btreemap![
"a".to_string() => Value::I64(5),
"b".to_string() => Value::I64(6),
"c".to_string() => Value::I64(7)
"a".to_string() => Value::U64(5),
"b".to_string() => Value::U64(6),
"c".to_string() => Value::U64(7)
])
);
}
#[test]
fn test_de_named_map() {
#[derive(Debug, PartialEq)]
#[derive_deserialize]
struct NamedMap<A, B, C> {
a: A,
b: B,
c: C,
}
let v = NamedMap {
let v = DeNamedMap {
a: 5,
b: 6,
c: 7,
};
assert_eq!(
json::from_str("{\"a\":5,\"b\":6,\"c\":7}").unwrap(),
v
);
let v2: DeNamedMap<i32, i32, i32> = json::from_str(
"{\"a\":5,\"b\":6,\"c\":7}"
).unwrap();
assert_eq!(v, v2);
assert_eq!(
json::from_value(Value::Object(btreemap![
"a".to_string() => Value::I64(5),
"b".to_string() => Value::I64(6),
"c".to_string() => Value::I64(7)
])).unwrap(),
v
);
let v2 = json::from_value(Value::Object(btreemap![
"a".to_string() => Value::U64(5),
"b".to_string() => Value::U64(6),
"c".to_string() => Value::U64(7)
])).unwrap();
assert_eq!(v, v2);
}
#[test]
@@ -250,12 +283,12 @@ fn test_ser_enum_seq() {
)),
Value::Object(btreemap!(
"Seq".to_string() => Value::Array(vec![
Value::I64(1),
Value::I64(2),
Value::I64(3),
//Value::I64(4),
Value::I64(5),
//Value::I64(6),
Value::U64(1),
Value::U64(2),
Value::U64(3),
//Value::U64(4),
Value::U64(5),
//Value::U64(6),
])
))
);
@@ -293,12 +326,12 @@ fn test_ser_enum_map() {
}),
Value::Object(btreemap!(
"Map".to_string() => Value::Object(btreemap![
"a".to_string() => Value::I64(1),
"b".to_string() => Value::I64(2),
"c".to_string() => Value::I64(3),
//"d".to_string() => Value::I64(4)
"e".to_string() => Value::I64(5)
//"f".to_string() => Value::I64(6)
"a".to_string() => Value::U64(1),
"b".to_string() => Value::U64(2),
"c".to_string() => Value::U64(3),
//"d".to_string() => Value::U64(4)
"e".to_string() => Value::U64(5)
//"f".to_string() => Value::U64(6)
])
))
);
@@ -306,15 +339,17 @@ fn test_ser_enum_map() {
#[test]
fn test_de_enum_unit() {
let v: DeEnum<_, _, _> = json::from_str("{\"Unit\":[]}").unwrap();
assert_eq!(
json::from_str("{\"Unit\":[]}").unwrap(),
v,
DeEnum::Unit::<u32, u32, u32>
);
let v: DeEnum<_, _, _> = json::from_value(Value::Object(btreemap!(
"Unit".to_string() => Value::Array(vec![]))
)).unwrap();
assert_eq!(
json::from_value(Value::Object(btreemap!(
"Unit".to_string() => Value::Array(vec![]))
)).unwrap(),
v,
DeEnum::Unit::<u32, u32, u32>
);
}
@@ -328,8 +363,9 @@ fn test_de_enum_seq() {
let e = 5;
//let f = 6;
let v: DeEnum<_, _, _> = json::from_str("{\"Seq\":[1,2,3,5]}").unwrap();
assert_eq!(
json::from_str("{\"Seq\":[1,2,3,5]}").unwrap(),
v,
DeEnum::Seq(
a,
b,
@@ -340,17 +376,18 @@ fn test_de_enum_seq() {
)
);
let v: DeEnum<_, _, _> = json::from_value(Value::Object(btreemap!(
"Seq".to_string() => Value::Array(vec![
Value::U64(1),
Value::U64(2),
Value::U64(3),
//Value::U64(4),
Value::U64(5),
//Value::U64(6),
])
))).unwrap();
assert_eq!(
json::from_value(Value::Object(btreemap!(
"Seq".to_string() => Value::Array(vec![
Value::I64(1),
Value::I64(2),
Value::I64(3),
//Value::I64(4),
Value::I64(5),
//Value::I64(6),
])
))).unwrap(),
v,
DeEnum::Seq(
a,
b,
@@ -371,8 +408,11 @@ fn test_de_enum_map() {
let e = 5;
//let f = 6;
let v: DeEnum<_, _, _> = json::from_str(
"{\"Map\":{\"a\":1,\"b\":2,\"c\":3,\"e\":5}}"
).unwrap();
assert_eq!(
json::from_str("{\"Map\":{\"a\":1,\"b\":2,\"c\":3,\"e\":5}}").unwrap(),
v,
DeEnum::Map {
a: a,
b: b,
@@ -383,17 +423,19 @@ fn test_de_enum_map() {
}
);
let v: DeEnum<_, _, _> = json::from_value(Value::Object(btreemap!(
"Map".to_string() => Value::Object(btreemap![
"a".to_string() => Value::U64(1),
"b".to_string() => Value::U64(2),
"c".to_string() => Value::U64(3),
//"d".to_string() => Value::U64(4)
"e".to_string() => Value::U64(5)
//"f".to_string() => Value::U64(6)
])
))).unwrap();
assert_eq!(
json::from_value(Value::Object(btreemap!(
"Map".to_string() => Value::Object(btreemap![
"a".to_string() => Value::I64(1),
"b".to_string() => Value::I64(2),
"c".to_string() => Value::I64(3),
//"d".to_string() => Value::I64(4)
"e".to_string() => Value::I64(5)
//"f".to_string() => Value::I64(6)
])
))).unwrap(),
v,
DeEnum::Map {
a: a,
b: b,
@@ -404,3 +446,32 @@ fn test_de_enum_map() {
}
);
}
#[test]
fn test_lifetimes() {
let value = 5;
let lifetime = Lifetimes::LifetimeSeq(&value);
assert_eq!(
json::to_string(&lifetime).unwrap(),
"{\"LifetimeSeq\":[5]}"
);
let lifetime = Lifetimes::NoLifetimeSeq(5);
assert_eq!(
json::to_string(&lifetime).unwrap(),
"{\"NoLifetimeSeq\":[5]}"
);
let value = 5;
let lifetime = Lifetimes::LifetimeMap { a: &value };
assert_eq!(
json::to_string(&lifetime).unwrap(),
"{\"LifetimeMap\":{\"a\":5}}"
);
let lifetime = Lifetimes::NoLifetimeMap { a: 5 };
assert_eq!(
json::to_string(&lifetime).unwrap(),
"{\"NoLifetimeMap\":{\"a\":5}}"
);
}
@@ -1,13 +1,7 @@
#![feature(custom_derive, plugin, test)]
#![plugin(serde_macros)]
extern crate test;
extern crate serde;
use std::vec;
use std::collections::BTreeMap;
use serde::ser::{Serialize, Serializer, Visitor, SeqVisitor, MapVisitor};
use serde::ser::{Serialize, Serializer, SeqVisitor, MapVisitor};
#[derive(Clone, PartialEq, Debug)]
pub enum Token<'a> {
@@ -33,16 +27,16 @@ pub enum Token<'a> {
NamedUnit(&'a str),
EnumUnit(&'a str, &'a str),
SeqStart(usize),
NamedSeqStart(&'a str, usize),
EnumSeqStart(&'a str, &'a str, usize),
SeqSep(bool),
SeqStart(Option<usize>),
NamedSeqStart(&'a str, Option<usize>),
EnumSeqStart(&'a str, &'a str, Option<usize>),
SeqSep,
SeqEnd,
MapStart(usize),
NamedMapStart(&'a str, usize),
EnumMapStart(&'a str, &'a str, usize),
MapSep(bool),
MapStart(Option<usize>),
NamedMapStart(&'a str, Option<usize>),
EnumMapStart(&'a str, &'a str, Option<usize>),
MapSep,
MapEnd,
}
@@ -79,16 +73,6 @@ impl<'a> AssertSerializer<'a> {
}
impl<'a> Serializer for AssertSerializer<'a> {
type Value = ();
type Error = ();
fn visit<T: Serialize>(&mut self, value: &T) -> Result<(), ()> {
value.visit(self)
}
}
impl<'a> Visitor for AssertSerializer<'a> {
type Value = ();
type Error = ();
fn visit_unit(&mut self) -> Result<(), ()> {
@@ -190,14 +174,14 @@ impl<'a> Visitor for AssertSerializer<'a> {
where V: Serialize,
{
assert_eq!(self.iter.next(), Some(Token::Option(true)));
value.visit(self)
value.serialize(self)
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<(), ()>
where V: SeqVisitor
{
let (len, _) = visitor.size_hint();
let len = visitor.len();
assert_eq!(self.iter.next(), Some(Token::SeqStart(len)));
@@ -207,7 +191,7 @@ impl<'a> Visitor for AssertSerializer<'a> {
fn visit_named_seq<V>(&mut self, name: &str, visitor: V) -> Result<(), ()>
where V: SeqVisitor
{
let (len, _) = visitor.size_hint();
let len = visitor.len();
assert_eq!(self.iter.next().unwrap(), Token::NamedSeqStart(name, len));
@@ -220,24 +204,24 @@ impl<'a> Visitor for AssertSerializer<'a> {
visitor: V) -> Result<(), ()>
where V: SeqVisitor
{
let (len, _) = visitor.size_hint();
let len = visitor.len();
assert_eq!(self.iter.next().unwrap(), Token::EnumSeqStart(name, variant, len));
self.visit_sequence(visitor)
}
fn visit_seq_elt<T>(&mut self, first: bool, value: T) -> Result<(), ()>
fn visit_seq_elt<T>(&mut self, value: T) -> Result<(), ()>
where T: Serialize
{
assert_eq!(self.iter.next(), Some(Token::SeqSep(first)));
value.visit(self)
assert_eq!(self.iter.next(), Some(Token::SeqSep));
value.serialize(self)
}
fn visit_map<V>(&mut self, visitor: V) -> Result<(), ()>
where V: MapVisitor
{
let (len, _) = visitor.size_hint();
let len = visitor.len();
assert_eq!(self.iter.next(), Some(Token::MapStart(len)));
@@ -247,56 +231,50 @@ impl<'a> Visitor for AssertSerializer<'a> {
fn visit_named_map<V>(&mut self, name: &str, visitor: V) -> Result<(), ()>
where V: MapVisitor
{
let (len, _) = visitor.size_hint();
let len = visitor.len();
assert_eq!(self.iter.next().unwrap(), Token::NamedMapStart(name, len));
self.visit_mapping(visitor)
}
fn visit_enum_map<V>(&mut self,
name: &str,
variant: &str,
visitor: V) -> Result<(), ()>
fn visit_enum_map<V>(&mut self, name: &str, variant: &str, visitor: V) -> Result<(), ()>
where V: MapVisitor
{
let (len, _) = visitor.size_hint();
let len = visitor.len();
assert_eq!(self.iter.next().unwrap(), Token::EnumMapStart(name, variant, len));
self.visit_mapping(visitor)
}
fn visit_map_elt<K, V>(&mut self,
first: bool,
key: K,
value: V) -> Result<(), ()>
fn visit_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), ()>
where K: Serialize,
V: Serialize,
{
assert_eq!(self.iter.next(), Some(Token::MapSep(first)));
assert_eq!(self.iter.next(), Some(Token::MapSep));
try!(key.visit(self));
value.visit(self)
try!(key.serialize(self));
value.serialize(self)
}
}
//////////////////////////////////////////////////////////////////////////
#[derive_serialize]
#[derive(Serialize)]
struct NamedUnit;
#[derive_serialize]
#[derive(Serialize)]
struct NamedSeq(i32, i32, i32);
#[derive_serialize]
#[derive(Serialize)]
struct NamedMap {
a: i32,
b: i32,
c: i32,
}
#[derive_serialize]
#[derive(Serialize)]
enum Enum {
Unit,
Seq(i32, i32),
@@ -324,7 +302,7 @@ macro_rules! declare_test {
fn $name() {
$(
let mut ser = AssertSerializer::new($tokens);
assert_eq!(ser.visit(&$value), Ok(()));
assert_eq!($value.serialize(&mut ser), Ok(()));
)+
}
}
@@ -380,45 +358,63 @@ declare_tests! {
}
test_slice {
&[0][..0] => vec![
Token::SeqStart(0),
Token::SeqStart(Some(0)),
Token::SeqEnd,
],
&[1, 2, 3][..] => vec![
Token::SeqStart(3),
Token::SeqSep(true),
Token::SeqStart(Some(3)),
Token::SeqSep,
Token::I32(1),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(2),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
],
}
test_array {
[0; 0] => vec![
Token::SeqStart(Some(0)),
Token::SeqEnd,
],
[1, 2, 3] => vec![
Token::SeqStart(Some(3)),
Token::SeqSep,
Token::I32(1),
Token::SeqSep,
Token::I32(2),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
],
}
test_vec {
Vec::<isize>::new() => vec![
Token::SeqStart(0),
Token::SeqStart(Some(0)),
Token::SeqEnd,
],
vec![vec![], vec![1], vec![2, 3]] => vec![
Token::SeqStart(3),
Token::SeqSep(true),
Token::SeqStart(0),
Token::SeqStart(Some(3)),
Token::SeqSep,
Token::SeqStart(Some(0)),
Token::SeqEnd,
Token::SeqSep(false),
Token::SeqStart(1),
Token::SeqSep(true),
Token::SeqSep,
Token::SeqStart(Some(1)),
Token::SeqSep,
Token::I32(1),
Token::SeqEnd,
Token::SeqSep(false),
Token::SeqStart(2),
Token::SeqSep(true),
Token::SeqSep,
Token::SeqStart(Some(2)),
Token::SeqSep,
Token::I32(2),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
Token::SeqEnd,
@@ -426,58 +422,58 @@ declare_tests! {
}
test_tuple {
(1,) => vec![
Token::SeqStart(1),
Token::SeqSep(true),
Token::SeqStart(Some(1)),
Token::SeqSep,
Token::I32(1),
Token::SeqEnd,
],
(1, 2, 3) => vec![
Token::SeqStart(3),
Token::SeqSep(true),
Token::SeqStart(Some(3)),
Token::SeqSep,
Token::I32(1),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(2),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
],
}
test_btreemap {
btreemap![1 => 2] => vec![
Token::MapStart(1),
Token::MapSep(true),
Token::MapStart(Some(1)),
Token::MapSep,
Token::I32(1),
Token::I32(2),
Token::MapEnd,
],
btreemap![1 => 2, 3 => 4] => vec![
Token::MapStart(2),
Token::MapSep(true),
Token::MapStart(Some(2)),
Token::MapSep,
Token::I32(1),
Token::I32(2),
Token::MapSep(false),
Token::MapSep,
Token::I32(3),
Token::I32(4),
Token::MapEnd,
],
btreemap![1 => btreemap![], 2 => btreemap![3 => 4, 5 => 6]] => vec![
Token::MapStart(2),
Token::MapSep(true),
Token::MapStart(Some(2)),
Token::MapSep,
Token::I32(1),
Token::MapStart(0),
Token::MapStart(Some(0)),
Token::MapEnd,
Token::MapSep(false),
Token::MapSep,
Token::I32(2),
Token::MapStart(2),
Token::MapSep(true),
Token::MapStart(Some(2)),
Token::MapSep,
Token::I32(3),
Token::I32(4),
Token::MapSep(false),
Token::MapSep,
Token::I32(5),
Token::I32(6),
Token::MapEnd,
@@ -489,30 +485,30 @@ declare_tests! {
}
test_named_seq {
NamedSeq(1, 2, 3) => vec![
Token::NamedSeqStart("NamedSeq", 3),
Token::SeqSep(true),
Token::NamedSeqStart("NamedSeq", Some(3)),
Token::SeqSep,
Token::I32(1),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(2),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
],
}
test_named_map {
NamedMap { a: 1, b: 2, c: 3 } => vec![
Token::NamedMapStart("NamedMap", 3),
Token::MapSep(true),
Token::NamedMapStart("NamedMap", Some(3)),
Token::MapSep,
Token::Str("a"),
Token::I32(1),
Token::MapSep(false),
Token::MapSep,
Token::Str("b"),
Token::I32(2),
Token::MapSep(false),
Token::MapSep,
Token::Str("c"),
Token::I32(3),
Token::MapEnd,
@@ -521,21 +517,21 @@ declare_tests! {
test_enum {
Enum::Unit => vec![Token::EnumUnit("Enum", "Unit")],
Enum::Seq(1, 2) => vec![
Token::EnumSeqStart("Enum", "Seq", 2),
Token::SeqSep(true),
Token::EnumSeqStart("Enum", "Seq", Some(2)),
Token::SeqSep,
Token::I32(1),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(2),
Token::SeqEnd,
],
Enum::Map { a: 1, b: 2 } => vec![
Token::EnumMapStart("Enum", "Map", 2),
Token::MapSep(true),
Token::EnumMapStart("Enum", "Map", Some(2)),
Token::MapSep,
Token::Str("a"),
Token::I32(1),
Token::MapSep(false),
Token::MapSep,
Token::Str("b"),
Token::I32(2),
Token::MapEnd,
-819
View File
@@ -1,819 +0,0 @@
use std::collections::{HashMap, BTreeMap};
use std::hash::Hash;
use std::marker::PhantomData;
use std::num::FromPrimitive;
use std::path;
use std::str;
///////////////////////////////////////////////////////////////////////////////
pub trait Error {
fn syntax_error() -> Self;
fn end_of_stream_error() -> Self;
fn missing_field_error(&'static str) -> Self;
}
pub trait Deserialize {
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
where D: Deserializer;
}
pub trait Deserializer {
type Error: Error;
fn visit<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor;
/// The `visit_option` method allows a `Deserialize` type to inform the
/// `Deserializer` that it's expecting an optional value. This allows
/// deserializers that encode an optional value as a nullable value to
/// convert the null value into a `None`, and a regular value as
/// `Some(value)`.
#[inline]
fn visit_option<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// The `visit_enum` method allows a `Deserialize` type to inform the
/// `Deserializer` that it's expecting an enum value. This allows
/// deserializers that provide a custom enumeration serialization to
/// properly deserialize the type.
#[inline]
fn visit_enum<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
}
pub trait Visitor {
type Value;
fn visit_bool<E>(&mut self, _v: bool) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
fn visit_isize<E>(&mut self, v: isize) -> Result<Self::Value, E>
where E: Error,
{
self.visit_i64(v as i64)
}
fn visit_i8<E>(&mut self, v: i8) -> Result<Self::Value, E>
where E: Error,
{
self.visit_i64(v as i64)
}
fn visit_i16<E>(&mut self, v: i16) -> Result<Self::Value, E>
where E: Error,
{
self.visit_i64(v as i64)
}
fn visit_i32<E>(&mut self, v: i32) -> Result<Self::Value, E>
where E: Error,
{
self.visit_i64(v as i64)
}
fn visit_i64<E>(&mut self, _v: i64) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
fn visit_usize<E>(&mut self, v: usize) -> Result<Self::Value, E>
where E: Error,
{
self.visit_u64(v as u64)
}
fn visit_u8<E>(&mut self, v: u8) -> Result<Self::Value, E>
where E: Error,
{
self.visit_u64(v as u64)
}
fn visit_u16<E>(&mut self, v: u16) -> Result<Self::Value, E>
where E: Error,
{
self.visit_u64(v as u64)
}
fn visit_u32<E>(&mut self, v: u32) -> Result<Self::Value, E>
where E: Error,
{
self.visit_u64(v as u64)
}
fn visit_u64<E>(&mut self, _v: u64) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
fn visit_f32<E>(&mut self, v: f32) -> Result<Self::Value, E>
where E: Error,
{
self.visit_f64(v as f64)
}
fn visit_f64<E>(&mut self, _v: f64) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
#[inline]
fn visit_char<E>(&mut self, v: char) -> Result<Self::Value, E>
where E: Error,
{
// The unwraps in here should be safe.
let mut s = &mut [0; 4];
let len = v.encode_utf8(s).unwrap();
self.visit_str(str::from_utf8(&s[..len]).unwrap())
}
fn visit_str<E>(&mut self, _v: &str) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
#[inline]
fn visit_string<E>(&mut self, v: String) -> Result<Self::Value, E>
where E: Error,
{
self.visit_str(&v)
}
fn visit_unit<E>(&mut self) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
#[inline]
fn visit_named_unit<E>(&mut self, _name: &str) -> Result<Self::Value, E>
where E: Error,
{
self.visit_unit()
}
fn visit_none<E>(&mut self) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
fn visit_some<D>(&mut self, _deserializer: &mut D) -> Result<Self::Value, D::Error>
where D: Deserializer,
{
Err(Error::syntax_error())
}
fn visit_seq<V>(&mut self, _visitor: V) -> Result<Self::Value, V::Error>
where V: SeqVisitor,
{
Err(Error::syntax_error())
}
#[inline]
fn visit_named_seq<V>(&mut self, _name: &str, visitor: V) -> Result<Self::Value, V::Error>
where V: SeqVisitor,
{
self.visit_seq(visitor)
}
fn visit_map<V>(&mut self, _visitor: V) -> Result<Self::Value, V::Error>
where V: MapVisitor,
{
Err(Error::syntax_error())
}
#[inline]
fn visit_named_map<V>(&mut self, _name: &str, visitor: V) -> Result<Self::Value, V::Error>
where V: MapVisitor,
{
self.visit_map(visitor)
}
#[inline]
fn visit_enum<V>(&mut self,
_name: &str,
_variant: &str,
_visitor: V) -> Result<Self::Value, V::Error>
where V: EnumVisitor,
{
Err(Error::syntax_error())
}
#[inline]
fn visit_variant<V>(&mut self, _name: &str, _visitor: V) -> Result<Self::Value, V::Error>
where V: EnumVisitor,
{
Err(Error::syntax_error())
}
}
///////////////////////////////////////////////////////////////////////////////
pub trait SeqVisitor {
type Error: Error;
fn visit<T>(&mut self) -> Result<Option<T>, Self::Error>
where T: Deserialize;
fn end(&mut self) -> Result<(), Self::Error>;
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
}
impl<'a, V> SeqVisitor for &'a mut V where V: SeqVisitor {
type Error = V::Error;
#[inline]
fn visit<T>(&mut self) -> Result<Option<T>, V::Error>
where T: Deserialize
{
(**self).visit()
}
#[inline]
fn end(&mut self) -> Result<(), V::Error> {
(**self).end()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(**self).size_hint()
}
}
///////////////////////////////////////////////////////////////////////////////
pub trait MapVisitor {
type Error: Error;
#[inline]
fn visit<K, V>(&mut self) -> Result<Option<(K, V)>, Self::Error>
where K: Deserialize,
V: Deserialize,
{
match try!(self.visit_key()) {
Some(key) => {
let value = try!(self.visit_value());
Ok(Some((key, value)))
}
None => Ok(None)
}
}
fn visit_key<K>(&mut self) -> Result<Option<K>, Self::Error>
where K: Deserialize;
fn visit_value<V>(&mut self) -> Result<V, Self::Error>
where V: Deserialize;
fn end(&mut self) -> Result<(), Self::Error>;
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
}
impl<'a, V_> MapVisitor for &'a mut V_ where V_: MapVisitor {
type Error = V_::Error;
#[inline]
fn visit<K, V>(&mut self) -> Result<Option<(K, V)>, V_::Error>
where K: Deserialize,
V: Deserialize,
{
(**self).visit()
}
#[inline]
fn visit_key<K>(&mut self) -> Result<Option<K>, V_::Error>
where K: Deserialize
{
(**self).visit_key()
}
#[inline]
fn visit_value<V>(&mut self) -> Result<V, V_::Error>
where V: Deserialize
{
(**self).visit_value()
}
#[inline]
fn end(&mut self) -> Result<(), V_::Error> {
(**self).end()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(**self).size_hint()
}
}
///////////////////////////////////////////////////////////////////////////////
pub trait EnumVisitor {
type Error: Error;
fn visit_unit(&mut self) -> Result<(), Self::Error> {
Err(Error::syntax_error())
}
fn visit_seq<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
where V: EnumSeqVisitor,
{
Err(Error::syntax_error())
}
fn visit_map<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
where V: EnumMapVisitor,
{
Err(Error::syntax_error())
}
}
///////////////////////////////////////////////////////////////////////////////
pub trait EnumSeqVisitor {
type Value;
fn visit<V>(&mut self, visitor: V) -> Result<Self::Value, V::Error>
where V: SeqVisitor;
}
///////////////////////////////////////////////////////////////////////////////
pub trait EnumMapVisitor {
type Value;
fn visit<V>(&mut self, visitor: V) -> Result<Self::Value, V::Error>
where V: MapVisitor;
}
///////////////////////////////////////////////////////////////////////////////
struct UnitVisitor;
impl Visitor for UnitVisitor {
type Value = ();
fn visit_unit<E>(&mut self) -> Result<(), E>
where E: Error,
{
Ok(())
}
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<(), V::Error>
where V: SeqVisitor,
{
visitor.end()
}
}
impl Deserialize for () {
fn deserialize<D>(deserializer: &mut D) -> Result<(), D::Error>
where D: Deserializer,
{
deserializer.visit(UnitVisitor)
}
}
///////////////////////////////////////////////////////////////////////////////
struct BoolVisitor;
impl Visitor for BoolVisitor {
type Value = bool;
fn visit_bool<E>(&mut self, v: bool) -> Result<bool, E>
where E: Error,
{
Ok(v)
}
}
impl Deserialize for bool {
fn deserialize<D>(deserializer: &mut D) -> Result<bool, D::Error>
where D: Deserializer,
{
deserializer.visit(BoolVisitor)
}
}
///////////////////////////////////////////////////////////////////////////////
macro_rules! impl_deserialize_num_method {
($src_ty:ty, $method:ident, $from_method:ident) => {
#[inline]
fn $method<E>(&mut self, v: $src_ty) -> Result<T, E>
where E: Error,
{
match FromPrimitive::$from_method(v) {
Some(v) => Ok(v),
None => Err(Error::syntax_error()),
}
}
}
}
pub struct PrimitiveVisitor<T> {
marker: PhantomData<T>,
}
impl<T> PrimitiveVisitor<T> {
#[inline]
pub fn new() -> Self {
PrimitiveVisitor {
marker: PhantomData,
}
}
}
impl<
T: Deserialize + FromPrimitive
> self::Visitor for PrimitiveVisitor<T> {
type Value = T;
impl_deserialize_num_method!(isize, visit_isize, from_isize);
impl_deserialize_num_method!(i8, visit_i8, from_i8);
impl_deserialize_num_method!(i16, visit_i16, from_i16);
impl_deserialize_num_method!(i32, visit_i32, from_i32);
impl_deserialize_num_method!(i64, visit_i64, from_i64);
impl_deserialize_num_method!(usize, visit_usize, from_usize);
impl_deserialize_num_method!(u8, visit_u8, from_u8);
impl_deserialize_num_method!(u16, visit_u16, from_u16);
impl_deserialize_num_method!(u32, visit_u32, from_u32);
impl_deserialize_num_method!(u64, visit_u64, from_u64);
impl_deserialize_num_method!(f32, visit_f32, from_f32);
impl_deserialize_num_method!(f64, visit_f64, from_f64);
}
macro_rules! impl_deserialize_num {
($ty:ty) => {
impl Deserialize for $ty {
#[inline]
fn deserialize<D>(deserializer: &mut D) -> Result<$ty, D::Error>
where D: Deserializer,
{
deserializer.visit(PrimitiveVisitor::new())
}
}
}
}
impl_deserialize_num!(isize);
impl_deserialize_num!(i8);
impl_deserialize_num!(i16);
impl_deserialize_num!(i32);
impl_deserialize_num!(i64);
impl_deserialize_num!(usize);
impl_deserialize_num!(u8);
impl_deserialize_num!(u16);
impl_deserialize_num!(u32);
impl_deserialize_num!(u64);
impl_deserialize_num!(f32);
impl_deserialize_num!(f64);
///////////////////////////////////////////////////////////////////////////////
struct CharVisitor;
impl Visitor for CharVisitor {
type Value = char;
#[inline]
fn visit_char<E>(&mut self, v: char) -> Result<char, E>
where E: Error,
{
Ok(v)
}
#[inline]
fn visit_str<E>(&mut self, v: &str) -> Result<char, E>
where E: Error,
{
let mut iter = v.chars();
if let Some(v) = iter.next() {
if iter.next().is_some() {
Err(Error::syntax_error())
} else {
Ok(v)
}
} else {
Err(Error::end_of_stream_error())
}
}
}
impl Deserialize for char {
#[inline]
fn deserialize<D>(deserializer: &mut D) -> Result<char, D::Error>
where D: Deserializer,
{
deserializer.visit(CharVisitor)
}
}
///////////////////////////////////////////////////////////////////////////////
struct StringVisitor;
impl Visitor for StringVisitor {
type Value = String;
fn visit_str<E>(&mut self, v: &str) -> Result<String, E>
where E: Error,
{
Ok(v.to_string())
}
fn visit_string<E>(&mut self, v: String) -> Result<String, E>
where E: Error,
{
Ok(v)
}
}
impl Deserialize for String {
fn deserialize<D>(deserializer: &mut D) -> Result<String, D::Error>
where D: Deserializer,
{
deserializer.visit(StringVisitor)
}
}
///////////////////////////////////////////////////////////////////////////////
struct OptionVisitor<T> {
marker: PhantomData<T>,
}
impl<
T: Deserialize,
> Visitor for OptionVisitor<T> {
type Value = Option<T>;
#[inline]
fn visit_none<E>(&mut self) -> Result<Option<T>, E>
where E: Error,
{
Ok(None)
}
#[inline]
fn visit_some<D>(&mut self, deserializer: &mut D) -> Result<Option<T>, D::Error>
where D: Deserializer,
{
Ok(Some(try!(Deserialize::deserialize(deserializer))))
}
}
impl<T> Deserialize for Option<T> where T: Deserialize {
fn deserialize<D>(deserializer: &mut D) -> Result<Option<T>, D::Error>
where D: Deserializer,
{
deserializer.visit_option(OptionVisitor { marker: PhantomData })
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct VecVisitor<T> {
marker: PhantomData<T>,
}
impl<T> VecVisitor<T> {
pub fn new() -> Self {
VecVisitor {
marker: PhantomData,
}
}
}
impl<T> Visitor for VecVisitor<T> where T: Deserialize {
type Value = Vec<T>;
#[inline]
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<Vec<T>, V::Error>
where V: SeqVisitor,
{
let (len, _) = visitor.size_hint();
let mut values = Vec::with_capacity(len);
while let Some(value) = try!(visitor.visit()) {
values.push(value);
}
Ok(values)
}
}
impl<T: Deserialize> Deserialize for Vec<T> {
fn deserialize<D>(deserializer: &mut D) -> Result<Vec<T>, D::Error>
where D: Deserializer,
{
deserializer.visit(VecVisitor::new())
}
}
///////////////////////////////////////////////////////////////////////////////
macro_rules! tuple_impls {
() => {};
($($visitor:ident => ($($name:ident),+),)+) => {
$(
struct $visitor<$($name,)+> {
marker: PhantomData<($($name,)+)>,
}
impl<
$($name: Deserialize,)+
> Visitor for $visitor<$($name,)+> {
type Value = ($($name,)+);
#[inline]
#[allow(non_snake_case)]
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<($($name,)+), V::Error>
where V: SeqVisitor,
{
$(
let $name = match try!(visitor.visit()) {
Some(value) => value,
None => { return Err(Error::end_of_stream_error()); }
};
)+;
try!(visitor.end());
Ok(($($name,)+))
}
}
impl<
$($name: Deserialize),+
> Deserialize for ($($name,)+) {
#[inline]
fn deserialize<D>(deserializer: &mut D) -> Result<($($name,)+), D::Error>
where D: Deserializer,
{
deserializer.visit($visitor { marker: PhantomData })
}
}
)+
}
}
tuple_impls! {
TupleVisitor1 => (T0),
TupleVisitor2 => (T0, T1),
TupleVisitor3 => (T0, T1, T2),
TupleVisitor4 => (T0, T1, T2, T3),
TupleVisitor5 => (T0, T1, T2, T3, T4),
TupleVisitor6 => (T0, T1, T2, T3, T4, T5),
TupleVisitor7 => (T0, T1, T2, T3, T4, T5, T6),
TupleVisitor8 => (T0, T1, T2, T3, T4, T5, T6, T7),
TupleVisitor9 => (T0, T1, T2, T3, T4, T5, T6, T7, T8),
TupleVisitor10 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9),
TupleVisitor11 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10),
TupleVisitor12 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11),
}
///////////////////////////////////////////////////////////////////////////////
pub struct HashMapVisitor<K, V> {
marker: PhantomData<HashMap<K, V>>,
}
impl<K, V> HashMapVisitor<K, V> {
#[inline]
pub fn new() -> Self {
HashMapVisitor {
marker: PhantomData,
}
}
}
impl<K, V> Visitor for HashMapVisitor<K, V>
where K: Deserialize + Eq + Hash,
V: Deserialize,
{
type Value = HashMap<K, V>;
#[inline]
fn visit_map<V_>(&mut self, mut visitor: V_) -> Result<HashMap<K, V>, V_::Error>
where V_: MapVisitor,
{
let (len, _) = visitor.size_hint();
let mut values = HashMap::with_capacity(len);
while let Some((key, value)) = try!(visitor.visit()) {
values.insert(key, value);
}
Ok(values)
}
}
impl<K, V> Deserialize for HashMap<K, V>
where K: Deserialize + Eq + Hash,
V: Deserialize,
{
fn deserialize<D>(deserializer: &mut D) -> Result<HashMap<K, V>, D::Error>
where D: Deserializer,
{
deserializer.visit(HashMapVisitor::new())
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct BTreeMapVisitor<K, V> {
marker: PhantomData<BTreeMap<K, V>>,
}
impl<K, V> BTreeMapVisitor<K, V> {
#[inline]
pub fn new() -> Self {
BTreeMapVisitor {
marker: PhantomData,
}
}
}
impl<K, V> Visitor for BTreeMapVisitor<K, V>
where K: Deserialize + Ord,
V: Deserialize
{
type Value = BTreeMap<K, V>;
#[inline]
fn visit_map<Visitor>(&mut self, mut visitor: Visitor) -> Result<BTreeMap<K, V>, Visitor::Error>
where Visitor: MapVisitor,
{
let mut values = BTreeMap::new();
while let Some((key, value)) = try!(visitor.visit()) {
values.insert(key, value);
}
Ok(values)
}
}
impl<
K: Deserialize + Eq + Ord,
V: Deserialize,
> Deserialize for BTreeMap<K, V> {
fn deserialize<D>(deserializer: &mut D) -> Result<BTreeMap<K, V>, D::Error>
where D: Deserializer,
{
deserializer.visit(BTreeMapVisitor::new())
}
}
///////////////////////////////////////////////////////////////////////////////
struct PathBufVisitor;
impl Visitor for PathBufVisitor {
type Value = path::PathBuf;
fn visit_str<E>(&mut self, v: &str) -> Result<path::PathBuf, E>
where E: Error,
{
Ok(path::PathBuf::new(&v))
}
fn visit_string<E>(&mut self, v: String) -> Result<path::PathBuf, E>
where E: Error,
{
self.visit_str(&v)
}
}
impl Deserialize for path::PathBuf {
fn deserialize<D>(deserializer: &mut D) -> Result<path::PathBuf, D::Error>
where D: Deserializer,
{
deserializer.visit(PathBufVisitor)
}
}
-19
View File
@@ -1,19 +0,0 @@
pub use self::de::{Deserializer, from_str};
pub use self::error::{Error, ErrorCode};
pub use self::ser::{
Serializer,
to_writer,
to_writer_pretty,
to_vec,
to_vec_pretty,
to_string,
to_string_pretty,
escape_str,
};
pub use self::value::{Value, to_value, from_value};
pub mod builder;
pub mod de;
pub mod error;
pub mod ser;
pub mod value;
-457
View File
@@ -1,457 +0,0 @@
use std::{f32, f64};
use std::io;
use std::num::{Float, FpCategory};
use std::string::FromUtf8Error;
use ser;
/// A structure for implementing serialization to JSON.
pub struct Serializer<W> {
writer: W,
format: Format,
current_indent: usize,
indent: usize,
}
#[derive(Copy, PartialEq)]
enum Format {
Compact,
Pretty,
}
impl<W: io::Write> Serializer<W> {
/// Creates a new JSON visitr whose output will be written to the writer
/// specified.
#[inline]
pub fn new(writer: W) -> Serializer<W> {
Serializer {
writer: writer,
format: Format::Compact,
current_indent: 0,
indent: 0,
}
}
/// Creates a new JSON visitr whose output will be written to the writer
/// specified.
#[inline]
pub fn new_pretty(writer: W) -> Serializer<W> {
Serializer {
writer: writer,
format: Format::Pretty,
current_indent: 0,
indent: 2,
}
}
/// Unwrap the `Writer` from the `Serializer`.
#[inline]
pub fn into_inner(self) -> W {
self.writer
}
}
impl<W: io::Write> ser::Serializer for Serializer<W> {
type Value = ();
type Error = io::Error;
#[inline]
fn visit<T>(&mut self, value: &T) -> io::Result<()>
where T: ser::Serialize,
{
value.visit(&mut Visitor {
writer: &mut self.writer,
format: self.format,
current_indent: self.current_indent,
indent: self.indent,
})
}
}
struct Visitor<'a, W: 'a> {
writer: &'a mut W,
format: Format,
current_indent: usize,
indent: usize,
}
impl<'a, W> Visitor<'a, W> where W: io::Write, {
fn serialize_sep(&mut self, first: bool) -> io::Result<()> {
match self.format {
Format::Compact => {
if first {
Ok(())
} else {
self.writer.write_all(b",")
}
}
Format::Pretty => {
if first {
self.current_indent += self.indent;
try!(self.writer.write_all(b"\n"));
} else {
try!(self.writer.write_all(b",\n"));
}
spaces(&mut self.writer, self.current_indent)
}
}
}
fn serialize_colon(&mut self) -> io::Result<()> {
match self.format {
Format::Compact => self.writer.write_all(b":"),
Format::Pretty => self.writer.write_all(b": "),
}
}
fn serialize_end(&mut self, current_indent: usize, s: &[u8]) -> io::Result<()> {
if self.format == Format::Pretty && current_indent != self.current_indent {
self.current_indent -= self.indent;
try!(self.writer.write(b"\n"));
try!(spaces(&mut self.writer, self.current_indent));
}
self.writer.write_all(s)
}
}
impl<'a, W> ser::Visitor for Visitor<'a, W> where W: io::Write, {
type Value = ();
type Error = io::Error;
#[inline]
fn visit_bool(&mut self, value: bool) -> io::Result<()> {
if value {
self.writer.write_all(b"true")
} else {
self.writer.write_all(b"false")
}
}
#[inline]
fn visit_isize(&mut self, value: isize) -> io::Result<()> {
write!(self.writer, "{}", value)
}
#[inline]
fn visit_i8(&mut self, value: i8) -> io::Result<()> {
write!(self.writer, "{}", value)
}
#[inline]
fn visit_i16(&mut self, value: i16) -> io::Result<()> {
write!(self.writer, "{}", value)
}
#[inline]
fn visit_i32(&mut self, value: i32) -> io::Result<()> {
write!(self.writer, "{}", value)
}
#[inline]
fn visit_i64(&mut self, value: i64) -> io::Result<()> {
write!(self.writer, "{}", value)
}
#[inline]
fn visit_usize(&mut self, value: usize) -> io::Result<()> {
write!(self.writer, "{}", value)
}
#[inline]
fn visit_u8(&mut self, value: u8) -> io::Result<()> {
write!(self.writer, "{}", value)
}
#[inline]
fn visit_u16(&mut self, value: u16) -> io::Result<()> {
write!(self.writer, "{}", value)
}
#[inline]
fn visit_u32(&mut self, value: u32) -> io::Result<()> {
write!(self.writer, "{}", value)
}
#[inline]
fn visit_u64(&mut self, value: u64) -> io::Result<()> {
write!(self.writer, "{}", value)
}
#[inline]
fn visit_f32(&mut self, value: f32) -> io::Result<()> {
fmt_f32_or_null(self.writer, value)
}
#[inline]
fn visit_f64(&mut self, value: f64) -> io::Result<()> {
fmt_f64_or_null(self.writer, value)
}
#[inline]
fn visit_char(&mut self, value: char) -> io::Result<()> {
escape_char(self.writer, value)
}
#[inline]
fn visit_str(&mut self, value: &str) -> io::Result<()> {
escape_str(self.writer, value)
}
#[inline]
fn visit_none(&mut self) -> io::Result<()> {
self.visit_unit()
}
#[inline]
fn visit_some<V>(&mut self, value: V) -> io::Result<()>
where V: ser::Serialize
{
value.visit(self)
}
#[inline]
fn visit_unit(&mut self) -> io::Result<()> {
self.writer.write_all(b"null")
}
#[inline]
fn visit_enum_unit(&mut self, _name: &str, variant: &str) -> io::Result<()> {
let current_indent = self.current_indent;
try!(self.writer.write_all(b"{"));
try!(self.serialize_sep(true));
try!(self.visit_str(variant));
try!(self.serialize_colon());
try!(self.writer.write_all(b"[]"));
self.serialize_end(current_indent, b"}")
}
#[inline]
fn visit_seq<V>(&mut self, mut visitor: V) -> io::Result<()>
where V: ser::SeqVisitor,
{
let current_indent = self.current_indent;
try!(self.writer.write_all(b"["));
while let Some(()) = try!(visitor.visit(self)) { }
self.serialize_end(current_indent, b"]")
}
#[inline]
fn visit_enum_seq<V>(&mut self, _name: &str, variant: &str, visitor: V) -> io::Result<()>
where V: ser::SeqVisitor,
{
let current_indent = self.current_indent;
try!(self.writer.write_all(b"{"));
try!(self.serialize_sep(true));
try!(self.visit_str(variant));
try!(self.serialize_colon());
try!(self.visit_seq(visitor));
self.serialize_end(current_indent, b"}")
}
#[inline]
fn visit_seq_elt<T>(&mut self, first: bool, value: T) -> io::Result<()>
where T: ser::Serialize,
{
try!(self.serialize_sep(first));
value.visit(self)
}
#[inline]
fn visit_map<V>(&mut self, mut visitor: V) -> io::Result<()>
where V: ser::MapVisitor,
{
let current_indent = self.current_indent;
try!(self.writer.write_all(b"{"));
while let Some(()) = try!(visitor.visit(self)) { }
self.serialize_end(current_indent, b"}")
}
#[inline]
fn visit_enum_map<V>(&mut self, _name: &str, variant: &str, visitor: V) -> io::Result<()>
where V: ser::MapVisitor,
{
let current_indent = self.current_indent;
try!(self.writer.write_all(b"{"));
try!(self.serialize_sep(true));
try!(self.visit_str(variant));
try!(self.serialize_colon());
try!(self.visit_map(visitor));
self.serialize_end(current_indent, b"}")
}
#[inline]
fn visit_map_elt<K, V>(&mut self, first: bool, key: K, value: V) -> io::Result<()>
where K: ser::Serialize,
V: ser::Serialize,
{
try!(self.serialize_sep(first));
try!(key.visit(self));
try!(self.serialize_colon());
value.visit(self)
}
}
#[inline]
pub fn escape_bytes<W>(wr: &mut W, bytes: &[u8]) -> io::Result<()>
where W: io::Write
{
try!(wr.write_all(b"\""));
let mut start = 0;
for (i, byte) in bytes.iter().enumerate() {
let escaped = match *byte {
b'"' => b"\\\"",
b'\\' => b"\\\\",
b'\x08' => b"\\b",
b'\x0c' => b"\\f",
b'\n' => b"\\n",
b'\r' => b"\\r",
b'\t' => b"\\t",
_ => { continue; }
};
if start < i {
try!(wr.write_all(&bytes[start..i]));
}
try!(wr.write_all(escaped));
start = i + 1;
}
if start != bytes.len() {
try!(wr.write_all(&bytes[start..]));
}
try!(wr.write_all(b"\""));
Ok(())
}
#[inline]
pub fn escape_str<W>(wr: &mut W, value: &str) -> io::Result<()>
where W: io::Write
{
escape_bytes(wr, value.as_bytes())
}
#[inline]
fn escape_char<W>(wr: &mut W, value: char) -> io::Result<()>
where W: io::Write
{
let buf = &mut [0; 4];
value.encode_utf8(buf);
escape_bytes(wr, buf)
}
fn fmt_f32_or_null<W>(wr: &mut W, value: f32) -> io::Result<()>
where W: io::Write
{
match value.classify() {
FpCategory::Nan | FpCategory::Infinite => wr.write_all(b"null"),
_ => wr.write_all(f32::to_str_digits(value, 6).as_bytes()),
}
}
fn fmt_f64_or_null<W>(wr: &mut W, value: f64) -> io::Result<()>
where W: io::Write
{
match value.classify() {
FpCategory::Nan | FpCategory::Infinite => wr.write_all(b"null"),
_ => wr.write_all(f64::to_str_digits(value, 6).as_bytes()),
}
}
/// Encode the specified struct into a json `[u8]` writer.
#[inline]
pub fn to_writer<W, T>(writer: &mut W, value: &T) -> io::Result<()>
where W: io::Write,
T: ser::Serialize,
{
let mut ser = Serializer::new(writer);
try!(ser::Serializer::visit(&mut ser, value));
Ok(())
}
/// Encode the specified struct into a json `[u8]` writer.
#[inline]
pub fn to_writer_pretty<W, T>(writer: &mut W, value: &T) -> io::Result<()>
where W: io::Write,
T: ser::Serialize,
{
let mut ser = Serializer::new_pretty(writer);
try!(ser::Serializer::visit(&mut ser, value));
Ok(())
}
/// Encode the specified struct into a json `[u8]` buffer.
#[inline]
pub fn to_vec<T>(value: &T) -> Vec<u8>
where T: ser::Serialize,
{
// We are writing to a Vec, which doesn't fail. So we can ignore
// the error.
let mut writer = Vec::with_capacity(128);
to_writer(&mut writer, value).unwrap();
writer
}
/// Encode the specified struct into a json `[u8]` buffer.
#[inline]
pub fn to_vec_pretty<T>(value: &T) -> Vec<u8>
where T: ser::Serialize,
{
// We are writing to a Vec, which doesn't fail. So we can ignore
// the error.
let mut writer = Vec::with_capacity(128);
to_writer_pretty(&mut writer, value).unwrap();
writer
}
/// Encode the specified struct into a json `String` buffer.
#[inline]
pub fn to_string<T>(value: &T) -> Result<String, FromUtf8Error>
where T: ser::Serialize
{
let vec = to_vec(value);
String::from_utf8(vec)
}
/// Encode the specified struct into a json `String` buffer.
#[inline]
pub fn to_string_pretty<T>(value: &T) -> Result<String, FromUtf8Error>
where T: ser::Serialize
{
let vec = to_vec_pretty(value);
String::from_utf8(vec)
}
fn spaces<W>(wr: &mut W, mut n: usize) -> io::Result<()>
where W: io::Write,
{
const LEN: usize = 16;
const BUF: &'static [u8; LEN] = &[b' '; 16];
while n >= LEN {
try!(wr.write_all(BUF));
n -= LEN;
}
if n > 0 {
wr.write_all(&BUF[..n])
} else {
Ok(())
}
}
-10
View File
@@ -1,10 +0,0 @@
#![feature(core, io, path, std_misc, unicode)]
extern crate unicode;
pub use ser::{Serialize, Serializer};
pub use de::{Deserialize, Deserializer, Error};
pub mod ser;
pub mod de;
pub mod json;
-660
View File
@@ -1,660 +0,0 @@
use std::collections::hash_state::HashState;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::hash::Hash;
use std::path;
use std::rc::Rc;
use std::str;
use std::sync::Arc;
///////////////////////////////////////////////////////////////////////////////
pub trait Serialize {
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor;
}
///////////////////////////////////////////////////////////////////////////////
pub trait Serializer {
type Value;
type Error;
fn visit<T>(&mut self, value: &T) -> Result<Self::Value, Self::Error>
where T: Serialize;
}
///////////////////////////////////////////////////////////////////////////////
pub trait Visitor {
type Value;
type Error;
fn visit_bool(&mut self, v: bool) -> Result<Self::Value, Self::Error>;
#[inline]
fn visit_isize(&mut self, v: isize) -> Result<Self::Value, Self::Error> {
self.visit_i64(v as i64)
}
#[inline]
fn visit_i8(&mut self, v: i8) -> Result<Self::Value, Self::Error> {
self.visit_i64(v as i64)
}
#[inline]
fn visit_i16(&mut self, v: i16) -> Result<Self::Value, Self::Error> {
self.visit_i64(v as i64)
}
#[inline]
fn visit_i32(&mut self, v: i32) -> Result<Self::Value, Self::Error> {
self.visit_i64(v as i64)
}
#[inline]
fn visit_i64(&mut self, v: i64) -> Result<Self::Value, Self::Error>;
#[inline]
fn visit_usize(&mut self, v: usize) -> Result<Self::Value, Self::Error> {
self.visit_u64(v as u64)
}
#[inline]
fn visit_u8(&mut self, v: u8) -> Result<Self::Value, Self::Error> {
self.visit_u64(v as u64)
}
#[inline]
fn visit_u16(&mut self, v: u16) -> Result<Self::Value, Self::Error> {
self.visit_u64(v as u64)
}
#[inline]
fn visit_u32(&mut self, v: u32) -> Result<Self::Value, Self::Error> {
self.visit_u64(v as u64)
}
#[inline]
fn visit_u64(&mut self, v: u64) -> Result<Self::Value, Self::Error>;
#[inline]
fn visit_f32(&mut self, v: f32) -> Result<Self::Value, Self::Error> {
self.visit_f64(v as f64)
}
fn visit_f64(&mut self, v: f64) -> Result<Self::Value, Self::Error>;
#[inline]
fn visit_char(&mut self, v: char) -> Result<Self::Value, Self::Error> {
// The unwraps in here should be safe.
let mut s = &mut [0; 4];
let len = v.encode_utf8(s).unwrap();
self.visit_str(str::from_utf8(&s[..len]).unwrap())
}
fn visit_str(&mut self, value: &str) -> Result<Self::Value, Self::Error>;
fn visit_unit(&mut self) -> Result<Self::Value, Self::Error>;
#[inline]
fn visit_named_unit(&mut self, _name: &str) -> Result<Self::Value, Self::Error> {
self.visit_unit()
}
#[inline]
fn visit_enum_unit(&mut self,
_name: &str,
_variant: &str) -> Result<Self::Value, Self::Error> {
self.visit_unit()
}
fn visit_none(&mut self) -> Result<Self::Value, Self::Error>;
fn visit_some<V>(&mut self, value: V) -> Result<Self::Value, Self::Error>
where V: Serialize;
fn visit_seq<V>(&mut self, visitor: V) -> Result<Self::Value, Self::Error>
where V: SeqVisitor;
#[inline]
fn visit_named_seq<V>(&mut self,
_name: &'static str,
visitor: V) -> Result<Self::Value, Self::Error>
where V: SeqVisitor,
{
self.visit_seq(visitor)
}
#[inline]
fn visit_enum_seq<V>(&mut self,
_name: &'static str,
_variant: &'static str,
visitor: V) -> Result<Self::Value, Self::Error>
where V: SeqVisitor,
{
self.visit_seq(visitor)
}
fn visit_seq_elt<T>(&mut self,
first: bool,
value: T) -> Result<Self::Value, Self::Error>
where T: Serialize;
fn visit_map<V>(&mut self, visitor: V) -> Result<Self::Value, Self::Error>
where V: MapVisitor;
#[inline]
fn visit_named_map<V>(&mut self,
_name: &'static str,
visitor: V) -> Result<Self::Value, Self::Error>
where V: MapVisitor,
{
self.visit_map(visitor)
}
#[inline]
fn visit_enum_map<V>(&mut self,
_name: &'static str,
_variant: &'static str,
visitor: V) -> Result<Self::Value, Self::Error>
where V: MapVisitor,
{
self.visit_map(visitor)
}
fn visit_map_elt<K, V>(&mut self,
first: bool,
key: K,
value: V) -> Result<Self::Value, Self::Error>
where K: Serialize,
V: Serialize;
}
pub trait SeqVisitor {
fn visit<V>(&mut self, visitor: &mut V) -> Result<Option<V::Value>, V::Error>
where V: Visitor;
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
}
pub trait MapVisitor {
fn visit<V>(&mut self, visitor: &mut V) -> Result<Option<V::Value>, V::Error>
where V: Visitor;
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
}
///////////////////////////////////////////////////////////////////////////////
macro_rules! impl_visit {
($ty:ty, $method:ident) => {
impl Serialize for $ty {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
visitor.$method(*self)
}
}
}
}
impl_visit!(bool, visit_bool);
impl_visit!(isize, visit_isize);
impl_visit!(i8, visit_i8);
impl_visit!(i16, visit_i16);
impl_visit!(i32, visit_i32);
impl_visit!(i64, visit_i64);
impl_visit!(usize, visit_usize);
impl_visit!(u8, visit_u8);
impl_visit!(u16, visit_u16);
impl_visit!(u32, visit_u32);
impl_visit!(u64, visit_u64);
impl_visit!(f32, visit_f32);
impl_visit!(f64, visit_f64);
impl_visit!(char, visit_char);
///////////////////////////////////////////////////////////////////////////////
impl<'a> Serialize for &'a str {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
visitor.visit_str(*self)
}
}
impl Serialize for String {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
(&self[..]).visit(visitor)
}
}
///////////////////////////////////////////////////////////////////////////////
impl<T> Serialize for Option<T> where T: Serialize {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
match *self {
Some(ref value) => visitor.visit_some(value),
None => visitor.visit_none(),
}
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct SeqIteratorVisitor<Iter> {
iter: Iter,
first: bool,
}
impl<T, Iter> SeqIteratorVisitor<Iter>
where Iter: Iterator<Item=T>
{
#[inline]
pub fn new(iter: Iter) -> SeqIteratorVisitor<Iter> {
SeqIteratorVisitor {
iter: iter,
first: true,
}
}
}
impl<T, Iter> SeqVisitor for SeqIteratorVisitor<Iter>
where T: Serialize,
Iter: Iterator<Item=T>,
{
#[inline]
fn visit<V>(&mut self, visitor: &mut V) -> Result<Option<V::Value>, V::Error>
where V: Visitor,
{
let first = self.first;
self.first = false;
match self.iter.next() {
Some(value) => {
let value = try!(visitor.visit_seq_elt(first, value));
Ok(Some(value))
}
None => Ok(None),
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
///////////////////////////////////////////////////////////////////////////////
impl<'a, T> Serialize for &'a [T]
where T: Serialize,
{
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
visitor.visit_seq(SeqIteratorVisitor::new(self.iter()))
}
}
impl<T> Serialize for Vec<T> where T: Serialize {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
(&self[..]).visit(visitor)
}
}
impl<T> Serialize for BTreeSet<T> where T: Serialize {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
visitor.visit_seq(SeqIteratorVisitor::new(self.iter()))
}
}
impl<T, S> Serialize for HashSet<T, S>
where T: Serialize + Eq + Hash,
S: HashState,
{
#[inline]
fn visit<V: Visitor>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
visitor.visit_seq(SeqIteratorVisitor::new(self.iter()))
}
}
///////////////////////////////////////////////////////////////////////////////
impl Serialize for () {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
visitor.visit_unit()
}
}
///////////////////////////////////////////////////////////////////////////////
// FIXME(rust #19630) Remove this work-around
macro_rules! e {
($e:expr) => { $e }
}
macro_rules! tuple_impls {
($(
$TupleVisitor:ident ($len:expr, $($T:ident),+) {
$($state:pat => $idx:tt,)+
}
)+) => {
$(
pub struct $TupleVisitor<'a, $($T: 'a),+> {
tuple: &'a ($($T,)+),
state: u8,
first: bool,
}
impl<'a, $($T: 'a),+> $TupleVisitor<'a, $($T),+> {
pub fn new(tuple: &'a ($($T,)+)) -> $TupleVisitor<'a, $($T),+> {
$TupleVisitor {
tuple: tuple,
state: 0,
first: true,
}
}
}
impl<'a, $($T),+> SeqVisitor for $TupleVisitor<'a, $($T),+>
where $($T: Serialize),+
{
fn visit<V>(&mut self, visitor: &mut V) -> Result<Option<V::Value>, V::Error>
where V: Visitor,
{
let first = self.first;
self.first = false;
match self.state {
$(
$state => {
self.state += 1;
Ok(Some(try!(visitor.visit_seq_elt(first, &e!(self.tuple.$idx)))))
}
)+
_ => {
Ok(None)
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
($len, Some($len))
}
}
impl<$($T),+> Serialize for ($($T,)+)
where $($T: Serialize),+
{
#[inline]
fn visit<V: Visitor>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
visitor.visit_seq($TupleVisitor::new(self))
}
}
)+
}
}
tuple_impls! {
TupleVisitor1 (1, T0) {
0 => 0,
}
TupleVisitor2 (2, T0, T1) {
0 => 0,
1 => 1,
}
TupleVisitor3 (3, T0, T1, T2) {
0 => 0,
1 => 1,
2 => 2,
}
TupleVisitor4 (4, T0, T1, T2, T3) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
}
TupleVisitor5 (5, T0, T1, T2, T3, T4) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
}
TupleVisitor6 (6, T0, T1, T2, T3, T4, T5) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
}
TupleVisitor7 (7, T0, T1, T2, T3, T4, T5, T6) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
}
TupleVisitor8 (8, T0, T1, T2, T3, T4, T5, T6, T7) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
}
TupleVisitor9 (9, T0, T1, T2, T3, T4, T5, T6, T7, T8) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
}
TupleVisitor10 (10, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
}
TupleVisitor11 (11, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
10 => 10,
}
TupleVisitor12 (12, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
10 => 10,
11 => 11,
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct MapIteratorVisitor<Iter> {
iter: Iter,
first: bool,
}
impl<K, V, Iter> MapIteratorVisitor<Iter>
where Iter: Iterator<Item=(K, V)>
{
#[inline]
pub fn new(iter: Iter) -> MapIteratorVisitor<Iter> {
MapIteratorVisitor {
iter: iter,
first: true,
}
}
}
impl<K, V, I> MapVisitor for MapIteratorVisitor<I>
where K: Serialize,
V: Serialize,
I: Iterator<Item=(K, V)>,
{
#[inline]
fn visit<V_>(&mut self, visitor: &mut V_) -> Result<Option<V_::Value>, V_::Error>
where V_: Visitor,
{
let first = self.first;
self.first = false;
match self.iter.next() {
Some((key, value)) => {
let value = try!(visitor.visit_map_elt(first, key, value));
Ok(Some(value))
}
None => Ok(None)
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
///////////////////////////////////////////////////////////////////////////////
impl<K, V> Serialize for BTreeMap<K, V>
where K: Serialize + Ord,
V: Serialize,
{
#[inline]
fn visit<V_: Visitor>(&self, visitor: &mut V_) -> Result<V_::Value, V_::Error> {
visitor.visit_map(MapIteratorVisitor::new(self.iter()))
}
}
impl<K, V, S> Serialize for HashMap<K, V, S>
where K: Serialize + Eq + Hash,
V: Serialize,
S: HashState,
{
#[inline]
fn visit<V_: Visitor>(&self, visitor: &mut V_) -> Result<V_::Value, V_::Error> {
visitor.visit_map(MapIteratorVisitor::new(self.iter()))
}
}
///////////////////////////////////////////////////////////////////////////////
impl<'a, T> Serialize for &'a T where T: Serialize {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
(**self).visit(visitor)
}
}
impl<'a, T> Serialize for &'a mut T where T: Serialize {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
(**self).visit(visitor)
}
}
impl<T> Serialize for Box<T> where T: Serialize {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
(**self).visit(visitor)
}
}
impl<T> Serialize for Rc<T> where T: Serialize, {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
(**self).visit(visitor)
}
}
impl<T> Serialize for Arc<T> where T: Serialize, {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
(**self).visit(visitor)
}
}
///////////////////////////////////////////////////////////////////////////////
impl Serialize for path::Path {
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
self.to_str().unwrap().visit(visitor)
}
}
impl Serialize for path::PathBuf {
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
self.to_str().unwrap().visit(visitor)
}
}