My working unpac space for OCaml projects in development
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge git/patches/serde_ipld_dagcbor

+5247
+5
vendor/git/serde_ipld_dagcbor/.editorconfig
··· 1 + # see https://editorconfig.org for more options, and setup instructions for yours editor 2 + 3 + [*.rs] 4 + indent_style = space 5 + indent_size = 4
+6
vendor/git/serde_ipld_dagcbor/.github/dependabot.yml
··· 1 + version: 2 2 + updates: 3 + - package-ecosystem: "github-actions" 4 + directory: "/" 5 + schedule: 6 + interval: "weekly"
+53
vendor/git/serde_ipld_dagcbor/.github/workflows/build.yml
··· 1 + name: build 2 + 3 + on: [push, pull_request] 4 + 5 + jobs: 6 + build: 7 + name: Build 8 + strategy: 9 + fail-fast: false 10 + matrix: 11 + platform: [ubuntu-latest, macos-latest, windows-latest] 12 + toolchain: [stable] 13 + runs-on: ${{ matrix.platform }} 14 + 15 + steps: 16 + - name: Checkout Sources 17 + uses: actions/checkout@v6 18 + 19 + - name: Cache Dependencies & Build Outputs 20 + uses: actions/cache@v5 21 + with: 22 + path: ~/.cargo 23 + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} 24 + 25 + - name: Install Rust Toolchain 26 + uses: dtolnay/rust-toolchain@master 27 + with: 28 + toolchain: ${{ matrix.toolchain }} 29 + components: rustfmt, clippy 30 + 31 + - name: Check Code Format 32 + run: cargo fmt --all -- --check 33 + 34 + - name: Code lint with default features 35 + run: cargo clippy --all-targets --workspace -- -D warnings 36 + 37 + - name: Code lint without default features 38 + run: cargo clippy --all-targets --workspace --no-default-features -- -D warnings 39 + 40 + - name: Code lint with all features 41 + run: cargo clippy --all-targets --workspace --all-features -- -D warnings 42 + 43 + - name: Test with default features 44 + run: cargo test --all-targets --workspace 45 + 46 + - name: Test without default features 47 + run: cargo test --all-targets --workspace --no-default-features 48 + 49 + - name: Test with all features 50 + run: cargo test --all-targets --workspace --all-features 51 + 52 + - name: Test no-cid-as-bytes feature 53 + run: cargo test --all-targets --workspace --features no-cid-as-bytes
+14
vendor/git/serde_ipld_dagcbor/.github/workflows/generated-pr.yml
··· 1 + name: Close Generated PRs 2 + 3 + on: 4 + schedule: 5 + - cron: '0 0 * * *' 6 + workflow_dispatch: 7 + 8 + permissions: 9 + issues: write 10 + pull-requests: write 11 + 12 + jobs: 13 + stale: 14 + uses: ipdxco/unified-github-workflows/.github/workflows/reusable-generated-pr.yml@v1
+14
vendor/git/serde_ipld_dagcbor/.github/workflows/stale.yml
··· 1 + name: Close Stale Issues 2 + 3 + on: 4 + schedule: 5 + - cron: '0 0 * * *' 6 + workflow_dispatch: 7 + 8 + permissions: 9 + issues: write 10 + pull-requests: write 11 + 12 + jobs: 13 + stale: 14 + uses: ipdxco/unified-github-workflows/.github/workflows/reusable-stale-issue.yml@v1
+8
vendor/git/serde_ipld_dagcbor/.gitignore
··· 1 + target 2 + Cargo.lock 3 + *.rs.bk 4 + tokamak.toml 5 + .idea 6 + *.iml 7 + examples/ferris.cbor 8 + .cargo/config
+38
vendor/git/serde_ipld_dagcbor/Cargo.toml
··· 1 + [package] 2 + name = "serde_ipld_dagcbor" 3 + version = "0.6.4" 4 + authors = [ 5 + "Pyfisch <pyfisch@posteo.org>", 6 + "Steven Fackler <sfackler@gmail.com>", 7 + "Volker Mische <volker.mische@gmail.com>" 8 + ] 9 + repository = "https://github.com/ipld/serde_ipld_dagcbor" 10 + readme = "README.md" 11 + license = "MIT/Apache-2.0" 12 + description = "IPLD DAG-CBOR support for Serde." 13 + keywords = ["serde", "cbor", "serialization", "no_std"] 14 + categories = ["encoding"] 15 + edition = "2018" 16 + 17 + [dependencies] 18 + cbor4ii = { version = "0.2.14", default-features = false, features = ["use_alloc"] } 19 + ipld-core = { version = "0.4.2", default-features = false, features = ["serde"] } 20 + scopeguard = { version = "1.1.0", default-features = false } 21 + serde = { version = "1.0.164", default-features = false, features = ["alloc"] } 22 + 23 + [dev-dependencies] 24 + serde_derive = { version = "1.0.164", default-features = false } 25 + serde_bytes = { version = "0.11.9", default-features = false, features = ["alloc"]} 26 + serde-transcode = "1.1.1" 27 + const-hex = "1.14.0" 28 + serde_tuple = "1.1.0" 29 + # We need the RC feature to test a trait edge-case. 30 + serde = { version = "1.0.164", default-features = false, features = ["rc"] } 31 + 32 + [features] 33 + default = ["codec", "std"] 34 + std = ["cbor4ii/use_std", "ipld-core/std", "serde/std", "serde_bytes/std"] 35 + # Enable the `Codec` trait implementation. It's a separate feature as it needs Rust >= 1.75. 36 + codec = ["ipld-core/codec"] 37 + # Prevent deserializing CIDs as bytes as much as possible. 38 + no-cid-as-bytes = []
+201
vendor/git/serde_ipld_dagcbor/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.
+19
vendor/git/serde_ipld_dagcbor/LICENSE-MIT
··· 1 + Copyright (c) 2015 Pyfisch 2 + 3 + Permission is hereby granted, free of charge, to any person obtaining a copy 4 + of this software and associated documentation files (the "Software"), to deal 5 + in the Software without restriction, including without limitation the rights 6 + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 + copies of the Software, and to permit persons to whom the Software is 8 + furnished to do so, subject to the following conditions: 9 + 10 + The above copyright notice and this permission notice shall be included in 11 + all copies or substantial portions of the Software. 12 + 13 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 + THE SOFTWARE.
+93
vendor/git/serde_ipld_dagcbor/README.md
··· 1 + Serde IPLD DAG-CBOR 2 + =================== 3 + 4 + [![Crates.io](https://img.shields.io/crates/v/serde_ipld_dagcbor.svg)](https://crates.io/crates/serde_ipld_dagcbor) 5 + [![Documentation](https://docs.rs/serde_ipld_dagcbor/badge.svg)](https://docs.rs/serde_ipld_dagcbor) 6 + 7 + This is a [Serde] implementation for [DAG-CBOR]. It can be use in conjunction with [ipld-core]. 8 + 9 + The underlying library for CBOR encoding/decoding is [cbor4ii]. Their Serde implementation is used as a basis. A copy of their code was copied into this repo on April 2022 and is used under the MIT/Apache-2.0 license, with permission from [@quininer]. 10 + 11 + This crate started as a fork of [serde_cbor], thanks everyone involved there. 12 + 13 + [Serde]: https://github.com/serde-rs/serde 14 + [DAG-CBOR]: https://ipld.io/specs/codecs/dag-cbor/spec/ 15 + [ipld-core]: https://github.com/ipld/rust-ipld-core 16 + [cbor4ii]: https://github.com/quininer/cbor4ii 17 + [@quininer]: https://github.com/quininer/ 18 + [serde_cbor]: https://github.com/pyfisch/cbor 19 + 20 + 21 + Usage 22 + ----- 23 + 24 + Storing and loading Rust types is easy and requires only 25 + minimal modifications to the program code. 26 + 27 + ```rust 28 + use serde_derive::{Deserialize, Serialize}; 29 + use std::error::Error; 30 + use std::fs::File; 31 + use std::io::BufReader; 32 + 33 + // Types annotated with `Serialize` can be stored as DAG-CBOR. 34 + // To be able to load them again add `Deserialize`. 35 + #[derive(Debug, Serialize, Deserialize)] 36 + struct Mascot { 37 + name: String, 38 + species: String, 39 + year_of_birth: u32, 40 + } 41 + 42 + fn main() -> Result<(), Box<dyn Error>> { 43 + let ferris = Mascot { 44 + name: "Ferris".to_owned(), 45 + species: "crab".to_owned(), 46 + year_of_birth: 2015, 47 + }; 48 + 49 + let ferris_file = File::create("examples/ferris.cbor")?; 50 + // Write Ferris to the given file. 51 + // Instead of a file you can use any type that implements `io::Write` 52 + // like a HTTP body, database connection etc. 53 + serde_ipld_dagcbor::to_writer(ferris_file, &ferris)?; 54 + 55 + let tux_file = File::open("examples/tux.cbor")?; 56 + let tux_reader = BufReader::new(tux_file); 57 + // Load Tux from a file. 58 + // Serde IPLD DAG-CBOR performs roundtrip serialization meaning that 59 + // the data will not change in any way. 60 + let tux: Mascot = serde_ipld_dagcbor::from_reader(tux_reader)?; 61 + 62 + println!("{:?}", tux); 63 + // prints: Mascot { name: "Tux", species: "penguin", year_of_birth: 1996 } 64 + 65 + Ok(()) 66 + } 67 + ``` 68 + 69 + 70 + Features 71 + -------- 72 + 73 + ### `codec` 74 + 75 + The `codec` feature is enabled by default, it provides the `Codec` trait, which enables encoding and decoding independent of the IPLD Codec. The minimum supported Rust version (MSRV) can significantly be reduced to 1.64 by disabling this feature. 76 + 77 + 78 + ### `no-cid-as-bytes` 79 + 80 + Sometimes it is desired that a CID is not accidentally deserialized into bytes. This can happen because the intermediate serde data model does not retain enough information to be able to differentiate between a bytes container and a CID container when there is a conflicting choice to be made, as in the case of some enum cases. The `no-cid-as-bytes` feature can be enabled in order to error at runtime in such cases. 81 + 82 + The problem with that feature is, that it breaks Serde's derive attributes for [internally tagged enums](https://serde.rs/enum-representations.html#internally-tagged) (`#[serde(tag = "sometag")]`) and [untagged enums](https://serde.rs/enum-representations.html#untagged) (`#serde(untagged)`). If this feature is enabled and you still need similar functionality, you could implement a deserializer manually. Examples of how to do that are in the [enum example](examples/enums.rs). 83 + 84 + 85 + License 86 + ------- 87 + 88 + Licensed under either of 89 + 90 + * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) 91 + * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) 92 + 93 + at your option.
+137
vendor/git/serde_ipld_dagcbor/examples/enums.rs
··· 1 + /// Serde untagged (`#[serde(untagged)]`) and internaly tagged enums (`#[serde(tag = "tag")]`) are 2 + /// not supported by CIDs. Here examples are provided on how to implement similar behaviour. This 3 + /// file also contains an example for a kinded enum. 4 + use std::convert::{TryFrom, TryInto}; 5 + 6 + use ipld_core::{cid::Cid, ipld::Ipld}; 7 + use serde::{de, Deserialize}; 8 + use serde_bytes::ByteBuf; 9 + use serde_ipld_dagcbor::from_slice; 10 + 11 + /// The CID `bafkreibme22gw2h7y2h7tg2fhqotaqjucnbc24deqo72b6mkl2egezxhvy` encoded as CBOR 12 + /// 42(h'00015512202C26B46B68FFC68FF99B453C1D30413413422D706483BFA0F98A5E886266E7AE') 13 + const CBOR_CID_FIXTURE: [u8; 41] = [ 14 + 0xd8, 0x2a, 0x58, 0x25, 0x00, 0x01, 0x55, 0x12, 0x20, 0x2c, 0x26, 0xb4, 0x6b, 0x68, 0xff, 0xc6, 15 + 0x8f, 0xf9, 0x9b, 0x45, 0x3c, 0x1d, 0x30, 0x41, 0x34, 0x13, 0x42, 0x2d, 0x70, 0x64, 0x83, 0xbf, 16 + 0xa0, 0xf9, 0x8a, 0x5e, 0x88, 0x62, 0x66, 0xe7, 0xae, 17 + ]; 18 + 19 + /// This enum shows how an internally tagged enum could be implemented. 20 + #[derive(Debug, PartialEq)] 21 + enum CidInInternallyTaggedEnum { 22 + MyCid { cid: Cid }, 23 + } 24 + 25 + // This manual deserializer implementation works as if you would derive `Deserialize` and add 26 + // `#[serde(tag = "type")]` to the `CidInternallyTaggedEnum` enum. 27 + impl<'de> de::Deserialize<'de> for CidInInternallyTaggedEnum { 28 + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 29 + where 30 + D: de::Deserializer<'de>, 31 + { 32 + #[derive(Deserialize)] 33 + struct Tagged { 34 + r#type: String, 35 + cid: Cid, 36 + } 37 + 38 + let Tagged { r#type, cid } = Deserialize::deserialize(deserializer)?; 39 + if r#type == "MyCid" { 40 + Ok(CidInInternallyTaggedEnum::MyCid { cid }) 41 + } else { 42 + Err(de::Error::custom("No matching enum variant found")) 43 + } 44 + } 45 + } 46 + 47 + /// This enum shows how an untagged enum could be implemented. 48 + #[derive(Debug, PartialEq)] 49 + enum CidInUntaggedEnum { 50 + MyCid(Cid), 51 + } 52 + 53 + // This manual deserializer implementation works as if you would derive `Deserialize` and add 54 + // `#[serde(untagged)]`. 55 + impl<'de> de::Deserialize<'de> for CidInUntaggedEnum { 56 + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 57 + where 58 + D: de::Deserializer<'de>, 59 + { 60 + Cid::deserialize(deserializer) 61 + .map(CidInUntaggedEnum::MyCid) 62 + .map_err(|_| de::Error::custom("No matching enum variant found")) 63 + } 64 + } 65 + 66 + /// This enum shows how a kinded enum could be implemented. 67 + #[derive(Debug, PartialEq)] 68 + pub enum Kinded { 69 + Bytes(ByteBuf), 70 + Link(Cid), 71 + } 72 + 73 + impl TryFrom<Ipld> for Kinded { 74 + type Error = (); 75 + 76 + fn try_from(ipld: Ipld) -> Result<Self, Self::Error> { 77 + match ipld { 78 + Ipld::Bytes(bytes) => Ok(Self::Bytes(ByteBuf::from(bytes))), 79 + Ipld::Link(cid) => Ok(Self::Link(cid)), 80 + _ => Err(()), 81 + } 82 + } 83 + } 84 + 85 + impl<'de> de::Deserialize<'de> for Kinded { 86 + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 87 + where 88 + D: de::Deserializer<'de>, 89 + { 90 + Ipld::deserialize(deserializer).and_then(|ipld| { 91 + ipld.try_into() 92 + .map_err(|_| de::Error::custom("No matching enum variant found")) 93 + }) 94 + } 95 + } 96 + 97 + pub fn main() { 98 + let cid: Cid = from_slice(&CBOR_CID_FIXTURE).unwrap(); 99 + 100 + // {"type": "MyCid", "cid": 42(h'00015512202C26B46B68FFC68FF99B453C1D30413413422D706483BFA0F98A5E886266E7AE')} 101 + let cbor_internally_tagged_enum = [ 102 + &[ 103 + 0xa2, 0x64, 0x74, 0x79, 0x70, 0x65, 0x65, 0x4d, 0x79, 0x43, 0x69, 0x64, 0x63, 0x63, 104 + 0x69, 0x64, 105 + ], 106 + &CBOR_CID_FIXTURE[..], 107 + ] 108 + .concat(); 109 + assert_eq!( 110 + from_slice::<CidInInternallyTaggedEnum>(&cbor_internally_tagged_enum).unwrap(), 111 + CidInInternallyTaggedEnum::MyCid { cid } 112 + ); 113 + 114 + assert_eq!( 115 + from_slice::<CidInUntaggedEnum>(&CBOR_CID_FIXTURE).unwrap(), 116 + CidInUntaggedEnum::MyCid(cid) 117 + ); 118 + 119 + assert_eq!( 120 + from_slice::<Kinded>(&CBOR_CID_FIXTURE).unwrap(), 121 + Kinded::Link(cid) 122 + ); 123 + 124 + // The CID without the tag 42 prefix, so that it decodes as just bytes. 125 + let cbor_bytes = &CBOR_CID_FIXTURE[2..]; 126 + let decoded_bytes: Kinded = from_slice(cbor_bytes).unwrap(); 127 + // The CBOR decoded bytes don't contain the prefix with the bytes type identifier and the 128 + // length. 129 + let bytes = cbor_bytes[2..].to_vec(); 130 + assert_eq!(decoded_bytes, Kinded::Bytes(ByteBuf::from(bytes))); 131 + } 132 + 133 + // Make it possible to run this example as test. 134 + #[test] 135 + fn test_main() { 136 + main() 137 + }
+50
vendor/git/serde_ipld_dagcbor/examples/readme.rs
··· 1 + // NOTE: This file should be kept in sync with README.md 2 + 3 + #[cfg(feature = "std")] 4 + use serde_derive::{Deserialize, Serialize}; 5 + #[cfg(feature = "std")] 6 + use std::error::Error; 7 + #[cfg(feature = "std")] 8 + use std::fs::File; 9 + #[cfg(feature = "std")] 10 + use std::io::BufReader; 11 + 12 + // Types annotated with `Serialize` can be stored as DAG-CBOR. 13 + // To be able to load them again add `Deserialize`. 14 + #[cfg(feature = "std")] 15 + #[derive(Debug, Serialize, Deserialize)] 16 + struct Mascot { 17 + name: String, 18 + species: String, 19 + year_of_birth: u32, 20 + } 21 + 22 + #[cfg(feature = "std")] 23 + fn main() -> Result<(), Box<dyn Error>> { 24 + let ferris = Mascot { 25 + name: "Ferris".to_owned(), 26 + species: "crab".to_owned(), 27 + year_of_birth: 2015, 28 + }; 29 + 30 + let ferris_file = File::create("examples/ferris.cbor")?; 31 + // Write Ferris to the given file. 32 + // Instead of a file you can use any type that implements `io::Write` 33 + // like a HTTP body, database connection etc. 34 + serde_ipld_dagcbor::to_writer(ferris_file, &ferris)?; 35 + 36 + let tux_file = File::open("examples/tux.cbor")?; 37 + let tux_reader = BufReader::new(tux_file); 38 + // Load Tux from a file. 39 + // Serde IPLD DAG-CBOR performs roundtrip serialization meaning that 40 + // the data will not change in any way. 41 + let tux: Mascot = serde_ipld_dagcbor::from_reader(tux_reader)?; 42 + 43 + println!("{:?}", tux); 44 + // prints: Mascot { name: "Tux", species: "penguin", year_of_birth: 1996 } 45 + 46 + Ok(()) 47 + } 48 + 49 + #[cfg(not(feature = "std"))] 50 + fn main() {}
+1
vendor/git/serde_ipld_dagcbor/examples/tux.cbor
··· 1 + �dnamecTuxgspeciesgpenguinmyear_of_birth�
+4
vendor/git/serde_ipld_dagcbor/fuzz/.gitignore
··· 1 + 2 + target 3 + corpus 4 + artifacts
+26
vendor/git/serde_ipld_dagcbor/fuzz/Cargo.toml
··· 1 + 2 + [package] 3 + name = "serde_cbor-fuzz" 4 + version = "0.0.1" 5 + authors = ["Automatically generated"] 6 + publish = false 7 + 8 + [package.metadata] 9 + cargo-fuzz = true 10 + 11 + [dependencies.serde_cbor] 12 + path = ".." 13 + [dependencies.libfuzzer-sys] 14 + git = "https://github.com/rust-fuzz/libfuzzer-sys.git" 15 + 16 + # Prevent this from interfering with workspaces 17 + [workspace] 18 + members = ["."] 19 + 20 + [[bin]] 21 + name = "from_slice" 22 + path = "fuzz_targets/from_slice.rs" 23 + 24 + [[bin]] 25 + name = "from_reader" 26 + path = "fuzz_targets/from_reader.rs"
+636
vendor/git/serde_ipld_dagcbor/fuzz/appendix_a.json
··· 1 + [ 2 + { 3 + "cbor": "AA==", 4 + "hex": "00", 5 + "roundtrip": true, 6 + "decoded": 0 7 + }, 8 + { 9 + "cbor": "AQ==", 10 + "hex": "01", 11 + "roundtrip": true, 12 + "decoded": 1 13 + }, 14 + { 15 + "cbor": "Cg==", 16 + "hex": "0a", 17 + "roundtrip": true, 18 + "decoded": 10 19 + }, 20 + { 21 + "cbor": "Fw==", 22 + "hex": "17", 23 + "roundtrip": true, 24 + "decoded": 23 25 + }, 26 + { 27 + "cbor": "GBg=", 28 + "hex": "1818", 29 + "roundtrip": true, 30 + "decoded": 24 31 + }, 32 + { 33 + "cbor": "GBk=", 34 + "hex": "1819", 35 + "roundtrip": true, 36 + "decoded": 25 37 + }, 38 + { 39 + "cbor": "GGQ=", 40 + "hex": "1864", 41 + "roundtrip": true, 42 + "decoded": 100 43 + }, 44 + { 45 + "cbor": "GQPo", 46 + "hex": "1903e8", 47 + "roundtrip": true, 48 + "decoded": 1000 49 + }, 50 + { 51 + "cbor": "GgAPQkA=", 52 + "hex": "1a000f4240", 53 + "roundtrip": true, 54 + "decoded": 1000000 55 + }, 56 + { 57 + "cbor": "GwAAAOjUpRAA", 58 + "hex": "1b000000e8d4a51000", 59 + "roundtrip": true, 60 + "decoded": 1000000000000 61 + }, 62 + { 63 + "cbor": "G///////////", 64 + "hex": "1bffffffffffffffff", 65 + "roundtrip": true, 66 + "decoded": 18446744073709551615 67 + }, 68 + { 69 + "cbor": "wkkBAAAAAAAAAAA=", 70 + "hex": "c249010000000000000000", 71 + "roundtrip": true, 72 + "decoded": 18446744073709551616 73 + }, 74 + { 75 + "cbor": "O///////////", 76 + "hex": "3bffffffffffffffff", 77 + "roundtrip": true, 78 + "decoded": -18446744073709551616 79 + }, 80 + { 81 + "cbor": "w0kBAAAAAAAAAAA=", 82 + "hex": "c349010000000000000000", 83 + "roundtrip": true, 84 + "decoded": -18446744073709551617 85 + }, 86 + { 87 + "cbor": "IA==", 88 + "hex": "20", 89 + "roundtrip": true, 90 + "decoded": -1 91 + }, 92 + { 93 + "cbor": "KQ==", 94 + "hex": "29", 95 + "roundtrip": true, 96 + "decoded": -10 97 + }, 98 + { 99 + "cbor": "OGM=", 100 + "hex": "3863", 101 + "roundtrip": true, 102 + "decoded": -100 103 + }, 104 + { 105 + "cbor": "OQPn", 106 + "hex": "3903e7", 107 + "roundtrip": true, 108 + "decoded": -1000 109 + }, 110 + { 111 + "cbor": "+QAA", 112 + "hex": "f90000", 113 + "roundtrip": true, 114 + "decoded": 0.0 115 + }, 116 + { 117 + "cbor": "+YAA", 118 + "hex": "f98000", 119 + "roundtrip": true, 120 + "decoded": -0.0 121 + }, 122 + { 123 + "cbor": "+TwA", 124 + "hex": "f93c00", 125 + "roundtrip": true, 126 + "decoded": 1.0 127 + }, 128 + { 129 + "cbor": "+z/xmZmZmZma", 130 + "hex": "fb3ff199999999999a", 131 + "roundtrip": true, 132 + "decoded": 1.1 133 + }, 134 + { 135 + "cbor": "+T4A", 136 + "hex": "f93e00", 137 + "roundtrip": true, 138 + "decoded": 1.5 139 + }, 140 + { 141 + "cbor": "+Xv/", 142 + "hex": "f97bff", 143 + "roundtrip": true, 144 + "decoded": 65504.0 145 + }, 146 + { 147 + "cbor": "+kfDUAA=", 148 + "hex": "fa47c35000", 149 + "roundtrip": true, 150 + "decoded": 100000.0 151 + }, 152 + { 153 + "cbor": "+n9///8=", 154 + "hex": "fa7f7fffff", 155 + "roundtrip": true, 156 + "decoded": 3.4028234663852886e+38 157 + }, 158 + { 159 + "cbor": "+3435DyIAHWc", 160 + "hex": "fb7e37e43c8800759c", 161 + "roundtrip": true, 162 + "decoded": 1.0e+300 163 + }, 164 + { 165 + "cbor": "+QAB", 166 + "hex": "f90001", 167 + "roundtrip": true, 168 + "decoded": 5.960464477539063e-08 169 + }, 170 + { 171 + "cbor": "+QQA", 172 + "hex": "f90400", 173 + "roundtrip": true, 174 + "decoded": 6.103515625e-05 175 + }, 176 + { 177 + "cbor": "+cQA", 178 + "hex": "f9c400", 179 + "roundtrip": true, 180 + "decoded": -4.0 181 + }, 182 + { 183 + "cbor": "+8AQZmZmZmZm", 184 + "hex": "fbc010666666666666", 185 + "roundtrip": true, 186 + "decoded": -4.1 187 + }, 188 + { 189 + "cbor": "+XwA", 190 + "hex": "f97c00", 191 + "roundtrip": true, 192 + "diagnostic": "Infinity" 193 + }, 194 + { 195 + "cbor": "+X4A", 196 + "hex": "f97e00", 197 + "roundtrip": true, 198 + "diagnostic": "NaN" 199 + }, 200 + { 201 + "cbor": "+fwA", 202 + "hex": "f9fc00", 203 + "roundtrip": true, 204 + "diagnostic": "-Infinity" 205 + }, 206 + { 207 + "cbor": "+n+AAAA=", 208 + "hex": "fa7f800000", 209 + "roundtrip": false, 210 + "diagnostic": "Infinity" 211 + }, 212 + { 213 + "cbor": "+n/AAAA=", 214 + "hex": "fa7fc00000", 215 + "roundtrip": false, 216 + "diagnostic": "NaN" 217 + }, 218 + { 219 + "cbor": "+v+AAAA=", 220 + "hex": "faff800000", 221 + "roundtrip": false, 222 + "diagnostic": "-Infinity" 223 + }, 224 + { 225 + "cbor": "+3/wAAAAAAAA", 226 + "hex": "fb7ff0000000000000", 227 + "roundtrip": false, 228 + "diagnostic": "Infinity" 229 + }, 230 + { 231 + "cbor": "+3/4AAAAAAAA", 232 + "hex": "fb7ff8000000000000", 233 + "roundtrip": false, 234 + "diagnostic": "NaN" 235 + }, 236 + { 237 + "cbor": "+//wAAAAAAAA", 238 + "hex": "fbfff0000000000000", 239 + "roundtrip": false, 240 + "diagnostic": "-Infinity" 241 + }, 242 + { 243 + "cbor": "9A==", 244 + "hex": "f4", 245 + "roundtrip": true, 246 + "decoded": false 247 + }, 248 + { 249 + "cbor": "9Q==", 250 + "hex": "f5", 251 + "roundtrip": true, 252 + "decoded": true 253 + }, 254 + { 255 + "cbor": "9g==", 256 + "hex": "f6", 257 + "roundtrip": true, 258 + "decoded": null 259 + }, 260 + { 261 + "cbor": "9w==", 262 + "hex": "f7", 263 + "roundtrip": true, 264 + "diagnostic": "undefined" 265 + }, 266 + { 267 + "cbor": "8A==", 268 + "hex": "f0", 269 + "roundtrip": true, 270 + "diagnostic": "simple(16)" 271 + }, 272 + { 273 + "cbor": "+Bg=", 274 + "hex": "f818", 275 + "roundtrip": true, 276 + "diagnostic": "simple(24)" 277 + }, 278 + { 279 + "cbor": "+P8=", 280 + "hex": "f8ff", 281 + "roundtrip": true, 282 + "diagnostic": "simple(255)" 283 + }, 284 + { 285 + "cbor": "wHQyMDEzLTAzLTIxVDIwOjA0OjAwWg==", 286 + "hex": "c074323031332d30332d32315432303a30343a30305a", 287 + "roundtrip": true, 288 + "diagnostic": "0(\"2013-03-21T20:04:00Z\")" 289 + }, 290 + { 291 + "cbor": "wRpRS2ew", 292 + "hex": "c11a514b67b0", 293 + "roundtrip": true, 294 + "diagnostic": "1(1363896240)" 295 + }, 296 + { 297 + "cbor": "wftB1FLZ7CAAAA==", 298 + "hex": "c1fb41d452d9ec200000", 299 + "roundtrip": true, 300 + "diagnostic": "1(1363896240.5)" 301 + }, 302 + { 303 + "cbor": "10QBAgME", 304 + "hex": "d74401020304", 305 + "roundtrip": true, 306 + "diagnostic": "23(h'01020304')" 307 + }, 308 + { 309 + "cbor": "2BhFZElFVEY=", 310 + "hex": "d818456449455446", 311 + "roundtrip": true, 312 + "diagnostic": "24(h'6449455446')" 313 + }, 314 + { 315 + "cbor": "2CB2aHR0cDovL3d3dy5leGFtcGxlLmNvbQ==", 316 + "hex": "d82076687474703a2f2f7777772e6578616d706c652e636f6d", 317 + "roundtrip": true, 318 + "diagnostic": "32(\"http://www.example.com\")" 319 + }, 320 + { 321 + "cbor": "QA==", 322 + "hex": "40", 323 + "roundtrip": true, 324 + "diagnostic": "h''" 325 + }, 326 + { 327 + "cbor": "RAECAwQ=", 328 + "hex": "4401020304", 329 + "roundtrip": true, 330 + "diagnostic": "h'01020304'" 331 + }, 332 + { 333 + "cbor": "YA==", 334 + "hex": "60", 335 + "roundtrip": true, 336 + "decoded": "" 337 + }, 338 + { 339 + "cbor": "YWE=", 340 + "hex": "6161", 341 + "roundtrip": true, 342 + "decoded": "a" 343 + }, 344 + { 345 + "cbor": "ZElFVEY=", 346 + "hex": "6449455446", 347 + "roundtrip": true, 348 + "decoded": "IETF" 349 + }, 350 + { 351 + "cbor": "YiJc", 352 + "hex": "62225c", 353 + "roundtrip": true, 354 + "decoded": "\"\\" 355 + }, 356 + { 357 + "cbor": "YsO8", 358 + "hex": "62c3bc", 359 + "roundtrip": true, 360 + "decoded": "ü" 361 + }, 362 + { 363 + "cbor": "Y+awtA==", 364 + "hex": "63e6b0b4", 365 + "roundtrip": true, 366 + "decoded": "水" 367 + }, 368 + { 369 + "cbor": "ZPCQhZE=", 370 + "hex": "64f0908591", 371 + "roundtrip": true, 372 + "decoded": "𐅑" 373 + }, 374 + { 375 + "cbor": "gA==", 376 + "hex": "80", 377 + "roundtrip": true, 378 + "decoded": [ 379 + 380 + ] 381 + }, 382 + { 383 + "cbor": "gwECAw==", 384 + "hex": "83010203", 385 + "roundtrip": true, 386 + "decoded": [ 387 + 1, 388 + 2, 389 + 3 390 + ] 391 + }, 392 + { 393 + "cbor": "gwGCAgOCBAU=", 394 + "hex": "8301820203820405", 395 + "roundtrip": true, 396 + "decoded": [ 397 + 1, 398 + [ 399 + 2, 400 + 3 401 + ], 402 + [ 403 + 4, 404 + 5 405 + ] 406 + ] 407 + }, 408 + { 409 + "cbor": "mBkBAgMEBQYHCAkKCwwNDg8QERITFBUWFxgYGBk=", 410 + "hex": "98190102030405060708090a0b0c0d0e0f101112131415161718181819", 411 + "roundtrip": true, 412 + "decoded": [ 413 + 1, 414 + 2, 415 + 3, 416 + 4, 417 + 5, 418 + 6, 419 + 7, 420 + 8, 421 + 9, 422 + 10, 423 + 11, 424 + 12, 425 + 13, 426 + 14, 427 + 15, 428 + 16, 429 + 17, 430 + 18, 431 + 19, 432 + 20, 433 + 21, 434 + 22, 435 + 23, 436 + 24, 437 + 25 438 + ] 439 + }, 440 + { 441 + "cbor": "oA==", 442 + "hex": "a0", 443 + "roundtrip": true, 444 + "decoded": { 445 + } 446 + }, 447 + { 448 + "cbor": "ogECAwQ=", 449 + "hex": "a201020304", 450 + "roundtrip": true, 451 + "diagnostic": "{1: 2, 3: 4}" 452 + }, 453 + { 454 + "cbor": "omFhAWFiggID", 455 + "hex": "a26161016162820203", 456 + "roundtrip": true, 457 + "decoded": { 458 + "a": 1, 459 + "b": [ 460 + 2, 461 + 3 462 + ] 463 + } 464 + }, 465 + { 466 + "cbor": "gmFhoWFiYWM=", 467 + "hex": "826161a161626163", 468 + "roundtrip": true, 469 + "decoded": [ 470 + "a", 471 + { 472 + "b": "c" 473 + } 474 + ] 475 + }, 476 + { 477 + "cbor": "pWFhYUFhYmFCYWNhQ2FkYURhZWFF", 478 + "hex": "a56161614161626142616361436164614461656145", 479 + "roundtrip": true, 480 + "decoded": { 481 + "a": "A", 482 + "b": "B", 483 + "c": "C", 484 + "d": "D", 485 + "e": "E" 486 + } 487 + }, 488 + { 489 + "cbor": "X0IBAkMDBAX/", 490 + "hex": "5f42010243030405ff", 491 + "roundtrip": false, 492 + "diagnostic": "(_ h'0102', h'030405')" 493 + }, 494 + { 495 + "cbor": "f2VzdHJlYWRtaW5n/w==", 496 + "hex": "7f657374726561646d696e67ff", 497 + "roundtrip": false, 498 + "decoded": "streaming" 499 + }, 500 + { 501 + "cbor": "n/8=", 502 + "hex": "9fff", 503 + "roundtrip": false, 504 + "decoded": [ 505 + 506 + ] 507 + }, 508 + { 509 + "cbor": "nwGCAgOfBAX//w==", 510 + "hex": "9f018202039f0405ffff", 511 + "roundtrip": false, 512 + "decoded": [ 513 + 1, 514 + [ 515 + 2, 516 + 3 517 + ], 518 + [ 519 + 4, 520 + 5 521 + ] 522 + ] 523 + }, 524 + { 525 + "cbor": "nwGCAgOCBAX/", 526 + "hex": "9f01820203820405ff", 527 + "roundtrip": false, 528 + "decoded": [ 529 + 1, 530 + [ 531 + 2, 532 + 3 533 + ], 534 + [ 535 + 4, 536 + 5 537 + ] 538 + ] 539 + }, 540 + { 541 + "cbor": "gwGCAgOfBAX/", 542 + "hex": "83018202039f0405ff", 543 + "roundtrip": false, 544 + "decoded": [ 545 + 1, 546 + [ 547 + 2, 548 + 3 549 + ], 550 + [ 551 + 4, 552 + 5 553 + ] 554 + ] 555 + }, 556 + { 557 + "cbor": "gwGfAgP/ggQF", 558 + "hex": "83019f0203ff820405", 559 + "roundtrip": false, 560 + "decoded": [ 561 + 1, 562 + [ 563 + 2, 564 + 3 565 + ], 566 + [ 567 + 4, 568 + 5 569 + ] 570 + ] 571 + }, 572 + { 573 + "cbor": "nwECAwQFBgcICQoLDA0ODxAREhMUFRYXGBgYGf8=", 574 + "hex": "9f0102030405060708090a0b0c0d0e0f101112131415161718181819ff", 575 + "roundtrip": false, 576 + "decoded": [ 577 + 1, 578 + 2, 579 + 3, 580 + 4, 581 + 5, 582 + 6, 583 + 7, 584 + 8, 585 + 9, 586 + 10, 587 + 11, 588 + 12, 589 + 13, 590 + 14, 591 + 15, 592 + 16, 593 + 17, 594 + 18, 595 + 19, 596 + 20, 597 + 21, 598 + 22, 599 + 23, 600 + 24, 601 + 25 602 + ] 603 + }, 604 + { 605 + "cbor": "v2FhAWFinwID//8=", 606 + "hex": "bf61610161629f0203ffff", 607 + "roundtrip": false, 608 + "decoded": { 609 + "a": 1, 610 + "b": [ 611 + 2, 612 + 3 613 + ] 614 + } 615 + }, 616 + { 617 + "cbor": "gmFhv2FiYWP/", 618 + "hex": "826161bf61626163ff", 619 + "roundtrip": false, 620 + "decoded": [ 621 + "a", 622 + { 623 + "b": "c" 624 + } 625 + ] 626 + }, 627 + { 628 + "cbor": "v2NGdW71Y0FtdCH/", 629 + "hex": "bf6346756ef563416d7421ff", 630 + "roundtrip": false, 631 + "decoded": { 632 + "Fun": true, 633 + "Amt": -2 634 + } 635 + } 636 + ]
+10
vendor/git/serde_ipld_dagcbor/fuzz/fuzz_targets/from_reader.rs
··· 1 + #![no_main] 2 + #[macro_use] extern crate libfuzzer_sys; 3 + extern crate serde_cbor; 4 + 5 + use serde_cbor::Value; 6 + 7 + fuzz_target!(|data: &[u8]| { 8 + let mut data = data; 9 + let _ = serde_cbor::from_reader::<Value, _>(&mut data); 10 + });
+9
vendor/git/serde_ipld_dagcbor/fuzz/fuzz_targets/from_slice.rs
··· 1 + #![no_main] 2 + #[macro_use] extern crate libfuzzer_sys; 3 + extern crate serde_cbor; 4 + 5 + use serde_cbor::Value; 6 + 7 + fuzz_target!(|data: &[u8]| { 8 + let _ = serde_cbor::from_slice::<Value>(data); 9 + });
+17
vendor/git/serde_ipld_dagcbor/fuzz/make_corpus.py
··· 1 + #!/usr/bin/env python 2 + 3 + import base64 4 + import json 5 + import sys 6 + import os.path 7 + 8 + out_dir = sys.argv[1] 9 + os.makedirs(out_dir) 10 + 11 + with open("appendix_a.json") as f: 12 + appendix = json.load(f) 13 + 14 + for i, entry in enumerate(appendix): 15 + buf = base64.b64decode(entry["cbor"]) 16 + with open(os.path.join(out_dir, str(i)), 'wb') as f: 17 + f.write(buf)
+41
vendor/git/serde_ipld_dagcbor/src/cbor4ii_nonpub.rs
··· 1 + //! This module contains code that was just copied from cbor4ii. 2 + //! 3 + //! Some things needed for the Serde implementation are not public in the cbor4ii crate. Those are 4 + //! copied into this file. 5 + 6 + use cbor4ii::core::dec; 7 + 8 + use crate::error::DecodeError; 9 + 10 + // Copy from cbor4ii/core.rs. 11 + #[allow(dead_code)] 12 + pub(crate) mod marker { 13 + pub const START: u8 = 0x1f; 14 + pub const FALSE: u8 = 0xf4; // simple(20) 15 + pub const TRUE: u8 = 0xf5; // simple(21) 16 + pub const NULL: u8 = 0xf6; // simple(22) 17 + pub const UNDEFINED: u8 = 0xf7; // simple(23) 18 + pub const F16: u8 = 0xf9; 19 + pub const F32: u8 = 0xfa; 20 + pub const F64: u8 = 0xfb; 21 + pub const BREAK: u8 = 0xff; 22 + } 23 + 24 + // Copy from cbor4ii/core/dec.rs. 25 + #[inline] 26 + pub(crate) fn peek_one<'a, R: dec::Read<'a>>(reader: &mut R) -> Result<u8, DecodeError<R::Error>> { 27 + let buf = match reader.fill(1)? { 28 + dec::Reference::Long(buf) => buf, 29 + dec::Reference::Short(buf) => buf, 30 + }; 31 + let byte = buf.first().copied().ok_or(DecodeError::Eof)?; 32 + Ok(byte) 33 + } 34 + 35 + // Copy from cbor4ii/core/dec.rs. 36 + #[inline] 37 + pub(crate) fn pull_one<'a, R: dec::Read<'a>>(reader: &mut R) -> Result<u8, DecodeError<R::Error>> { 38 + let byte = peek_one(reader)?; 39 + reader.advance(1); 40 + Ok(byte) 41 + }
+43
vendor/git/serde_ipld_dagcbor/src/codec.rs
··· 1 + //! Implementation of ipld-core's `Codec` trait. 2 + 3 + use std::io::{BufRead, Write}; 4 + 5 + use ipld_core::{ 6 + cid::Cid, 7 + codec::{Codec, Links}, 8 + serde::ExtractLinks, 9 + }; 10 + use serde::{de::Deserialize, ser::Serialize}; 11 + 12 + use crate::{de::Deserializer, error::CodecError, DAG_CBOR_CODE}; 13 + 14 + /// DAG-CBOR implementation of ipld-core's `Codec` trait. 15 + #[derive(Copy, Clone, Debug, PartialEq, Eq)] 16 + pub struct DagCborCodec; 17 + 18 + impl<T> Codec<T> for DagCborCodec 19 + where 20 + T: for<'a> Deserialize<'a> + Serialize, 21 + { 22 + const CODE: u64 = DAG_CBOR_CODE; 23 + type Error = CodecError; 24 + 25 + fn decode<R: BufRead>(reader: R) -> Result<T, Self::Error> { 26 + Ok(crate::from_reader(reader)?) 27 + } 28 + 29 + fn encode<W: Write>(writer: W, data: &T) -> Result<(), Self::Error> { 30 + Ok(crate::to_writer(writer, data)?) 31 + } 32 + } 33 + 34 + impl Links for DagCborCodec { 35 + type LinksError = CodecError; 36 + 37 + fn links(data: &[u8]) -> Result<impl Iterator<Item = Cid>, Self::LinksError> { 38 + let mut deserializer = Deserializer::from_slice(data); 39 + Ok(ExtractLinks::deserialize(&mut deserializer)? 40 + .into_vec() 41 + .into_iter()) 42 + } 43 + }
+884
vendor/git/serde_ipld_dagcbor/src/de.rs
··· 1 + //! Deserialization. 2 + #[cfg(not(feature = "std"))] 3 + use alloc::borrow::Cow; 4 + use core::convert::{Infallible, TryFrom}; 5 + use core::marker::PhantomData; 6 + use serde::Deserialize; 7 + #[cfg(feature = "std")] 8 + use std::borrow::Cow; 9 + 10 + use cbor4ii::core::dec::{self, Decode}; 11 + use cbor4ii::core::{major, types, utils::SliceReader}; 12 + use ipld_core::cid::serde::CID_SERDE_PRIVATE_IDENTIFIER; 13 + use serde::de::{self, Visitor}; 14 + 15 + use crate::cbor4ii_nonpub::{marker, peek_one, pull_one}; 16 + use crate::error::DecodeError; 17 + use crate::CBOR_TAGS_CID; 18 + #[cfg(feature = "std")] 19 + use cbor4ii::core::utils::IoReader; 20 + 21 + /// Decodes a value from CBOR data in a slice. 22 + /// 23 + /// # Examples 24 + /// 25 + /// Deserialize a `String` 26 + /// 27 + /// ``` 28 + /// # use serde_ipld_dagcbor::de; 29 + /// let v: Vec<u8> = vec![0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]; 30 + /// let value: String = de::from_slice(&v[..]).unwrap(); 31 + /// assert_eq!(value, "foobar"); 32 + /// ``` 33 + /// 34 + /// Deserialize a borrowed string with zero copies. 35 + /// 36 + /// ``` 37 + /// # use serde_ipld_dagcbor::de; 38 + /// let v: Vec<u8> = vec![0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]; 39 + /// let value: &str = de::from_slice(&v[..]).unwrap(); 40 + /// assert_eq!(value, "foobar"); 41 + /// ``` 42 + pub fn from_slice<'a, T>(buf: &'a [u8]) -> Result<T, DecodeError<Infallible>> 43 + where 44 + T: de::Deserialize<'a>, 45 + { 46 + let reader = SliceReader::new(buf); 47 + let mut deserializer = Deserializer::from_reader(reader); 48 + let value = serde::Deserialize::deserialize(&mut deserializer)?; 49 + deserializer.end()?; 50 + Ok(value) 51 + } 52 + 53 + /// Decodes a value from CBOR data in a reader. 54 + /// 55 + /// # Examples 56 + /// 57 + /// Deserialize a `String` 58 + /// 59 + /// ``` 60 + /// # use serde_ipld_dagcbor::de; 61 + /// let v: Vec<u8> = vec![0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]; 62 + /// let value: String = de::from_reader(&v[..]).unwrap(); 63 + /// assert_eq!(value, "foobar"); 64 + /// ``` 65 + /// 66 + /// Note that `from_reader` cannot borrow data: 67 + /// 68 + /// ```compile_fail 69 + /// # use serde_ipld_dagcbor::de; 70 + /// let v: Vec<u8> = vec![0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]; 71 + /// let value: &str = de::from_reader(&v[..]).unwrap(); 72 + /// assert_eq!(value, "foobar"); 73 + /// ``` 74 + #[cfg(feature = "std")] 75 + pub fn from_reader<T, R>(reader: R) -> Result<T, DecodeError<std::io::Error>> 76 + where 77 + T: de::DeserializeOwned, 78 + R: std::io::BufRead, 79 + { 80 + let reader = IoReader::new(reader); 81 + let mut deserializer = Deserializer::from_reader(reader); 82 + let value = serde::Deserialize::deserialize(&mut deserializer)?; 83 + deserializer.end()?; 84 + Ok(value) 85 + } 86 + 87 + /// Decodes a single value from CBOR data in a reader. If there are multiple 88 + /// concatenated values in the reader, this function will succeed. On success, 89 + /// it returns the decoded value. The reader will be left with all trailing 90 + /// data. This function allows a user to decode multiple CBOR values from the 91 + /// same reader that are not the same type. If you have many values of the same 92 + /// type, consider [`StreamDeserializer`]. 93 + /// 94 + /// # Examples 95 + /// 96 + /// Deserialize a `String` 97 + /// 98 + /// ``` 99 + /// # use serde_ipld_dagcbor::de; 100 + /// let v: &[u8] = &[0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]; 101 + /// let mut reader = std::io::Cursor::new(v); 102 + /// let value: String = de::from_reader_once(&mut reader).unwrap(); 103 + /// assert_eq!(value, "foobar"); 104 + /// assert_eq!(v.len(), reader.position() as usize); 105 + /// 106 + /// let v: &[u8] = &[0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x0A]; 107 + /// let mut reader = std::io::Cursor::new(v); 108 + /// let value_1: String = de::from_reader_once(&mut reader).unwrap(); 109 + /// let value_2: i32 = de::from_reader_once(&mut reader).unwrap(); 110 + /// assert_eq!(value_1, "foobar"); 111 + /// assert_eq!(value_2, 10); 112 + /// assert_eq!(v.len(), reader.position() as usize); 113 + /// ``` 114 + #[cfg(feature = "std")] 115 + pub fn from_reader_once<T, R>(reader: R) -> Result<T, DecodeError<std::io::Error>> 116 + where 117 + T: de::DeserializeOwned, 118 + R: std::io::BufRead, 119 + { 120 + let reader = IoReader::new(reader); 121 + let mut deserializer = Deserializer::from_reader(reader); 122 + let value = serde::Deserialize::deserialize(&mut deserializer)?; 123 + Ok(value) 124 + } 125 + 126 + /// Create an iterator over the CBOR values in the reader. 127 + /// 128 + /// # Examples 129 + /// 130 + /// Deserialize several `String` values 131 + /// 132 + /// ``` 133 + /// # use serde_ipld_dagcbor::de; 134 + /// let v: &[u8] = &[0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]; 135 + /// let mut reader = std::io::Cursor::new(v); 136 + /// let mut iter = de::iter_from_reader::<String, _>(&mut reader); 137 + /// let value: String = iter.next().unwrap().unwrap(); 138 + /// assert_eq!(value, "foobar"); 139 + /// assert!(iter.next().is_none()); 140 + /// 141 + /// let v: &[u8] = &[0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x63, 0x62, 0x61, 0x7A]; 142 + /// let mut reader = std::io::Cursor::new(v); 143 + /// let mut iter = de::iter_from_reader::<String, _>(&mut reader); 144 + /// let value_1: String = iter.next().unwrap().unwrap(); 145 + /// let value_2: String = iter.next().unwrap().unwrap(); 146 + /// assert_eq!(value_1, "foobar"); 147 + /// assert_eq!(value_2, "baz"); 148 + /// assert!(iter.next().is_none()); 149 + /// ``` 150 + #[cfg(feature = "std")] 151 + pub fn iter_from_reader<T, R>(reader: R) -> StreamDeserializer<'static, IoReader<R>, T> 152 + where 153 + T: de::DeserializeOwned, 154 + R: std::io::BufRead, 155 + { 156 + let reader = IoReader::new(reader); 157 + Deserializer::from_reader(reader).into_iter() 158 + } 159 + 160 + /// A Serde `Deserialize`r of DAG-CBOR data. 161 + #[derive(Debug)] 162 + pub struct Deserializer<R> { 163 + reader: R, 164 + } 165 + 166 + impl<R> Deserializer<R> { 167 + /// Constructs a `Deserializer` which reads from a `Read`er. 168 + pub fn from_reader(reader: R) -> Deserializer<R> { 169 + Deserializer { reader } 170 + } 171 + } 172 + 173 + impl<'de, R: dec::Read<'de>> Deserializer<R> { 174 + /// Create an iterator over all the CBOR values in the iterator 175 + #[allow(clippy::should_implement_trait)] 176 + pub fn into_iter<T: Deserialize<'de>>(self) -> StreamDeserializer<'de, R, T> { 177 + // This cannot be an implementation of std::iter::IntoIterator because 178 + // we need the caller to choose what T is. 179 + StreamDeserializer::new(self) 180 + } 181 + } 182 + 183 + impl<'a> Deserializer<SliceReader<'a>> { 184 + /// Constructs a `Deserializer` that reads from a slice. 185 + pub fn from_slice(buf: &'a [u8]) -> Self { 186 + Deserializer { 187 + reader: SliceReader::new(buf), 188 + } 189 + } 190 + } 191 + 192 + impl<'de, R: dec::Read<'de>> Deserializer<R> { 193 + #[allow(clippy::type_complexity)] 194 + #[inline] 195 + fn try_step<'a>( 196 + &'a mut self, 197 + ) -> Result<scopeguard::ScopeGuard<&'a mut Self, fn(&'a mut Self) -> ()>, DecodeError<R::Error>> 198 + { 199 + if self.reader.step_in() { 200 + Ok(scopeguard::guard(self, |de| de.reader.step_out())) 201 + } else { 202 + Err(DecodeError::DepthLimit) 203 + } 204 + } 205 + 206 + #[inline] 207 + fn deserialize_cid<V>(&mut self, visitor: V) -> Result<V::Value, DecodeError<R::Error>> 208 + where 209 + V: Visitor<'de>, 210 + { 211 + let tag = dec::TagStart::decode(&mut self.reader)?; 212 + 213 + match tag.0 { 214 + CBOR_TAGS_CID => visitor.visit_newtype_struct(&mut CidDeserializer(self)), 215 + _ => Err(DecodeError::TypeMismatch { 216 + name: "CBOR tag", 217 + byte: tag.0 as u8, 218 + }), 219 + } 220 + } 221 + 222 + /// This method should be called after a value has been deserialized to ensure there is no 223 + /// trailing data in the input source. 224 + pub fn end(&mut self) -> Result<(), DecodeError<R::Error>> { 225 + match peek_one(&mut self.reader) { 226 + Ok(_) => Err(DecodeError::TrailingData), 227 + Err(DecodeError::Eof) => Ok(()), 228 + Err(error) => Err(error), 229 + } 230 + } 231 + 232 + fn visit_seq<V>( 233 + &mut self, 234 + name: &'static str, 235 + visitor: V, 236 + ) -> Result<V::Value, DecodeError<R::Error>> 237 + where 238 + V: Visitor<'de>, 239 + { 240 + let mut de = self.try_step()?; 241 + let mut seq = Accessor::array(&mut de)?; 242 + let value = seq.len; 243 + let res = visitor.visit_seq(&mut seq)?; 244 + match seq.len { 245 + 0 => Ok(res), 246 + remaining => Err(DecodeError::RequireLength { 247 + name, 248 + expect: value - remaining, 249 + value, 250 + }), 251 + } 252 + } 253 + 254 + fn visit_map<V>( 255 + &mut self, 256 + name: &'static str, 257 + visitor: V, 258 + ) -> Result<V::Value, DecodeError<R::Error>> 259 + where 260 + V: Visitor<'de>, 261 + { 262 + let mut de = self.try_step()?; 263 + let mut map = Accessor::map(&mut de)?; 264 + let value = map.len; 265 + let res = visitor.visit_map(&mut map)?; 266 + match map.len { 267 + 0 => Ok(res), 268 + remaining => Err(DecodeError::RequireLength { 269 + name, 270 + expect: value - remaining, 271 + value, 272 + }), 273 + } 274 + } 275 + } 276 + 277 + macro_rules! deserialize_type { 278 + ( @ $t:ty , $name:ident , $visit:ident ) => { 279 + #[inline] 280 + fn $name<V>(self, visitor: V) -> Result<V::Value, Self::Error> 281 + where V: Visitor<'de> 282 + { 283 + let value = <$t>::decode(&mut self.reader)?; 284 + visitor.$visit(value) 285 + } 286 + }; 287 + ( $( $t:ty , $name:ident , $visit:ident );* $( ; )? ) => { 288 + $( 289 + deserialize_type!(@ $t, $name, $visit); 290 + )* 291 + }; 292 + } 293 + 294 + impl<'de, R: dec::Read<'de>> serde::Deserializer<'de> for &mut Deserializer<R> { 295 + type Error = DecodeError<R::Error>; 296 + 297 + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> 298 + where 299 + V: Visitor<'de>, 300 + { 301 + let mut de = self.try_step()?; 302 + let de = &mut *de; 303 + 304 + let byte = peek_one(&mut de.reader)?; 305 + if is_indefinite(byte) { 306 + return Err(DecodeError::IndefiniteSize); 307 + } 308 + match dec::if_major(byte) { 309 + major::UNSIGNED => de.deserialize_u64(visitor), 310 + major::NEGATIVE => { 311 + // CBOR supports negative integers up to -2^64 which is less than i64::MIN. Only 312 + // treat it as i128, if it is outside the i64 range. 313 + let value = i128::decode(&mut de.reader)?; 314 + match i64::try_from(value) { 315 + Ok(value_i64) => visitor.visit_i64(value_i64), 316 + Err(_) => visitor.visit_i128(value), 317 + } 318 + } 319 + major::BYTES => de.deserialize_byte_buf(visitor), 320 + major::STRING => de.deserialize_string(visitor), 321 + major::ARRAY => de.deserialize_seq(visitor), 322 + major::MAP => de.deserialize_map(visitor), 323 + // The only supported tag is tag 42 (CID). 324 + major::TAG => de.deserialize_cid(visitor), 325 + major::SIMPLE => match byte { 326 + marker::FALSE => { 327 + de.reader.advance(1); 328 + visitor.visit_bool(false) 329 + } 330 + marker::TRUE => { 331 + de.reader.advance(1); 332 + visitor.visit_bool(true) 333 + } 334 + marker::NULL => { 335 + de.reader.advance(1); 336 + visitor.visit_none() 337 + } 338 + marker::F32 => de.deserialize_f32(visitor), 339 + marker::F64 => de.deserialize_f64(visitor), 340 + _ => Err(DecodeError::Unsupported { byte }), 341 + }, 342 + _ => Err(DecodeError::Unsupported { byte }), 343 + } 344 + } 345 + 346 + deserialize_type!( 347 + bool, deserialize_bool, visit_bool; 348 + 349 + i8, deserialize_i8, visit_i8; 350 + i16, deserialize_i16, visit_i16; 351 + i32, deserialize_i32, visit_i32; 352 + i64, deserialize_i64, visit_i64; 353 + i128, deserialize_i128, visit_i128; 354 + 355 + u8, deserialize_u8, visit_u8; 356 + u16, deserialize_u16, visit_u16; 357 + u32, deserialize_u32, visit_u32; 358 + u64, deserialize_u64, visit_u64; 359 + u128, deserialize_u128, visit_u128; 360 + 361 + // f32 deserialize is handled as a special case below 362 + f64, deserialize_f64, visit_f64; 363 + ); 364 + 365 + #[inline] 366 + fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error> 367 + where 368 + V: Visitor<'de>, 369 + { 370 + // DAG-CBOR strictly requires all floats to be encoded as f64. 371 + // When deserializing to f32, we need to handle f64 encoding. 372 + // We also accept f32 encoding, although a strict DAG-CBOR 373 + // implementation should reject it (please don't write new data 374 + // with f32 encoding). 375 + let byte = peek_one(&mut self.reader)?; 376 + match byte { 377 + marker::F32 => { 378 + // Note: f32 encoding is not valid in strict DAG-CBOR. 379 + let value = <f32>::decode(&mut self.reader)?; 380 + visitor.visit_f32(value) 381 + } 382 + marker::F64 => { 383 + // DAG-CBOR always uses f64 encoding, even for f32 values 384 + let value = <f64>::decode(&mut self.reader)?; 385 + 386 + let f32_value = value as f32; 387 + 388 + // Check if conversion causes overflow to infinity 389 + if !f32_value.is_finite() && value.is_finite() { 390 + // The f64 value is finite but becomes infinite when converted to f32 391 + return Err(DecodeError::Msg("Float value out of range for f32".into())); 392 + } 393 + 394 + // Check if the f64 value is exactly representable as f32. Reject values that 395 + // lose precision in the conversion. If you must decode to f32, then you should 396 + // only encode f32 values. 397 + if (f32_value as f64).to_bits() != value.to_bits() { 398 + return Err(DecodeError::Msg( 399 + "Float value has more precision than f32 can represent, loss of precision" 400 + .into(), 401 + )); 402 + } 403 + 404 + visitor.visit_f32(f32_value) 405 + } 406 + _ => Err(DecodeError::TypeMismatch { name: "f32", byte }), 407 + } 408 + } 409 + 410 + #[inline] 411 + fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error> 412 + where 413 + V: Visitor<'de>, 414 + { 415 + // Treat it as a String. 416 + // This is a bit wasteful when encountering strings of more than one character, 417 + // but we are optimistic this is a cold path. 418 + self.deserialize_str(visitor) 419 + } 420 + 421 + #[inline] 422 + fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error> 423 + where 424 + V: Visitor<'de>, 425 + { 426 + match <types::Bytes<Cow<[u8]>>>::decode(&mut self.reader)?.0 { 427 + Cow::Borrowed(buf) => visitor.visit_borrowed_bytes(buf), 428 + Cow::Owned(buf) => visitor.visit_byte_buf(buf), 429 + } 430 + } 431 + 432 + #[inline] 433 + fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error> 434 + where 435 + V: Visitor<'de>, 436 + { 437 + self.deserialize_bytes(visitor) 438 + } 439 + 440 + #[inline] 441 + fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error> 442 + where 443 + V: Visitor<'de>, 444 + { 445 + match <Cow<str>>::decode(&mut self.reader)? { 446 + Cow::Borrowed(buf) => visitor.visit_borrowed_str(buf), 447 + Cow::Owned(buf) => visitor.visit_string(buf), 448 + } 449 + } 450 + 451 + #[inline] 452 + fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error> 453 + where 454 + V: Visitor<'de>, 455 + { 456 + self.deserialize_str(visitor) 457 + } 458 + 459 + #[inline] 460 + fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error> 461 + where 462 + V: Visitor<'de>, 463 + { 464 + let byte = peek_one(&mut self.reader)?; 465 + if byte != marker::NULL { 466 + let mut de = self.try_step()?; 467 + visitor.visit_some(&mut **de) 468 + } else { 469 + self.reader.advance(1); 470 + visitor.visit_none() 471 + } 472 + } 473 + 474 + #[inline] 475 + fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error> 476 + where 477 + V: Visitor<'de>, 478 + { 479 + let byte = pull_one(&mut self.reader)?; 480 + if byte == marker::NULL { 481 + visitor.visit_unit() 482 + } else { 483 + Err(DecodeError::TypeMismatch { name: "unit", byte }) 484 + } 485 + } 486 + 487 + #[inline] 488 + fn deserialize_unit_struct<V>( 489 + self, 490 + _name: &'static str, 491 + visitor: V, 492 + ) -> Result<V::Value, Self::Error> 493 + where 494 + V: Visitor<'de>, 495 + { 496 + self.deserialize_unit(visitor) 497 + } 498 + 499 + #[inline] 500 + fn deserialize_newtype_struct<V>( 501 + self, 502 + name: &'static str, 503 + visitor: V, 504 + ) -> Result<V::Value, Self::Error> 505 + where 506 + V: Visitor<'de>, 507 + { 508 + if name == CID_SERDE_PRIVATE_IDENTIFIER { 509 + self.deserialize_cid(visitor) 510 + } else { 511 + visitor.visit_newtype_struct(self) 512 + } 513 + } 514 + 515 + #[inline] 516 + fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error> 517 + where 518 + V: Visitor<'de>, 519 + { 520 + self.visit_seq("array", visitor) 521 + } 522 + 523 + #[inline] 524 + fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error> 525 + where 526 + V: Visitor<'de>, 527 + { 528 + self.visit_seq("tuple", visitor) 529 + } 530 + 531 + #[inline] 532 + fn deserialize_tuple_struct<V>( 533 + self, 534 + name: &'static str, 535 + _len: usize, 536 + visitor: V, 537 + ) -> Result<V::Value, Self::Error> 538 + where 539 + V: Visitor<'de>, 540 + { 541 + self.visit_seq(name, visitor) 542 + } 543 + 544 + #[inline] 545 + fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error> 546 + where 547 + V: Visitor<'de>, 548 + { 549 + self.visit_map("map", visitor) 550 + } 551 + 552 + #[inline] 553 + fn deserialize_struct<V>( 554 + self, 555 + name: &'static str, 556 + _fields: &'static [&'static str], 557 + visitor: V, 558 + ) -> Result<V::Value, Self::Error> 559 + where 560 + V: Visitor<'de>, 561 + { 562 + self.visit_map(name, visitor) 563 + } 564 + 565 + #[inline] 566 + fn deserialize_enum<V>( 567 + self, 568 + _name: &'static str, 569 + _variants: &'static [&'static str], 570 + visitor: V, 571 + ) -> Result<V::Value, Self::Error> 572 + where 573 + V: Visitor<'de>, 574 + { 575 + let mut de = self.try_step()?; 576 + let accessor = EnumAccessor::enum_(&mut de)?; 577 + visitor.visit_enum(accessor) 578 + } 579 + 580 + #[inline] 581 + fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error> 582 + where 583 + V: Visitor<'de>, 584 + { 585 + self.deserialize_str(visitor) 586 + } 587 + 588 + #[inline] 589 + fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> 590 + where 591 + V: Visitor<'de>, 592 + { 593 + let _ignore = dec::IgnoredAny::decode(&mut self.reader)?; 594 + visitor.visit_unit() 595 + } 596 + 597 + #[inline] 598 + fn is_human_readable(&self) -> bool { 599 + false 600 + } 601 + } 602 + 603 + /// An iterator over all the CBOR values in the iterator. 604 + pub struct StreamDeserializer<'de, R, T> { 605 + de: Deserializer<R>, 606 + output: PhantomData<fn() -> T>, 607 + lifetime: PhantomData<&'de ()>, 608 + } 609 + 610 + impl<R, T> StreamDeserializer<'_, R, T> { 611 + /// Create a new streaming deserializer. 612 + pub fn new(de: Deserializer<R>) -> Self { 613 + Self { 614 + de, 615 + output: PhantomData, 616 + lifetime: PhantomData, 617 + } 618 + } 619 + } 620 + 621 + impl<'de, R, T> Iterator for StreamDeserializer<'de, R, T> 622 + where 623 + R: dec::Read<'de>, 624 + T: de::Deserialize<'de>, 625 + { 626 + type Item = Result<T, DecodeError<R::Error>>; 627 + 628 + fn next(&mut self) -> Option<Self::Item> { 629 + if let Ok(()) = self.de.end() { 630 + return None; 631 + } 632 + 633 + let result = serde::Deserialize::deserialize(&mut self.de); 634 + 635 + match result { 636 + Ok(value) => Some(Ok(value)), 637 + Err(err) => Some(Err(err)), 638 + } 639 + } 640 + } 641 + 642 + struct Accessor<'a, R> { 643 + de: &'a mut Deserializer<R>, 644 + len: usize, 645 + } 646 + 647 + impl<'de, 'a, R: dec::Read<'de>> Accessor<'a, R> { 648 + #[inline] 649 + fn array(de: &'a mut Deserializer<R>) -> Result<Accessor<'a, R>, DecodeError<R::Error>> { 650 + let array_start = dec::ArrayStart::decode(&mut de.reader)?; 651 + array_start.0.map_or_else( 652 + || Err(DecodeError::IndefiniteSize), 653 + move |len| Ok(Accessor { de, len }), 654 + ) 655 + } 656 + 657 + #[inline] 658 + fn map(de: &'a mut Deserializer<R>) -> Result<Accessor<'a, R>, DecodeError<R::Error>> { 659 + let map_start = dec::MapStart::decode(&mut de.reader)?; 660 + map_start.0.map_or_else( 661 + || Err(DecodeError::IndefiniteSize), 662 + move |len| Ok(Accessor { de, len }), 663 + ) 664 + } 665 + } 666 + 667 + impl<'de, R> de::SeqAccess<'de> for Accessor<'_, R> 668 + where 669 + R: dec::Read<'de>, 670 + { 671 + type Error = DecodeError<R::Error>; 672 + 673 + #[inline] 674 + fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> 675 + where 676 + T: de::DeserializeSeed<'de>, 677 + { 678 + if self.len > 0 { 679 + self.len -= 1; 680 + Ok(Some(seed.deserialize(&mut *self.de)?)) 681 + } else { 682 + Ok(None) 683 + } 684 + } 685 + 686 + #[inline] 687 + fn size_hint(&self) -> Option<usize> { 688 + Some(self.len) 689 + } 690 + } 691 + 692 + impl<'de, R: dec::Read<'de>> de::MapAccess<'de> for Accessor<'_, R> { 693 + type Error = DecodeError<R::Error>; 694 + 695 + #[inline] 696 + fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error> 697 + where 698 + K: de::DeserializeSeed<'de>, 699 + { 700 + if self.len > 0 { 701 + self.len -= 1; 702 + Ok(Some(seed.deserialize(&mut *self.de)?)) 703 + } else { 704 + Ok(None) 705 + } 706 + } 707 + 708 + #[inline] 709 + fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error> 710 + where 711 + V: de::DeserializeSeed<'de>, 712 + { 713 + seed.deserialize(&mut *self.de) 714 + } 715 + 716 + #[inline] 717 + fn size_hint(&self) -> Option<usize> { 718 + Some(self.len) 719 + } 720 + } 721 + 722 + struct EnumAccessor<'a, R> { 723 + de: &'a mut Deserializer<R>, 724 + } 725 + 726 + impl<'de, 'a, R: dec::Read<'de>> EnumAccessor<'a, R> { 727 + #[inline] 728 + pub fn enum_( 729 + de: &'a mut Deserializer<R>, 730 + ) -> Result<EnumAccessor<'a, R>, DecodeError<R::Error>> { 731 + let byte = peek_one(&mut de.reader)?; 732 + match dec::if_major(byte) { 733 + // string 734 + major::STRING => Ok(EnumAccessor { de }), 735 + // 1 length map 736 + major::MAP if byte == (major::MAP << 5) | 1 => { 737 + de.reader.advance(1); 738 + Ok(EnumAccessor { de }) 739 + } 740 + _ => Err(DecodeError::TypeMismatch { name: "enum", byte }), 741 + } 742 + } 743 + } 744 + 745 + impl<'de, 'a, R> de::EnumAccess<'de> for EnumAccessor<'a, R> 746 + where 747 + R: dec::Read<'de>, 748 + { 749 + type Error = DecodeError<R::Error>; 750 + type Variant = EnumAccessor<'a, R>; 751 + 752 + #[inline] 753 + fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> 754 + where 755 + V: de::DeserializeSeed<'de>, 756 + { 757 + let variant = seed.deserialize(&mut *self.de)?; 758 + Ok((variant, self)) 759 + } 760 + } 761 + 762 + impl<'de, R> de::VariantAccess<'de> for EnumAccessor<'_, R> 763 + where 764 + R: dec::Read<'de>, 765 + { 766 + type Error = DecodeError<R::Error>; 767 + 768 + #[inline] 769 + fn unit_variant(self) -> Result<(), Self::Error> { 770 + Ok(()) 771 + } 772 + 773 + #[inline] 774 + fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error> 775 + where 776 + T: de::DeserializeSeed<'de>, 777 + { 778 + seed.deserialize(&mut *self.de) 779 + } 780 + 781 + #[inline] 782 + fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error> 783 + where 784 + V: Visitor<'de>, 785 + { 786 + use serde::Deserializer; 787 + 788 + self.de.deserialize_tuple(len, visitor) 789 + } 790 + 791 + #[inline] 792 + fn struct_variant<V>( 793 + self, 794 + _fields: &'static [&'static str], 795 + visitor: V, 796 + ) -> Result<V::Value, Self::Error> 797 + where 798 + V: Visitor<'de>, 799 + { 800 + use serde::Deserializer; 801 + 802 + self.de.deserialize_map(visitor) 803 + } 804 + } 805 + 806 + /// Deserialize a DAG-CBOR encoded CID. 807 + /// 808 + /// This is without the CBOR tag information. It is only the CBOR byte string identifier (major 809 + /// type 2), the number of bytes, and a null byte prefixed CID. 810 + /// 811 + /// The reason for not including the CBOR tag information is the [`Value`] implementation. That one 812 + /// starts to parse the bytes, before we could interfere. If the data only includes a CID, we are 813 + /// parsing over the tag to determine whether it is a CID or not and go from there. 814 + struct CidDeserializer<'a, R>(&'a mut Deserializer<R>); 815 + 816 + impl<'de, 'a, R: dec::Read<'de>> de::Deserializer<'de> for &'a mut CidDeserializer<'a, R> { 817 + type Error = DecodeError<R::Error>; 818 + 819 + #[cfg(not(feature = "no-cid-as-bytes"))] 820 + fn deserialize_any<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> { 821 + self.deserialize_bytes(visitor) 822 + } 823 + #[cfg(feature = "no-cid-as-bytes")] 824 + fn deserialize_any<V: de::Visitor<'de>>(self, _visitor: V) -> Result<V::Value, Self::Error> { 825 + Err(de::Error::custom( 826 + "Only bytes can be deserialized into a CID", 827 + )) 828 + } 829 + 830 + #[inline] 831 + fn deserialize_bytes<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> { 832 + let byte = peek_one(&mut self.0.reader)?; 833 + match dec::if_major(byte) { 834 + major::BYTES => { 835 + // CBOR encoded CIDs have a zero byte prefix we have to remove. 836 + match <types::Bytes<Cow<[u8]>>>::decode(&mut self.0.reader)?.0 { 837 + Cow::Borrowed(buf) => { 838 + if buf.len() <= 1 || buf[0] != 0 { 839 + Err(DecodeError::Msg("Invalid CID".into())) 840 + } else { 841 + visitor.visit_borrowed_bytes(&buf[1..]) 842 + } 843 + } 844 + Cow::Owned(mut buf) => { 845 + if buf.len() <= 1 || buf[0] != 0 { 846 + Err(DecodeError::Msg("Invalid CID".into())) 847 + } else { 848 + buf.remove(0); 849 + visitor.visit_byte_buf(buf) 850 + } 851 + } 852 + } 853 + } 854 + _ => Err(DecodeError::Unsupported { byte }), 855 + } 856 + } 857 + 858 + fn deserialize_newtype_struct<V: de::Visitor<'de>>( 859 + self, 860 + name: &str, 861 + visitor: V, 862 + ) -> Result<V::Value, Self::Error> { 863 + if name == CID_SERDE_PRIVATE_IDENTIFIER { 864 + self.deserialize_bytes(visitor) 865 + } else { 866 + Err(de::Error::custom([ 867 + "This deserializer must not be called on newtype structs other than one named `", 868 + CID_SERDE_PRIVATE_IDENTIFIER, 869 + "`" 870 + ].concat())) 871 + } 872 + } 873 + 874 + serde::forward_to_deserialize_any! { 875 + bool byte_buf char enum f32 f64 i8 i16 i32 i64 identifier ignored_any map option seq str 876 + string struct tuple tuple_struct u8 u16 u32 u64 unit unit_struct 877 + } 878 + } 879 + 880 + /// Check if byte is a major type with indefinite length. 881 + #[inline] 882 + pub fn is_indefinite(byte: u8) -> bool { 883 + byte & marker::START == marker::START 884 + }
+256
vendor/git/serde_ipld_dagcbor/src/error.rs
··· 1 + //! When serializing or deserializing DAG-CBOR goes wrong. 2 + 3 + use alloc::{ 4 + collections::TryReserveError, 5 + string::{String, ToString}, 6 + }; 7 + use core::{convert::Infallible, fmt, num::TryFromIntError}; 8 + 9 + use serde::{de, ser}; 10 + 11 + /// An encoding error. 12 + #[derive(Debug)] 13 + pub enum EncodeError<E> { 14 + /// Custom error message. 15 + Msg(String), 16 + /// IO Error. 17 + Write(E), 18 + } 19 + 20 + impl<E> From<E> for EncodeError<E> { 21 + fn from(err: E) -> EncodeError<E> { 22 + EncodeError::Write(err) 23 + } 24 + } 25 + 26 + #[cfg(feature = "std")] 27 + impl<E: std::error::Error + 'static> ser::Error for EncodeError<E> { 28 + fn custom<T: fmt::Display>(msg: T) -> Self { 29 + EncodeError::Msg(msg.to_string()) 30 + } 31 + } 32 + 33 + #[cfg(not(feature = "std"))] 34 + impl<E: fmt::Debug> ser::Error for EncodeError<E> { 35 + fn custom<T: fmt::Display>(msg: T) -> Self { 36 + EncodeError::Msg(msg.to_string()) 37 + } 38 + } 39 + 40 + #[cfg(feature = "std")] 41 + impl<E: std::error::Error + 'static> std::error::Error for EncodeError<E> { 42 + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { 43 + match self { 44 + EncodeError::Msg(_) => None, 45 + EncodeError::Write(err) => Some(err), 46 + } 47 + } 48 + } 49 + 50 + #[cfg(not(feature = "std"))] 51 + impl<E: fmt::Debug> ser::StdError for EncodeError<E> {} 52 + 53 + impl<E: fmt::Debug> fmt::Display for EncodeError<E> { 54 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 55 + fmt::Debug::fmt(self, f) 56 + } 57 + } 58 + 59 + impl<E: fmt::Debug> From<cbor4ii::EncodeError<E>> for EncodeError<E> { 60 + fn from(err: cbor4ii::EncodeError<E>) -> EncodeError<E> { 61 + match err { 62 + cbor4ii::EncodeError::Write(e) => EncodeError::Write(e), 63 + // Needed as `cbor4ii::EncodeError` is markes as non_exhaustive 64 + _ => EncodeError::Msg(err.to_string()), 65 + } 66 + } 67 + } 68 + 69 + /// A decoding error. 70 + #[derive(Debug, PartialEq)] 71 + pub enum DecodeError<E> { 72 + /// Custom error message. 73 + Msg(String), 74 + /// IO error. 75 + Read(E), 76 + /// End of file. 77 + Eof, 78 + /// Unexpected byte. 79 + Mismatch { 80 + /// Expected CBOR major type. 81 + expect_major: u8, 82 + /// Unexpected byte. 83 + byte: u8, 84 + }, 85 + /// Unexpected type. 86 + TypeMismatch { 87 + /// Type name. 88 + name: &'static str, 89 + /// Type byte. 90 + byte: u8, 91 + }, 92 + /// Too large integer. 93 + CastOverflow(TryFromIntError), 94 + /// Overflowing 128-bit integers. 95 + Overflow { 96 + /// Type of integer. 97 + name: &'static str, 98 + }, 99 + /// Decoding bytes/strings might require a borrow. 100 + RequireBorrowed { 101 + /// Type name (e.g. "bytes", "str"). 102 + name: &'static str, 103 + }, 104 + /// Length wasn't large enough. This error comes after attempting to consume the entirety of a 105 + /// item with a known length and failing to do so. 106 + RequireLength { 107 + /// Type name. 108 + name: &'static str, 109 + /// Required length. 110 + expect: usize, 111 + /// Given length. 112 + value: usize, 113 + }, 114 + /// Invalid UTF-8. 115 + InvalidUtf8(core::str::Utf8Error), 116 + /// Unsupported byte. 117 + Unsupported { 118 + /// Unsupported bute. 119 + byte: u8, 120 + }, 121 + /// Recursion limit reached. 122 + DepthLimit, 123 + /// Trailing data. 124 + TrailingData, 125 + /// Indefinite sized item was encountered. 126 + IndefiniteSize, 127 + } 128 + 129 + impl<E> From<E> for DecodeError<E> { 130 + fn from(err: E) -> DecodeError<E> { 131 + DecodeError::Read(err) 132 + } 133 + } 134 + 135 + #[cfg(feature = "std")] 136 + impl<E: std::error::Error + 'static> de::Error for DecodeError<E> { 137 + fn custom<T: fmt::Display>(msg: T) -> Self { 138 + DecodeError::Msg(msg.to_string()) 139 + } 140 + } 141 + 142 + #[cfg(not(feature = "std"))] 143 + impl<E: fmt::Debug> de::Error for DecodeError<E> { 144 + fn custom<T: fmt::Display>(msg: T) -> Self { 145 + DecodeError::Msg(msg.to_string()) 146 + } 147 + } 148 + 149 + #[cfg(feature = "std")] 150 + impl<E: std::error::Error + 'static> std::error::Error for DecodeError<E> { 151 + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { 152 + match self { 153 + DecodeError::Msg(_) => None, 154 + DecodeError::Read(err) => Some(err), 155 + _ => None, 156 + } 157 + } 158 + } 159 + 160 + #[cfg(not(feature = "std"))] 161 + impl<E: fmt::Debug> ser::StdError for DecodeError<E> {} 162 + 163 + impl<E: fmt::Debug> fmt::Display for DecodeError<E> { 164 + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 165 + fmt::Debug::fmt(self, f) 166 + } 167 + } 168 + 169 + impl<E: fmt::Debug> From<cbor4ii::DecodeError<E>> for DecodeError<E> { 170 + fn from(err: cbor4ii::DecodeError<E>) -> DecodeError<E> { 171 + match err { 172 + cbor4ii::DecodeError::Read(read) => DecodeError::Read(read), 173 + cbor4ii::DecodeError::Eof => DecodeError::Eof, 174 + cbor4ii::DecodeError::Mismatch { expect_major, byte } => { 175 + DecodeError::Mismatch { expect_major, byte } 176 + } 177 + cbor4ii::DecodeError::TypeMismatch { name, byte } => { 178 + DecodeError::TypeMismatch { name, byte } 179 + } 180 + cbor4ii::DecodeError::CastOverflow(overflow) => DecodeError::CastOverflow(overflow), 181 + cbor4ii::DecodeError::Overflow { name } => DecodeError::Overflow { name }, 182 + cbor4ii::DecodeError::RequireBorrowed { name } => DecodeError::RequireBorrowed { name }, 183 + cbor4ii::DecodeError::RequireLength { 184 + name, 185 + expect, 186 + value, 187 + } => DecodeError::RequireLength { 188 + name, 189 + expect, 190 + value, 191 + }, 192 + cbor4ii::DecodeError::InvalidUtf8(invalid) => DecodeError::InvalidUtf8(invalid), 193 + cbor4ii::DecodeError::Unsupported { byte } => DecodeError::Unsupported { byte }, 194 + cbor4ii::DecodeError::DepthLimit => DecodeError::DepthLimit, 195 + // Needed as `cbor4ii::EncodeError` is markes as non_exhaustive 196 + _ => DecodeError::Msg(err.to_string()), 197 + } 198 + } 199 + } 200 + 201 + /// Encode and Decode error combined. 202 + #[derive(Debug)] 203 + pub enum CodecError { 204 + /// A decoding error. 205 + Decode(DecodeError<Infallible>), 206 + /// An encoding error. 207 + Encode(EncodeError<TryReserveError>), 208 + /// A decoding error. 209 + #[cfg(feature = "std")] 210 + DecodeIo(DecodeError<std::io::Error>), 211 + /// An encoding error. 212 + #[cfg(feature = "std")] 213 + EncodeIo(EncodeError<std::io::Error>), 214 + } 215 + 216 + impl fmt::Display for CodecError { 217 + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 218 + match self { 219 + Self::Decode(error) => write!(f, "decode error: {}", error), 220 + Self::Encode(error) => write!(f, "encode error: {}", error), 221 + #[cfg(feature = "std")] 222 + Self::DecodeIo(error) => write!(f, "decode io error: {}", error), 223 + #[cfg(feature = "std")] 224 + Self::EncodeIo(error) => write!(f, "encode io error: {}", error), 225 + } 226 + } 227 + } 228 + 229 + #[cfg(feature = "std")] 230 + impl std::error::Error for CodecError {} 231 + 232 + impl From<DecodeError<Infallible>> for CodecError { 233 + fn from(error: DecodeError<Infallible>) -> Self { 234 + Self::Decode(error) 235 + } 236 + } 237 + 238 + #[cfg(feature = "std")] 239 + impl From<DecodeError<std::io::Error>> for CodecError { 240 + fn from(error: DecodeError<std::io::Error>) -> Self { 241 + Self::DecodeIo(error) 242 + } 243 + } 244 + 245 + impl From<EncodeError<TryReserveError>> for CodecError { 246 + fn from(error: EncodeError<TryReserveError>) -> Self { 247 + Self::Encode(error) 248 + } 249 + } 250 + 251 + #[cfg(feature = "std")] 252 + impl From<EncodeError<std::io::Error>> for CodecError { 253 + fn from(error: EncodeError<std::io::Error>) -> Self { 254 + Self::EncodeIo(error) 255 + } 256 + }
+148
vendor/git/serde_ipld_dagcbor/src/lib.rs
··· 1 + //! DAG-CBOR serialization and deserialization. 2 + //! 3 + //! # Usage 4 + //! 5 + //! Add this to your `Cargo.toml`: 6 + //! ```toml 7 + //! [dependencies] 8 + //! serde_ipld_dagcbor = "0.1.0" 9 + //! ``` 10 + //! 11 + //! Storing and loading Rust types is easy and requires only 12 + //! minimal modifications to the program code. 13 + //! 14 + //! ```rust 15 + //! # #[cfg(not(feature = "std"))] 16 + //! # fn main() {} 17 + //! use serde_derive::{Deserialize, Serialize}; 18 + //! use std::error::Error; 19 + //! use std::fs::File; 20 + //! use std::io::BufReader; 21 + //! 22 + //! // Types annotated with `Serialize` can be stored as CBOR. 23 + //! // To be able to load them again add `Deserialize`. 24 + //! #[derive(Debug, Serialize, Deserialize)] 25 + //! struct Mascot { 26 + //! name: String, 27 + //! species: String, 28 + //! year_of_birth: u32, 29 + //! } 30 + //! 31 + //! # #[cfg(feature = "std")] 32 + //! fn main() -> Result<(), Box<dyn Error>> { 33 + //! let ferris = Mascot { 34 + //! name: "Ferris".to_owned(), 35 + //! species: "crab".to_owned(), 36 + //! year_of_birth: 2015, 37 + //! }; 38 + //! 39 + //! let ferris_file = File::create("examples/ferris.cbor")?; 40 + //! // Write Ferris to the given file. 41 + //! // Instead of a file you can use any type that implements `io::Write` 42 + //! // like a HTTP body, database connection etc. 43 + //! serde_ipld_dagcbor::to_writer(ferris_file, &ferris)?; 44 + //! 45 + //! let tux_file = File::open("examples/tux.cbor")?; 46 + //! let tux_reader = BufReader::new(tux_file); 47 + //! // Load Tux from a file. 48 + //! // Serde CBOR performs roundtrip serialization meaning that 49 + //! // the data will not change in any way. 50 + //! let tux: Mascot = serde_ipld_dagcbor::from_reader(tux_reader)?; 51 + //! 52 + //! println!("{:?}", tux); 53 + //! // prints: Mascot { name: "Tux", species: "penguin", year_of_birth: 1996 } 54 + //! 55 + //! Ok(()) 56 + //! } 57 + //! ``` 58 + //! 59 + //! There are a lot of options available to customize the format. 60 + //! To operate on untyped DAG-CBOR values have a look at the [`ipld_core::ipld::Ipld`] type. 61 + //! 62 + //! # Type-based Serialization and Deserialization 63 + //! Serde provides a mechanism for low boilerplate serialization & deserialization of values to and 64 + //! from CBOR via the serialization API. To be able to serialize a piece of data, it must implement 65 + //! the `serde::Serialize` trait. To be able to deserialize a piece of data, it must implement the 66 + //! `serde::Deserialize` trait. Serde provides an annotation to automatically generate the 67 + //! code for these traits: `#[derive(Serialize, Deserialize)]`. 68 + //! 69 + //! Read a general CBOR value with an unknown content. 70 + //! 71 + //! ```rust 72 + //! use serde_ipld_dagcbor::from_slice; 73 + //! use ipld_core::ipld::Ipld; 74 + //! 75 + //! let slice = b"\x82\x01\xa1aaab"; 76 + //! let value: Ipld = from_slice(slice).unwrap(); 77 + //! println!("{:?}", value); // List([Integer(1), Map({"a": String("b")})]) 78 + //! ``` 79 + //! 80 + //! Serialize an object. 81 + //! 82 + //! ```rust 83 + //! use std::collections::BTreeMap; 84 + //! use serde_ipld_dagcbor::to_vec; 85 + //! 86 + //! let mut programming_languages = BTreeMap::new(); 87 + //! programming_languages.insert("rust", vec!["safe", "concurrent", "fast"]); 88 + //! programming_languages.insert("python", vec!["powerful", "friendly", "open"]); 89 + //! programming_languages.insert("js", vec!["lightweight", "interpreted", "object-oriented"]); 90 + //! let encoded = to_vec(&programming_languages); 91 + //! assert_eq!(encoded.unwrap().len(), 103); 92 + //! ``` 93 + //! 94 + //! # `no-std` support 95 + //! 96 + //! Serde CBOR supports building in a `no_std` context, use the following lines 97 + //! in your `Cargo.toml` dependencies: 98 + //! ``` toml 99 + //! [dependencies] 100 + //! serde = { version = "1.0", default-features = false } 101 + //! serde_ipld_dagcbor = { version = "0.1.0", default-features = false } 102 + //! ``` 103 + //! 104 + //! Without the `std` feature the functions [from_reader], and [to_writer] are not exported. 105 + //! 106 + //! *Note*: to use derive macros in serde you will need to declare `serde` 107 + //! dependency like so: 108 + //! ``` toml 109 + //! serde = { version = "1.0", default-features = false, features = ["derive"] } 110 + //! ``` 111 + 112 + #![deny(missing_docs)] 113 + #![cfg_attr(not(feature = "std"), no_std)] 114 + 115 + extern crate alloc; 116 + 117 + mod cbor4ii_nonpub; 118 + // The `Codec` implementation is only available if the `no-cid-as-bytes` feature is disabled, due 119 + // to the links being extracted with a Serde based approach. 120 + #[cfg(all(feature = "std", not(feature = "no-cid-as-bytes"), feature = "codec"))] 121 + pub mod codec; 122 + pub mod de; 123 + pub mod error; 124 + pub mod ser; 125 + 126 + #[doc(inline)] 127 + pub use crate::error::{DecodeError, EncodeError}; 128 + 129 + // Convenience functions for serialization and deserialization. 130 + #[doc(inline)] 131 + pub use crate::de::from_slice; 132 + 133 + #[cfg(feature = "std")] 134 + #[doc(inline)] 135 + pub use crate::de::from_reader; 136 + 137 + #[doc(inline)] 138 + pub use crate::ser::to_vec; 139 + 140 + #[cfg(feature = "std")] 141 + #[doc(inline)] 142 + pub use crate::ser::to_writer; 143 + 144 + /// The multicodec code for DAG-CBOR. 145 + pub const DAG_CBOR_CODE: u64 = 0x71; 146 + 147 + /// The CBOR tag that is used for CIDs. 148 + const CBOR_TAGS_CID: u64 = 42;
+699
vendor/git/serde_ipld_dagcbor/src/ser.rs
··· 1 + //! Serialization. 2 + #[cfg(not(feature = "std"))] 3 + use alloc::{collections::TryReserveError, string::ToString, vec::Vec}; 4 + #[cfg(feature = "std")] 5 + use std::collections::TryReserveError; 6 + 7 + pub use cbor4ii::core::utils::BufWriter; 8 + #[cfg(feature = "std")] 9 + use cbor4ii::core::utils::IoWriter; 10 + use cbor4ii::core::{ 11 + enc::{self, Encode}, 12 + types, 13 + }; 14 + use ipld_core::cid::serde::CID_SERDE_PRIVATE_IDENTIFIER; 15 + use serde::{ser, Serialize}; 16 + 17 + use crate::error::EncodeError; 18 + use crate::CBOR_TAGS_CID; 19 + 20 + /// Serializes a value to a vector. 21 + pub fn to_vec<T>(value: &T) -> Result<Vec<u8>, EncodeError<TryReserveError>> 22 + where 23 + T: Serialize + ?Sized, 24 + { 25 + let writer = BufWriter::new(Vec::new()); 26 + let mut serializer = Serializer::new(writer); 27 + value.serialize(&mut serializer)?; 28 + Ok(serializer.into_inner().into_inner()) 29 + } 30 + 31 + /// Serializes a value to a writer. 32 + #[cfg(feature = "std")] 33 + pub fn to_writer<W, T>(writer: W, value: &T) -> Result<(), EncodeError<std::io::Error>> 34 + where 35 + W: std::io::Write, 36 + T: Serialize, 37 + { 38 + let mut serializer = Serializer::new(IoWriter::new(writer)); 39 + value.serialize(&mut serializer) 40 + } 41 + 42 + /// A structure for serializing Rust values to DAG-CBOR. 43 + pub struct Serializer<W> { 44 + writer: W, 45 + } 46 + 47 + impl<W> Serializer<W> { 48 + /// Creates a new CBOR serializer. 49 + pub fn new(writer: W) -> Serializer<W> { 50 + Serializer { writer } 51 + } 52 + 53 + /// Returns the underlying writer. 54 + pub fn into_inner(self) -> W { 55 + self.writer 56 + } 57 + } 58 + 59 + impl<'a, W: enc::Write> serde::Serializer for &'a mut Serializer<W> { 60 + type Ok = (); 61 + type Error = EncodeError<W::Error>; 62 + 63 + type SerializeSeq = CollectSeq<'a, W>; 64 + type SerializeTuple = BoundedCollect<'a, W>; 65 + type SerializeTupleStruct = BoundedCollect<'a, W>; 66 + type SerializeTupleVariant = BoundedCollect<'a, W>; 67 + type SerializeMap = CollectMap<'a, W>; 68 + type SerializeStruct = CollectMap<'a, W>; 69 + type SerializeStructVariant = CollectMap<'a, W>; 70 + 71 + #[inline] 72 + fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> { 73 + v.encode(&mut self.writer)?; 74 + Ok(()) 75 + } 76 + 77 + #[inline] 78 + fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> { 79 + v.encode(&mut self.writer)?; 80 + Ok(()) 81 + } 82 + 83 + #[inline] 84 + fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> { 85 + v.encode(&mut self.writer)?; 86 + Ok(()) 87 + } 88 + 89 + #[inline] 90 + fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> { 91 + v.encode(&mut self.writer)?; 92 + Ok(()) 93 + } 94 + 95 + #[inline] 96 + fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> { 97 + v.encode(&mut self.writer)?; 98 + Ok(()) 99 + } 100 + 101 + #[inline] 102 + fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> { 103 + v.encode(&mut self.writer)?; 104 + Ok(()) 105 + } 106 + 107 + #[inline] 108 + fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> { 109 + v.encode(&mut self.writer)?; 110 + Ok(()) 111 + } 112 + 113 + #[inline] 114 + fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> { 115 + v.encode(&mut self.writer)?; 116 + Ok(()) 117 + } 118 + 119 + #[inline] 120 + fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> { 121 + v.encode(&mut self.writer)?; 122 + Ok(()) 123 + } 124 + 125 + #[inline] 126 + fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> { 127 + // In DAG-CBOR floats are always encoded as f64. 128 + self.serialize_f64(f64::from(v)) 129 + } 130 + 131 + #[inline] 132 + fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> { 133 + // In DAG-CBOR only finite floats are supported. 134 + if !v.is_finite() { 135 + Err(EncodeError::Msg( 136 + "Float must be a finite number, not Infinity or NaN".into(), 137 + )) 138 + } else { 139 + v.encode(&mut self.writer)?; 140 + Ok(()) 141 + } 142 + } 143 + 144 + #[inline] 145 + fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> { 146 + let mut buf = [0; 4]; 147 + self.serialize_str(v.encode_utf8(&mut buf)) 148 + } 149 + 150 + #[inline] 151 + fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> { 152 + v.encode(&mut self.writer)?; 153 + Ok(()) 154 + } 155 + 156 + #[inline] 157 + fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> { 158 + types::Bytes(v).encode(&mut self.writer)?; 159 + Ok(()) 160 + } 161 + 162 + #[inline] 163 + fn serialize_none(self) -> Result<Self::Ok, Self::Error> { 164 + types::Null.encode(&mut self.writer)?; 165 + Ok(()) 166 + } 167 + 168 + #[inline] 169 + fn serialize_some<T: Serialize + ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error> { 170 + value.serialize(self) 171 + } 172 + 173 + #[inline] 174 + fn serialize_unit(self) -> Result<Self::Ok, Self::Error> { 175 + // The cbor4ii Serde implementation encodes unit as an empty array, for DAG-CBOR we encode 176 + // it as `NULL`. 177 + types::Null.encode(&mut self.writer)?; 178 + Ok(()) 179 + } 180 + 181 + #[inline] 182 + fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> { 183 + self.serialize_unit() 184 + } 185 + 186 + #[inline] 187 + fn serialize_unit_variant( 188 + self, 189 + _name: &'static str, 190 + _variant_index: u32, 191 + variant: &'static str, 192 + ) -> Result<Self::Ok, Self::Error> { 193 + self.serialize_str(variant) 194 + } 195 + 196 + #[inline] 197 + fn serialize_newtype_struct<T: Serialize + ?Sized>( 198 + self, 199 + name: &'static str, 200 + value: &T, 201 + ) -> Result<Self::Ok, Self::Error> { 202 + if name == CID_SERDE_PRIVATE_IDENTIFIER { 203 + value.serialize(&mut CidSerializer(self)) 204 + } else { 205 + value.serialize(self) 206 + } 207 + } 208 + 209 + #[inline] 210 + fn serialize_newtype_variant<T: Serialize + ?Sized>( 211 + self, 212 + _name: &'static str, 213 + _variant_index: u32, 214 + variant: &'static str, 215 + value: &T, 216 + ) -> Result<Self::Ok, Self::Error> { 217 + enc::MapStartBounded(1).encode(&mut self.writer)?; 218 + variant.encode(&mut self.writer)?; 219 + value.serialize(self) 220 + } 221 + 222 + #[inline] 223 + fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> { 224 + CollectSeq::new(self, len) 225 + } 226 + 227 + #[inline] 228 + fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> { 229 + enc::ArrayStartBounded(len).encode(&mut self.writer)?; 230 + Ok(BoundedCollect { ser: self }) 231 + } 232 + 233 + #[inline] 234 + fn serialize_tuple_struct( 235 + self, 236 + _name: &'static str, 237 + len: usize, 238 + ) -> Result<Self::SerializeTupleStruct, Self::Error> { 239 + self.serialize_tuple(len) 240 + } 241 + 242 + #[inline] 243 + fn serialize_tuple_variant( 244 + self, 245 + _name: &'static str, 246 + _variant_index: u32, 247 + variant: &'static str, 248 + len: usize, 249 + ) -> Result<Self::SerializeTupleVariant, Self::Error> { 250 + enc::MapStartBounded(1).encode(&mut self.writer)?; 251 + variant.encode(&mut self.writer)?; 252 + enc::ArrayStartBounded(len).encode(&mut self.writer)?; 253 + Ok(BoundedCollect { ser: self }) 254 + } 255 + 256 + #[inline] 257 + fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> { 258 + Ok(CollectMap::new(self)) 259 + } 260 + 261 + #[inline] 262 + fn serialize_struct( 263 + self, 264 + _name: &'static str, 265 + len: usize, 266 + ) -> Result<Self::SerializeStruct, Self::Error> { 267 + enc::MapStartBounded(len).encode(&mut self.writer)?; 268 + Ok(CollectMap::new(self)) 269 + } 270 + 271 + #[inline] 272 + fn serialize_struct_variant( 273 + self, 274 + _name: &'static str, 275 + _variant_index: u32, 276 + variant: &'static str, 277 + len: usize, 278 + ) -> Result<Self::SerializeStructVariant, Self::Error> { 279 + enc::MapStartBounded(1).encode(&mut self.writer)?; 280 + variant.encode(&mut self.writer)?; 281 + enc::MapStartBounded(len).encode(&mut self.writer)?; 282 + Ok(CollectMap::new(self)) 283 + } 284 + 285 + #[inline] 286 + fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> { 287 + if !(u64::MAX as i128 >= v && -(u64::MAX as i128 + 1) <= v) { 288 + return Err(EncodeError::Msg( 289 + "Integer must be within [-u64::MAX-1, u64::MAX] range".into(), 290 + )); 291 + } 292 + 293 + v.encode(&mut self.writer)?; 294 + Ok(()) 295 + } 296 + 297 + #[inline] 298 + fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> { 299 + if (u64::MAX as u128) < v { 300 + return Err(EncodeError::Msg( 301 + "Unsigned integer must be within [0, u64::MAX] range".into(), 302 + )); 303 + } 304 + v.encode(&mut self.writer)?; 305 + Ok(()) 306 + } 307 + 308 + #[inline] 309 + fn is_human_readable(&self) -> bool { 310 + false 311 + } 312 + } 313 + 314 + /// Struct for implementign SerializeSeq. 315 + pub struct CollectSeq<'a, W> { 316 + /// The number of elements. This is used in case the number of elements is not known 317 + /// beforehand. 318 + count: usize, 319 + ser: &'a mut Serializer<W>, 320 + /// An in-memory serializer in case the number of elements is not known beforehand. 321 + mem_ser: Option<Serializer<BufWriter>>, 322 + } 323 + 324 + impl<'a, W: enc::Write> CollectSeq<'a, W> { 325 + /// If the length of the sequence is given, use it. Else buffer the sequence in order to count 326 + /// the number of elements, which is then written before the elements are. 327 + fn new(ser: &'a mut Serializer<W>, len: Option<usize>) -> Result<Self, EncodeError<W::Error>> { 328 + let mem_ser = if let Some(len) = len { 329 + enc::ArrayStartBounded(len).encode(&mut ser.writer)?; 330 + None 331 + } else { 332 + Some(Serializer::new(BufWriter::new(Vec::new()))) 333 + }; 334 + Ok(Self { 335 + count: 0, 336 + ser, 337 + mem_ser, 338 + }) 339 + } 340 + } 341 + 342 + /// Helper for processing collections. 343 + pub struct BoundedCollect<'a, W> { 344 + ser: &'a mut Serializer<W>, 345 + } 346 + 347 + impl<W: enc::Write> serde::ser::SerializeSeq for CollectSeq<'_, W> { 348 + type Ok = (); 349 + type Error = EncodeError<W::Error>; 350 + 351 + #[inline] 352 + fn serialize_element<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> { 353 + self.count += 1; 354 + if let Some(ser) = self.mem_ser.as_mut() { 355 + value 356 + .serialize(&mut *ser) 357 + .map_err(|_| EncodeError::Msg("List element cannot be serialized".to_string())) 358 + } else { 359 + value.serialize(&mut *self.ser) 360 + } 361 + } 362 + 363 + #[inline] 364 + fn end(self) -> Result<Self::Ok, Self::Error> { 365 + // Data was buffered in order to be able to write out the number of elements before they 366 + // are serialized. 367 + if let Some(ser) = self.mem_ser { 368 + enc::ArrayStartBounded(self.count).encode(&mut self.ser.writer)?; 369 + self.ser.writer.push(&ser.into_inner().into_inner())?; 370 + } 371 + 372 + Ok(()) 373 + } 374 + } 375 + 376 + impl<W: enc::Write> serde::ser::SerializeTuple for BoundedCollect<'_, W> { 377 + type Ok = (); 378 + type Error = EncodeError<W::Error>; 379 + 380 + #[inline] 381 + fn serialize_element<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> { 382 + value.serialize(&mut *self.ser) 383 + } 384 + 385 + #[inline] 386 + fn end(self) -> Result<Self::Ok, Self::Error> { 387 + Ok(()) 388 + } 389 + } 390 + 391 + impl<W: enc::Write> serde::ser::SerializeTupleStruct for BoundedCollect<'_, W> { 392 + type Ok = (); 393 + type Error = EncodeError<W::Error>; 394 + 395 + #[inline] 396 + fn serialize_field<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> { 397 + value.serialize(&mut *self.ser) 398 + } 399 + 400 + #[inline] 401 + fn end(self) -> Result<Self::Ok, Self::Error> { 402 + Ok(()) 403 + } 404 + } 405 + 406 + impl<W: enc::Write> serde::ser::SerializeTupleVariant for BoundedCollect<'_, W> { 407 + type Ok = (); 408 + type Error = EncodeError<W::Error>; 409 + 410 + #[inline] 411 + fn serialize_field<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> { 412 + value.serialize(&mut *self.ser) 413 + } 414 + 415 + #[inline] 416 + fn end(self) -> Result<Self::Ok, Self::Error> { 417 + Ok(()) 418 + } 419 + } 420 + 421 + /// CBOR RFC-7049 specifies a canonical sort order, where keys are sorted by length first. This 422 + /// was later revised with RFC-8949, but we need to stick to the original order to stay compatible 423 + /// with existing data. 424 + /// We first serialize each map entry (the key and the value) into a buffer and then sort those 425 + /// buffers. Once sorted they are written to the actual output. 426 + pub struct CollectMap<'a, W> { 427 + buffer: BufWriter, 428 + entries: Vec<Vec<u8>>, 429 + ser: &'a mut Serializer<W>, 430 + } 431 + 432 + impl<'a, W> CollectMap<'a, W> 433 + where 434 + W: enc::Write, 435 + { 436 + fn new(ser: &'a mut Serializer<W>) -> Self { 437 + Self { 438 + buffer: BufWriter::new(Vec::new()), 439 + entries: Vec::new(), 440 + ser, 441 + } 442 + } 443 + 444 + fn serialize<T: Serialize + ?Sized>( 445 + &mut self, 446 + maybe_key: Option<&'static str>, 447 + value: &T, 448 + ) -> Result<(), EncodeError<W::Error>> { 449 + // Instantiate a new serializer, so that the buffer can be re-used. 450 + let mut mem_serializer = Serializer::new(&mut self.buffer); 451 + if let Some(key) = maybe_key { 452 + key.serialize(&mut mem_serializer) 453 + .map_err(|_| EncodeError::Msg("Struct key cannot be serialized.".to_string()))?; 454 + } 455 + value 456 + .serialize(&mut mem_serializer) 457 + .map_err(|_| EncodeError::Msg("Struct value cannot be serialized.".to_string()))?; 458 + 459 + self.entries.push(self.buffer.buffer().to_vec()); 460 + self.buffer.clear(); 461 + 462 + Ok(()) 463 + } 464 + 465 + fn end(mut self) -> Result<(), EncodeError<W::Error>> { 466 + // This sorting step makes sure we have the expected order of the keys. Byte-wise 467 + // comparison over the encoded forms gives us the right order as keys in DAG-CBOR are 468 + // always (text) strings, hence have the same CBOR major type 3. The length of the string 469 + // is encoded in the prefix bits along with the major type. This means that a shorter string 470 + // always sorts before a longer string even with the compact length representation. 471 + self.entries.sort_unstable(); 472 + for entry in self.entries { 473 + self.ser.writer.push(&entry)?; 474 + } 475 + Ok(()) 476 + } 477 + } 478 + 479 + impl<W> serde::ser::SerializeMap for CollectMap<'_, W> 480 + where 481 + W: enc::Write, 482 + { 483 + type Ok = (); 484 + type Error = EncodeError<W::Error>; 485 + 486 + #[inline] 487 + fn serialize_key<T: Serialize + ?Sized>(&mut self, key: &T) -> Result<(), Self::Error> { 488 + // The key needs to be add to the buffer without any further operations. Serializing the 489 + // value will then do the necessary flushing etc. 490 + let mut mem_serializer = Serializer::new(&mut self.buffer); 491 + key.serialize(&mut mem_serializer) 492 + .map_err(|_| EncodeError::Msg("Map key cannot be serialized.".to_string()))?; 493 + Ok(()) 494 + } 495 + 496 + #[inline] 497 + fn serialize_value<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> { 498 + self.serialize(None, value) 499 + } 500 + 501 + #[inline] 502 + fn end(self) -> Result<Self::Ok, Self::Error> { 503 + enc::MapStartBounded(self.entries.len()).encode(&mut self.ser.writer)?; 504 + self.end() 505 + } 506 + } 507 + 508 + impl<W> serde::ser::SerializeStruct for CollectMap<'_, W> 509 + where 510 + W: enc::Write, 511 + { 512 + type Ok = (); 513 + type Error = EncodeError<W::Error>; 514 + 515 + #[inline] 516 + fn serialize_field<T: Serialize + ?Sized>( 517 + &mut self, 518 + key: &'static str, 519 + value: &T, 520 + ) -> Result<(), Self::Error> { 521 + self.serialize(Some(key), value) 522 + } 523 + 524 + #[inline] 525 + fn end(self) -> Result<Self::Ok, Self::Error> { 526 + self.end() 527 + } 528 + } 529 + 530 + impl<W> serde::ser::SerializeStructVariant for CollectMap<'_, W> 531 + where 532 + W: enc::Write, 533 + { 534 + type Ok = (); 535 + type Error = EncodeError<W::Error>; 536 + 537 + #[inline] 538 + fn serialize_field<T: Serialize + ?Sized>( 539 + &mut self, 540 + key: &'static str, 541 + value: &T, 542 + ) -> Result<(), Self::Error> { 543 + self.serialize(Some(key), value) 544 + } 545 + 546 + #[inline] 547 + fn end(self) -> Result<Self::Ok, Self::Error> { 548 + self.end() 549 + } 550 + } 551 + 552 + /// Serializing a CID correctly as DAG-CBOR. 553 + struct CidSerializer<'a, W>(&'a mut Serializer<W>); 554 + 555 + impl<'a, W: enc::Write> ser::Serializer for &'a mut CidSerializer<'a, W> 556 + where 557 + W::Error: core::fmt::Debug, 558 + { 559 + type Ok = (); 560 + type Error = EncodeError<W::Error>; 561 + 562 + type SerializeSeq = ser::Impossible<Self::Ok, Self::Error>; 563 + type SerializeTuple = ser::Impossible<Self::Ok, Self::Error>; 564 + type SerializeTupleStruct = ser::Impossible<Self::Ok, Self::Error>; 565 + type SerializeTupleVariant = ser::Impossible<Self::Ok, Self::Error>; 566 + type SerializeMap = ser::Impossible<Self::Ok, Self::Error>; 567 + type SerializeStruct = ser::Impossible<Self::Ok, Self::Error>; 568 + type SerializeStructVariant = ser::Impossible<Self::Ok, Self::Error>; 569 + 570 + fn serialize_bool(self, _value: bool) -> Result<Self::Ok, Self::Error> { 571 + Err(ser::Error::custom("unreachable")) 572 + } 573 + fn serialize_i8(self, _value: i8) -> Result<Self::Ok, Self::Error> { 574 + Err(ser::Error::custom("unreachable")) 575 + } 576 + fn serialize_i16(self, _value: i16) -> Result<Self::Ok, Self::Error> { 577 + Err(ser::Error::custom("unreachable")) 578 + } 579 + fn serialize_i32(self, _value: i32) -> Result<Self::Ok, Self::Error> { 580 + Err(ser::Error::custom("unreachable")) 581 + } 582 + fn serialize_i64(self, _value: i64) -> Result<Self::Ok, Self::Error> { 583 + Err(ser::Error::custom("unreachable")) 584 + } 585 + fn serialize_u8(self, _value: u8) -> Result<Self::Ok, Self::Error> { 586 + Err(ser::Error::custom("unreachable")) 587 + } 588 + fn serialize_u16(self, _value: u16) -> Result<Self::Ok, Self::Error> { 589 + Err(ser::Error::custom("unreachable")) 590 + } 591 + fn serialize_u32(self, _value: u32) -> Result<Self::Ok, Self::Error> { 592 + Err(ser::Error::custom("unreachable")) 593 + } 594 + fn serialize_u64(self, _value: u64) -> Result<Self::Ok, Self::Error> { 595 + Err(ser::Error::custom("unreachable")) 596 + } 597 + fn serialize_f32(self, _value: f32) -> Result<Self::Ok, Self::Error> { 598 + Err(ser::Error::custom("unreachable")) 599 + } 600 + fn serialize_f64(self, _value: f64) -> Result<Self::Ok, Self::Error> { 601 + Err(ser::Error::custom("unreachable")) 602 + } 603 + fn serialize_char(self, _value: char) -> Result<Self::Ok, Self::Error> { 604 + Err(ser::Error::custom("unreachable")) 605 + } 606 + fn serialize_str(self, _value: &str) -> Result<Self::Ok, Self::Error> { 607 + Err(ser::Error::custom("unreachable")) 608 + } 609 + 610 + fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok, Self::Error> { 611 + // The bytes of the CID is prefixed with a null byte when encoded as CBOR. 612 + let prefixed = [&[0x00], value].concat(); 613 + // CIDs are serialized with CBOR tag 42. 614 + types::Tag(CBOR_TAGS_CID, types::Bytes(&prefixed[..])).encode(&mut self.0.writer)?; 615 + Ok(()) 616 + } 617 + 618 + fn serialize_none(self) -> Result<Self::Ok, Self::Error> { 619 + Err(ser::Error::custom("unreachable")) 620 + } 621 + fn serialize_some<T: ?Sized + ser::Serialize>( 622 + self, 623 + _value: &T, 624 + ) -> Result<Self::Ok, Self::Error> { 625 + Err(ser::Error::custom("unreachable")) 626 + } 627 + fn serialize_unit(self) -> Result<Self::Ok, Self::Error> { 628 + Err(ser::Error::custom("unreachable")) 629 + } 630 + fn serialize_unit_struct(self, _name: &str) -> Result<Self::Ok, Self::Error> { 631 + Err(ser::Error::custom("unreachable")) 632 + } 633 + fn serialize_unit_variant( 634 + self, 635 + _name: &str, 636 + _variant_index: u32, 637 + _variant: &str, 638 + ) -> Result<Self::Ok, Self::Error> { 639 + Err(ser::Error::custom("unreachable")) 640 + } 641 + 642 + fn serialize_newtype_struct<T: ?Sized + ser::Serialize>( 643 + self, 644 + _name: &str, 645 + _value: &T, 646 + ) -> Result<Self::Ok, Self::Error> { 647 + Err(ser::Error::custom("unreachable")) 648 + } 649 + fn serialize_newtype_variant<T: ?Sized + ser::Serialize>( 650 + self, 651 + _name: &str, 652 + _variant_index: u32, 653 + _variant: &str, 654 + _value: &T, 655 + ) -> Result<Self::Ok, Self::Error> { 656 + Err(ser::Error::custom("unreachable")) 657 + } 658 + fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> { 659 + Err(ser::Error::custom("unreachable")) 660 + } 661 + fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> { 662 + Err(ser::Error::custom("unreachable")) 663 + } 664 + fn serialize_tuple_struct( 665 + self, 666 + _name: &str, 667 + _len: usize, 668 + ) -> Result<Self::SerializeTupleStruct, Self::Error> { 669 + Err(ser::Error::custom("unreachable")) 670 + } 671 + fn serialize_tuple_variant( 672 + self, 673 + _name: &str, 674 + _variant_index: u32, 675 + _variant: &str, 676 + _len: usize, 677 + ) -> Result<Self::SerializeTupleVariant, Self::Error> { 678 + Err(ser::Error::custom("unreachable")) 679 + } 680 + fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> { 681 + Err(ser::Error::custom("unreachable")) 682 + } 683 + fn serialize_struct( 684 + self, 685 + _name: &str, 686 + _len: usize, 687 + ) -> Result<Self::SerializeStruct, Self::Error> { 688 + Err(ser::Error::custom("unreachable")) 689 + } 690 + fn serialize_struct_variant( 691 + self, 692 + _name: &str, 693 + _variant_index: u32, 694 + _variant: &str, 695 + _len: usize, 696 + ) -> Result<Self::SerializeStructVariant, Self::Error> { 697 + Err(ser::Error::custom("unreachable")) 698 + } 699 + }
+355
vendor/git/serde_ipld_dagcbor/tests/cid.rs
··· 1 + use std::convert::{TryFrom, TryInto}; 2 + use std::str::FromStr; 3 + 4 + use ipld_core::{cid::Cid, ipld::Ipld}; 5 + use serde::de; 6 + use serde_bytes::ByteBuf; 7 + use serde_derive::{Deserialize, Serialize}; 8 + use serde_ipld_dagcbor::{from_slice, to_vec}; 9 + 10 + #[test] 11 + fn test_cid_struct() { 12 + #[derive(Debug, PartialEq, Deserialize, Serialize)] 13 + struct MyStruct { 14 + cid: Cid, 15 + data: bool, 16 + } 17 + 18 + let cid = Cid::from_str("bafkreibme22gw2h7y2h7tg2fhqotaqjucnbc24deqo72b6mkl2egezxhvy").unwrap(); 19 + let cid_encoded = to_vec(&cid).unwrap(); 20 + assert_eq!( 21 + cid_encoded, 22 + [ 23 + 0xd8, 0x2a, 0x58, 0x25, 0x00, 0x01, 0x55, 0x12, 0x20, 0x2c, 0x26, 0xb4, 0x6b, 0x68, 24 + 0xff, 0xc6, 0x8f, 0xf9, 0x9b, 0x45, 0x3c, 0x1d, 0x30, 0x41, 0x34, 0x13, 0x42, 0x2d, 25 + 0x70, 0x64, 0x83, 0xbf, 0xa0, 0xf9, 0x8a, 0x5e, 0x88, 0x62, 0x66, 0xe7, 0xae, 26 + ] 27 + ); 28 + 29 + let cid_decoded_as_cid: Cid = from_slice(&cid_encoded).unwrap(); 30 + assert_eq!(cid_decoded_as_cid, cid); 31 + 32 + let cid_decoded_as_ipld: Ipld = from_slice(&cid_encoded).unwrap(); 33 + assert_eq!(cid_decoded_as_ipld, Ipld::Link(cid)); 34 + 35 + // Tests with the Type nested in a struct 36 + 37 + let mystruct = MyStruct { cid, data: true }; 38 + let mystruct_encoded = to_vec(&mystruct).unwrap(); 39 + assert_eq!( 40 + mystruct_encoded, 41 + [ 42 + 0xa2, 0x63, 0x63, 0x69, 0x64, 0xd8, 0x2a, 0x58, 0x25, 0x00, 0x01, 0x55, 0x12, 0x20, 43 + 0x2c, 0x26, 0xb4, 0x6b, 0x68, 0xff, 0xc6, 0x8f, 0xf9, 0x9b, 0x45, 0x3c, 0x1d, 0x30, 44 + 0x41, 0x34, 0x13, 0x42, 0x2d, 0x70, 0x64, 0x83, 0xbf, 0xa0, 0xf9, 0x8a, 0x5e, 0x88, 45 + 0x62, 0x66, 0xe7, 0xae, 0x64, 0x64, 0x61, 0x74, 0x61, 0xf5 46 + ] 47 + ); 48 + 49 + let mystruct_decoded_as_mystruct: MyStruct = from_slice(&mystruct_encoded).unwrap(); 50 + assert_eq!(mystruct_decoded_as_mystruct, mystruct); 51 + 52 + let mystruct_decoded_as_ipld: Ipld = from_slice(&mystruct_encoded).unwrap(); 53 + let mut expected_map = std::collections::BTreeMap::new(); 54 + expected_map.insert("cid".to_string(), Ipld::Link(cid)); 55 + expected_map.insert("data".to_string(), Ipld::Bool(true)); 56 + assert_eq!(mystruct_decoded_as_ipld, Ipld::Map(expected_map)); 57 + } 58 + 59 + /// Test that arbitrary bytes are not interpreted as CID. 60 + #[test] 61 + fn test_binary_not_as_cid() { 62 + // h'affe' 63 + // 42 # bytes(2) 64 + // AFFE # "\xAF\xFE" 65 + let bytes = [0x42, 0xaf, 0xfe]; 66 + let bytes_as_ipld: Ipld = from_slice(&bytes).unwrap(); 67 + assert_eq!(bytes_as_ipld, Ipld::Bytes(vec![0xaf, 0xfe])); 68 + } 69 + 70 + /// Test that CIDs don't decode into byte buffers, lists, etc. 71 + #[test] 72 + fn test_cid_not_as_bytes() { 73 + let cbor_cid = [ 74 + 0xd8, 0x2a, 0x58, 0x25, 0x00, 0x01, 0x55, 0x12, 0x20, 0x2c, 0x26, 0xb4, 0x6b, 0x68, 0xff, 75 + 0xc6, 0x8f, 0xf9, 0x9b, 0x45, 0x3c, 0x1d, 0x30, 0x41, 0x34, 0x13, 0x42, 0x2d, 0x70, 0x64, 76 + 0x83, 0xbf, 0xa0, 0xf9, 0x8a, 0x5e, 0x88, 0x62, 0x66, 0xe7, 0xae, 77 + ]; 78 + from_slice::<Vec<u8>>(&cbor_cid).expect_err("shouldn't have parsed a tagged CID as a sequence"); 79 + from_slice::<serde_bytes::ByteBuf>(&cbor_cid) 80 + .expect_err("shouldn't have parsed a tagged CID as a byte array"); 81 + from_slice::<serde_bytes::ByteBuf>(&cbor_cid[2..]) 82 + .expect("should have parsed an untagged CID as a byte array"); 83 + 84 + #[derive(Debug, Deserialize, PartialEq)] 85 + struct NewType(ByteBuf); 86 + 87 + #[derive(Debug, Deserialize, PartialEq)] 88 + #[serde(untagged)] 89 + enum BytesInEnum { 90 + MyCid(NewType), 91 + } 92 + 93 + // With the `no-cid-as-bytes` feature enabled, we make sure that it will error, when we try to 94 + // decode a CID as bytes. 95 + #[cfg(feature = "no-cid-as-bytes")] 96 + from_slice::<BytesInEnum>(&cbor_cid) 97 + .expect_err("shouldn't have parsed a tagged CID as byte array"); 98 + 99 + // With that feature disabled, then it will decode the CID (without the TAG and the zero 100 + // prefix) as bytes. 101 + #[cfg(not(feature = "no-cid-as-bytes"))] 102 + { 103 + let cid_without_tag = &cbor_cid[5..]; 104 + assert_eq!( 105 + from_slice::<BytesInEnum>(&cbor_cid).unwrap(), 106 + BytesInEnum::MyCid(NewType(ByteBuf::from(cid_without_tag))) 107 + ); 108 + } 109 + } 110 + 111 + /// Test whether a binary CID could be serialized if it isn't prefixed by tag 42. It should fail. 112 + #[test] 113 + fn test_cid_bytes_without_tag() { 114 + let cbor_cid = [ 115 + 0xd8, 0x2a, 0x58, 0x25, 0x00, 0x01, 0x55, 0x12, 0x20, 0x2c, 0x26, 0xb4, 0x6b, 0x68, 0xff, 116 + 0xc6, 0x8f, 0xf9, 0x9b, 0x45, 0x3c, 0x1d, 0x30, 0x41, 0x34, 0x13, 0x42, 0x2d, 0x70, 0x64, 117 + 0x83, 0xbf, 0xa0, 0xf9, 0x8a, 0x5e, 0x88, 0x62, 0x66, 0xe7, 0xae, 118 + ]; 119 + let decoded_cbor_cid: Cid = from_slice(&cbor_cid).unwrap(); 120 + assert_eq!(decoded_cbor_cid.to_bytes(), &cbor_cid[5..]); 121 + 122 + // The CID without the tag 42 prefix 123 + let cbor_bytes = &cbor_cid[2..]; 124 + from_slice::<Cid>(cbor_bytes).expect_err("should have failed to decode bytes as cid"); 125 + } 126 + 127 + /// This test shows how a kinded enum could be implemented. 128 + #[test] 129 + fn test_cid_in_kinded_enum() { 130 + #[derive(Debug, PartialEq)] 131 + pub enum Kinded { 132 + Bytes(ByteBuf), 133 + Link(Cid), 134 + } 135 + 136 + let cbor_cid = [ 137 + 0xd8, 0x2a, 0x58, 0x25, 0x00, 0x01, 0x55, 0x12, 0x20, 0x2c, 0x26, 0xb4, 0x6b, 0x68, 0xff, 138 + 0xc6, 0x8f, 0xf9, 0x9b, 0x45, 0x3c, 0x1d, 0x30, 0x41, 0x34, 0x13, 0x42, 0x2d, 0x70, 0x64, 139 + 0x83, 0xbf, 0xa0, 0xf9, 0x8a, 0x5e, 0x88, 0x62, 0x66, 0xe7, 0xae, 140 + ]; 141 + 142 + impl TryFrom<Ipld> for Kinded { 143 + type Error = (); 144 + 145 + fn try_from(ipld: Ipld) -> Result<Self, Self::Error> { 146 + match ipld { 147 + Ipld::Bytes(bytes) => Ok(Self::Bytes(ByteBuf::from(bytes))), 148 + Ipld::Link(cid) => Ok(Self::Link(cid)), 149 + _ => Err(()), 150 + } 151 + } 152 + } 153 + 154 + impl<'de> de::Deserialize<'de> for Kinded { 155 + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 156 + where 157 + D: de::Deserializer<'de>, 158 + { 159 + Ipld::deserialize(deserializer).and_then(|ipld| { 160 + ipld.try_into() 161 + .map_err(|_| de::Error::custom("No matching enum variant found")) 162 + }) 163 + } 164 + } 165 + 166 + let decoded_cid: Kinded = from_slice(&cbor_cid).unwrap(); 167 + let cid = Cid::try_from(&cbor_cid[5..]).unwrap(); 168 + assert_eq!(decoded_cid, Kinded::Link(cid)); 169 + 170 + // The CID without the tag 42 prefix 171 + let cbor_bytes = &cbor_cid[2..]; 172 + let decoded_bytes: Kinded = from_slice(cbor_bytes).unwrap(); 173 + // The CBOR decoded bytes don't contain the prefix with the bytes type identifier and the 174 + // length. 175 + let bytes = cbor_bytes[2..].to_vec(); 176 + assert_eq!(decoded_bytes, Kinded::Bytes(ByteBuf::from(bytes))); 177 + 178 + // Check that random bytes cannot be deserialized. 179 + let random_bytes = &cbor_cid[10..]; 180 + let decoded_random_bytes: Result<Kinded, _> = from_slice(random_bytes); 181 + assert!(decoded_random_bytes.is_err()); 182 + } 183 + 184 + /// This test shows how a kinded enum could be implemented, when bytes as well as a CID are wrapped 185 + /// in a newtype struct. 186 + #[test] 187 + fn test_cid_in_kinded_enum_with_newtype() { 188 + #[derive(Debug, Deserialize, PartialEq)] 189 + pub struct Foo(#[serde(with = "serde_bytes")] Vec<u8>); 190 + 191 + #[derive(Debug, PartialEq)] 192 + pub enum Kinded { 193 + MyBytes(Foo), 194 + Link(Cid), 195 + } 196 + 197 + let cbor_cid = [ 198 + 0xd8, 0x2a, 0x58, 0x25, 0x00, 0x01, 0x55, 0x12, 0x20, 0x2c, 0x26, 0xb4, 0x6b, 0x68, 0xff, 199 + 0xc6, 0x8f, 0xf9, 0x9b, 0x45, 0x3c, 0x1d, 0x30, 0x41, 0x34, 0x13, 0x42, 0x2d, 0x70, 0x64, 200 + 0x83, 0xbf, 0xa0, 0xf9, 0x8a, 0x5e, 0x88, 0x62, 0x66, 0xe7, 0xae, 201 + ]; 202 + 203 + impl TryFrom<Ipld> for Kinded { 204 + type Error = (); 205 + 206 + fn try_from(ipld: Ipld) -> Result<Self, Self::Error> { 207 + match ipld { 208 + Ipld::Bytes(bytes) => Ok(Self::MyBytes(Foo(bytes))), 209 + Ipld::Link(cid) => Ok(Self::Link(cid)), 210 + _ => Err(()), 211 + } 212 + } 213 + } 214 + 215 + impl<'de> de::Deserialize<'de> for Kinded { 216 + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 217 + where 218 + D: de::Deserializer<'de>, 219 + { 220 + Ipld::deserialize(deserializer).and_then(|ipld| { 221 + ipld.try_into() 222 + .map_err(|_| de::Error::custom("No matching enum variant found")) 223 + }) 224 + } 225 + } 226 + 227 + let decoded_cid: Kinded = from_slice(&cbor_cid).unwrap(); 228 + // The actual CID is without the CBOR tag 42, the byte identifier and the data length. 229 + let cid = Cid::try_from(&cbor_cid[5..]).unwrap(); 230 + assert_eq!(decoded_cid, Kinded::Link(cid)); 231 + 232 + // The CID without the tag 42 prefix 233 + let cbor_bytes = &cbor_cid[2..]; 234 + let decoded_bytes: Kinded = from_slice(cbor_bytes).unwrap(); 235 + // The CBOR decoded bytes don't contain the prefix with the bytes type identifier and the 236 + // length. 237 + let bytes = cbor_bytes[2..].to_vec(); 238 + assert_eq!(decoded_bytes, Kinded::MyBytes(Foo(bytes))); 239 + 240 + // Check that random bytes cannot be deserialized. 241 + let random_bytes = &cbor_cid[10..]; 242 + let decoded_random_bytes: Result<Kinded, _> = from_slice(random_bytes); 243 + assert!(decoded_random_bytes.is_err()); 244 + } 245 + 246 + #[test] 247 + fn test_cid_in_tagged_enum() { 248 + #[derive(Debug, Deserialize, PartialEq)] 249 + pub enum Externally { 250 + Cid(Cid), 251 + } 252 + 253 + #[derive(Debug, Deserialize, PartialEq)] 254 + #[serde(tag = "type")] 255 + pub enum Internally { 256 + Cid { cid: Cid }, 257 + } 258 + 259 + #[derive(Debug, Deserialize, PartialEq)] 260 + #[serde(untagged)] 261 + pub enum Untagged { 262 + Cid(Cid), 263 + } 264 + 265 + let cbor_cid = [ 266 + 0xd8, 0x2a, 0x58, 0x25, 0x00, 0x01, 0x55, 0x12, 0x20, 0x2c, 0x26, 0xb4, 0x6b, 0x68, 0xff, 267 + 0xc6, 0x8f, 0xf9, 0x9b, 0x45, 0x3c, 0x1d, 0x30, 0x41, 0x34, 0x13, 0x42, 0x2d, 0x70, 0x64, 268 + 0x83, 0xbf, 0xa0, 0xf9, 0x8a, 0x5e, 0x88, 0x62, 0x66, 0xe7, 0xae, 269 + ]; 270 + 271 + // {"Cid": cid} 272 + let cbor_map1 = [vec![0xa1, 0x63, 0x43, 0x69, 0x64], Vec::from(cbor_cid)].concat(); 273 + 274 + // {"cid": cid, "type": "Cid"} 275 + let cbor_map2 = [ 276 + vec![ 277 + 0xa2, 0x64, 0x74, 0x79, 0x70, 0x65, 0x63, 0x43, 0x69, 0x64, 0x63, 0x63, 0x69, 0x64, 278 + ], 279 + Vec::from(cbor_cid), 280 + ] 281 + .concat(); 282 + 283 + let cid = Cid::try_from(&cbor_cid[5..]).unwrap(); 284 + 285 + let decoded: Externally = from_slice(&cbor_map1).unwrap(); 286 + assert_eq!(decoded, Externally::Cid(cid)); 287 + 288 + // With the `no-cid-as-bytes` feature enabled, it's not possible to use internally tagged or 289 + // untaggd enums. This behaviour is *not* intentionally, but incidentally due to how Serde 290 + // internally works.. This test is only added to see what one could expect, and to get 291 + // notified in case it ever gets supported. 292 + #[cfg(feature = "no-cid-as-bytes")] 293 + { 294 + from_slice::<Internally>(&cbor_map2) 295 + .expect_err("shouldn't be able to decode the intanlly tagged enum"); 296 + from_slice::<Untagged>(&cbor_cid) 297 + .expect_err("shouldn't be able to decode the untagged enum"); 298 + } 299 + 300 + // With that feature disabled, it's the expected desired behaviour. 301 + #[cfg(not(feature = "no-cid-as-bytes"))] 302 + { 303 + let decoded: Internally = from_slice(&cbor_map2).unwrap(); 304 + assert_eq!(decoded, Internally::Cid { cid }); 305 + 306 + let decoded: Untagged = from_slice(&cbor_cid).unwrap(); 307 + assert_eq!(decoded, Untagged::Cid(cid)); 308 + } 309 + } 310 + 311 + #[test] 312 + fn test_cid_empty_errors() { 313 + // Tag 42 with zero bytes 314 + let cbor_empty_cid = [0xd8, 0x2a, 0x40]; 315 + 316 + let decoded: Result<Cid, _> = from_slice(&cbor_empty_cid); 317 + assert!(decoded.is_err()); 318 + } 319 + 320 + #[test] 321 + fn test_cid_non_minimally_encoded() { 322 + let cid = Cid::from_str("bafkreibme22gw2h7y2h7tg2fhqotaqjucnbc24deqo72b6mkl2egezxhvy").unwrap(); 323 + let cid_encoded = to_vec(&cid).unwrap(); 324 + 325 + let decoded: Cid = from_slice(&cid_encoded).unwrap(); 326 + assert_eq!(decoded, cid); 327 + 328 + // Strip off the CBOR tag. 329 + let without_tag = &cid_encoded[2..]; 330 + 331 + let tag_2_bytes_encoded = [&[0xd9, 0x00, 0x2a], without_tag].concat(); 332 + let tag_2_bytes_decoded: Cid = from_slice(&tag_2_bytes_encoded).unwrap(); 333 + assert_eq!(tag_2_bytes_decoded, cid); 334 + 335 + let tag_4_bytes_encoded = [&[0xda, 0x00, 0x00, 0x00, 0x2a], without_tag].concat(); 336 + let tag_4_bytes_decoded: Cid = from_slice(&tag_4_bytes_encoded).unwrap(); 337 + assert_eq!(tag_4_bytes_decoded, cid); 338 + 339 + let tag_8_bytes_encoded = [ 340 + &[0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a], 341 + without_tag, 342 + ] 343 + .concat(); 344 + let tag_8_bytes_decoded: Cid = from_slice(&tag_8_bytes_encoded).unwrap(); 345 + assert_eq!(tag_8_bytes_decoded, cid); 346 + } 347 + 348 + #[test] 349 + fn test_cid_decode_from_reader() { 350 + let cid_encoded = [ 351 + 0xd8, 0x2a, 0x49, 0x00, 0x01, 0xce, 0x01, 0x9b, 0x01, 0x02, 0x63, 0xc8, 352 + ]; 353 + let cid_decoded: Cid = from_slice(&cid_encoded).unwrap(); 354 + assert_eq!(&cid_encoded[4..], &cid_decoded.to_bytes()); 355 + }
+66
vendor/git/serde_ipld_dagcbor/tests/codec.rs
··· 1 + #![cfg(all(feature = "std", not(feature = "no-cid-as-bytes")))] 2 + 3 + use core::{convert::TryFrom, iter}; 4 + 5 + use ipld_core::{ 6 + cid::Cid, 7 + codec::{Codec, Links}, 8 + ipld, 9 + ipld::Ipld, 10 + }; 11 + use serde_ipld_dagcbor::codec::DagCborCodec; 12 + 13 + #[test] 14 + fn test_codec_encode() { 15 + let data = "hello world!".to_string(); 16 + let expected = b"\x6chello world!"; 17 + 18 + let mut output = Vec::new(); 19 + DagCborCodec::encode(&mut output, &data).unwrap(); 20 + assert_eq!(output, expected); 21 + 22 + let encoded = DagCborCodec::encode_to_vec(&data).unwrap(); 23 + assert_eq!(encoded, expected); 24 + } 25 + 26 + #[test] 27 + fn test_codec_decode() { 28 + let data = b"\x6chello world!"; 29 + let expected = "hello world!".to_string(); 30 + 31 + let decoded: String = DagCborCodec::decode(&data[..]).unwrap(); 32 + assert_eq!(decoded, expected); 33 + 34 + let decoded_from_slice: String = DagCborCodec::decode_from_slice(data).unwrap(); 35 + assert_eq!(decoded_from_slice, expected); 36 + } 37 + 38 + #[test] 39 + fn test_codec_links() { 40 + let cid = Cid::try_from("bafkreibme22gw2h7y2h7tg2fhqotaqjucnbc24deqo72b6mkl2egezxhvy").unwrap(); 41 + let data: Ipld = ipld!({"some": {"nested": cid}, "or": [cid, cid], "foo": true}); 42 + let expected = iter::repeat_n(cid, 3).collect::<Vec<_>>(); 43 + 44 + let mut encoded = Vec::new(); 45 + DagCborCodec::encode(&mut encoded, &data).unwrap(); 46 + 47 + let links = DagCborCodec::links(&encoded).unwrap(); 48 + assert_eq!(links.collect::<Vec<_>>(), expected); 49 + } 50 + 51 + #[test] 52 + fn test_codec_generic() { 53 + fn encode_generic<C, T>(value: T) -> Vec<u8> 54 + where 55 + C: Codec<T>, 56 + C::Error: std::fmt::Debug, 57 + { 58 + C::encode_to_vec(&value).unwrap() 59 + } 60 + 61 + let data = "hello world!".to_string(); 62 + let expected = b"\x6chello world!"; 63 + 64 + let encoded = encode_generic::<DagCborCodec, _>(data); 65 + assert_eq!(encoded, expected); 66 + }
vendor/git/serde_ipld_dagcbor/tests/crash.cbor

This is a binary file and will not be displayed.

+688
vendor/git/serde_ipld_dagcbor/tests/de.rs
··· 1 + use std::collections::BTreeMap; 2 + 3 + use ipld_core::ipld::Ipld; 4 + use serde::{Deserialize, Serialize}; 5 + use serde_ipld_dagcbor::{de, to_vec, DecodeError}; 6 + use serde_tuple::{Deserialize_tuple, Serialize_tuple}; 7 + use std::convert::Infallible; 8 + 9 + #[test] 10 + fn test_string1() { 11 + let ipld: Result<Ipld, _> = de::from_slice(&[0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]); 12 + assert_eq!(ipld.unwrap(), Ipld::String("foobar".to_string())); 13 + } 14 + 15 + #[test] 16 + fn test_string2() { 17 + let ipld: Result<Ipld, _> = de::from_slice(&[ 18 + 0x71, 0x49, 0x20, 0x6d, 0x65, 0x74, 0x20, 0x61, 0x20, 0x74, 0x72, 0x61, 0x76, 0x65, 0x6c, 19 + 0x6c, 0x65, 0x72, 20 + ]); 21 + assert_eq!(ipld.unwrap(), Ipld::String("I met a traveller".to_string())); 22 + } 23 + 24 + #[test] 25 + fn test_string3() { 26 + let slice = b"\x78\x2fI met a traveller from an antique land who said"; 27 + let ipld: Result<Ipld, _> = de::from_slice(slice); 28 + assert_eq!( 29 + ipld.unwrap(), 30 + Ipld::String("I met a traveller from an antique land who said".to_string()) 31 + ); 32 + } 33 + 34 + #[test] 35 + fn test_byte_string() { 36 + let ipld: Result<Ipld, _> = de::from_slice(&[0x46, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]); 37 + assert_eq!(ipld.unwrap(), Ipld::Bytes(b"foobar".to_vec())); 38 + } 39 + 40 + #[test] 41 + fn test_numbers1() { 42 + let ipld: Result<Ipld, _> = de::from_slice(&[0x00]); 43 + assert_eq!(ipld.unwrap(), Ipld::Integer(0)); 44 + } 45 + 46 + #[test] 47 + fn test_numbers2() { 48 + let ipld: Result<Ipld, _> = de::from_slice(&[0x1a, 0x00, 0xbc, 0x61, 0x4e]); 49 + assert_eq!(ipld.unwrap(), Ipld::Integer(12345678)); 50 + } 51 + 52 + #[test] 53 + fn test_numbers3() { 54 + let ipld: Result<Ipld, _> = de::from_slice(&[0x39, 0x07, 0xde]); 55 + assert_eq!(ipld.unwrap(), Ipld::Integer(-2015)); 56 + } 57 + 58 + #[test] 59 + fn test_numbers_large_negative() { 60 + let ipld: Result<Ipld, _> = 61 + de::from_slice(&[0x3b, 0xa5, 0xf7, 0x02, 0xb3, 0xa5, 0xf7, 0x02, 0xb3]); 62 + let expected: i128 = -11959030306112471732; 63 + assert!(expected < i128::from(i64::MIN)); 64 + assert_eq!(ipld.unwrap(), Ipld::Integer(expected)); 65 + } 66 + 67 + #[test] 68 + fn test_bool() { 69 + let ipld: Result<Ipld, _> = de::from_slice(b"\xf4"); 70 + assert_eq!(ipld.unwrap(), Ipld::Bool(false)); 71 + } 72 + 73 + #[test] 74 + fn test_trailing_bytes() { 75 + let ipld: Result<Ipld, _> = de::from_slice(b"\xf4trailing"); 76 + assert!(matches!(ipld.unwrap_err(), DecodeError::TrailingData)); 77 + } 78 + 79 + #[test] 80 + fn test_list1() { 81 + let ipld: Result<Ipld, _> = de::from_slice(b"\x83\x01\x02\x03"); 82 + assert_eq!( 83 + ipld.unwrap(), 84 + Ipld::List(vec![Ipld::Integer(1), Ipld::Integer(2), Ipld::Integer(3)]) 85 + ); 86 + } 87 + 88 + #[test] 89 + fn test_list2() { 90 + let ipld: Result<Ipld, _> = de::from_slice(b"\x82\x01\x82\x02\x81\x03"); 91 + assert_eq!( 92 + ipld.unwrap(), 93 + Ipld::List(vec![ 94 + Ipld::Integer(1), 95 + Ipld::List(vec![Ipld::Integer(2), Ipld::List(vec![Ipld::Integer(3)])]) 96 + ]) 97 + ); 98 + } 99 + 100 + #[test] 101 + fn test_object() { 102 + let ipld: Result<Ipld, _> = de::from_slice(b"\xa5aaaAabaBacaCadaDaeaE"); 103 + let mut object = BTreeMap::new(); 104 + object.insert("a".to_string(), Ipld::String("A".to_string())); 105 + object.insert("b".to_string(), Ipld::String("B".to_string())); 106 + object.insert("c".to_string(), Ipld::String("C".to_string())); 107 + object.insert("d".to_string(), Ipld::String("D".to_string())); 108 + object.insert("e".to_string(), Ipld::String("E".to_string())); 109 + assert_eq!(ipld.unwrap(), Ipld::Map(object)); 110 + } 111 + 112 + #[test] 113 + fn test_indefinite_object_error() { 114 + let ipld: Result<Ipld, _> = de::from_slice(b"\xbfaa\x01ab\x9f\x02\x03\xff\xff"); 115 + let mut object = BTreeMap::new(); 116 + object.insert("a".to_string(), Ipld::Integer(1)); 117 + object.insert( 118 + "b".to_string(), 119 + Ipld::List(vec![Ipld::Integer(2), Ipld::Integer(3)]), 120 + ); 121 + assert!(matches!(ipld.unwrap_err(), DecodeError::IndefiniteSize)); 122 + } 123 + 124 + #[test] 125 + fn test_indefinite_list_error() { 126 + let ipld: Result<Ipld, _> = de::from_slice(b"\x9f\x01\x02\x03\xff"); 127 + assert!(matches!(ipld.unwrap_err(), DecodeError::IndefiniteSize)); 128 + } 129 + 130 + #[test] 131 + fn test_indefinite_string_error() { 132 + let ipld: Result<Ipld, _> = 133 + de::from_slice(b"\x7f\x65Mary \x64Had \x62a \x67Little \x60\x64Lamb\xff"); 134 + assert!(matches!(ipld.unwrap_err(), DecodeError::IndefiniteSize)); 135 + } 136 + 137 + #[test] 138 + fn test_indefinite_byte_string_error() { 139 + let ipld: Result<Ipld, _> = de::from_slice(b"\x5f\x42\x01\x23\x42\x45\x67\xff"); 140 + assert!(matches!(ipld.unwrap_err(), DecodeError::IndefiniteSize)); 141 + } 142 + 143 + #[test] 144 + fn test_multiple_indefinite_strings_error() { 145 + let input = b"\x82\x7f\x65Mary \x64Had \x62a \x67Little \x60\x64Lamb\xff\x5f\x42\x01\x23\x42\x45\x67\xff"; 146 + let ipld: Result<Ipld, _> = de::from_slice(input); 147 + assert!(matches!(ipld.unwrap_err(), DecodeError::IndefiniteSize)); 148 + } 149 + 150 + #[test] 151 + fn test_float() { 152 + // 0xfb (f64) followed by 8 bytes of IEEE 754 double precision for 100000.0 153 + let ipld: Result<Ipld, _> = de::from_slice(b"\xfb\x40\xf8\x6a\x00\x00\x00\x00\x00"); 154 + assert_eq!(ipld.unwrap(), Ipld::Float(100000.0)); 155 + } 156 + 157 + #[test] 158 + fn test_rejected_tag() { 159 + let ipld: Result<Ipld, _> = 160 + de::from_slice(&[0xd9, 0xd9, 0xf7, 0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]); 161 + assert!(matches!( 162 + ipld.unwrap_err(), 163 + DecodeError::TypeMismatch { 164 + name: "CBOR tag", 165 + byte: 0xf7 166 + } 167 + )); 168 + } 169 + 170 + #[test] 171 + fn test_crazy_list() { 172 + let slice = b"\x86\x1b\x00\x00\x00\x1c\xbe\x99\x1d\xc7\x3b\x00\x7a\xcf\x51\xdc\x51\x70\xdb\x3a\x1b\x3a\x06\xdd\xf5\xf6\xfb\x41\x76\x5e\xb1\xf8\x00\x00\x00"; 173 + let ipld: Vec<Ipld> = de::from_slice(slice).unwrap(); 174 + assert_eq!( 175 + ipld, 176 + vec![ 177 + Ipld::Integer(123456789959), 178 + Ipld::Integer(-34567897654325468), 179 + Ipld::Integer(-456787678), 180 + Ipld::Bool(true), 181 + Ipld::Null, 182 + Ipld::Float(23456543.5), 183 + ] 184 + ); 185 + } 186 + 187 + #[test] 188 + fn test_nan() { 189 + let ipld: Result<f64, _> = de::from_slice(b"\xf9\x7e\x00"); 190 + assert!(matches!( 191 + ipld.unwrap_err(), 192 + DecodeError::TypeMismatch { .. } 193 + )); 194 + } 195 + 196 + #[test] 197 + // The file was reported as not working by user kie0tauB 198 + // but it parses to a cbor value. 199 + fn test_kietaub_file() { 200 + let file = include_bytes!("kietaub.cbor"); 201 + let value_result: Result<Ipld, _> = de::from_slice(file); 202 + value_result.unwrap(); 203 + } 204 + 205 + #[test] 206 + fn test_option_roundtrip() { 207 + let obj1 = Some(10u32); 208 + 209 + let v = to_vec(&obj1).unwrap(); 210 + let obj2: Result<Option<u32>, _> = de::from_slice(&v[..]); 211 + println!("{:?}", obj2); 212 + 213 + assert_eq!(obj1, obj2.unwrap()); 214 + } 215 + 216 + #[test] 217 + fn test_option_none_roundtrip() { 218 + let obj1 = None; 219 + 220 + let v = to_vec(&obj1).unwrap(); 221 + println!("{:?}", v); 222 + let obj2: Result<Option<u32>, _> = de::from_slice(&v[..]); 223 + 224 + assert_eq!(obj1, obj2.unwrap()); 225 + } 226 + 227 + #[test] 228 + fn test_unit() { 229 + #[allow(clippy::let_unit_value)] 230 + let unit = (); 231 + let v = to_vec(&unit).unwrap(); 232 + assert_eq!(v, [0xf6], "unit is serialized as NULL."); 233 + let result: Result<(), _> = from_slice(&v); 234 + assert!(result.is_ok(), "unit was successfully deserialized"); 235 + } 236 + 237 + #[test] 238 + fn test_variable_length_map_error() { 239 + let slice = b"\xbf\x67\x6d\x65\x73\x73\x61\x67\x65\x64\x70\x6f\x6e\x67\xff"; 240 + let ipld: Result<Ipld, _> = de::from_slice(slice); 241 + assert!(matches!(ipld.unwrap_err(), DecodeError::IndefiniteSize)); 242 + } 243 + 244 + #[test] 245 + fn test_object_determinism_roundtrip() { 246 + let expected = b"\xa2aa\x01ab\x82\x02\x03"; 247 + 248 + // 0.1% chance of not catching failure 249 + for _ in 0..10 { 250 + assert_eq!( 251 + &to_vec(&de::from_slice::<Ipld>(expected).unwrap()).unwrap(), 252 + expected 253 + ); 254 + } 255 + } 256 + 257 + #[cfg(feature = "std")] 258 + #[test] 259 + fn test_from_reader_once() { 260 + let v: &[u8] = &[0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x0a]; 261 + let mut reader = std::io::Cursor::new(v); 262 + let value_1: String = de::from_reader_once(&mut reader).unwrap(); 263 + assert_eq!(value_1, "foobar"); 264 + let value_2: i32 = de::from_reader_once(&mut reader).unwrap(); 265 + assert_eq!(value_2, 10); 266 + assert_eq!(v.len(), reader.position() as usize); 267 + } 268 + 269 + #[cfg(feature = "std")] 270 + #[test] 271 + fn test_stream_deserializer() { 272 + let v: &[u8] = &[ 273 + 0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x63, 0x62, 0x61, 0x7A, 274 + ]; 275 + let reader = std::io::Cursor::new(v); 276 + let reader = cbor4ii::core::utils::IoReader::new(reader); 277 + let mut i = de::Deserializer::from_reader(reader).into_iter(); 278 + let value_1: String = i.next().unwrap().unwrap(); 279 + assert_eq!(value_1, "foobar"); 280 + let value_2: String = i.next().unwrap().unwrap(); 281 + assert_eq!(value_2, "baz"); 282 + assert!(i.next().is_none()); 283 + } 284 + 285 + #[cfg(feature = "std")] 286 + #[test] 287 + fn test_stream_deserializer_marker_traits() { 288 + use std::rc::Rc; 289 + 290 + fn is_send<T: Send>(_: &T) {} 291 + 292 + let v: &[u8] = &[ 293 + 0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x63, 0x62, 0x61, 0x7A, 294 + ]; 295 + let reader = std::io::Cursor::new(v); 296 + let reader = cbor4ii::core::utils::IoReader::new(reader); 297 + let mut i = de::Deserializer::from_reader(reader).into_iter(); 298 + is_send(&i); 299 + let value_1: Rc<String> = i.next().unwrap().unwrap(); 300 + assert_eq!(value_1.as_str(), "foobar"); 301 + } 302 + 303 + #[cfg(feature = "std")] 304 + #[test] 305 + fn test_stream_deserializer_trailing_data() { 306 + // one byte missing on the end 307 + let v: &[u8] = &[0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x63, 0x62, 0x61]; 308 + let reader = std::io::Cursor::new(v); 309 + let reader = cbor4ii::core::utils::IoReader::new(reader); 310 + let mut i = de::Deserializer::from_reader(reader).into_iter(); 311 + let value_1: String = i.next().unwrap().unwrap(); 312 + assert_eq!(value_1, "foobar"); 313 + 314 + // we should get back an Eof error 315 + assert!(matches!(i.next(), Some(Err(DecodeError::Eof)))); 316 + } 317 + 318 + #[test] 319 + fn crash() { 320 + let file = include_bytes!("crash.cbor"); 321 + let value_result: Result<Ipld, _> = de::from_slice(file); 322 + assert!(matches!(value_result.unwrap_err(), DecodeError::Eof)); 323 + } 324 + 325 + use serde_ipld_dagcbor::de::from_slice; 326 + use std::net::{IpAddr, Ipv4Addr}; 327 + #[test] 328 + fn test_ipaddr_deserialization() { 329 + let ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)); 330 + let buf = to_vec(&ip).unwrap(); 331 + let deserialized_ip = from_slice::<IpAddr>(&buf).unwrap(); 332 + assert_eq!(ip, deserialized_ip); 333 + } 334 + 335 + #[test] 336 + fn attempt_stack_overflow() { 337 + // Create a tag 17, followed by 999 more tag 17: 338 + // 17(17(17(17(17(17(17(17(17(17(17(17(17(17(17(17(17(17(... 339 + // This causes deep recursion in the decoder and may 340 + // exhaust the stack and therfore result in a stack overflow. 341 + let input = vec![0xd1; 1000]; 342 + serde_ipld_dagcbor::from_slice::<Ipld>(&input).expect_err("recursion limit"); 343 + } 344 + 345 + #[test] 346 + fn truncated_object() { 347 + let input: Vec<u8> = [ 348 + &b"\x84\x87\xD8\x2A\x58\x27\x00\x01\x71\xA0\xE4\x02\x20\x83\xEC\x9F\x76\x1D"[..], 349 + &b"\xB5\xEE\xA0\xC8\xE1\xB5\x74\x0D\x1F\x0A\x1D\xB1\x8A\x52\x6B\xCB\x42\x69"[..], 350 + &b"\xFD\x99\x24\x9E\xCE\xA9\xE8\xFD\x24\xD8\x2A\x58\x27\x00\x01\x71\xA0\xE4"[..], 351 + &b"\x02\x20\xF1\x9B\xC1\x42\x83\x31\xB1\x39\xB3\x3F\x43\x02\x87\xCC\x1C\x12"[..], 352 + &b"\xF2\x84\x47\xA3\x9B\x07\x59\x40\x17\x68\xFE\xE8\x09\xBB\xF2\x54\xD8\x2A"[..], 353 + &b"\x58\x27\x00\x01\x71\xA0\xE4\x02\x20\xB0\x75\x09\x92\x78\x6B\x6B\x4C\xED"[..], 354 + &b"\xF0\xE1\x50\xA3\x1C\xAB\xDF\x25\xA9\x26\x8C\x63\xDD\xCB\x25\x73\x6B\xF5"[..], 355 + &b"\x8D\xE8\xA4\x24\x29"[..], 356 + ] 357 + .concat(); 358 + serde_ipld_dagcbor::from_slice::<Ipld>(&input).expect_err("truncated"); 359 + } 360 + 361 + #[test] 362 + fn invalid_string() { 363 + // Non UTF-8 byte sequence, but using major type 3 (text string) 364 + let input = [0x63, 0xc5, 0x01, 0x02]; 365 + let result = serde_ipld_dagcbor::from_slice::<Ipld>(&input); 366 + assert!(matches!( 367 + result.unwrap_err(), 368 + DecodeError::InvalidUtf8 { .. } 369 + )); 370 + } 371 + 372 + #[test] 373 + fn error_on_undefined() { 374 + // CBOR smple type `undefined` 375 + let input = [0xf7]; 376 + let result = serde_ipld_dagcbor::from_slice::<Ipld>(&input); 377 + assert!(matches!( 378 + result.unwrap_err(), 379 + DecodeError::Unsupported { .. } 380 + )); 381 + } 382 + 383 + // Test for default values inside tuple structs 384 + #[derive(Debug, PartialEq, Deserialize_tuple, Serialize_tuple, Default, Clone)] 385 + struct TupleWithDefaultsStruct { 386 + #[serde(default)] 387 + a: u32, 388 + #[serde(default)] 389 + b: String, 390 + } 391 + 392 + // Test for default values inside tuple structs nested inside other tuple structs 393 + #[derive(Debug, PartialEq, Deserialize_tuple, Serialize_tuple, Clone)] 394 + struct TupleOuterStruct { 395 + boop: u64, 396 + inner: TupleWithDefaultsStruct, 397 + #[serde(default)] 398 + bop: u64, 399 + } 400 + 401 + // Test for default values inside tuple structs nested inside other tuple structs where 402 + // the outer struct has a default value itself 403 + #[derive(Debug, PartialEq, Deserialize_tuple, Serialize_tuple, Clone)] 404 + struct TupleOuterDefaultableStruct { 405 + boop: u64, 406 + #[serde(default)] 407 + inner: TupleWithDefaultsStruct, 408 + } 409 + 410 + // Test for tuple structs with overflow where the types are the same so the overflow could 411 + // spill into the next field of the outer struct 412 + #[derive(Debug, PartialEq, Deserialize_tuple, Serialize_tuple, Clone)] 413 + struct TupleIntInner { 414 + a: u32, 415 + b: u32, 416 + } 417 + 418 + #[derive(Debug, PartialEq, Deserialize_tuple, Serialize_tuple, Clone)] 419 + struct TupleIntOuterWithOverflow { 420 + inner: TupleIntInner, 421 + #[serde(default)] 422 + c: u32, 423 + } 424 + 425 + // Test for tuple structs with overflow where the types are the same so the overflow could 426 + // spill into the next field of the outer struct 427 + #[derive(Debug, PartialEq, Deserialize, Serialize, Clone)] 428 + #[serde(deny_unknown_fields)] 429 + struct MapIntInner { 430 + a: u32, 431 + b: u32, 432 + } 433 + 434 + #[derive(Debug, PartialEq, Deserialize, Serialize, Clone)] 435 + #[serde(deny_unknown_fields)] 436 + struct MapIntOuterWithOverflow { 437 + inner: MapIntInner, 438 + #[serde(default)] 439 + c: u32, 440 + } 441 + 442 + // The expected result is either an Ok value or an error check closure. 443 + enum Expected<T> { 444 + Ok(T), 445 + Err(fn(&DecodeError<Infallible>) -> bool), 446 + } 447 + 448 + struct TestCase<T> { 449 + hex: &'static str, 450 + expected: Expected<T>, 451 + } 452 + 453 + #[test] 454 + fn test_default_values() { 455 + let basic_cases = [ 456 + // [] -> default 457 + TestCase { 458 + hex: "80", 459 + expected: Expected::Ok(TupleWithDefaultsStruct { 460 + a: 0, // default 461 + b: "".to_string(), // default 462 + }), 463 + }, 464 + // [101] -> set a and default b 465 + TestCase { 466 + hex: "811865", 467 + expected: Expected::Ok(TupleWithDefaultsStruct { 468 + a: 101, 469 + b: "".to_string(), // default 470 + }), 471 + }, 472 + // [202, "yep"] 473 + TestCase { 474 + hex: "8218ca63796570", 475 + expected: Expected::Ok(TupleWithDefaultsStruct { 476 + a: 202, 477 + b: "yep".to_string(), 478 + }), 479 + }, 480 + // [202,"nup",false] has too many elements so it errors with RequireLength 481 + TestCase { 482 + hex: "8318ca636e7570f4", 483 + expected: Expected::Err( 484 + |err| matches!(err, DecodeError::RequireLength{ name, expect, value} if *name == "TupleWithDefaultsStruct" && *expect == 2 && *value == 3), 485 + ), 486 + }, 487 + ]; 488 + 489 + let outer_cases = [ 490 + // [505,[],606] 491 + TestCase { 492 + hex: "831901f98019025e", 493 + expected: Expected::Ok(TupleOuterStruct { 494 + boop: 505, 495 + inner: TupleWithDefaultsStruct { 496 + a: 0, // default 497 + b: "".to_string(), // default 498 + }, 499 + bop: 606, 500 + }), 501 + }, 502 + // [505,[202,"yep"],606] 503 + TestCase { 504 + hex: "831901f98218ca6379657019025e", 505 + expected: Expected::Ok(TupleOuterStruct { 506 + boop: 505, 507 + inner: TupleWithDefaultsStruct { 508 + a: 202, 509 + b: "yep".to_string(), 510 + }, 511 + bop: 606, 512 + }), 513 + }, 514 + // [505,[202,"nup",false],606] has too many elements on inner so it errors with RequireLength 515 + TestCase { 516 + hex: "831901f98318ca636e7570f419025e", 517 + expected: Expected::Err( 518 + |err| matches!(err, DecodeError::RequireLength{ name, expect, value} if *name == "TupleWithDefaultsStruct" && *expect == 2 && *value == 3), 519 + ), 520 + }, 521 + // [505,[]] 522 + TestCase { 523 + hex: "821901f980", 524 + expected: Expected::Ok(TupleOuterStruct { 525 + boop: 505, 526 + inner: TupleWithDefaultsStruct { 527 + a: 0, // default 528 + b: "".to_string(), // default 529 + }, 530 + bop: 0, // default 531 + }), 532 + }, 533 + // [505,[202,"yep"]] 534 + TestCase { 535 + hex: "821901f98218ca63796570", 536 + expected: Expected::Ok(TupleOuterStruct { 537 + boop: 505, 538 + inner: TupleWithDefaultsStruct { 539 + a: 202, 540 + b: "yep".to_string(), 541 + }, 542 + bop: 0, // default 543 + }), 544 + }, 545 + ]; 546 + 547 + let outer_defaultable_cases = [ 548 + // [404] -> default inner 549 + TestCase { 550 + hex: "81190194", 551 + expected: Expected::Ok(TupleOuterDefaultableStruct { 552 + boop: 404, 553 + inner: TupleWithDefaultsStruct { 554 + // default 555 + a: 0, 556 + b: "".to_string(), 557 + }, 558 + }), 559 + }, 560 + // [404,[]] -> default inner 561 + TestCase { 562 + hex: "8219019480", 563 + expected: Expected::Ok(TupleOuterDefaultableStruct { 564 + boop: 404, 565 + inner: TupleWithDefaultsStruct { 566 + a: 0, // default 567 + b: "".to_string(), // default 568 + }, 569 + }), 570 + }, 571 + // [] -> error because inner has too few elements 572 + TestCase { 573 + hex: "80", 574 + expected: Expected::Err( 575 + |err| matches!(err, DecodeError::Msg(ref m) if m == "invalid length 0, expected tuple struct Inner with 2 elements"), 576 + ), 577 + }, 578 + ]; 579 + 580 + let tuple_overflow_cases = [ 581 + // [[1,2],3] -> expected layout 582 + TestCase { 583 + hex: "8282010203", 584 + expected: Expected::Ok(TupleIntOuterWithOverflow { 585 + inner: TupleIntInner { a: 1, b: 2 }, 586 + c: 3, 587 + }), 588 + }, 589 + // [[1],2] -> error because inner has too few elements 590 + TestCase { 591 + hex: "82820102", 592 + expected: Expected::Err(|err| matches!(err, DecodeError::Eof)), 593 + }, 594 + // [[1,2,3],4] -> error because inner has too many elements 595 + TestCase { 596 + hex: "828301020304", 597 + expected: Expected::Err( 598 + |err| matches!(err, DecodeError::RequireLength{ name, expect, value} if *name == "TupleIntInner" && *expect == 2 && *value == 3), 599 + ), 600 + }, 601 + // [[1,2]] + 3 -> error because there's a trailing element 602 + TestCase { 603 + hex: "8182010203", 604 + expected: Expected::Err(|err| matches!(err, DecodeError::TrailingData)), 605 + }, 606 + // [[1,2,3]] -> error because outer has too few elements 607 + TestCase { 608 + hex: "8183010203", 609 + expected: Expected::Err( 610 + |err| matches!(err, DecodeError::RequireLength{ name, expect, value} if *name == "TupleIntInner" && *expect == 2 && *value == 3), 611 + ), 612 + }, 613 + ]; 614 + 615 + let map_overflow_cases = [ 616 + // {"inner":{"a":1,"b":2},"c":3} -> expected layout 617 + TestCase { 618 + hex: "a261630365696e6e6572a2616101616202", 619 + expected: Expected::Ok(MapIntOuterWithOverflow { 620 + inner: MapIntInner { a: 1, b: 2 }, 621 + c: 3, 622 + }), 623 + }, 624 + // {"inner":{"a":1},"c":3} -> error because inner has too few elements 625 + TestCase { 626 + hex: "a261630365696e6e6572a1616101", 627 + expected: Expected::Err( 628 + |err| matches!(err, DecodeError::Msg(ref m) if m == "missing field `b`"), 629 + ), 630 + }, 631 + // {"inner":{"a":1,"b":2,"c":3},"c":4} -> error because inner has too many elements 632 + TestCase { 633 + hex: "a261630465696e6e6572a3616101616202616303", 634 + expected: Expected::Err( 635 + |err| matches!(err, DecodeError::Msg(ref m) if m == "unknown field `c`, expected `a` or `b`"), 636 + ), 637 + }, 638 + // {"inner":{"a":1,"b":2}} + "c":3 -> error because there's a trailing element 639 + TestCase { 640 + hex: "a165696e6e6572a2616101616202616303", 641 + expected: Expected::Err(|err| matches!(err, DecodeError::TrailingData)), 642 + }, 643 + // {"inner":{"a":1,"b":2,"c":3}} -> error because outer has too few elements 644 + TestCase { 645 + hex: "a165696e6e6572a3616101616202616303", 646 + expected: Expected::Err( 647 + |err| matches!(err, DecodeError::Msg(ref m) if m == "unknown field `c`, expected `a` or `b`"), 648 + ), 649 + }, 650 + ]; 651 + 652 + check_cases(&basic_cases); 653 + check_cases(&outer_cases); 654 + check_cases(&outer_defaultable_cases); 655 + check_cases(&tuple_overflow_cases); 656 + check_cases(&map_overflow_cases); 657 + 658 + fn check_cases<T>(test_cases: &[TestCase<T>]) 659 + where 660 + T: serde::de::DeserializeOwned + std::fmt::Debug + PartialEq, 661 + { 662 + for case in test_cases { 663 + let input = const_hex::decode(case.hex).unwrap(); 664 + let result = from_slice::<T>(&input); 665 + match case.expected { 666 + Expected::Ok(ref expected_val) => match result { 667 + Ok(val) => assert_eq!(val, *expected_val, "for input {}", case.hex), 668 + Err(err) => panic!( 669 + "for input {} expected success with {:?} but got error: {:?}", 670 + case.hex, expected_val, err 671 + ), 672 + }, 673 + Expected::Err(check) => match result { 674 + Ok(val) => panic!( 675 + "for input {} expected an error but got success with value: {:?}", 676 + case.hex, val 677 + ), 678 + Err(err) => assert!( 679 + check(&err), 680 + "for input {} got unexpected error: {:?}", 681 + case.hex, 682 + err 683 + ), 684 + }, 685 + } 686 + } 687 + } 688 + }
+87
vendor/git/serde_ipld_dagcbor/tests/enum.rs
··· 1 + use serde_derive::{Deserialize, Serialize}; 2 + 3 + use serde_ipld_dagcbor::{from_slice, to_vec, DecodeError}; 4 + 5 + #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] 6 + enum Enum { 7 + A, 8 + B, 9 + } 10 + 11 + #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] 12 + struct EnumStruct { 13 + e: Enum, 14 + } 15 + 16 + #[test] 17 + fn test_enum() { 18 + let enum_struct = EnumStruct { e: Enum::B }; 19 + let raw = &to_vec(&enum_struct).unwrap(); 20 + println!("raw enum {:?}", raw); 21 + let re: EnumStruct = from_slice(raw).unwrap(); 22 + assert_eq!(enum_struct, re); 23 + } 24 + 25 + #[repr(u16)] 26 + #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] 27 + enum ReprEnum { 28 + A, 29 + B, 30 + } 31 + 32 + #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] 33 + struct ReprEnumStruct { 34 + e: ReprEnum, 35 + } 36 + 37 + #[test] 38 + fn test_repr_enum() { 39 + let repr_enum_struct = ReprEnumStruct { e: ReprEnum::B }; 40 + let re: ReprEnumStruct = from_slice(&to_vec(&repr_enum_struct).unwrap()).unwrap(); 41 + assert_eq!(repr_enum_struct, re); 42 + } 43 + 44 + #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] 45 + enum DataEnum { 46 + A(u32), 47 + B(bool, u8), 48 + C { x: u8, y: String }, 49 + } 50 + 51 + #[test] 52 + fn test_data_enum() { 53 + let data_enum_a = DataEnum::A(4); 54 + let re_a: DataEnum = from_slice(&to_vec(&data_enum_a).unwrap()).unwrap(); 55 + assert_eq!(data_enum_a, re_a); 56 + let data_enum_b = DataEnum::B(true, 42); 57 + let re_b: DataEnum = from_slice(&to_vec(&data_enum_b).unwrap()).unwrap(); 58 + assert_eq!(data_enum_b, re_b); 59 + let data_enum_c = DataEnum::C { 60 + x: 3, 61 + y: "foo".to_owned(), 62 + }; 63 + println!("{:?}", &to_vec(&data_enum_c).unwrap()); 64 + let re_c: DataEnum = from_slice(&to_vec(&data_enum_c).unwrap()).unwrap(); 65 + assert_eq!(data_enum_c, re_c); 66 + } 67 + 68 + #[test] 69 + fn test_newtype_struct() { 70 + #[derive(Debug, Deserialize, Serialize, PartialEq, Eq)] 71 + pub struct Newtype(u8); 72 + assert_eq!(to_vec(&142u8).unwrap(), to_vec(&Newtype(142u8)).unwrap()); 73 + assert_eq!(from_slice::<Newtype>(&[24, 142]).unwrap(), Newtype(142)); 74 + } 75 + 76 + #[derive(Deserialize, PartialEq, Debug)] 77 + enum Foo { 78 + #[serde(rename = "require")] 79 + Require, 80 + } 81 + 82 + #[test] 83 + fn test_variable_length_array_error() { 84 + let slice = b"\x9F\x67\x72\x65\x71\x75\x69\x72\x65\xFF"; 85 + let value: Result<Vec<Foo>, _> = from_slice(slice); 86 + assert!(matches!(value.unwrap_err(), DecodeError::IndefiniteSize)); 87 + }
+129
vendor/git/serde_ipld_dagcbor/tests/ipld.rs
··· 1 + use std::collections::BTreeMap; 2 + 3 + use ipld_core::ipld::Ipld; 4 + use serde_derive::{Deserialize, Serialize}; 5 + use serde_tuple::{Deserialize_tuple, Serialize_tuple}; 6 + 7 + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] 8 + struct TupleStruct(String, i32, u64); 9 + 10 + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] 11 + struct UnitStruct; 12 + 13 + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] 14 + struct Struct<'a> { 15 + tuple_struct: TupleStruct, 16 + tuple: (String, f32, f64), 17 + map: BTreeMap<String, String>, 18 + bytes: &'a [u8], 19 + array: Vec<String>, 20 + } 21 + 22 + use std::iter::FromIterator; 23 + 24 + #[allow(clippy::useless_format)] 25 + #[test] 26 + fn serde() { 27 + let tuple_struct = TupleStruct(format!("test"), -60, 3000); 28 + 29 + let tuple = (format!("hello"), -50.004097, -12.094635556478); 30 + 31 + let map = BTreeMap::from_iter( 32 + [ 33 + (format!("key1"), format!("value1")), 34 + (format!("key2"), format!("value2")), 35 + (format!("key3"), format!("value3")), 36 + (format!("key4"), format!("value4")), 37 + ] 38 + .iter() 39 + .cloned(), 40 + ); 41 + 42 + let bytes = b"test byte string"; 43 + 44 + let array = vec![format!("one"), format!("two"), format!("three")]; 45 + 46 + let data = Struct { 47 + tuple_struct, 48 + tuple, 49 + map, 50 + bytes, 51 + array, 52 + }; 53 + 54 + let ipld = ipld_core::serde::to_ipld(data.clone()).unwrap(); 55 + println!("{:?}", ipld); 56 + 57 + let data_ser = serde_ipld_dagcbor::to_vec(&ipld).unwrap(); 58 + let data_de_ipld: Ipld = serde_ipld_dagcbor::from_slice(&data_ser).unwrap(); 59 + 60 + fn as_object(ipld: &Ipld) -> &BTreeMap<String, Ipld> { 61 + if let Ipld::Map(ref v) = ipld { 62 + return v; 63 + } 64 + panic!() 65 + } 66 + 67 + for ((k1, v1), (k2, v2)) in as_object(&ipld).iter().zip(as_object(&data_de_ipld).iter()) { 68 + assert_eq!(k1, k2); 69 + assert_eq!(v1, v2); 70 + } 71 + 72 + assert_eq!(ipld, data_de_ipld); 73 + } 74 + 75 + #[test] 76 + fn unit_struct_not_supported() { 77 + let unit_array = vec![UnitStruct, UnitStruct, UnitStruct]; 78 + let ipld = ipld_core::serde::to_ipld(unit_array); 79 + assert!(ipld.is_err()); 80 + } 81 + 82 + #[derive(Debug, PartialEq, Clone, Deserialize_tuple, Serialize_tuple)] 83 + #[serde(deny_unknown_fields)] 84 + struct StructWithTupleSerialization { 85 + spam: u32, 86 + eggs: u32, 87 + #[serde(default)] 88 + ham: String, 89 + } 90 + 91 + #[test] 92 + fn struct_with_tuple_representation() { 93 + let st = StructWithTupleSerialization { 94 + spam: 42, 95 + eggs: 23, 96 + ham: "smoked".to_string(), 97 + }; 98 + 99 + let ipld = ipld_core::serde::to_ipld(st.clone()).unwrap(); 100 + println!("{:?}", ipld); 101 + 102 + let data_ser = serde_ipld_dagcbor::to_vec(&ipld).unwrap(); 103 + println!("{:?}", data_ser); 104 + let data_de_ipld: Ipld = serde_ipld_dagcbor::from_slice(&data_ser).unwrap(); 105 + 106 + let strt: StructWithTupleSerialization = ipld_core::serde::from_ipld(data_de_ipld).unwrap(); 107 + assert_eq!(st, strt); 108 + 109 + let data_ser = vec![0x82, 0x17, 0x18, 0x2a]; // two element array [23,42] 110 + let data_de_ipld: Ipld = serde_ipld_dagcbor::from_slice(&data_ser).unwrap(); 111 + let strt: StructWithTupleSerialization = ipld_core::serde::from_ipld(data_de_ipld).unwrap(); 112 + assert_eq!( 113 + strt, 114 + StructWithTupleSerialization { 115 + spam: 23, 116 + eggs: 42, 117 + ham: "".to_string(), 118 + } 119 + ); 120 + 121 + let data_ser = vec![0x84, 0x17, 0x18, 0x2a, 0x64, 0xf0, 0x9f, 0x91, 0x8c, 0xf4]; // [23,42,"👌",false] 122 + let data_de_ipld: Ipld = serde_ipld_dagcbor::from_slice(&data_ser).unwrap(); 123 + let err = 124 + ipld_core::serde::from_ipld::<StructWithTupleSerialization>(data_de_ipld).unwrap_err(); 125 + assert_eq!( 126 + err.to_string(), 127 + "serde error: The type failed to consume the entire sequence: 1 items remaining" 128 + ); 129 + }
vendor/git/serde_ipld_dagcbor/tests/kietaub.cbor

