├── .gitignore ├── .travis.yml ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── appveyor.yml ├── benches ├── base64.rs ├── hex.rs └── json.rs └── src ├── base64.rs ├── collection_impls.rs ├── hex.rs ├── json.rs ├── lib.rs └── serialize.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /Cargo.lock 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | rust: 3 | - 1.0.0 4 | - stable 5 | - beta 6 | - nightly 7 | sudo: false 8 | before_script: 9 | - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH 10 | script: 11 | - cargo build --verbose 12 | - cargo test --verbose 13 | - cargo doc --no-deps 14 | after_success: 15 | - travis-cargo --only nightly doc-upload 16 | env: 17 | global: 18 | secure: "kJnqqAXRl0C7Afx0c8Y3vA6TAEZsxlasu7eIZMdCbNS4N1+Rwh0jNTa2jy2D3CQCrzW5OCefnkpkPTu8mADrAjedM4p/9X5UXZi0sgg2lzCgfGwrRzitTnyPDkdYidiu4QeC/r0WPC8lYZKHkJXYhF8bZgchB9ypnZ6LAHCcDkA=" 19 | 20 | 21 | 22 | notifications: 23 | email: 24 | on_success: never 25 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | 3 | name = "rustc-serialize" 4 | version = "0.3.25" 5 | authors = ["The Rust Project Developers"] 6 | license = "MIT/Apache-2.0" 7 | readme = "README.md" 8 | repository = "https://github.com/rust-lang/rustc-serialize" 9 | homepage = "https://github.com/rust-lang/rustc-serialize" 10 | documentation = "https://doc.rust-lang.org/rustc-serialize" 11 | description = """ 12 | Generic serialization/deserialization support corresponding to the 13 | `derive(RustcEncodable, RustcDecodable)` mode in the compiler. Also includes 14 | support for hex, base64, and json encoding and decoding. 15 | 16 | This crate is deprecated in favor of serde. 17 | """ 18 | 19 | [dev-dependencies] 20 | rand = "0.3" 21 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 The Rust Project Developers 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rustc-serialize 2 | 3 | > **NOTE**: This crate is deprecated in favor of [`serde`]. No new feature 4 | > development will happen in this crate, although bug fixes proposed through PRs 5 | > will still be merged. It is very highly recommended by the Rust Library Team 6 | > that you use [`serde`], not this crate. 7 | 8 | [`serde`]: https://serde.rs 9 | 10 | Serialization and deserialization support provided by the compiler in the form 11 | of `derive(RustcEncodable, RustcDecodable)`. 12 | 13 | [![Linux Build Status](https://travis-ci.org/rust-lang-nursery/rustc-serialize.svg?branch=master)](https://travis-ci.org/rust-lang-nursery/rustc-serialize) 14 | [![Windows Build Status](https://ci.appveyor.com/api/projects/status/ka194de75aapwpft?svg=true)](https://ci.appveyor.com/project/alexcrichton/rustc-serialize) 15 | 16 | [Documentation](https://docs.rs/rustc-serialize) 17 | 18 | ## Usage 19 | 20 | Add this to your `Cargo.toml`: 21 | 22 | ```toml 23 | [dependencies] 24 | rustc-serialize = "0.3" 25 | ``` 26 | 27 | and this to your crate root: 28 | 29 | ```rust 30 | extern crate rustc_serialize; 31 | ``` 32 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | matrix: 3 | - TARGET: x86_64-pc-windows-msvc 4 | - TARGET: i686-pc-windows-msvc 5 | - TARGET: i686-pc-windows-gnu 6 | install: 7 | - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:TARGET}.exe" 8 | - rust-nightly-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust" 9 | - SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin 10 | - SET PATH=%PATH%;C:\MinGW\bin 11 | - rustc -V 12 | - cargo -V 13 | 14 | build: false 15 | 16 | test_script: 17 | - cargo test --verbose 18 | -------------------------------------------------------------------------------- /benches/base64.rs: -------------------------------------------------------------------------------- 1 | #![feature(test)] 2 | 3 | extern crate test; 4 | extern crate rustc_serialize; 5 | 6 | use rustc_serialize::base64::{FromBase64, ToBase64, STANDARD}; 7 | use test::Bencher; 8 | 9 | #[bench] 10 | fn bench_to_base64(b: &mut Bencher) { 11 | let s = "イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム \ 12 | ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン"; 13 | b.iter(|| { 14 | s.as_bytes().to_base64(STANDARD); 15 | }); 16 | b.bytes = s.len() as u64; 17 | } 18 | 19 | #[bench] 20 | fn bench_from_base64(b: &mut Bencher) { 21 | let s = "イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム \ 22 | ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン"; 23 | let sb = s.as_bytes().to_base64(STANDARD); 24 | b.iter(|| { 25 | sb.from_base64().unwrap(); 26 | }); 27 | b.bytes = sb.len() as u64; 28 | } 29 | 30 | 31 | #[bench] 32 | fn bench_to_base64_large(b: &mut Bencher) { 33 | let s: Vec<_> = (0..10000).map(|i| ((i as u32 * 12345) % 256) as u8).collect(); 34 | b.iter(|| { 35 | s.to_base64(STANDARD); 36 | }); 37 | b.bytes = s.len() as u64; 38 | } 39 | 40 | #[bench] 41 | fn bench_from_base64_large(b: &mut Bencher) { 42 | let s: Vec<_> = (0..10000).map(|i| ((i as u32 * 12345) % 256) as u8).collect(); 43 | let sb = s.to_base64(STANDARD); 44 | b.iter(|| { 45 | sb.from_base64().unwrap(); 46 | }); 47 | b.bytes = sb.len() as u64; 48 | } 49 | -------------------------------------------------------------------------------- /benches/hex.rs: -------------------------------------------------------------------------------- 1 | #![feature(test)] 2 | 3 | extern crate test; 4 | extern crate rustc_serialize; 5 | 6 | use test::Bencher; 7 | use rustc_serialize::hex::{FromHex, ToHex}; 8 | 9 | #[bench] 10 | fn bench_to_hex(b: &mut Bencher) { 11 | let s = "イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム \ 12 | ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン"; 13 | b.iter(|| { 14 | s.as_bytes().to_hex(); 15 | }); 16 | b.bytes = s.len() as u64; 17 | } 18 | 19 | #[bench] 20 | fn bench_from_hex(b: &mut Bencher) { 21 | let s = "イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム \ 22 | ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン"; 23 | let sb = s.as_bytes().to_hex(); 24 | b.iter(|| { 25 | sb.from_hex().unwrap(); 26 | }); 27 | b.bytes = sb.len() as u64; 28 | } 29 | -------------------------------------------------------------------------------- /benches/json.rs: -------------------------------------------------------------------------------- 1 | #![feature(test)] 2 | 3 | extern crate test; 4 | extern crate rustc_serialize; 5 | 6 | use std::string; 7 | use rustc_serialize::json::{Json, Parser}; 8 | use test::Bencher; 9 | 10 | #[bench] 11 | fn bench_streaming_small(b: &mut Bencher) { 12 | b.iter( || { 13 | let mut parser = Parser::new( 14 | r#"{ 15 | "a": 1.0, 16 | "b": [ 17 | true, 18 | "foo\nbar", 19 | { "c": {"d": null} } 20 | ] 21 | }"#.chars() 22 | ); 23 | loop { 24 | match parser.next() { 25 | None => return, 26 | _ => {} 27 | } 28 | } 29 | }); 30 | } 31 | #[bench] 32 | fn bench_small(b: &mut Bencher) { 33 | b.iter( || { 34 | let _ = Json::from_str(r#"{ 35 | "a": 1.0, 36 | "b": [ 37 | true, 38 | "foo\nbar", 39 | { "c": {"d": null} } 40 | ] 41 | }"#); 42 | }); 43 | } 44 | 45 | #[bench] 46 | fn bench_decode_hex_escape(b: &mut Bencher) { 47 | let mut src = "\"".to_string(); 48 | for _ in 0..10 { 49 | src.push_str("\\uF975\\uf9bc\\uF9A0\\uF9C4\\uF975\\uf9bc\\uF9A0\\uF9C4"); 50 | } 51 | src.push_str("\""); 52 | b.iter( || { 53 | let _ = Json::from_str(&src); 54 | }); 55 | } 56 | 57 | fn big_json() -> string::String { 58 | let mut src = "[\n".to_string(); 59 | for _ in 0..500 { 60 | src.push_str(r#"{ "a": true, "b": null, "c":3.1415, "d": "Hello world", "e": \ 61 | [1,2,3]},"#); 62 | } 63 | src.push_str("{}]"); 64 | return src; 65 | } 66 | 67 | #[bench] 68 | fn bench_streaming_large(b: &mut Bencher) { 69 | let src = big_json(); 70 | b.iter( || { 71 | let mut parser = Parser::new(src.chars()); 72 | loop { 73 | match parser.next() { 74 | None => return, 75 | _ => {} 76 | } 77 | } 78 | }); 79 | } 80 | #[bench] 81 | fn bench_large(b: &mut Bencher) { 82 | let src = big_json(); 83 | b.iter( || { let _ = Json::from_str(&src); }); 84 | } 85 | -------------------------------------------------------------------------------- /src/base64.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | // 11 | // ignore-lexer-test FIXME #15679 12 | 13 | //! Base64 binary-to-text encoding 14 | 15 | pub use self::FromBase64Error::*; 16 | pub use self::CharacterSet::*; 17 | 18 | use std::fmt; 19 | use std::error; 20 | 21 | /// Available encoding character sets 22 | #[derive(Clone, Copy, Debug)] 23 | pub enum CharacterSet { 24 | /// The standard character set (uses `+` and `/`) 25 | Standard, 26 | /// The URL safe character set (uses `-` and `_`) 27 | UrlSafe 28 | } 29 | 30 | /// Available newline types 31 | #[derive(Clone, Copy, Debug)] 32 | pub enum Newline { 33 | /// A linefeed (i.e. Unix-style newline) 34 | LF, 35 | /// A carriage return and a linefeed (i.e. Windows-style newline) 36 | CRLF 37 | } 38 | 39 | /// Contains configuration parameters for `to_base64`. 40 | #[derive(Clone, Copy, Debug)] 41 | pub struct Config { 42 | /// Character set to use 43 | pub char_set: CharacterSet, 44 | /// Newline to use 45 | pub newline: Newline, 46 | /// True to pad output with `=` characters 47 | pub pad: bool, 48 | /// `Some(len)` to wrap lines at `len`, `None` to disable line wrapping 49 | pub line_length: Option 50 | } 51 | 52 | /// Configuration for RFC 4648 standard base64 encoding 53 | pub static STANDARD: Config = 54 | Config {char_set: Standard, newline: Newline::CRLF, pad: true, line_length: None}; 55 | 56 | /// Configuration for RFC 4648 base64url encoding 57 | pub static URL_SAFE: Config = 58 | Config {char_set: UrlSafe, newline: Newline::CRLF, pad: false, line_length: None}; 59 | 60 | /// Configuration for RFC 2045 MIME base64 encoding 61 | pub static MIME: Config = 62 | Config {char_set: Standard, newline: Newline::CRLF, pad: true, line_length: Some(76)}; 63 | 64 | static STANDARD_CHARS: &'static[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\ 65 | abcdefghijklmnopqrstuvwxyz\ 66 | 0123456789+/"; 67 | 68 | static URLSAFE_CHARS: &'static[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\ 69 | abcdefghijklmnopqrstuvwxyz\ 70 | 0123456789-_"; 71 | 72 | /// A trait for converting a value to base64 encoding. 73 | pub trait ToBase64 { 74 | /// Converts the value of `self` to a base64 value following the specified 75 | /// format configuration, returning the owned string. 76 | fn to_base64(&self, config: Config) -> String; 77 | } 78 | 79 | impl ToBase64 for [u8] { 80 | /// Turn a vector of `u8` bytes into a base64 string. 81 | /// 82 | /// # Example 83 | /// 84 | /// ```rust 85 | /// extern crate rustc_serialize; 86 | /// use rustc_serialize::base64::{ToBase64, STANDARD}; 87 | /// 88 | /// fn main () { 89 | /// let str = [52,32].to_base64(STANDARD); 90 | /// println!("base 64 output: {:?}", str); 91 | /// } 92 | /// ``` 93 | fn to_base64(&self, config: Config) -> String { 94 | let bytes = match config.char_set { 95 | Standard => STANDARD_CHARS, 96 | UrlSafe => URLSAFE_CHARS 97 | }; 98 | 99 | let len = self.len(); 100 | let newline = match config.newline { 101 | Newline::LF => "\n", 102 | Newline::CRLF => "\r\n", 103 | }; 104 | 105 | // Preallocate memory. 106 | let mut prealloc_len = (len + 2) / 3 * 4; 107 | if let Some(line_length) = config.line_length { 108 | let num_lines = match prealloc_len { 109 | 0 => 0, 110 | n => (n - 1) / line_length 111 | }; 112 | prealloc_len += num_lines * newline.bytes().count(); 113 | } 114 | 115 | let mut out_bytes = vec![b'='; prealloc_len]; 116 | 117 | // Deal with padding bytes 118 | let mod_len = len % 3; 119 | 120 | // Use iterators to reduce branching 121 | { 122 | let mut cur_length = 0; 123 | 124 | let mut s_in = self[..len - mod_len].iter().map(|&x| x as u32); 125 | let mut s_out = out_bytes.iter_mut(); 126 | 127 | // Convenient shorthand 128 | let enc = |val| bytes[val as usize]; 129 | let mut write = |val| *s_out.next().unwrap() = val; 130 | 131 | // Iterate though blocks of 4 132 | while let (Some(first), Some(second), Some(third)) = 133 | (s_in.next(), s_in.next(), s_in.next()) { 134 | 135 | // Line break if needed 136 | if let Some(line_length) = config.line_length { 137 | if cur_length >= line_length { 138 | for b in newline.bytes() { write(b) }; 139 | cur_length = 0; 140 | } 141 | } 142 | 143 | let n = first << 16 | second << 8 | third; 144 | 145 | // This 24-bit number gets separated into four 6-bit numbers. 146 | write(enc((n >> 18) & 63)); 147 | write(enc((n >> 12) & 63)); 148 | write(enc((n >> 6 ) & 63)); 149 | write(enc((n >> 0 ) & 63)); 150 | 151 | cur_length += 4; 152 | } 153 | 154 | // Line break only needed if padding is required 155 | if mod_len != 0 { 156 | if let Some(line_length) = config.line_length { 157 | if cur_length >= line_length { 158 | for b in newline.bytes() { write(b) }; 159 | } 160 | } 161 | } 162 | 163 | // Heh, would be cool if we knew this was exhaustive 164 | // (the dream of bounded integer types) 165 | match mod_len { 166 | 0 => (), 167 | 1 => { 168 | let n = (self[len-1] as u32) << 16; 169 | write(enc((n >> 18) & 63)); 170 | write(enc((n >> 12) & 63)); 171 | } 172 | 2 => { 173 | let n = (self[len-2] as u32) << 16 | 174 | (self[len-1] as u32) << 8; 175 | write(enc((n >> 18) & 63)); 176 | write(enc((n >> 12) & 63)); 177 | write(enc((n >> 6 ) & 63)); 178 | } 179 | _ => panic!("Algebra is broken, please alert the math police") 180 | } 181 | } 182 | 183 | // We get padding for "free", so only have to drop it if unwanted. 184 | if !config.pad { 185 | while let Some(&b'=') = out_bytes.last() { 186 | out_bytes.pop(); 187 | } 188 | } 189 | 190 | unsafe { String::from_utf8_unchecked(out_bytes) } 191 | } 192 | } 193 | 194 | impl<'a, T: ?Sized + ToBase64> ToBase64 for &'a T { 195 | fn to_base64(&self, config: Config) -> String { 196 | (**self).to_base64(config) 197 | } 198 | } 199 | 200 | /// A trait for converting from base64 encoded values. 201 | pub trait FromBase64 { 202 | /// Converts the value of `self`, interpreted as base64 encoded data, into 203 | /// an owned vector of bytes, returning the vector. 204 | fn from_base64(&self) -> Result, FromBase64Error>; 205 | } 206 | 207 | /// Errors that can occur when decoding a base64 encoded string 208 | #[derive(Clone, Copy)] 209 | pub enum FromBase64Error { 210 | /// The input contained a character not part of the base64 format 211 | InvalidBase64Byte(u8, usize), 212 | /// The input had an invalid length 213 | InvalidBase64Length, 214 | } 215 | 216 | impl fmt::Debug for FromBase64Error { 217 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 218 | match *self { 219 | InvalidBase64Byte(ch, idx) => 220 | write!(f, "Invalid character '{}' at position {}", ch, idx), 221 | InvalidBase64Length => write!(f, "Invalid length"), 222 | } 223 | } 224 | } 225 | 226 | impl error::Error for FromBase64Error { 227 | fn description(&self) -> &str { 228 | match *self { 229 | InvalidBase64Byte(_, _) => "invalid character", 230 | InvalidBase64Length => "invalid length", 231 | } 232 | } 233 | } 234 | 235 | impl fmt::Display for FromBase64Error { 236 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 237 | fmt::Debug::fmt(&self, f) 238 | } 239 | } 240 | 241 | impl FromBase64 for str { 242 | /// Convert any base64 encoded string (literal, `@`, `&`, or `~`) 243 | /// to the byte values it encodes. 244 | /// 245 | /// You can use the `String::from_utf8` function to turn a `Vec` into a 246 | /// string with characters corresponding to those values. 247 | /// 248 | /// # Example 249 | /// 250 | /// This converts a string literal to base64 and back. 251 | /// 252 | /// ```rust 253 | /// extern crate rustc_serialize; 254 | /// use rustc_serialize::base64::{ToBase64, FromBase64, STANDARD}; 255 | /// 256 | /// fn main () { 257 | /// let hello_str = b"Hello, World".to_base64(STANDARD); 258 | /// println!("base64 output: {}", hello_str); 259 | /// let res = hello_str.from_base64(); 260 | /// if res.is_ok() { 261 | /// let opt_bytes = String::from_utf8(res.unwrap()); 262 | /// if opt_bytes.is_ok() { 263 | /// println!("decoded from base64: {:?}", opt_bytes.unwrap()); 264 | /// } 265 | /// } 266 | /// } 267 | /// ``` 268 | #[inline] 269 | fn from_base64(&self) -> Result, FromBase64Error> { 270 | self.as_bytes().from_base64() 271 | } 272 | } 273 | 274 | impl FromBase64 for [u8] { 275 | fn from_base64(&self) -> Result, FromBase64Error> { 276 | let mut r = Vec::with_capacity(self.len()); 277 | let mut buf: u32 = 0; 278 | let mut modulus = 0; 279 | 280 | let mut it = self.iter(); 281 | for byte in it.by_ref() { 282 | let code = DECODE_TABLE[*byte as usize]; 283 | if code >= SPECIAL_CODES_START { 284 | match code { 285 | NEWLINE_CODE => continue, 286 | EQUALS_CODE => break, 287 | INVALID_CODE => return Err(InvalidBase64Byte( 288 | *byte, (byte as *const _ as usize) - self.as_ptr() as usize)), 289 | _ => unreachable!(), 290 | } 291 | } 292 | buf = (buf | code as u32) << 6; 293 | modulus += 1; 294 | if modulus == 4 { 295 | modulus = 0; 296 | r.push((buf >> 22) as u8); 297 | r.push((buf >> 14) as u8); 298 | r.push((buf >> 6 ) as u8); 299 | } 300 | } 301 | 302 | for byte in it { 303 | match *byte { 304 | b'=' | b'\r' | b'\n' => continue, 305 | _ => return Err(InvalidBase64Byte( 306 | *byte, (byte as *const _ as usize) - self.as_ptr() as usize)), 307 | } 308 | } 309 | 310 | match modulus { 311 | 2 => { 312 | r.push((buf >> 10) as u8); 313 | } 314 | 3 => { 315 | r.push((buf >> 16) as u8); 316 | r.push((buf >> 8 ) as u8); 317 | } 318 | 0 => (), 319 | _ => return Err(InvalidBase64Length), 320 | } 321 | 322 | Ok(r) 323 | } 324 | } 325 | 326 | impl<'a, T: ?Sized + FromBase64> FromBase64 for &'a T { 327 | fn from_base64(&self) -> Result, FromBase64Error> { 328 | (**self).from_base64() 329 | } 330 | } 331 | 332 | /// Base64 decoding lookup table, generated using: 333 | /// 334 | /// ``` 335 | /// let mut ch = 0u8; 336 | /// for ch in 0..255 { 337 | /// let mut ch = ch as u8; 338 | /// let code = match ch { 339 | /// b'A'...b'Z' => ch - 0x41, 340 | /// b'a'...b'z' => ch - 0x47, 341 | /// b'0'...b'9' => ch + 0x04, 342 | /// b'+' | b'-' => 0x3E, 343 | /// b'/' | b'_' => 0x3F, 344 | /// b'=' => 0xFE, 345 | /// b'\r' | b'\n' => 0xFD, 346 | /// _ => 0xFF, 347 | /// }; 348 | /// print!("0x{:02X}, ", code); 349 | /// if ch % 16 == 15 { println!(""); } 350 | /// else if ch == 0xFF { break; } 351 | /// ch += 1; 352 | /// } 353 | /// println!(""); 354 | /// ``` 355 | const DECODE_TABLE: [u8; 256] = [ 356 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 357 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 358 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0x3E, 0xFF, 0x3F, 359 | 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 360 | 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 361 | 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 362 | 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 363 | 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 364 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 365 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 366 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 367 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 368 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 369 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 370 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 371 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 372 | ]; 373 | const INVALID_CODE: u8 = 0xFF; 374 | const EQUALS_CODE: u8 = 0xFE; 375 | const NEWLINE_CODE: u8 = 0xFD; 376 | const SPECIAL_CODES_START: u8 = NEWLINE_CODE; 377 | 378 | #[cfg(test)] 379 | mod tests { 380 | use base64::{Config, Newline, FromBase64, ToBase64, STANDARD, URL_SAFE}; 381 | 382 | #[test] 383 | fn test_to_base64_basic() { 384 | assert_eq!("".as_bytes().to_base64(STANDARD), ""); 385 | assert_eq!("f".as_bytes().to_base64(STANDARD), "Zg=="); 386 | assert_eq!("fo".as_bytes().to_base64(STANDARD), "Zm8="); 387 | assert_eq!("foo".as_bytes().to_base64(STANDARD), "Zm9v"); 388 | assert_eq!("foob".as_bytes().to_base64(STANDARD), "Zm9vYg=="); 389 | assert_eq!("fooba".as_bytes().to_base64(STANDARD), "Zm9vYmE="); 390 | assert_eq!("foobar".as_bytes().to_base64(STANDARD), "Zm9vYmFy"); 391 | } 392 | 393 | #[test] 394 | fn test_to_base64_crlf_line_break() { 395 | assert!(![0; 1000].to_base64(Config {line_length: None, ..STANDARD}) 396 | .contains("\r\n")); 397 | assert_eq!(b"foobar".to_base64(Config {line_length: Some(4), 398 | ..STANDARD}), 399 | "Zm9v\r\nYmFy"); 400 | } 401 | 402 | #[test] 403 | fn test_to_base64_lf_line_break() { 404 | assert!(![0; 1000].to_base64(Config {line_length: None, 405 | newline: Newline::LF, 406 | ..STANDARD}) 407 | .contains("\n")); 408 | assert_eq!(b"foobar".to_base64(Config {line_length: Some(4), 409 | newline: Newline::LF, 410 | ..STANDARD}), 411 | "Zm9v\nYmFy"); 412 | } 413 | 414 | #[test] 415 | fn test_to_base64_padding() { 416 | assert_eq!("f".as_bytes().to_base64(Config {pad: false, ..STANDARD}), "Zg"); 417 | assert_eq!("fo".as_bytes().to_base64(Config {pad: false, ..STANDARD}), "Zm8"); 418 | } 419 | 420 | #[test] 421 | fn test_to_base64_url_safe() { 422 | assert_eq!([251, 255].to_base64(URL_SAFE), "-_8"); 423 | assert_eq!([251, 255].to_base64(STANDARD), "+/8="); 424 | } 425 | 426 | #[test] 427 | fn test_to_base64_empty_line_length() { 428 | [].to_base64(Config {line_length: Some(72), ..STANDARD}); 429 | } 430 | 431 | #[test] 432 | fn test_from_base64_basic() { 433 | assert_eq!("".from_base64().unwrap(), b""); 434 | assert_eq!("Zg==".from_base64().unwrap(), b"f"); 435 | assert_eq!("Zm8=".from_base64().unwrap(), b"fo"); 436 | assert_eq!("Zm9v".from_base64().unwrap(), b"foo"); 437 | assert_eq!("Zm9vYg==".from_base64().unwrap(), b"foob"); 438 | assert_eq!("Zm9vYmE=".from_base64().unwrap(), b"fooba"); 439 | assert_eq!("Zm9vYmFy".from_base64().unwrap(), b"foobar"); 440 | } 441 | 442 | #[test] 443 | fn test_from_base64_bytes() { 444 | assert_eq!(b"Zm9vYmFy".from_base64().unwrap(), b"foobar"); 445 | } 446 | 447 | #[test] 448 | fn test_from_base64_newlines() { 449 | assert_eq!("Zm9v\r\nYmFy".from_base64().unwrap(), 450 | b"foobar"); 451 | assert_eq!("Zm9vYg==\r\n".from_base64().unwrap(), 452 | b"foob"); 453 | assert_eq!("Zm9v\nYmFy".from_base64().unwrap(), 454 | b"foobar"); 455 | assert_eq!("Zm9vYg==\n".from_base64().unwrap(), 456 | b"foob"); 457 | } 458 | 459 | #[test] 460 | fn test_from_base64_urlsafe() { 461 | assert_eq!("-_8".from_base64().unwrap(), "+/8=".from_base64().unwrap()); 462 | } 463 | 464 | #[test] 465 | fn test_from_base64_invalid_char() { 466 | assert!("Zm$=".from_base64().is_err()); 467 | assert!("Zg==$".from_base64().is_err()); 468 | } 469 | 470 | #[test] 471 | fn test_from_base64_invalid_padding() { 472 | assert!("Z===".from_base64().is_err()); 473 | } 474 | 475 | #[test] 476 | fn test_base64_random() { 477 | use rand::{thread_rng, Rng}; 478 | 479 | for _ in 0..1000 { 480 | let times = thread_rng().gen_range(1, 100); 481 | let v = thread_rng().gen_iter::().take(times) 482 | .collect::>(); 483 | assert_eq!(v.to_base64(STANDARD) 484 | .from_base64() 485 | .unwrap(), 486 | v); 487 | } 488 | } 489 | } 490 | -------------------------------------------------------------------------------- /src/collection_impls.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! Implementations of serialization for structures found in libcollections 12 | 13 | use std::hash::Hash; 14 | 15 | use {Decodable, Encodable, Decoder, Encoder, cap_capacity}; 16 | use std::collections::{LinkedList, VecDeque, BTreeMap, BTreeSet, HashMap, HashSet}; 17 | 18 | impl< 19 | T: Encodable 20 | > Encodable for LinkedList { 21 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 22 | s.emit_seq(self.len(), |s| { 23 | for (i, e) in self.iter().enumerate() { 24 | try!(s.emit_seq_elt(i, |s| e.encode(s))); 25 | } 26 | Ok(()) 27 | }) 28 | } 29 | } 30 | 31 | impl Decodable for LinkedList { 32 | fn decode(d: &mut D) -> Result, D::Error> { 33 | d.read_seq(|d, len| { 34 | let mut list = LinkedList::new(); 35 | for i in 0..len { 36 | list.push_back(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); 37 | } 38 | Ok(list) 39 | }) 40 | } 41 | } 42 | 43 | impl Encodable for VecDeque { 44 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 45 | s.emit_seq(self.len(), |s| { 46 | for (i, e) in self.iter().enumerate() { 47 | try!(s.emit_seq_elt(i, |s| e.encode(s))); 48 | } 49 | Ok(()) 50 | }) 51 | } 52 | } 53 | 54 | impl Decodable for VecDeque { 55 | fn decode(d: &mut D) -> Result, D::Error> { 56 | d.read_seq(|d, len| { 57 | let mut deque: VecDeque = VecDeque::new(); 58 | for i in 0..len { 59 | deque.push_back(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); 60 | } 61 | Ok(deque) 62 | }) 63 | } 64 | } 65 | 66 | impl< 67 | K: Encodable + Ord, 68 | V: Encodable 69 | > Encodable for BTreeMap { 70 | fn encode(&self, e: &mut S) -> Result<(), S::Error> { 71 | e.emit_map(self.len(), |e| { 72 | let mut i = 0; 73 | for (key, val) in self.iter() { 74 | try!(e.emit_map_elt_key(i, |e| key.encode(e))); 75 | try!(e.emit_map_elt_val(i, |e| val.encode(e))); 76 | i += 1; 77 | } 78 | Ok(()) 79 | }) 80 | } 81 | } 82 | 83 | impl< 84 | K: Decodable + Ord, 85 | V: Decodable 86 | > Decodable for BTreeMap { 87 | fn decode(d: &mut D) -> Result, D::Error> { 88 | d.read_map(|d, len| { 89 | let mut map = BTreeMap::new(); 90 | for i in 0..len { 91 | let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d))); 92 | let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d))); 93 | map.insert(key, val); 94 | } 95 | Ok(map) 96 | }) 97 | } 98 | } 99 | 100 | impl< 101 | T: Encodable + Ord 102 | > Encodable for BTreeSet { 103 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 104 | s.emit_seq(self.len(), |s| { 105 | let mut i = 0; 106 | for e in self.iter() { 107 | try!(s.emit_seq_elt(i, |s| e.encode(s))); 108 | i += 1; 109 | } 110 | Ok(()) 111 | }) 112 | } 113 | } 114 | 115 | impl< 116 | T: Decodable + Ord 117 | > Decodable for BTreeSet { 118 | fn decode(d: &mut D) -> Result, D::Error> { 119 | d.read_seq(|d, len| { 120 | let mut set = BTreeSet::new(); 121 | for i in 0..len { 122 | set.insert(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); 123 | } 124 | Ok(set) 125 | }) 126 | } 127 | } 128 | 129 | impl Encodable for HashMap 130 | where K: Encodable + Hash + Eq, 131 | V: Encodable, 132 | { 133 | fn encode(&self, e: &mut E) -> Result<(), E::Error> { 134 | e.emit_map(self.len(), |e| { 135 | let mut i = 0; 136 | for (key, val) in self.iter() { 137 | try!(e.emit_map_elt_key(i, |e| key.encode(e))); 138 | try!(e.emit_map_elt_val(i, |e| val.encode(e))); 139 | i += 1; 140 | } 141 | Ok(()) 142 | }) 143 | } 144 | } 145 | 146 | impl Decodable for HashMap 147 | where K: Decodable + Hash + Eq, 148 | V: Decodable, 149 | { 150 | fn decode(d: &mut D) -> Result, D::Error> { 151 | d.read_map(|d, len| { 152 | let mut map = HashMap::with_capacity(cap_capacity::<(K, V)>(len)); 153 | for i in 0..len { 154 | let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d))); 155 | let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d))); 156 | map.insert(key, val); 157 | } 158 | Ok(map) 159 | }) 160 | } 161 | } 162 | 163 | impl Encodable for HashSet where T: Encodable + Hash + Eq { 164 | fn encode(&self, s: &mut E) -> Result<(), E::Error> { 165 | s.emit_seq(self.len(), |s| { 166 | let mut i = 0; 167 | for e in self.iter() { 168 | try!(s.emit_seq_elt(i, |s| e.encode(s))); 169 | i += 1; 170 | } 171 | Ok(()) 172 | }) 173 | } 174 | } 175 | 176 | impl Decodable for HashSet where T: Decodable + Hash + Eq, { 177 | fn decode(d: &mut D) -> Result, D::Error> { 178 | d.read_seq(|d, len| { 179 | let mut set = HashSet::with_capacity(cap_capacity::(len)); 180 | for i in 0..len { 181 | set.insert(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); 182 | } 183 | Ok(set) 184 | }) 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /src/hex.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | // 11 | // ignore-lexer-test FIXME #15679 12 | 13 | //! Hex binary-to-text encoding 14 | 15 | pub use self::FromHexError::*; 16 | 17 | use std::fmt; 18 | use std::error; 19 | 20 | /// A trait for converting a value to hexadecimal encoding 21 | pub trait ToHex { 22 | /// Converts the value of `self` to a hex value, returning the owned 23 | /// string. 24 | fn to_hex(&self) -> String; 25 | } 26 | 27 | static CHARS: &'static[u8] = b"0123456789abcdef"; 28 | 29 | impl ToHex for [u8] { 30 | /// Turn a vector of `u8` bytes into a hexadecimal string. 31 | /// 32 | /// # Example 33 | /// 34 | /// ```rust 35 | /// extern crate rustc_serialize; 36 | /// use rustc_serialize::hex::ToHex; 37 | /// 38 | /// fn main () { 39 | /// let str = [52,32].to_hex(); 40 | /// println!("{}", str); 41 | /// } 42 | /// ``` 43 | fn to_hex(&self) -> String { 44 | let mut v = Vec::with_capacity(self.len() * 2); 45 | for &byte in self.iter() { 46 | v.push(CHARS[(byte >> 4) as usize]); 47 | v.push(CHARS[(byte & 0xf) as usize]); 48 | } 49 | 50 | unsafe { 51 | String::from_utf8_unchecked(v) 52 | } 53 | } 54 | } 55 | 56 | impl<'a, T: ?Sized + ToHex> ToHex for &'a T { 57 | fn to_hex(&self) -> String { 58 | (**self).to_hex() 59 | } 60 | } 61 | 62 | /// A trait for converting hexadecimal encoded values 63 | pub trait FromHex { 64 | /// Converts the value of `self`, interpreted as hexadecimal encoded data, 65 | /// into an owned vector of bytes, returning the vector. 66 | fn from_hex(&self) -> Result, FromHexError>; 67 | } 68 | 69 | /// Errors that can occur when decoding a hex encoded string 70 | #[derive(Clone, Copy)] 71 | pub enum FromHexError { 72 | /// The input contained a character not part of the hex format 73 | InvalidHexCharacter(char, usize), 74 | /// The input had an invalid length 75 | InvalidHexLength, 76 | } 77 | 78 | impl fmt::Debug for FromHexError { 79 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 80 | match *self { 81 | InvalidHexCharacter(ch, idx) => 82 | write!(f, "Invalid character '{}' at position {}", ch, idx), 83 | InvalidHexLength => write!(f, "Invalid input length"), 84 | } 85 | } 86 | } 87 | 88 | impl error::Error for FromHexError { 89 | fn description(&self) -> &str { 90 | match *self { 91 | InvalidHexCharacter(_, _) => "invalid character", 92 | InvalidHexLength => "invalid length", 93 | } 94 | } 95 | } 96 | 97 | impl fmt::Display for FromHexError { 98 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 99 | fmt::Debug::fmt(&self, f) 100 | } 101 | } 102 | 103 | impl FromHex for str { 104 | /// Convert any hexadecimal encoded string (literal, `@`, `&`, or `~`) 105 | /// to the byte values it encodes. 106 | /// 107 | /// You can use the `String::from_utf8` function to turn a 108 | /// `Vec` into a string with characters corresponding to those values. 109 | /// 110 | /// # Example 111 | /// 112 | /// This converts a string literal to hexadecimal and back. 113 | /// 114 | /// ```rust 115 | /// extern crate rustc_serialize; 116 | /// use rustc_serialize::hex::{FromHex, ToHex}; 117 | /// 118 | /// fn main () { 119 | /// let hello_str = "Hello, World".as_bytes().to_hex(); 120 | /// println!("{}", hello_str); 121 | /// let bytes = hello_str.from_hex().unwrap(); 122 | /// println!("{:?}", bytes); 123 | /// let result_str = String::from_utf8(bytes).unwrap(); 124 | /// println!("{}", result_str); 125 | /// } 126 | /// ``` 127 | fn from_hex(&self) -> Result, FromHexError> { 128 | // This may be an overestimate if there is any whitespace 129 | let mut b = Vec::with_capacity(self.len() / 2); 130 | let mut modulus = 0; 131 | let mut buf = 0; 132 | 133 | for (idx, byte) in self.bytes().enumerate() { 134 | buf <<= 4; 135 | 136 | match byte { 137 | b'A'...b'F' => buf |= byte - b'A' + 10, 138 | b'a'...b'f' => buf |= byte - b'a' + 10, 139 | b'0'...b'9' => buf |= byte - b'0', 140 | b' '|b'\r'|b'\n'|b'\t' => { 141 | buf >>= 4; 142 | continue 143 | } 144 | _ => { 145 | let ch = self[idx..].chars().next().unwrap(); 146 | return Err(InvalidHexCharacter(ch, idx)) 147 | } 148 | } 149 | 150 | modulus += 1; 151 | if modulus == 2 { 152 | modulus = 0; 153 | b.push(buf); 154 | } 155 | } 156 | 157 | match modulus { 158 | 0 => Ok(b.into_iter().collect()), 159 | _ => Err(InvalidHexLength), 160 | } 161 | } 162 | } 163 | 164 | impl<'a, T: ?Sized + FromHex> FromHex for &'a T { 165 | fn from_hex(&self) -> Result, FromHexError> { 166 | (**self).from_hex() 167 | } 168 | } 169 | 170 | #[cfg(test)] 171 | mod tests { 172 | use hex::{FromHex, ToHex}; 173 | 174 | #[test] 175 | pub fn test_to_hex() { 176 | assert_eq!("foobar".as_bytes().to_hex(), "666f6f626172"); 177 | } 178 | 179 | #[test] 180 | pub fn test_from_hex_okay() { 181 | assert_eq!("666f6f626172".from_hex().unwrap(), 182 | b"foobar"); 183 | assert_eq!("666F6F626172".from_hex().unwrap(), 184 | b"foobar"); 185 | } 186 | 187 | #[test] 188 | pub fn test_from_hex_odd_len() { 189 | assert!("666".from_hex().is_err()); 190 | assert!("66 6".from_hex().is_err()); 191 | } 192 | 193 | #[test] 194 | pub fn test_from_hex_invalid_char() { 195 | assert!("66y6".from_hex().is_err()); 196 | } 197 | 198 | #[test] 199 | pub fn test_from_hex_ignores_whitespace() { 200 | assert_eq!("666f 6f6\r\n26172 ".from_hex().unwrap(), 201 | b"foobar"); 202 | } 203 | 204 | #[test] 205 | pub fn test_to_hex_all_bytes() { 206 | for i in 0..256 { 207 | assert_eq!([i as u8].to_hex(), format!("{:02x}", i)); 208 | } 209 | } 210 | 211 | #[test] 212 | pub fn test_from_hex_all_bytes() { 213 | for i in 0..256 { 214 | let ii: &[u8] = &[i as u8]; 215 | assert_eq!(format!("{:02x}", i).from_hex().unwrap(), 216 | ii); 217 | assert_eq!(format!("{:02X}", i).from_hex().unwrap(), 218 | ii); 219 | } 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! Support code for encoding and decoding types. 12 | //! 13 | //! > **NOTE**: This crate is deprecated in favor of [`serde`]. No new feature 14 | //! > development will happen in this crate, although bug fixes proposed through 15 | //! > PRs will still be merged. It is very highly recommended by the Rust 16 | //! > Library Team that you use [`serde`], not this crate. 17 | //! 18 | //! [`serde`]: https://serde.rs 19 | //! 20 | //! # Usage 21 | //! 22 | //! This crate is [on crates.io](https://crates.io/crates/rustc-serialize) and 23 | //! can be used by adding `rustc-serialize` to the dependencies in your 24 | //! project's `Cargo.toml`. 25 | //! 26 | //! ```toml 27 | //! [dependencies] 28 | //! rustc-serialize = "0.3" 29 | //! ``` 30 | //! 31 | //! and this to your crate root: 32 | //! 33 | //! ```rust 34 | //! extern crate rustc_serialize; 35 | //! ``` 36 | 37 | #![cfg_attr(rustbuild, feature(staged_api, rustc_private))] 38 | #![cfg_attr(rustbuild, unstable(feature = "rustc_private", issue = "27812"))] 39 | 40 | #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", 41 | html_favicon_url = "https://www.rust-lang.org/favicon.ico", 42 | html_root_url = "https://doc.rust-lang.org/rustc-serialize/")] 43 | #![cfg_attr(test, deny(warnings))] 44 | #![allow(trivial_numeric_casts)] 45 | #![cfg_attr(rust_build, feature(staged_api))] 46 | #![cfg_attr(rust_build, staged_api)] 47 | #![cfg_attr(rust_build, 48 | unstable(feature = "rustc_private", 49 | reason = "use the crates.io `rustc-serialize` library instead"))] 50 | 51 | #[cfg(test)] extern crate rand; 52 | 53 | pub use self::serialize::{Decoder, Encoder, Decodable, Encodable, 54 | DecoderHelpers, EncoderHelpers}; 55 | 56 | 57 | // Limit collections from allocating more than 58 | // 1 MB for calls to `with_capacity`. 59 | fn cap_capacity(given_len: usize) -> usize { 60 | use std::cmp::min; 61 | use std::mem::size_of; 62 | const PRE_ALLOCATE_CAP: usize = 0x100000; 63 | 64 | match size_of::() { 65 | 0 => min(given_len, PRE_ALLOCATE_CAP), 66 | n => min(given_len, PRE_ALLOCATE_CAP / n) 67 | } 68 | } 69 | 70 | mod serialize; 71 | mod collection_impls; 72 | 73 | pub mod base64; 74 | pub mod hex; 75 | pub mod json; 76 | 77 | mod rustc_serialize { 78 | pub use serialize::*; 79 | } 80 | -------------------------------------------------------------------------------- /src/serialize.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! Support code for encoding and decoding types. 12 | //! 13 | //! In order to allow extensibility in both what types can be encoded and how 14 | //! they are encoded, encoding and decoding are split into two part each. An 15 | //! implementation of the Encodable trait knows how to turn a specific type into 16 | //! a generic form, and then uses an implementation of the Encoder trait to turn 17 | //! this into concrete output (such as a JSON string). Decoder and Decodable do 18 | //! the same for decoding. 19 | 20 | /* 21 | Core encoding and decoding interfaces. 22 | */ 23 | 24 | use std::cell::{Cell, RefCell}; 25 | use std::ffi::OsString; 26 | use std::path; 27 | use std::rc::Rc; 28 | use std::sync::Arc; 29 | use std::marker::PhantomData; 30 | use std::borrow::Cow; 31 | 32 | use cap_capacity; 33 | 34 | /// Trait for writing out an encoding when serializing. 35 | /// 36 | /// This trait provides methods to encode basic types and generic forms of 37 | /// collections. Implementations of `Encodable` use it to perform the actual 38 | /// encoding of a type. 39 | /// 40 | /// It is unspecified what is done with the encoding - it could be stored in a 41 | /// variable, or written directly to a file, for example. 42 | /// 43 | /// Encoders can expect to only have a single "root" method call made on this 44 | /// trait. Non-trivial types will call one of the collection-emitting methods, 45 | /// passing a function that may call other methods on the trait, but once the 46 | /// collection-emitting method has returned, encoding should be complete. 47 | pub trait Encoder { 48 | /// The error type for method results. 49 | type Error; 50 | 51 | // Primitive types: 52 | /// Emit a nil value. 53 | /// 54 | /// For example, this might be stored as the null keyword in JSON. 55 | fn emit_nil(&mut self) -> Result<(), Self::Error>; 56 | 57 | /// Emit a usize value. 58 | fn emit_usize(&mut self, v: usize) -> Result<(), Self::Error>; 59 | 60 | /// Emit a u64 value. 61 | fn emit_u64(&mut self, v: u64) -> Result<(), Self::Error>; 62 | 63 | /// Emit a u32 value. 64 | fn emit_u32(&mut self, v: u32) -> Result<(), Self::Error>; 65 | 66 | /// Emit a u16 value. 67 | fn emit_u16(&mut self, v: u16) -> Result<(), Self::Error>; 68 | 69 | /// Emit a u8 value. 70 | fn emit_u8(&mut self, v: u8) -> Result<(), Self::Error>; 71 | 72 | /// Emit a isize value. 73 | fn emit_isize(&mut self, v: isize) -> Result<(), Self::Error>; 74 | 75 | /// Emit a i64 value. 76 | fn emit_i64(&mut self, v: i64) -> Result<(), Self::Error>; 77 | 78 | /// Emit a i32 value. 79 | fn emit_i32(&mut self, v: i32) -> Result<(), Self::Error>; 80 | 81 | /// Emit a i16 value. 82 | fn emit_i16(&mut self, v: i16) -> Result<(), Self::Error>; 83 | 84 | /// Emit a i8 value. 85 | fn emit_i8(&mut self, v: i8) -> Result<(), Self::Error>; 86 | 87 | /// Emit a bool value. 88 | /// 89 | /// For example, this might be stored as the true and false keywords in 90 | /// JSON. 91 | fn emit_bool(&mut self, v: bool) -> Result<(), Self::Error>; 92 | 93 | /// Emit a f64 value. 94 | fn emit_f64(&mut self, v: f64) -> Result<(), Self::Error>; 95 | 96 | /// Emit a f32 value. 97 | fn emit_f32(&mut self, v: f32) -> Result<(), Self::Error>; 98 | 99 | /// Emit a char value. 100 | /// 101 | /// Note that strings should be emitted using `emit_str`, not as a sequence 102 | /// of `emit_char` calls. 103 | fn emit_char(&mut self, v: char) -> Result<(), Self::Error>; 104 | 105 | /// Emit a string value. 106 | fn emit_str(&mut self, v: &str) -> Result<(), Self::Error>; 107 | 108 | // Compound types: 109 | /// Emit an enumeration value. 110 | /// 111 | /// * `name` indicates the enumeration type name. 112 | /// * `f` is a function that will call `emit_enum_variant` or 113 | /// `emit_enum_struct_variant` as appropriate to write the actual value. 114 | fn emit_enum(&mut self, name: &str, f: F) -> Result<(), Self::Error> 115 | where F: FnOnce(&mut Self) -> Result<(), Self::Error>; 116 | 117 | /// Emit a enumeration variant value with no or unnamed data. 118 | /// 119 | /// This should only be called from a function passed to `emit_enum`. 120 | /// Variants with named data should use `emit_enum_struct_variant`. 121 | /// 122 | /// * `v_name` is the variant name 123 | /// * `v_id` is the numeric identifier for the variant. 124 | /// * `len` is the number of data items associated with the variant. 125 | /// * `f` is a function that will call `emit_enum_variant_arg` for each data 126 | /// item. It may not be called if len is 0. 127 | /// 128 | /// # Examples 129 | /// 130 | /// ``` 131 | /// use rustc_serialize::Encodable; 132 | /// use rustc_serialize::Encoder; 133 | /// 134 | /// enum Message { 135 | /// Quit, 136 | /// ChangeColor(i32, i32, i32), 137 | /// } 138 | /// 139 | /// impl Encodable for Message { 140 | /// fn encode(&self, s: &mut S) -> Result<(), S::Error> { 141 | /// s.emit_enum("Message", |s| { 142 | /// match *self { 143 | /// Message::Quit => { 144 | /// s.emit_enum_variant("Quit", 0, 0, |s| Ok(())) 145 | /// } 146 | /// Message::ChangeColor(r, g, b) => { 147 | /// s.emit_enum_variant("ChangeColor", 1, 3, |s| { 148 | /// try!(s.emit_enum_variant_arg(0, |s| { 149 | /// s.emit_i32(r) 150 | /// })); 151 | /// try!(s.emit_enum_variant_arg(1, |s| { 152 | /// s.emit_i32(g) 153 | /// })); 154 | /// try!(s.emit_enum_variant_arg(2, |s| { 155 | /// s.emit_i32(b) 156 | /// })); 157 | /// Ok(()) 158 | /// }) 159 | /// } 160 | /// } 161 | /// }) 162 | /// } 163 | /// } 164 | /// ``` 165 | fn emit_enum_variant(&mut self, v_name: &str, 166 | v_id: usize, 167 | len: usize, 168 | f: F) -> Result<(), Self::Error> 169 | where F: FnOnce(&mut Self) -> Result<(), Self::Error>; 170 | 171 | /// Emit an unnamed data item for an enumeration variant. 172 | /// 173 | /// This should only be called from a function passed to 174 | /// `emit_enum_variant`. 175 | /// 176 | /// * `a_idx` is the (zero-based) index of the data item. 177 | /// * `f` is a function that will call the appropriate emit method to encode 178 | /// the data object. 179 | /// 180 | /// Note that variant data items must be emitted in order - starting with 181 | /// index `0` and finishing with index `len-1`. 182 | fn emit_enum_variant_arg(&mut self, a_idx: usize, f: F) 183 | -> Result<(), Self::Error> 184 | where F: FnOnce(&mut Self) -> Result<(), Self::Error>; 185 | 186 | /// Emit a enumeration variant value with no or named data. 187 | /// 188 | /// This should only be called from a function passed to `emit_enum`. 189 | /// Variants with unnamed data should use `emit_enum_variant`. 190 | /// 191 | /// * `v_name` is the variant name. 192 | /// * `v_id` is the numeric identifier for the variant. 193 | /// * `len` is the number of data items associated with the variant. 194 | /// * `f` is a function that will call `emit_enum_struct_variant_field` for 195 | /// each data item. It may not be called if `len` is `0`. 196 | /// 197 | /// # Examples 198 | /// 199 | /// ``` 200 | /// use rustc_serialize::Encodable; 201 | /// use rustc_serialize::Encoder; 202 | /// 203 | /// enum Message { 204 | /// Quit, 205 | /// Move { x: i32, y: i32 }, 206 | /// } 207 | /// 208 | /// impl Encodable for Message { 209 | /// fn encode(&self, s: &mut S) -> Result<(), S::Error> { 210 | /// s.emit_enum("Message", |s| { 211 | /// match *self { 212 | /// Message::Quit => { 213 | /// s.emit_enum_struct_variant("Quit", 0, 0, |s| Ok(())) 214 | /// } 215 | /// Message::Move { x: x, y: y } => { 216 | /// s.emit_enum_struct_variant("Move", 1, 2, |s| { 217 | /// try!(s.emit_enum_struct_variant_field("x", 0, |s| { 218 | /// s.emit_i32(x) 219 | /// })); 220 | /// try!(s.emit_enum_struct_variant_field("y", 1, |s| { 221 | /// s.emit_i32(y) 222 | /// })); 223 | /// Ok(()) 224 | /// }) 225 | /// } 226 | /// } 227 | /// }) 228 | /// } 229 | /// } 230 | /// ``` 231 | fn emit_enum_struct_variant(&mut self, v_name: &str, 232 | v_id: usize, 233 | len: usize, 234 | f: F) -> Result<(), Self::Error> 235 | where F: FnOnce(&mut Self) -> Result<(), Self::Error>; 236 | 237 | /// Emit a named data item for an enumeration variant. 238 | /// 239 | /// This should only be called from a function passed to 240 | /// `emit_enum_struct_variant`. 241 | /// 242 | /// * `f_name` is the name of the data item field. 243 | /// * `f_idx` is its (zero-based) index. 244 | /// * `f` is a function that will call the appropriate emit method to encode 245 | /// the data object. 246 | /// 247 | /// Note that fields must be emitted in order - starting with index `0` and 248 | /// finishing with index `len-1`. 249 | fn emit_enum_struct_variant_field(&mut self, 250 | f_name: &str, 251 | f_idx: usize, 252 | f: F) -> Result<(), Self::Error> 253 | where F: FnOnce(&mut Self) -> Result<(), Self::Error>; 254 | 255 | /// Emit a struct value. 256 | /// 257 | /// * `name` is the name of the struct. 258 | /// * `len` is the number of members. 259 | /// * `f` is a function that calls `emit_struct_field` for each member. 260 | /// 261 | /// # Examples 262 | /// 263 | /// ``` 264 | /// use rustc_serialize::Encodable; 265 | /// use rustc_serialize::Encoder; 266 | /// 267 | /// struct Point { 268 | /// x: i32, 269 | /// y: i32, 270 | /// } 271 | /// 272 | /// impl Encodable for Point { 273 | /// fn encode(&self, s: &mut S) -> Result<(), S::Error> { 274 | /// s.emit_struct("Point", 2, |s| { 275 | /// try!(s.emit_struct_field("x", 0, |s| { 276 | /// s.emit_i32(self.x) 277 | /// })); 278 | /// try!(s.emit_struct_field("y", 1, |s| { 279 | /// s.emit_i32(self.y) 280 | /// })); 281 | /// Ok(()) 282 | /// }) 283 | /// } 284 | /// } 285 | /// ``` 286 | fn emit_struct(&mut self, name: &str, len: usize, f: F) 287 | -> Result<(), Self::Error> 288 | where F: FnOnce(&mut Self) -> Result<(), Self::Error>; 289 | /// Emit a field item for a struct. 290 | /// 291 | /// This should only be called from a function passed to `emit_struct`. 292 | /// 293 | /// * `f_name` is the name of the data item field. 294 | /// * `f_idx` is its (zero-based) index. 295 | /// * `f` is a function that will call the appropriate emit method to encode 296 | /// the data object. 297 | /// 298 | /// Note that fields must be emitted in order - starting with index `0` and 299 | /// finishing with index `len-1`. 300 | fn emit_struct_field(&mut self, f_name: &str, f_idx: usize, f: F) 301 | -> Result<(), Self::Error> 302 | where F: FnOnce(&mut Self) -> Result<(), Self::Error>; 303 | 304 | /// Emit a tuple value. 305 | /// 306 | /// * `len` is the number of items in the tuple. 307 | /// * `f` is a function that calls `emit_tuple_arg` for each member. 308 | /// 309 | /// Note that external `Encodable` implementations should not normally need 310 | /// to use this method directly; it is meant for the use of this module's 311 | /// own implementation of `Encodable` for tuples. 312 | fn emit_tuple(&mut self, len: usize, f: F) -> Result<(), Self::Error> 313 | where F: FnOnce(&mut Self) -> Result<(), Self::Error>; 314 | 315 | /// Emit a data item for a tuple. 316 | /// 317 | /// This should only be called from a function passed to `emit_tuple`. 318 | /// 319 | /// * `idx` is the (zero-based) index of the data item. 320 | /// * `f` is a function that will call the appropriate emit method to encode 321 | /// the data object. 322 | /// 323 | /// Note that tuple items must be emitted in order - starting with index `0` 324 | /// and finishing with index `len-1`. 325 | fn emit_tuple_arg(&mut self, idx: usize, f: F) -> Result<(), Self::Error> 326 | where F: FnOnce(&mut Self) -> Result<(), Self::Error>; 327 | 328 | /// Emit a tuple struct value. 329 | /// 330 | /// * `name` is the name of the tuple struct. 331 | /// * `len` is the number of items in the tuple struct. 332 | /// * `f` is a function that calls `emit_tuple_struct_arg` for each member. 333 | /// 334 | /// # Examples 335 | /// 336 | /// ``` 337 | /// use rustc_serialize::Encodable; 338 | /// use rustc_serialize::Encoder; 339 | /// 340 | /// struct Pair(i32,i32); 341 | /// 342 | /// impl Encodable for Pair { 343 | /// fn encode(&self, s: &mut S) -> Result<(), S::Error> { 344 | /// let Pair(first,second) = *self; 345 | /// s.emit_tuple_struct("Pair", 2, |s| { 346 | /// try!(s.emit_tuple_arg(0, |s| { 347 | /// s.emit_i32(first) 348 | /// })); 349 | /// try!(s.emit_tuple_arg(1, |s| { 350 | /// s.emit_i32(second) 351 | /// })); 352 | /// Ok(()) 353 | /// }) 354 | /// } 355 | /// } 356 | /// ``` 357 | fn emit_tuple_struct(&mut self, name: &str, len: usize, f: F) 358 | -> Result<(), Self::Error> 359 | where F: FnOnce(&mut Self) -> Result<(), Self::Error>; 360 | 361 | /// Emit a data item for a tuple struct. 362 | /// 363 | /// This should only be called from a function passed to 364 | /// `emit_tuple_struct`. 365 | /// 366 | /// * `f_idx` is the (zero-based) index of the data item. 367 | /// * `f` is a function that will call the appropriate emit method to encode 368 | /// the data object. 369 | /// 370 | /// Note that tuple items must be emitted in order - starting with index `0` 371 | /// and finishing with index `len-1`. 372 | fn emit_tuple_struct_arg(&mut self, f_idx: usize, f: F) 373 | -> Result<(), Self::Error> 374 | where F: FnOnce(&mut Self) -> Result<(), Self::Error>; 375 | 376 | // Specialized types: 377 | /// Emit an optional value. 378 | /// 379 | /// `f` is a function that will call either `emit_option_none` or 380 | /// `emit_option_some` as appropriate. 381 | /// 382 | /// This method allows encoders to handle `Option` values specially, 383 | /// rather than using the generic enum methods, because many encoding 384 | /// formats have a built-in "optional" concept. 385 | /// 386 | /// Note that external `Encodable` implementations should not normally need 387 | /// to use this method directly; it is meant for the use of this module's 388 | /// own implementation of `Encodable` for `Option`. 389 | fn emit_option(&mut self, f: F) -> Result<(), Self::Error> 390 | where F: FnOnce(&mut Self) -> Result<(), Self::Error>; 391 | 392 | /// Emit the `None` optional value. 393 | /// 394 | /// This should only be called from a function passed to `emit_option`. 395 | fn emit_option_none(&mut self) -> Result<(), Self::Error>; 396 | 397 | /// Emit the `Some(x)` optional value. 398 | /// 399 | /// `f` is a function that will call the appropriate emit method to encode 400 | /// the data object. 401 | /// 402 | /// This should only be called from a function passed to `emit_option`. 403 | fn emit_option_some(&mut self, f: F) -> Result<(), Self::Error> 404 | where F: FnOnce(&mut Self) -> Result<(), Self::Error>; 405 | 406 | /// Emit a sequence of values. 407 | /// 408 | /// This should be used for both array-like ordered sequences and set-like 409 | /// unordered ones. 410 | /// 411 | /// * `len` is the number of values in the sequence. 412 | /// * `f` is a function that will call `emit_seq_elt` for each value in the 413 | /// sequence. 414 | fn emit_seq(&mut self, len: usize, f: F) -> Result<(), Self::Error> 415 | where F: FnOnce(&mut Self) -> Result<(), Self::Error>; 416 | 417 | /// Emit an element in a sequence. 418 | /// 419 | /// This should only be called from a function passed to `emit_seq`. 420 | /// 421 | /// * `idx` is the (zero-based) index of the value in the sequence. 422 | /// * `f` is a function that will call the appropriate emit method to encode 423 | /// the data object. 424 | /// 425 | /// Note that sequence elements must be emitted in order - starting with 426 | /// index `0` and finishing with index `len-1`. 427 | fn emit_seq_elt(&mut self, idx: usize, f: F) -> Result<(), Self::Error> 428 | where F: FnOnce(&mut Self) -> Result<(), Self::Error>; 429 | 430 | /// Emit an associative container (map). 431 | /// 432 | /// * `len` is the number of entries in the map. 433 | /// * `f` is a function that will call `emit_map_elt_key` and 434 | /// `emit_map_elt_val` for each entry in the map. 435 | /// 436 | /// # Examples 437 | /// 438 | /// ``` 439 | /// use rustc_serialize::Encodable; 440 | /// use rustc_serialize::Encoder; 441 | /// 442 | /// struct SimpleMap { 443 | /// entries: Vec<(K,V)>, 444 | /// } 445 | /// 446 | /// impl Encodable for SimpleMap { 447 | /// fn encode(&self, s: &mut S) -> Result<(), S::Error> { 448 | /// s.emit_map(self.entries.len(), |s| { 449 | /// for (i, e) in self.entries.iter().enumerate() { 450 | /// let (ref k, ref v) = *e; 451 | /// try!(s.emit_map_elt_key(i, |s| k.encode(s))); 452 | /// try!(s.emit_map_elt_val(i, |s| v.encode(s))); 453 | /// } 454 | /// Ok(()) 455 | /// }) 456 | /// } 457 | /// } 458 | /// ``` 459 | fn emit_map(&mut self, len: usize, f: F) -> Result<(), Self::Error> 460 | where F: FnOnce(&mut Self) -> Result<(), Self::Error>; 461 | 462 | /// Emit the key for an entry in a map. 463 | /// 464 | /// This should only be called from a function passed to `emit_map`. 465 | /// 466 | /// * `idx` is the (zero-based) index of the entry in the map 467 | /// * `f` is a function that will call the appropriate emit method to encode 468 | /// the key. 469 | /// 470 | /// Note that map entries must be emitted in order - starting with index `0` 471 | /// and finishing with index `len-1` - and for each entry, the key should be 472 | /// emitted followed immediately by the value. 473 | fn emit_map_elt_key(&mut self, idx: usize, f: F) -> Result<(), Self::Error> 474 | where F: FnOnce(&mut Self) -> Result<(), Self::Error>; 475 | 476 | /// Emit the value for an entry in a map. 477 | /// 478 | /// This should only be called from a function passed to `emit_map`. 479 | /// 480 | /// * `idx` is the (zero-based) index of the entry in the map 481 | /// * `f` is a function that will call the appropriate emit method to encode 482 | /// the value. 483 | /// 484 | /// Note that map entries must be emitted in order - starting with index `0` 485 | /// and finishing with index `len-1` - and for each entry, the key should be 486 | /// emitted followed immediately by the value. 487 | fn emit_map_elt_val(&mut self, idx: usize, f: F) -> Result<(), Self::Error> 488 | where F: FnOnce(&mut Self) -> Result<(), Self::Error>; 489 | } 490 | 491 | /// Trait for reading in an encoding for deserialization. 492 | /// 493 | /// This trait provides methods to decode basic types and generic forms of 494 | /// collections. Implementations of `Decodable` use it to perform the actual 495 | /// decoding of a type. 496 | /// 497 | /// Note that, as is typical with deserialization, the design of this API 498 | /// assumes you know in advance the form of the data you are decoding (ie: what 499 | /// type is encoded). 500 | /// 501 | /// Decoders can expect to only have a single "root" method call made on this 502 | /// trait. Non-trivial types will call one of the collection-reading methods, 503 | /// passing a function that may call other methods on the trait, but once the 504 | /// collection-reading method has returned, decoding should be complete. 505 | pub trait Decoder { 506 | /// The error type for method results. 507 | type Error; 508 | 509 | // Primitive types: 510 | /// Read a nil value. 511 | fn read_nil(&mut self) -> Result<(), Self::Error>; 512 | 513 | /// Read a usize value. 514 | fn read_usize(&mut self) -> Result; 515 | 516 | /// Read a u64 value. 517 | fn read_u64(&mut self) -> Result; 518 | 519 | /// Read a u32 value. 520 | fn read_u32(&mut self) -> Result; 521 | 522 | /// Read a u16 value. 523 | fn read_u16(&mut self) -> Result; 524 | 525 | /// Read a u8 value. 526 | fn read_u8(&mut self) -> Result; 527 | 528 | /// Read a isize value. 529 | fn read_isize(&mut self) -> Result; 530 | 531 | /// Read a i64 value. 532 | fn read_i64(&mut self) -> Result; 533 | 534 | /// Read a i32 value. 535 | fn read_i32(&mut self) -> Result; 536 | 537 | /// Read a i16 value. 538 | fn read_i16(&mut self) -> Result; 539 | 540 | /// Read a i8 value. 541 | fn read_i8(&mut self) -> Result; 542 | 543 | /// Read a bool value. 544 | fn read_bool(&mut self) -> Result; 545 | 546 | /// Read a f64 value. 547 | fn read_f64(&mut self) -> Result; 548 | 549 | /// Read a f32 value. 550 | fn read_f32(&mut self) -> Result; 551 | 552 | /// Read a char value. 553 | fn read_char(&mut self) -> Result; 554 | 555 | /// Read a string value. 556 | fn read_str(&mut self) -> Result; 557 | 558 | // Compound types: 559 | /// Read an enumeration value. 560 | /// 561 | /// * `name` indicates the enumeration type name. It may be used to 562 | /// sanity-check the data being read. 563 | /// * `f` is a function that will call `read_enum_variant` (or 564 | /// `read_enum_struct_variant`) to read the actual value. 565 | fn read_enum(&mut self, name: &str, f: F) -> Result 566 | where F: FnOnce(&mut Self) -> Result; 567 | 568 | /// Read an enumeration value. 569 | /// 570 | /// * `names` is a list of the enumeration variant names. 571 | /// * `f` is a function that will call `read_enum_variant_arg` or 572 | /// `read_enum_struct_variant_field` as appropriate to read the 573 | /// associated values. It will be passed the index into `names` for the 574 | /// variant that is encoded. 575 | fn read_enum_variant(&mut self, names: &[&str], f: F) 576 | -> Result 577 | where F: FnMut(&mut Self, usize) -> Result; 578 | 579 | /// Read an unnamed data item for an enumeration variant. 580 | /// 581 | /// This should only be called from a function passed to `read_enum_variant` 582 | /// or `read_enum_struct_variant`, and only when the index provided to that 583 | /// function indicates that the variant has associated unnamed data. It 584 | /// should be called once for each associated data item. 585 | /// 586 | /// * `a_idx` is the (zero-based) index of the data item. 587 | /// * `f` is a function that will call the appropriate read method to deocde 588 | /// the data object. 589 | /// 590 | /// Note that variant data items must be read in order - starting with index 591 | /// `0` and finishing with index `len-1`. Implementations may use `a_idx`, 592 | /// the call order or both to select the correct data to decode. 593 | fn read_enum_variant_arg(&mut self, a_idx: usize, f: F) 594 | -> Result 595 | where F: FnOnce(&mut Self) -> Result; 596 | 597 | /// Read an enumeration value. 598 | /// 599 | /// This is identical to `read_enum_variant`, and is only provided for 600 | /// symmetry with the `Encoder` API. 601 | fn read_enum_struct_variant(&mut self, names: &[&str], f: F) 602 | -> Result 603 | where F: FnMut(&mut Self, usize) -> Result; 604 | 605 | /// Read a named data item for an enumeration variant. 606 | /// 607 | /// This should only be called from a function passed to `read_enum_variant` 608 | /// or `read_enum_struct_variant`, and only when the index provided to that 609 | /// function indicates that the variant has associated named data. It should 610 | /// be called once for each associated field. 611 | /// 612 | /// * `f_name` is the name of the field. 613 | /// * `f_idx` is the (zero-based) index of the data item. 614 | /// * `f` is a function that will call the appropriate read method to deocde 615 | /// the data object. 616 | /// 617 | /// Note that fields must be read in order - starting with index `0` and 618 | /// finishing with index `len-1`. Implementations may use `f_idx`, `f_name`, 619 | /// the call order or any combination to choose the correct data to decode, 620 | /// and may (but are not required to) return an error if these are 621 | /// inconsistent. 622 | fn read_enum_struct_variant_field(&mut self, 623 | f_name: &str, 624 | f_idx: usize, 625 | f: F) 626 | -> Result 627 | where F: FnOnce(&mut Self) -> Result; 628 | 629 | /// Read an struct value. 630 | /// 631 | /// * `s_name` indicates the struct type name. It may be used to 632 | /// sanity-check the data being read. 633 | /// * `len` indicates the number of fields in the struct. 634 | /// * `f` is a function that will call `read_struct_field` for each field in 635 | /// the struct. 636 | fn read_struct(&mut self, s_name: &str, len: usize, f: F) 637 | -> Result 638 | where F: FnOnce(&mut Self) -> Result; 639 | 640 | /// Read a field for a struct value. 641 | /// 642 | /// This should only be called from a function passed to `read_struct`. It 643 | /// should be called once for each associated field. 644 | /// 645 | /// * `f_name` is the name of the field. 646 | /// * `f_idx` is the (zero-based) index of the data item. 647 | /// * `f` is a function that will call the appropriate read method to deocde 648 | /// the data object. 649 | /// 650 | /// Note that fields must be read in order - starting with index `0` and 651 | /// finishing with index `len-1`. Implementations may use `f_idx`, `f_name`, 652 | /// the call order or any combination to choose the correct data to decode, 653 | /// and may (but are not required to) return an error if these are 654 | /// inconsistent. 655 | fn read_struct_field(&mut self, 656 | f_name: &str, 657 | f_idx: usize, 658 | f: F) 659 | -> Result 660 | where F: FnOnce(&mut Self) -> Result; 661 | 662 | /// Read a tuple value. 663 | /// 664 | /// * `len` is the number of items in the tuple. 665 | /// * `f` is a function that will call `read_tuple_arg` for each item in the 666 | /// tuple. 667 | /// 668 | /// Note that external `Decodable` implementations should not normally need 669 | /// to use this method directly; it is meant for the use of this module's 670 | /// own implementation of `Decodable` for tuples. 671 | fn read_tuple(&mut self, len: usize, f: F) -> Result 672 | where F: FnOnce(&mut Self) -> Result; 673 | 674 | /// Read a data item for a tuple. 675 | /// 676 | /// This should only be called from a function passed to `read_tuple`. 677 | /// 678 | /// * `a_idx` is the (zero-based) index of the data item. 679 | /// * `f` is a function that will call the appropriate read method to encode 680 | /// the data object. 681 | /// 682 | /// Note that tuple items must be read in order - starting with index `0` 683 | /// and finishing with index `len-1`. 684 | fn read_tuple_arg(&mut self, a_idx: usize, f: F) 685 | -> Result 686 | where F: FnOnce(&mut Self) -> Result; 687 | 688 | /// Read a tuple struct value. 689 | /// 690 | /// * `s_name` is the name of the tuple struct. 691 | /// * `len` is the number of items in the tuple struct. 692 | /// * `f` is a function that calls `read_tuple_struct_arg` for each member. 693 | fn read_tuple_struct(&mut self, s_name: &str, len: usize, f: F) 694 | -> Result 695 | where F: FnOnce(&mut Self) -> Result; 696 | 697 | /// Read a data item for a tuple struct. 698 | /// 699 | /// This should only be called from a function passed to 700 | /// `read_tuple_struct`. 701 | /// 702 | /// * `a_idx` is the (zero-based) index of the data item. 703 | /// * `f` is a function that will call the appropriate read method to encode 704 | /// the data object. 705 | /// 706 | /// Note that tuple struct items must be read in order - starting with index 707 | /// `0` and finishing with index `len-1`. 708 | fn read_tuple_struct_arg(&mut self, a_idx: usize, f: F) 709 | -> Result 710 | where F: FnOnce(&mut Self) -> Result; 711 | 712 | // Specialized types: 713 | /// Read an optional value. 714 | /// 715 | /// `f` is a function that will will be passed be passed `false` if the 716 | /// value is unset, and `true` if it is set. If the function is passed 717 | /// `true`, it will call the appropriate read methods to read the associated 718 | /// data type. 719 | /// 720 | /// This method allows decoders to handle `Option` values specially, 721 | /// rather than using the generic enum methods, because many encoding 722 | /// formats have a built-in "optional" concept. 723 | /// 724 | /// Note that external `Decodable` implementations should not normally need 725 | /// to use this method directly; it is meant for the use of this module's 726 | /// own implementation of `Decodable` for `Option`. 727 | fn read_option(&mut self, f: F) -> Result 728 | where F: FnMut(&mut Self, bool) -> Result; 729 | 730 | /// Read a sequence of values. 731 | /// 732 | /// This should be used for both array-like ordered sequences and set-like 733 | /// unordered ones. 734 | /// 735 | /// * `f` is a function that will be passed the length of the sequence, and 736 | /// will call `read_seq_elt` for each value in the sequence. 737 | fn read_seq(&mut self, f: F) -> Result 738 | where F: FnOnce(&mut Self, usize) -> Result; 739 | 740 | /// Read an element in the sequence. 741 | /// 742 | /// This should only be called from a function passed to `read_seq`. 743 | /// 744 | /// * `idx` is the (zero-based) index of the value in the sequence. 745 | /// * `f` is a function that will call the appropriate read method to decode 746 | /// the data object. 747 | /// 748 | /// Note that sequence elements must be read in order - starting with index 749 | /// `0` and finishing with index `len-1`. 750 | fn read_seq_elt(&mut self, idx: usize, f: F) -> Result 751 | where F: FnOnce(&mut Self) -> Result; 752 | 753 | /// Read an associative container (map). 754 | /// 755 | /// * `f` is a function that will be passed the number of entries in the 756 | /// map, and will call `read_map_elt_key` and `read_map_elt_val` to decode 757 | /// each entry. 758 | fn read_map(&mut self, f: F) -> Result 759 | where F: FnOnce(&mut Self, usize) -> Result; 760 | 761 | /// Read the key for an entry in a map. 762 | /// 763 | /// This should only be called from a function passed to `read_map`. 764 | /// 765 | /// * `idx` is the (zero-based) index of the entry in the map 766 | /// * `f` is a function that will call the appropriate read method to decode 767 | /// the key. 768 | /// 769 | /// Note that map entries must be read in order - starting with index `0` 770 | /// and finishing with index `len-1` - and for each entry, the key should be 771 | /// read followed immediately by the value. 772 | fn read_map_elt_key(&mut self, idx: usize, f: F) 773 | -> Result 774 | where F: FnOnce(&mut Self) -> Result; 775 | 776 | /// Read the value for an entry in a map. 777 | /// 778 | /// This should only be called from a function passed to `read_map`. 779 | /// 780 | /// * `idx` is the (zero-based) index of the entry in the map 781 | /// * `f` is a function that will call the appropriate read method to decode 782 | /// the value. 783 | /// 784 | /// Note that map entries must be read in order - starting with index `0` 785 | /// and finishing with index `len-1` - and for each entry, the key should be 786 | /// read followed immediately by the value. 787 | fn read_map_elt_val(&mut self, idx: usize, f: F) 788 | -> Result 789 | where F: FnOnce(&mut Self) -> Result; 790 | 791 | // Failure 792 | /// Record a decoding error. 793 | /// 794 | /// This allows `Decodable` implementations to report an error using a 795 | /// `Decoder` implementation's error type when inconsistent data is read. 796 | /// For example, when reading a fixed-length array and the wrong length is 797 | /// given by `read_seq`. 798 | fn error(&mut self, err: &str) -> Self::Error; 799 | } 800 | 801 | /// Trait for serializing a type. 802 | /// 803 | /// This can be implemented for custom data types to allow them to be encoded 804 | /// with `Encoder` implementations. Most of Rust's built-in or standard data 805 | /// types (like `i32` and `Vec`) have `Encodable` implementations provided by 806 | /// this module. 807 | /// 808 | /// Note that, in general, you should let the compiler implement this for you by 809 | /// using the `derive(RustcEncodable)` attribute. 810 | /// 811 | /// # Examples 812 | /// 813 | /// ```rust 814 | /// extern crate rustc_serialize; 815 | /// 816 | /// #[derive(RustcEncodable)] 817 | /// struct Point { 818 | /// x: i32, 819 | /// y: i32, 820 | /// } 821 | /// # fn main() {} 822 | /// ``` 823 | /// 824 | /// This generates code equivalent to: 825 | /// 826 | /// ```rust 827 | /// extern crate rustc_serialize; 828 | /// use rustc_serialize::Encodable; 829 | /// use rustc_serialize::Encoder; 830 | /// 831 | /// struct Point { 832 | /// x: i32, 833 | /// y: i32, 834 | /// } 835 | /// 836 | /// impl Encodable for Point { 837 | /// fn encode(&self, s: &mut S) -> Result<(), S::Error> { 838 | /// s.emit_struct("Point", 2, |s| { 839 | /// try!(s.emit_struct_field("x", 0, |s| { 840 | /// s.emit_i32(self.x) 841 | /// })); 842 | /// try!(s.emit_struct_field("y", 1, |s| { 843 | /// s.emit_i32(self.y) 844 | /// })); 845 | /// Ok(()) 846 | /// }) 847 | /// } 848 | /// } 849 | /// # fn main() {} 850 | /// ``` 851 | pub trait Encodable { 852 | /// Serialize a value using an `Encoder`. 853 | fn encode(&self, s: &mut S) -> Result<(), S::Error>; 854 | } 855 | 856 | /// Trait for deserializing a type. 857 | /// 858 | /// This can be implemented for custom data types to allow them to be decoded 859 | /// with `Decoder` implementations. Most of Rust's built-in or standard data 860 | /// types (like `i32` and `Vec`) have `Decodable` implementations provided by 861 | /// this module. 862 | /// 863 | /// Note that, in general, you should let the compiler implement this for you by 864 | /// using the `derive(RustcDecodable)` attribute. 865 | /// 866 | /// # Examples 867 | /// 868 | /// ```rust 869 | /// extern crate rustc_serialize; 870 | /// 871 | /// #[derive(RustcDecodable)] 872 | /// struct Point { 873 | /// x: i32, 874 | /// y: i32, 875 | /// } 876 | /// # fn main() {} 877 | /// ``` 878 | /// 879 | /// This generates code equivalent to: 880 | /// 881 | /// ```rust 882 | /// extern crate rustc_serialize; 883 | /// use rustc_serialize::Decodable; 884 | /// use rustc_serialize::Decoder; 885 | /// 886 | /// struct Point { 887 | /// x: i32, 888 | /// y: i32, 889 | /// } 890 | /// 891 | /// impl Decodable for Point { 892 | /// fn decode(d: &mut D) -> Result { 893 | /// d.read_struct("Point", 2, |d| { 894 | /// let x = try!(d.read_struct_field("x", 0, |d| { d.read_i32() })); 895 | /// let y = try!(d.read_struct_field("y", 1, |d| { d.read_i32() })); 896 | /// Ok(Point{ x: x, y: y }) 897 | /// }) 898 | /// } 899 | /// } 900 | /// # fn main() {} 901 | /// ``` 902 | pub trait Decodable: Sized { 903 | /// Deserialize a value using a `Decoder`. 904 | fn decode(d: &mut D) -> Result; 905 | } 906 | 907 | impl Encodable for usize { 908 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 909 | s.emit_usize(*self) 910 | } 911 | } 912 | 913 | impl Decodable for usize { 914 | fn decode(d: &mut D) -> Result { 915 | d.read_usize() 916 | } 917 | } 918 | 919 | impl Encodable for u8 { 920 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 921 | s.emit_u8(*self) 922 | } 923 | } 924 | 925 | impl Decodable for u8 { 926 | fn decode(d: &mut D) -> Result { 927 | d.read_u8() 928 | } 929 | } 930 | 931 | impl Encodable for u16 { 932 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 933 | s.emit_u16(*self) 934 | } 935 | } 936 | 937 | impl Decodable for u16 { 938 | fn decode(d: &mut D) -> Result { 939 | d.read_u16() 940 | } 941 | } 942 | 943 | impl Encodable for u32 { 944 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 945 | s.emit_u32(*self) 946 | } 947 | } 948 | 949 | impl Decodable for u32 { 950 | fn decode(d: &mut D) -> Result { 951 | d.read_u32() 952 | } 953 | } 954 | 955 | impl Encodable for u64 { 956 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 957 | s.emit_u64(*self) 958 | } 959 | } 960 | 961 | impl Decodable for u64 { 962 | fn decode(d: &mut D) -> Result { 963 | d.read_u64() 964 | } 965 | } 966 | 967 | impl Encodable for isize { 968 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 969 | s.emit_isize(*self) 970 | } 971 | } 972 | 973 | impl Decodable for isize { 974 | fn decode(d: &mut D) -> Result { 975 | d.read_isize() 976 | } 977 | } 978 | 979 | impl Encodable for i8 { 980 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 981 | s.emit_i8(*self) 982 | } 983 | } 984 | 985 | impl Decodable for i8 { 986 | fn decode(d: &mut D) -> Result { 987 | d.read_i8() 988 | } 989 | } 990 | 991 | impl Encodable for i16 { 992 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 993 | s.emit_i16(*self) 994 | } 995 | } 996 | 997 | impl Decodable for i16 { 998 | fn decode(d: &mut D) -> Result { 999 | d.read_i16() 1000 | } 1001 | } 1002 | 1003 | impl Encodable for i32 { 1004 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1005 | s.emit_i32(*self) 1006 | } 1007 | } 1008 | 1009 | impl Decodable for i32 { 1010 | fn decode(d: &mut D) -> Result { 1011 | d.read_i32() 1012 | } 1013 | } 1014 | 1015 | impl Encodable for i64 { 1016 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1017 | s.emit_i64(*self) 1018 | } 1019 | } 1020 | 1021 | impl Decodable for i64 { 1022 | fn decode(d: &mut D) -> Result { 1023 | d.read_i64() 1024 | } 1025 | } 1026 | 1027 | impl Encodable for str { 1028 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1029 | s.emit_str(self) 1030 | } 1031 | } 1032 | 1033 | impl Encodable for String { 1034 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1035 | s.emit_str(self) 1036 | } 1037 | } 1038 | 1039 | impl Decodable for String { 1040 | fn decode(d: &mut D) -> Result { 1041 | d.read_str() 1042 | } 1043 | } 1044 | 1045 | impl Encodable for f32 { 1046 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1047 | s.emit_f32(*self) 1048 | } 1049 | } 1050 | 1051 | impl Decodable for f32 { 1052 | fn decode(d: &mut D) -> Result { 1053 | d.read_f32() 1054 | } 1055 | } 1056 | 1057 | impl Encodable for f64 { 1058 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1059 | s.emit_f64(*self) 1060 | } 1061 | } 1062 | 1063 | impl Decodable for f64 { 1064 | fn decode(d: &mut D) -> Result { 1065 | d.read_f64() 1066 | } 1067 | } 1068 | 1069 | impl Encodable for bool { 1070 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1071 | s.emit_bool(*self) 1072 | } 1073 | } 1074 | 1075 | impl Decodable for bool { 1076 | fn decode(d: &mut D) -> Result { 1077 | d.read_bool() 1078 | } 1079 | } 1080 | 1081 | impl Encodable for char { 1082 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1083 | s.emit_char(*self) 1084 | } 1085 | } 1086 | 1087 | impl Decodable for char { 1088 | fn decode(d: &mut D) -> Result { 1089 | d.read_char() 1090 | } 1091 | } 1092 | 1093 | impl Encodable for () { 1094 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1095 | s.emit_nil() 1096 | } 1097 | } 1098 | 1099 | impl Decodable for () { 1100 | fn decode(d: &mut D) -> Result<(), D::Error> { 1101 | d.read_nil() 1102 | } 1103 | } 1104 | 1105 | impl<'a, T: ?Sized + Encodable> Encodable for &'a T { 1106 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1107 | (**self).encode(s) 1108 | } 1109 | } 1110 | 1111 | impl Encodable for Box { 1112 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1113 | (**self).encode(s) 1114 | } 1115 | } 1116 | 1117 | impl< T: Decodable> Decodable for Box { 1118 | fn decode(d: &mut D) -> Result, D::Error> { 1119 | Ok(Box::new(try!(Decodable::decode(d)))) 1120 | } 1121 | } 1122 | 1123 | impl< T: Decodable> Decodable for Box<[T]> { 1124 | fn decode(d: &mut D) -> Result, D::Error> { 1125 | let v: Vec = try!(Decodable::decode(d)); 1126 | Ok(v.into_boxed_slice()) 1127 | } 1128 | } 1129 | 1130 | impl Encodable for Rc { 1131 | #[inline] 1132 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1133 | (**self).encode(s) 1134 | } 1135 | } 1136 | 1137 | impl Decodable for Rc { 1138 | #[inline] 1139 | fn decode(d: &mut D) -> Result, D::Error> { 1140 | Ok(Rc::new(try!(Decodable::decode(d)))) 1141 | } 1142 | } 1143 | 1144 | impl<'a, T:Encodable + ToOwned + ?Sized> Encodable for Cow<'a, T> { 1145 | #[inline] 1146 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1147 | (**self).encode(s) 1148 | } 1149 | } 1150 | 1151 | impl<'a, T: ?Sized> Decodable for Cow<'a, T> 1152 | where T: ToOwned, T::Owned: Decodable 1153 | { 1154 | #[inline] 1155 | fn decode(d: &mut D) -> Result, D::Error> { 1156 | Ok(Cow::Owned(try!(Decodable::decode(d)))) 1157 | } 1158 | } 1159 | 1160 | impl Encodable for [T] { 1161 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1162 | s.emit_seq(self.len(), |s| { 1163 | for (i, e) in self.iter().enumerate() { 1164 | try!(s.emit_seq_elt(i, |s| e.encode(s))) 1165 | } 1166 | Ok(()) 1167 | }) 1168 | } 1169 | } 1170 | 1171 | impl Encodable for Vec { 1172 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1173 | s.emit_seq(self.len(), |s| { 1174 | for (i, e) in self.iter().enumerate() { 1175 | try!(s.emit_seq_elt(i, |s| e.encode(s))) 1176 | } 1177 | Ok(()) 1178 | }) 1179 | } 1180 | } 1181 | 1182 | impl Decodable for Vec { 1183 | fn decode(d: &mut D) -> Result, D::Error> { 1184 | d.read_seq(|d, len| { 1185 | let mut v = Vec::with_capacity(cap_capacity::(len)); 1186 | for i in 0..len { 1187 | v.push(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); 1188 | } 1189 | Ok(v) 1190 | }) 1191 | } 1192 | } 1193 | 1194 | impl Encodable for Option { 1195 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1196 | s.emit_option(|s| { 1197 | match *self { 1198 | None => s.emit_option_none(), 1199 | Some(ref v) => s.emit_option_some(|s| v.encode(s)), 1200 | } 1201 | }) 1202 | } 1203 | } 1204 | 1205 | impl Decodable for Option { 1206 | fn decode(d: &mut D) -> Result, D::Error> { 1207 | d.read_option(|d, b| { 1208 | if b { 1209 | Ok(Some(try!(Decodable::decode(d)))) 1210 | } else { 1211 | Ok(None) 1212 | } 1213 | }) 1214 | } 1215 | } 1216 | 1217 | impl Encodable for Result { 1218 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1219 | s.emit_enum("Result", |s| { 1220 | match *self { 1221 | Ok(ref v) => { 1222 | s.emit_enum_variant("Ok", 0, 1, |s| { 1223 | try!(s.emit_enum_variant_arg(0, |s| { 1224 | v.encode(s) 1225 | })); 1226 | Ok(()) 1227 | }) 1228 | } 1229 | Err(ref v) => { 1230 | s.emit_enum_variant("Err", 1, 1, |s| { 1231 | try!(s.emit_enum_variant_arg(0, |s| { 1232 | v.encode(s) 1233 | })); 1234 | Ok(()) 1235 | }) 1236 | } 1237 | } 1238 | }) 1239 | } 1240 | } 1241 | 1242 | impl Decodable for Result { 1243 | fn decode(d: &mut D) -> Result, D::Error> { 1244 | d.read_enum("Result", |d| { 1245 | d.read_enum_variant(&["Ok", "Err"], |d, idx| { 1246 | match idx { 1247 | 0 => { 1248 | d.read_enum_variant_arg(0, |d| { 1249 | T::decode(d) 1250 | }).map(|v| Ok(v)) 1251 | } 1252 | 1 => { 1253 | d.read_enum_variant_arg(0, |d| { 1254 | E::decode(d) 1255 | }).map(|v| Err(v)) 1256 | } 1257 | _ => panic!("Internal error"), 1258 | } 1259 | }) 1260 | }) 1261 | } 1262 | } 1263 | 1264 | impl Encodable for PhantomData { 1265 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1266 | s.emit_nil() 1267 | } 1268 | } 1269 | 1270 | impl Decodable for PhantomData { 1271 | fn decode(_d: &mut D) -> Result, D::Error> { 1272 | Ok(PhantomData) 1273 | } 1274 | } 1275 | 1276 | macro_rules! peel { 1277 | ($name:ident, $($other:ident,)*) => (tuple! { $($other,)* }) 1278 | } 1279 | 1280 | /// Evaluates to the number of identifiers passed to it, for example: 1281 | /// `count_idents!(a, b, c) == 3 1282 | macro_rules! count_idents { 1283 | () => { 0 }; 1284 | ($_i:ident, $($rest:ident,)*) => { 1 + count_idents!($($rest,)*) } 1285 | } 1286 | 1287 | macro_rules! tuple { 1288 | () => (); 1289 | ( $($name:ident,)+ ) => ( 1290 | impl<$($name:Decodable),*> Decodable for ($($name,)*) { 1291 | fn decode(d: &mut D) -> Result<($($name,)*), D::Error> { 1292 | let len: usize = count_idents!($($name,)*); 1293 | d.read_tuple(len, |d| { 1294 | let mut i = 0; 1295 | let ret = ($(try!(d.read_tuple_arg({ i+=1; i-1 }, 1296 | |d| -> Result<$name,D::Error> { 1297 | Decodable::decode(d) 1298 | })),)*); 1299 | return Ok(ret); 1300 | }) 1301 | } 1302 | } 1303 | impl<$($name:Encodable),*> Encodable for ($($name,)*) { 1304 | #[allow(non_snake_case)] 1305 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1306 | let ($(ref $name,)*) = *self; 1307 | let mut n = 0; 1308 | $(let $name = $name; n += 1;)* 1309 | s.emit_tuple(n, |s| { 1310 | let mut i = 0; 1311 | $(try!(s.emit_tuple_arg({ i+=1; i-1 }, |s| $name.encode(s)));)* 1312 | Ok(()) 1313 | }) 1314 | } 1315 | } 1316 | peel! { $($name,)* } 1317 | ) 1318 | } 1319 | 1320 | tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, } 1321 | 1322 | macro_rules! array { 1323 | () => (); 1324 | ($len:expr, $($idx:expr,)*) => { 1325 | impl Decodable for [T; $len] { 1326 | fn decode(d: &mut D) -> Result<[T; $len], D::Error> { 1327 | d.read_seq(|d, len| { 1328 | if len != $len { 1329 | return Err(d.error("wrong array length")); 1330 | } 1331 | Ok([$( 1332 | try!(d.read_seq_elt($len - $idx - 1, 1333 | |d| Decodable::decode(d))) 1334 | ),*]) 1335 | }) 1336 | } 1337 | } 1338 | 1339 | impl Encodable for [T; $len] { 1340 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1341 | s.emit_seq($len, |s| { 1342 | for i in 0..$len { 1343 | try!(s.emit_seq_elt(i, |s| self[i].encode(s))); 1344 | } 1345 | Ok(()) 1346 | }) 1347 | } 1348 | } 1349 | array! { $($idx,)* } 1350 | } 1351 | } 1352 | 1353 | array! { 1354 | 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 1355 | 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1356 | } 1357 | 1358 | impl Encodable for path::Path { 1359 | #[cfg(target_os = "redox")] 1360 | fn encode(&self, e: &mut S) -> Result<(), S::Error> { 1361 | self.as_os_str().to_str().unwrap().encode(e) 1362 | } 1363 | #[cfg(unix)] 1364 | fn encode(&self, e: &mut S) -> Result<(), S::Error> { 1365 | use std::os::unix::prelude::*; 1366 | self.as_os_str().as_bytes().encode(e) 1367 | } 1368 | #[cfg(windows)] 1369 | fn encode(&self, e: &mut S) -> Result<(), S::Error> { 1370 | use std::os::windows::prelude::*; 1371 | let v = self.as_os_str().encode_wide().collect::>(); 1372 | v.encode(e) 1373 | } 1374 | } 1375 | 1376 | impl Encodable for path::PathBuf { 1377 | fn encode(&self, e: &mut S) -> Result<(), S::Error> { 1378 | (**self).encode(e) 1379 | } 1380 | } 1381 | 1382 | impl Decodable for path::PathBuf { 1383 | #[cfg(target_os = "redox")] 1384 | fn decode(d: &mut D) -> Result { 1385 | let string: String = try!(Decodable::decode(d)); 1386 | let s: OsString = OsString::from(string); 1387 | let mut p = path::PathBuf::new(); 1388 | p.push(s); 1389 | Ok(p) 1390 | } 1391 | #[cfg(unix)] 1392 | fn decode(d: &mut D) -> Result { 1393 | use std::os::unix::prelude::*; 1394 | let bytes: Vec = try!(Decodable::decode(d)); 1395 | let s: OsString = OsStringExt::from_vec(bytes); 1396 | let mut p = path::PathBuf::new(); 1397 | p.push(s); 1398 | Ok(p) 1399 | } 1400 | #[cfg(windows)] 1401 | fn decode(d: &mut D) -> Result { 1402 | use std::os::windows::prelude::*; 1403 | let bytes: Vec = try!(Decodable::decode(d)); 1404 | let s: OsString = OsStringExt::from_wide(&bytes); 1405 | let mut p = path::PathBuf::new(); 1406 | p.push(s); 1407 | Ok(p) 1408 | } 1409 | } 1410 | 1411 | impl Encodable for Cell { 1412 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1413 | self.get().encode(s) 1414 | } 1415 | } 1416 | 1417 | impl Decodable for Cell { 1418 | fn decode(d: &mut D) -> Result, D::Error> { 1419 | Ok(Cell::new(try!(Decodable::decode(d)))) 1420 | } 1421 | } 1422 | 1423 | // FIXME: #15036 1424 | // Should use `try_borrow`, returning a 1425 | // `encoder.error("attempting to Encode borrowed RefCell")` 1426 | // from `encode` when `try_borrow` returns `None`. 1427 | 1428 | impl Encodable for RefCell { 1429 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1430 | self.borrow().encode(s) 1431 | } 1432 | } 1433 | 1434 | impl Decodable for RefCell { 1435 | fn decode(d: &mut D) -> Result, D::Error> { 1436 | Ok(RefCell::new(try!(Decodable::decode(d)))) 1437 | } 1438 | } 1439 | 1440 | impl Encodable for Arc { 1441 | fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1442 | (**self).encode(s) 1443 | } 1444 | } 1445 | 1446 | impl Decodable for Arc { 1447 | fn decode(d: &mut D) -> Result, D::Error> { 1448 | Ok(Arc::new(try!(Decodable::decode(d)))) 1449 | } 1450 | } 1451 | 1452 | // ___________________________________________________________________________ 1453 | // Helper routines 1454 | 1455 | /// Trait with helper functions for implementing `Encodable`. 1456 | /// 1457 | /// This trait is implemented for everything that implements `Encoder`. 1458 | /// `Encodable` implementations can make use of it to make their implementations 1459 | /// easier. 1460 | pub trait EncoderHelpers: Encoder { 1461 | /// Emit a vector as a sequence. 1462 | /// 1463 | /// Storing sequences as vectors is a common pattern. This method makes 1464 | /// encoding such sequences easier by wrapping the calls to 1465 | /// `Encoder::emit_seq` and `Encoder::emit_seq_elt`. 1466 | /// 1467 | /// # Examples 1468 | /// 1469 | /// ``` 1470 | /// use rustc_serialize::Encodable; 1471 | /// use rustc_serialize::Encoder; 1472 | /// use rustc_serialize::EncoderHelpers; 1473 | /// 1474 | /// struct NumberSequence { 1475 | /// elements: Vec, 1476 | /// } 1477 | /// 1478 | /// impl Encodable for NumberSequence { 1479 | /// fn encode(&self, s: &mut S) -> Result<(), S::Error> { 1480 | /// s.emit_struct("NumberSequence", 1, |s| { 1481 | /// s.emit_struct_field("elements", 0, |s| { 1482 | /// s.emit_from_vec(&self.elements, |s,e| { 1483 | /// s.emit_i32(*e) 1484 | /// }) 1485 | /// }) 1486 | /// }) 1487 | /// } 1488 | /// } 1489 | /// ``` 1490 | fn emit_from_vec(&mut self, v: &[T], f: F) 1491 | -> Result<(), ::Error> 1492 | where F: FnMut(&mut Self, &T) -> Result<(), ::Error>; 1493 | } 1494 | 1495 | impl EncoderHelpers for S { 1496 | fn emit_from_vec(&mut self, v: &[T], mut f: F) -> Result<(), S::Error> where 1497 | F: FnMut(&mut S, &T) -> Result<(), S::Error>, 1498 | { 1499 | self.emit_seq(v.len(), |this| { 1500 | for (i, e) in v.iter().enumerate() { 1501 | try!(this.emit_seq_elt(i, |this| { 1502 | f(this, e) 1503 | })); 1504 | } 1505 | Ok(()) 1506 | }) 1507 | } 1508 | } 1509 | 1510 | /// Trait with helper functions for implementing `Decodable`. 1511 | /// 1512 | /// This trait is implemented for everything that implements `Decoder`. 1513 | /// `Decodable` implementations can make use of it to make their implementations 1514 | /// easier. 1515 | pub trait DecoderHelpers: Decoder { 1516 | /// Read a sequence into a vector. 1517 | /// 1518 | /// Storing sequences as vectors is a common pattern. This method makes 1519 | /// deserializing such sequences easier by wrapping the calls to 1520 | /// `Decoder::read_seq` and `Decoder::read_seq_elt`. 1521 | /// 1522 | /// # Examples 1523 | /// 1524 | /// ``` 1525 | /// use rustc_serialize::Decodable; 1526 | /// use rustc_serialize::Decoder; 1527 | /// use rustc_serialize::DecoderHelpers; 1528 | /// 1529 | /// struct NumberSequence { 1530 | /// elements: Vec, 1531 | /// } 1532 | /// 1533 | /// impl Decodable for NumberSequence { 1534 | /// fn decode(d: &mut D) -> Result { 1535 | /// d.read_struct("NumberSequence", 2, |d| { 1536 | /// Ok(NumberSequence{ 1537 | /// elements: try!(d.read_struct_field("elements", 0, |d| { 1538 | /// d.read_to_vec(|d| { d.read_i32() }) 1539 | /// })) 1540 | /// }) 1541 | /// }) 1542 | /// } 1543 | /// } 1544 | /// ``` 1545 | fn read_to_vec(&mut self, f: F) 1546 | -> Result, ::Error> where 1547 | F: FnMut(&mut Self) -> Result::Error>; 1548 | } 1549 | 1550 | impl DecoderHelpers for D { 1551 | fn read_to_vec(&mut self, mut f: F) -> Result, D::Error> where F: 1552 | FnMut(&mut D) -> Result, 1553 | { 1554 | self.read_seq(|this, len| { 1555 | let mut v = Vec::with_capacity(cap_capacity::(len)); 1556 | for i in 0..len { 1557 | v.push(try!(this.read_seq_elt(i, |this| f(this)))); 1558 | } 1559 | Ok(v) 1560 | }) 1561 | } 1562 | } 1563 | 1564 | #[test] 1565 | #[allow(unused_variables)] 1566 | fn capacity_rules() { 1567 | use std::usize::MAX; 1568 | use std::collections::{HashMap, HashSet}; 1569 | 1570 | struct MyDecoder; 1571 | impl Decoder for MyDecoder { 1572 | type Error = (); 1573 | 1574 | // Primitive types: 1575 | fn read_nil(&mut self) -> Result<(), Self::Error> { Err(()) } 1576 | fn read_usize(&mut self) -> Result { Err(()) } 1577 | fn read_u64(&mut self) -> Result { Err(()) } 1578 | fn read_u32(&mut self) -> Result { Err(()) } 1579 | fn read_u16(&mut self) -> Result { Err(()) } 1580 | fn read_u8(&mut self) -> Result { Err(()) } 1581 | fn read_isize(&mut self) -> Result { Err(()) } 1582 | fn read_i64(&mut self) -> Result { Err(()) } 1583 | fn read_i32(&mut self) -> Result { Err(()) } 1584 | fn read_i16(&mut self) -> Result { Err(()) } 1585 | fn read_i8(&mut self) -> Result { Err(()) } 1586 | fn read_bool(&mut self) -> Result { Err(()) } 1587 | fn read_f64(&mut self) -> Result { Err(()) } 1588 | fn read_f32(&mut self) -> Result { Err(()) } 1589 | fn read_char(&mut self) -> Result { Err(()) } 1590 | fn read_str(&mut self) -> Result { Err(()) } 1591 | 1592 | // Compound types: 1593 | fn read_enum(&mut self, name: &str, f: F) -> Result 1594 | where F: FnOnce(&mut Self) -> Result { Err(()) } 1595 | 1596 | fn read_enum_variant(&mut self, names: &[&str], f: F) 1597 | -> Result 1598 | where F: FnMut(&mut Self, usize) -> Result { Err(()) } 1599 | fn read_enum_variant_arg(&mut self, a_idx: usize, f: F) 1600 | -> Result 1601 | where F: FnOnce(&mut Self) -> Result { Err(()) } 1602 | 1603 | fn read_enum_struct_variant(&mut self, names: &[&str], f: F) 1604 | -> Result 1605 | where F: FnMut(&mut Self, usize) -> Result { Err(()) } 1606 | fn read_enum_struct_variant_field(&mut self, 1607 | f_name: &str, 1608 | f_idx: usize, 1609 | f: F) 1610 | -> Result 1611 | where F: FnOnce(&mut Self) -> Result { Err(()) } 1612 | 1613 | fn read_struct(&mut self, s_name: &str, len: usize, f: F) 1614 | -> Result 1615 | where F: FnOnce(&mut Self) -> Result { Err(()) } 1616 | fn read_struct_field(&mut self, 1617 | f_name: &str, 1618 | f_idx: usize, 1619 | f: F) 1620 | -> Result 1621 | where F: FnOnce(&mut Self) -> Result { Err(()) } 1622 | 1623 | fn read_tuple(&mut self, len: usize, f: F) -> Result 1624 | where F: FnOnce(&mut Self) -> Result { Err(()) } 1625 | fn read_tuple_arg(&mut self, a_idx: usize, f: F) 1626 | -> Result 1627 | where F: FnOnce(&mut Self) -> Result { Err(()) } 1628 | 1629 | fn read_tuple_struct(&mut self, s_name: &str, len: usize, f: F) 1630 | -> Result 1631 | where F: FnOnce(&mut Self) -> Result { Err(()) } 1632 | fn read_tuple_struct_arg(&mut self, a_idx: usize, f: F) 1633 | -> Result 1634 | where F: FnOnce(&mut Self) -> Result { Err(()) } 1635 | 1636 | // Specialized types: 1637 | fn read_option(&mut self, f: F) -> Result 1638 | where F: FnMut(&mut Self, bool) -> Result { Err(()) } 1639 | 1640 | fn read_seq(&mut self, f: F) -> Result 1641 | where F: FnOnce(&mut Self, usize) -> Result { 1642 | f(self, MAX) 1643 | } 1644 | fn read_seq_elt(&mut self, idx: usize, f: F) -> Result 1645 | where F: FnOnce(&mut Self) -> Result { Err(()) } 1646 | 1647 | fn read_map(&mut self, f: F) -> Result 1648 | where F: FnOnce(&mut Self, usize) -> Result { 1649 | f(self, MAX) 1650 | } 1651 | fn read_map_elt_key(&mut self, idx: usize, f: F) 1652 | -> Result 1653 | where F: FnOnce(&mut Self) -> Result { Err(()) } 1654 | fn read_map_elt_val(&mut self, idx: usize, f: F) 1655 | -> Result 1656 | where F: FnOnce(&mut Self) -> Result { Err(()) } 1657 | 1658 | // Failure 1659 | fn error(&mut self, err: &str) -> Self::Error { () } 1660 | } 1661 | 1662 | let mut dummy = MyDecoder; 1663 | let vec_result: Result, ()> = Decodable::decode(&mut dummy); 1664 | assert!(vec_result.is_err()); 1665 | 1666 | let map_result: Result, ()> = Decodable::decode(&mut dummy); 1667 | assert!(map_result.is_err()); 1668 | 1669 | let set_result: Result, ()> = Decodable::decode(&mut dummy); 1670 | assert!(set_result.is_err()); 1671 | } 1672 | --------------------------------------------------------------------------------