This is a binary file and will not be displayed.

+254
vendor/git/serde_ipld_dagcbor/tests/ser.rs
··· 1 + use std::{collections::BTreeMap, iter}; 2 + 3 + use serde::de::value::{self, MapDeserializer, SeqDeserializer}; 4 + use serde_bytes::{ByteBuf, Bytes}; 5 + use serde_derive::Serialize; 6 + use serde_ipld_dagcbor::{ 7 + from_slice, 8 + ser::{BufWriter, Serializer}, 9 + to_vec, 10 + }; 11 + 12 + #[test] 13 + fn test_string() { 14 + let value = "foobar".to_owned(); 15 + assert_eq!(&to_vec(&value).unwrap()[..], b"ffoobar"); 16 + } 17 + 18 + #[test] 19 + fn test_list() { 20 + let value = vec![1, 2, 3]; 21 + assert_eq!(&to_vec(&value).unwrap()[..], b"\x83\x01\x02\x03"); 22 + } 23 + 24 + #[test] 25 + fn test_object() { 26 + let mut object = BTreeMap::new(); 27 + object.insert("a".to_owned(), "A".to_owned()); 28 + object.insert("b".to_owned(), "B".to_owned()); 29 + object.insert("c".to_owned(), "C".to_owned()); 30 + object.insert("d".to_owned(), "D".to_owned()); 31 + object.insert("e".to_owned(), "E".to_owned()); 32 + let vec = to_vec(&object).unwrap(); 33 + let test_object = from_slice(&vec[..]).unwrap(); 34 + assert_eq!(object, test_object); 35 + } 36 + 37 + #[test] 38 + fn test_float() { 39 + let vec = to_vec(&12.3f64).unwrap(); 40 + assert_eq!(vec, b"\xfb@(\x99\x99\x99\x99\x99\x9a"); 41 + } 42 + 43 + #[test] 44 + fn test_f32() { 45 + let vec = to_vec(&4000.5f32).unwrap(); 46 + assert_eq!(vec, b"\xfb\x40\xaf\x41\x00\x00\x00\x00\x00"); 47 + } 48 + 49 + #[test] 50 + fn test_infinity() { 51 + let vec = to_vec(&f32::INFINITY); 52 + assert!(vec.is_err(), "Only finite numbers are supported."); 53 + 54 + let vec = to_vec(&f64::INFINITY); 55 + assert!(vec.is_err(), "Only finite numbers are supported."); 56 + } 57 + 58 + #[test] 59 + fn test_neg_infinity() { 60 + let vec = to_vec(&f32::NEG_INFINITY); 61 + assert!(vec.is_err(), "Only finite numbers are supported."); 62 + 63 + let vec = to_vec(&f64::NEG_INFINITY); 64 + assert!(vec.is_err(), "Only finite numbers are supported."); 65 + } 66 + 67 + #[test] 68 + fn test_nan() { 69 + let vec = to_vec(&f32::NAN); 70 + assert!(vec.is_err(), "Only finite numbers are supported."); 71 + 72 + let vec = to_vec(&f64::NAN); 73 + assert!(vec.is_err(), "Only finite numbers are supported."); 74 + } 75 + 76 + #[test] 77 + fn test_integer() { 78 + // u8 79 + let vec = to_vec(&24).unwrap(); 80 + assert_eq!(vec, b"\x18\x18"); 81 + // i8 82 + let vec = to_vec(&-5).unwrap(); 83 + assert_eq!(vec, b"\x24"); 84 + // i16 85 + let vec = to_vec(&-300).unwrap(); 86 + assert_eq!(vec, b"\x39\x01\x2b"); 87 + // i32 88 + let vec = to_vec(&-23567997).unwrap(); 89 + assert_eq!(vec, b"\x3a\x01\x67\x9e\x7c"); 90 + // u64 91 + let vec = to_vec(&u64::MAX).unwrap(); 92 + assert_eq!(vec, b"\x1b\xff\xff\xff\xff\xff\xff\xff\xff"); 93 + // u128 within u64 range 94 + let vec = to_vec(&(u64::MAX as u128)).unwrap(); 95 + assert_eq!(vec, b"\x1b\xff\xff\xff\xff\xff\xff\xff\xff"); 96 + // u128 out of range 97 + assert!(to_vec(&(u64::MAX as u128 + 1)).is_err()); 98 + // i128 within u64 range 99 + let vec = to_vec(&(u64::MAX as i128)).unwrap(); 100 + assert_eq!(vec, b"\x1b\xff\xff\xff\xff\xff\xff\xff\xff"); 101 + // i128 within -u64 range 102 + let vec = to_vec(&(-(u64::MAX as i128))).unwrap(); 103 + assert_eq!(vec, b"\x3B\xff\xff\xff\xff\xff\xff\xff\xfe"); 104 + // minimum CBOR integer value 105 + let vec = to_vec(&(-(u64::MAX as i128 + 1))).unwrap(); 106 + assert_eq!(vec, b"\x3B\xff\xff\xff\xff\xff\xff\xff\xff"); 107 + // i128 out of -u64 range 108 + assert!(to_vec(&i128::MIN).is_err()); 109 + } 110 + 111 + #[test] 112 + fn test_ip_addr() { 113 + use std::net::Ipv4Addr; 114 + 115 + let addr = Ipv4Addr::new(8, 8, 8, 8); 116 + let vec = to_vec(&addr).unwrap(); 117 + println!("{:?}", vec); 118 + assert_eq!(vec.len(), 5); 119 + let test_addr: Ipv4Addr = from_slice(&vec).unwrap(); 120 + assert_eq!(addr, test_addr); 121 + } 122 + 123 + /// Test all of CBOR's fixed-length byte string types 124 + #[test] 125 + fn test_byte_string() { 126 + // Very short byte strings have 1-byte headers 127 + let short = serde_bytes::Bytes::new(&[0, 1, 2, 255]); 128 + let short_s = to_vec(&short).unwrap(); 129 + assert_eq!(short_s, [0x44, 0, 1, 2, 255]); 130 + 131 + // byte strings > 23 bytes have 2-byte headers 132 + let medium = Bytes::new(&[ 133 + 0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 255, 134 + ]); 135 + let medium_s = to_vec(&medium).unwrap(); 136 + assert_eq!( 137 + medium_s, 138 + [ 139 + 0x58, 24, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 140 + 22, 255 141 + ] 142 + ); 143 + 144 + // byte strings > 256 bytes have 3-byte headers 145 + let long_vec = ByteBuf::from((0..256).map(|i| (i & 0xFF) as u8).collect::<Vec<_>>()); 146 + let long_s = to_vec(&long_vec).unwrap(); 147 + assert_eq!(&long_s[0..3], [0x59, 1, 0]); 148 + assert_eq!(&long_s[3..], &long_vec[..]); 149 + 150 + // byte strings > 2^16 bytes have 5-byte headers 151 + let very_long_vec = ByteBuf::from((0..65536).map(|i| (i & 0xFF) as u8).collect::<Vec<_>>()); 152 + let very_long_s = to_vec(&very_long_vec).unwrap(); 153 + assert_eq!(&very_long_s[0..5], [0x5a, 0, 1, 0, 0]); 154 + assert_eq!(&very_long_s[5..], &very_long_vec[..]); 155 + 156 + // byte strings > 2^32 bytes have 9-byte headers, but they take too much RAM 157 + // to test in Travis. 158 + } 159 + 160 + /// This test checks that the keys of a map are sorted correctly, independently of the order of the 161 + /// input. 162 + #[test] 163 + fn test_key_order_transcode_map() { 164 + // CBOR encoded {"a": 1, "b": 2} 165 + let expected = [0xa2, 0x61, 0x61, 0x01, 0x61, 0x62, 0x02]; 166 + 167 + let data = vec![("b", 2), ("a", 1)]; 168 + let deserializer: MapDeserializer<'_, _, value::Error> = MapDeserializer::new(data.into_iter()); 169 + let writer = BufWriter::new(Vec::new()); 170 + let mut serializer = Serializer::new(writer); 171 + serde_transcode::transcode(deserializer, &mut serializer).unwrap(); 172 + let result = serializer.into_inner().into_inner(); 173 + assert_eq!(result, expected); 174 + } 175 + 176 + // This test makes sure that even unbound lists are not encoded as such (as lists in DAG-CBOR need 177 + // to be finite). 178 + #[test] 179 + fn test_non_unbound_list() { 180 + // Create an iterator that has no size hint. This would trigger the "unbounded code path" for 181 + // sequences. 182 + let one_two_three_iter = iter::successors( 183 + Some(1), 184 + move |&num| { 185 + if num < 3 { 186 + Some(num + 1) 187 + } else { 188 + None 189 + } 190 + }, 191 + ); 192 + 193 + // CBOR encoded [1, 2, 3] 194 + let expected = [0x83, 0x01, 0x02, 0x03]; 195 + 196 + let deserializer: SeqDeserializer<_, value::Error> = SeqDeserializer::new(one_two_three_iter); 197 + let writer = BufWriter::new(Vec::new()); 198 + let mut serializer = Serializer::new(writer); 199 + serde_transcode::transcode(deserializer, &mut serializer).unwrap(); 200 + let result = serializer.into_inner().into_inner(); 201 + assert_eq!(result, expected); 202 + } 203 + 204 + #[test] 205 + fn test_struct_canonical() { 206 + #[derive(Serialize)] 207 + struct First { 208 + a: u32, 209 + b: u32, 210 + } 211 + #[derive(Serialize)] 212 + struct Second { 213 + b: u32, 214 + a: u32, 215 + } 216 + 217 + let first = First { a: 1, b: 2 }; 218 + let second = Second { a: 1, b: 2 }; 219 + 220 + let first_bytes = serde_ipld_dagcbor::to_vec(&first).unwrap(); 221 + let second_bytes = serde_ipld_dagcbor::to_vec(&second).unwrap(); 222 + 223 + assert_eq!(first_bytes, second_bytes); 224 + // Do not only make sure that the order is the same, but also that it's correct. 225 + assert_eq!(first_bytes, b"\xa2\x61a\x01\x61b\x02") 226 + } 227 + 228 + #[test] 229 + fn test_struct_variant_canonical() { 230 + // The `abc` is there to make sure it really follows the DAG-CBOR sorting order, which sorts by 231 + // length of the keys first, then lexicographically. It means that `abc` sorts *after* `b`. 232 + #[derive(Serialize)] 233 + enum First { 234 + Data { a: u8, b: u8, abc: u8 }, 235 + } 236 + 237 + #[derive(Serialize)] 238 + enum Second { 239 + Data { b: u8, abc: u8, a: u8 }, 240 + } 241 + 242 + let first = First::Data { a: 1, b: 2, abc: 3 }; 243 + let second = Second::Data { a: 1, b: 2, abc: 3 }; 244 + 245 + let first_bytes = serde_ipld_dagcbor::to_vec(&first).unwrap(); 246 + let second_bytes = serde_ipld_dagcbor::to_vec(&second).unwrap(); 247 + 248 + assert_eq!(first_bytes, second_bytes); 249 + // Do not only make sure that the order is the same, but also that it's correct. 250 + assert_eq!( 251 + first_bytes, 252 + b"\xa1\x64Data\xa3\x61a\x01\x61b\x02\x63abc\x03" 253 + ) 254 + }
+256
vendor/git/serde_ipld_dagcbor/tests/std_types.rs
··· 1 + use serde_derive::{Deserialize, Serialize}; 2 + 3 + use serde_ipld_dagcbor::{from_slice, to_vec}; 4 + 5 + fn to_binary(s: &'static str) -> Vec<u8> { 6 + assert!(s.len().is_multiple_of(2)); 7 + let mut b = Vec::with_capacity(s.len() / 2); 8 + for i in 0..s.len() / 2 { 9 + b.push(u8::from_str_radix(&s[i * 2..(i + 1) * 2], 16).unwrap()); 10 + } 11 + b 12 + } 13 + 14 + macro_rules! testcase { 15 + ($name:ident, f64, $expr:expr, $s:expr) => { 16 + #[test] 17 + fn $name() { 18 + let expr: f64 = $expr; 19 + let serialized = to_binary($s); 20 + assert_eq!(to_vec(&expr).unwrap(), serialized); 21 + let parsed: f64 = from_slice(&serialized[..]).unwrap(); 22 + if !expr.is_nan() { 23 + assert_eq!(expr, parsed); 24 + } else { 25 + assert!(parsed.is_nan()) 26 + } 27 + 28 + #[cfg(feature = "std")] 29 + { 30 + let parsed: f64 = serde_ipld_dagcbor::from_reader(&mut &serialized[..]).unwrap(); 31 + if !expr.is_nan() { 32 + assert_eq!(expr, parsed); 33 + } else { 34 + assert!(parsed.is_nan()) 35 + } 36 + } 37 + } 38 + }; 39 + ($name:ident, $ty:ty, $expr:expr, $s:expr) => { 40 + #[test] 41 + fn $name() { 42 + let expr: $ty = $expr; 43 + let serialized = to_binary($s); 44 + assert_eq!( 45 + to_vec(&expr).expect("ser1 works"), 46 + serialized, 47 + "serialization differs" 48 + ); 49 + let parsed: $ty = from_slice(&serialized[..]).expect("de1 works"); 50 + assert_eq!(parsed, expr, "parsed result differs"); 51 + } 52 + }; 53 + } 54 + 55 + testcase!(test_bool_false, bool, false, "f4"); 56 + testcase!(test_bool_true, bool, true, "f5"); 57 + testcase!(test_isize_neg_256, isize, -256, "38ff"); 58 + testcase!(test_isize_neg_257, isize, -257, "390100"); 59 + testcase!(test_isize_255, isize, 255, "18ff"); 60 + testcase!(test_i8_5, i8, 5, "05"); 61 + testcase!(test_i8_23, i8, 23, "17"); 62 + testcase!(test_i8_24, i8, 24, "1818"); 63 + testcase!(test_i8_neg_128, i8, -128, "387f"); 64 + testcase!(test_u32_98745874, u32, 98745874, "1a05e2be12"); 65 + // In DAG-CBOR you cannot deserialize into f32, it's always f64. 66 + //testcase!(test_f32_1234_point_5, f32, 1234.5, "fb40934a0000000000"); 67 + testcase!(test_f64_12345_point_6, f64, 12345.6, "fb40c81ccccccccccd"); 68 + testcase!(test_char_null, char, '\x00', "6100"); 69 + testcase!(test_char_broken_heart, char, '💔', "64f09f9294"); 70 + testcase!( 71 + test_str_pangram_de, 72 + String, 73 + "aâø↓é".to_owned(), 74 + "6a61c3a2c3b8e28693c3a9" 75 + ); 76 + 77 + #[derive(Debug, PartialEq, Deserialize, Serialize)] 78 + struct NewtypeStruct(bool); 79 + testcase!( 80 + test_newtype_struct, 81 + NewtypeStruct, 82 + NewtypeStruct(true), 83 + "f5" 84 + ); 85 + 86 + testcase!(test_option_none, Option<u8>, None, "f6"); 87 + testcase!(test_option_some, Option<u8>, Some(42), "182a"); 88 + 89 + #[derive(Debug, PartialEq, Deserialize, Serialize)] 90 + struct Person { 91 + name: String, 92 + year_of_birth: u16, 93 + profession: Option<String>, 94 + } 95 + 96 + testcase!(test_person_struct, 97 + Person, 98 + Person { 99 + name: "Grace Hopper".to_string(), 100 + year_of_birth: 1906, 101 + profession: Some("computer scientist".to_string()), 102 + }, 103 + "a3646e616d656c477261636520486f707065726a70726f66657373696f6e72636f6d707574657220736369656e746973746d796561725f6f665f6269727468190772"); 104 + 105 + #[derive(Debug, PartialEq, Deserialize, Serialize)] 106 + struct OptionalPerson { 107 + name: String, 108 + #[serde(skip_serializing_if = "Option::is_none")] 109 + year_of_birth: Option<u16>, 110 + profession: Option<String>, 111 + } 112 + 113 + testcase!(test_optional_person_struct, 114 + OptionalPerson, 115 + OptionalPerson { 116 + name: "Grace Hopper".to_string(), 117 + year_of_birth: None, 118 + profession: Some("computer scientist".to_string()), 119 + }, 120 + "a2646e616d656c477261636520486f707065726a70726f66657373696f6e72636f6d707574657220736369656e74697374"); 121 + 122 + #[derive(Debug, PartialEq, Deserialize, Serialize)] 123 + enum Color { 124 + Red, 125 + Blue, 126 + Yellow, 127 + Other(u64), 128 + Alpha(u64, u8), 129 + } 130 + 131 + testcase!(test_color_enum, Color, Color::Blue, "64426c7565"); 132 + testcase!( 133 + test_color_enum_transparent, 134 + Color, 135 + Color::Other(42), 136 + "a1654f74686572182a" 137 + ); 138 + testcase!( 139 + test_color_enum_with_alpha, 140 + Color, 141 + Color::Alpha(234567, 60), 142 + "a165416c706861821a00039447183c" 143 + ); 144 + testcase!(test_i128_a, i128, -1i128, "20"); 145 + testcase!(test_u128, u128, 17, "11"); 146 + 147 + // f32 round-trip tests 148 + #[test] 149 + fn test_f32_roundtrip() { 150 + #[derive(Debug, PartialEq, Serialize, Deserialize)] 151 + struct SimpleF32 { 152 + value: f32, 153 + } 154 + 155 + // Test various f32 values 156 + let test_values = vec![ 157 + 0.0f32, 158 + -0.0f32, 159 + 1.0f32, 160 + -1.0f32, 161 + 1.5f32, 162 + f32::MIN, 163 + f32::MAX, 164 + f32::EPSILON, 165 + f32::MIN_POSITIVE, 166 + ]; 167 + 168 + for value in test_values { 169 + let original = SimpleF32 { value }; 170 + let encoded = to_vec(&original).expect("encoding should succeed"); 171 + let decoded: SimpleF32 = from_slice(&encoded).expect("decoding should succeed"); 172 + assert_eq!(original.value.to_bits(), decoded.value.to_bits()); 173 + } 174 + } 175 + 176 + #[test] 177 + fn test_f32_encoding_is_f64() { 178 + // Verify that f32 values are actually encoded as f64 in DAG-CBOR 179 + let value = 1.5f32; 180 + let encoded = to_vec(&value).expect("encoding should succeed"); 181 + 182 + // CBOR marker for f64 is 0xfb 183 + assert_eq!(encoded[0], 0xfb); 184 + // The encoded value should be 8 bytes (f64) + 1 byte marker = 9 bytes total 185 + assert_eq!(encoded.len(), 9); 186 + } 187 + 188 + #[test] 189 + fn test_accept_f32_cbor_marker_for_compatibility() { 190 + // Test that we accept CBOR f32 encoding (0xfa marker) for compatibility, 191 + // even though it's not valid in strict DAG-CBOR (please don't take this 192 + // test as permission to use f32 encoding in new data!). 193 + 194 + // Manually construct CBOR with f32 encoding 195 + // 0xfa = f32 marker, followed by 4 bytes of IEEE 754 single precision 196 + let f32_cbor = vec![ 197 + 0xfa, // f32 marker (not valid in strict DAG-CBOR, but we accept it) 198 + 0x3f, 0xc0, 0x00, 0x00, // 1.5 in IEEE 754 single precision 199 + ]; 200 + 201 + // Should successfully decode for compatibility 202 + let result: Result<f32, _> = from_slice(&f32_cbor); 203 + assert!(result.is_ok()); 204 + assert_eq!(result.unwrap(), 1.5f32); 205 + } 206 + 207 + #[test] 208 + fn test_f32_strict_precision_rejection() { 209 + // Test that f64 values with more precision than f32 can represent are rejected 210 + // when deserializing to f32 211 + 212 + #[derive(Debug, PartialEq, Serialize, Deserialize)] 213 + struct F32Wrapper { 214 + value: f32, 215 + } 216 + 217 + // Value that loses precision when converted to f32 218 + let precise_f64 = 0.1f64; 219 + let encoded = to_vec(&precise_f64).expect("encoding should succeed"); 220 + 221 + // Try to decode as f32 - should fail due to precision loss 222 + let result: Result<f32, _> = from_slice(&encoded); 223 + assert!(result.is_err()); 224 + if let Err(e) = result { 225 + let error_msg = format!("{}", e); 226 + assert!( 227 + error_msg.contains("precision"), 228 + "Expected precision error, got: {}", 229 + error_msg 230 + ); 231 + } 232 + 233 + // Value that is exactly representable in f32 should work 234 + let exact_f64 = 1.5f64; 235 + let encoded = to_vec(&exact_f64).expect("encoding should succeed"); 236 + let result: Result<f32, _> = from_slice(&encoded); 237 + assert!(result.is_ok()); 238 + assert_eq!(result.unwrap(), 1.5f32); 239 + 240 + // Test with struct containing f32 241 + let original = F32Wrapper { value: 1.5f32 }; 242 + let encoded = to_vec(&original).expect("encoding should succeed"); 243 + let decoded: Result<F32Wrapper, _> = from_slice(&encoded); 244 + assert!(decoded.is_ok()); 245 + assert_eq!(decoded.unwrap(), original); 246 + 247 + // Negative zero should preserve sign bit and work 248 + let neg_zero_f64 = -0.0f64; 249 + let encoded = to_vec(&neg_zero_f64).expect("encoding should succeed"); 250 + let result: Result<f32, _> = from_slice(&encoded); 251 + assert!(result.is_ok()); 252 + let decoded_f32 = result.unwrap(); 253 + assert_eq!(decoded_f32, -0.0f32); 254 + // Check that sign bit is preserved 255 + assert_eq!(decoded_f32.to_bits(), (-0.0f32).to_bits()); 256 + }