├── tests ├── main.rs └── json.rs ├── .gitignore ├── .github ├── FUNDING.yml ├── dependabot.yml ├── actions │ └── check │ │ └── action.yml └── workflows │ └── ci.yml ├── rust-toolchain.toml ├── rustfmt.toml ├── CONTRIBUTING.md ├── Cargo.toml ├── src ├── error.rs ├── lib.rs ├── value.rs ├── ser.rs └── de.rs ├── README.md └── LICENSE /tests/main.rs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /Cargo.lock 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [Xuanwo] 2 | -------------------------------------------------------------------------------- /rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "stable" 3 | components = ["rustfmt", "clippy"] 4 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | edition = "2021" 2 | reorder_imports = true 3 | #format_code_in_doc_comments = true 4 | #imports_granularity = "Module" 5 | #group_imports = "StdExternalCrate" 6 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | # Maintain dependencies for GitHub Actions 4 | - package-ecosystem: "github-actions" 5 | directory: "/" 6 | schedule: 7 | interval: "daily" 8 | 9 | # Maintain dependencies for rust 10 | - package-ecosystem: "cargo" 11 | directory: "/" 12 | schedule: 13 | interval: "daily" 14 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | ## Get Started 4 | 5 | This is a Rust project, so [rustup](https://rustup.rs/) is the best place to start. 6 | 7 | This is a pure rust project, so only `cargo` is needed. 8 | 9 | - `cargo check` to analyze the current package and report errors. 10 | - `cargo build` to compile the current package. 11 | - `cargo clippy` to catch common mistakes and improve code. 12 | - `cargo test` to run unit tests. 13 | - `cargo bench` to run benchmark tests. 14 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | authors = ["Xuanwo "] 3 | categories = ["command-line-utilities"] 4 | description = "Bridge between serde types" 5 | documentation = "https://docs.rs/serde-bridge" 6 | repository = "https://github.com/Xuanwo/serde-bridge" 7 | edition = "2021" 8 | license = "Apache-2.0" 9 | name = "serde-bridge" 10 | version = "0.1.0" 11 | 12 | [dependencies] 13 | indexmap = "2.0.0" 14 | serde = "1.0.136" 15 | anyhow = "1.0.56" 16 | 17 | [dev-dependencies] 18 | serde = { version = "1.0.136", features = ["derive"] } 19 | serde_json = "1.0.79" 20 | -------------------------------------------------------------------------------- /src/error.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::{self, Debug, Display}; 2 | use std::num::TryFromIntError; 3 | 4 | use anyhow::anyhow; 5 | use serde::{de, ser}; 6 | 7 | #[derive(Debug)] 8 | pub struct Error(pub anyhow::Error); 9 | 10 | impl ser::Error for Error { 11 | fn custom(msg: T) -> Self { 12 | Error(anyhow!("{}", msg)) 13 | } 14 | } 15 | 16 | impl de::Error for Error { 17 | fn custom(msg: T) -> Self { 18 | Error(anyhow!("{}", msg)) 19 | } 20 | } 21 | 22 | impl Display for Error { 23 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 24 | Display::fmt(&self.0, f) 25 | } 26 | } 27 | 28 | impl std::error::Error for Error {} 29 | 30 | impl From for Error { 31 | fn from(v: TryFromIntError) -> Self { 32 | Error(anyhow::anyhow!("convert from int: {:?}", v)) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /.github/actions/check/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Check' 2 | description: 'Check will do all essential checks' 3 | inputs: 4 | github_token: 5 | description: "Github Token" 6 | required: true 7 | runs: 8 | using: "composite" 9 | steps: 10 | - uses: Swatinem/rust-cache@v1 11 | with: 12 | sharedKey: base-v1 13 | 14 | - name: Format 15 | uses: actions-rs/cargo@v1 16 | with: 17 | command: fmt 18 | args: --all -- --check 19 | 20 | - name: Install cargo-audit 21 | uses: actions-rs/cargo@v1 22 | with: 23 | command: install 24 | args: cargo-audit 25 | 26 | - name: Audit dependencies 27 | uses: actions-rs/cargo@v1 28 | with: 29 | command: audit 30 | 31 | - name: Clippy 32 | uses: actions-rs/cargo@v1 33 | with: 34 | command: clippy 35 | args: --all-targets -- -D warnings 36 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! serde-bridge intends to be a bridge between different serde implementations. 2 | //! 3 | //! # Examples 4 | //! 5 | //! ``` 6 | //! use anyhow::Result; 7 | //! use serde_bridge::{from_value, into_value, FromValue, IntoValue, Value}; 8 | //! 9 | //! fn main() -> Result<()> { 10 | //! let v = bool::from_value(Value::Bool(true))?; 11 | //! assert!(v); 12 | //! 13 | //! let v: bool = from_value(Value::Bool(true))?; 14 | //! assert!(v); 15 | //! 16 | //! let v = true.into_value()?; 17 | //! assert_eq!(v, Value::Bool(true)); 18 | //! 19 | //! let v = into_value(true)?; 20 | //! assert_eq!(v, Value::Bool(true)); 21 | //! 22 | //! Ok(()) 23 | //! } 24 | //! ``` 25 | 26 | mod value; 27 | pub use value::Value; 28 | 29 | mod de; 30 | pub use de::{from_value, Deserializer, FromValue}; 31 | 32 | mod ser; 33 | pub use ser::{into_value, IntoValue}; 34 | 35 | mod error; 36 | use error::Error; 37 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push, pull_request] 4 | 5 | concurrency: 6 | group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }} 7 | cancel-in-progress: true 8 | 9 | jobs: 10 | check: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | - uses: ./.github/actions/check 15 | with: 16 | github_token: ${{ secrets.GITHUB_TOKEN }} 17 | 18 | build: 19 | runs-on: ${{ matrix.os }} 20 | strategy: 21 | matrix: 22 | os: 23 | - ubuntu-latest 24 | - macos-latest 25 | - windows-latest 26 | steps: 27 | - uses: actions/checkout@v3 28 | - uses: Swatinem/rust-cache@v2 29 | - name: Build 30 | uses: actions-rs/cargo@v1 31 | with: 32 | command: build 33 | 34 | unit: 35 | runs-on: ${{ matrix.os }} 36 | strategy: 37 | matrix: 38 | os: 39 | - ubuntu-latest 40 | - macos-latest 41 | - windows-latest 42 | steps: 43 | - uses: actions/checkout@v3 44 | - uses: Swatinem/rust-cache@v2 45 | - name: Test 46 | uses: actions-rs/cargo@v1 47 | with: 48 | command: test 49 | args: -- --nocapture 50 | env: 51 | RUST_LOG: DEBUG 52 | RUST_BACKTRACE: full 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # serde-bridge   [![Build Status]][actions] [![Latest Version]][crates.io] [![chat]][discord] 2 | 3 | [Build Status]: https://img.shields.io/github/actions/workflow/status/Xuanwo/serde-bridge/ci.yml?branch=main 4 | [actions]: https://github.com/Xuanwo/serde-bridge/actions?query=branch%3Amain 5 | [Latest Version]: https://img.shields.io/crates/v/serde-bridge.svg 6 | [crates.io]: https://crates.io/crates/serde-bridge 7 | [chat]: https://img.shields.io/discord/1111711408875393035 8 | [discord]: https://discord.gg/bmczSs2C69 9 | 10 | Bridge between serde types 11 | 12 | ## Quick Start 13 | 14 | ```rust 15 | use anyhow::Result; 16 | use serde_bridge::{from_value, into_value, FromValue, IntoValue, Value}; 17 | 18 | fn main() -> Result<()> { 19 | let v = bool::from_value(Value::Bool(true))?; 20 | assert!(v); 21 | 22 | let v: bool = from_value(Value::Bool(true))?; 23 | assert!(v); 24 | 25 | let v = true.into_value()?; 26 | assert_eq!(v, Value::Bool(true)); 27 | 28 | let v = into_value(true)?; 29 | assert_eq!(v, Value::Bool(true)); 30 | 31 | Ok(()) 32 | } 33 | ``` 34 | 35 | ## Contributing 36 | 37 | Check out the [CONTRIBUTING.md](./CONTRIBUTING.md) guide for more details on getting started with contributing to this project. 38 | 39 | ## Getting help 40 | 41 | Submit [issues](https://github.com/Xuanwo/serde-bridge/issues/new/choose) for bug report or asking questions in [discussion](https://github.com/Xuanwo/serde-bridge/discussions/new?category=q-a). 42 | 43 | ## Acknowledgment 44 | 45 | This project is highly inspired by [serde-value](https://github.com/arcnmx/serde-value) 46 | 47 | #### License 48 | 49 | 50 | Licensed under Apache License, Version 2.0. 51 | 52 | -------------------------------------------------------------------------------- /tests/json.rs: -------------------------------------------------------------------------------- 1 | use std::collections::BTreeMap; 2 | 3 | use anyhow::Result; 4 | use indexmap::indexmap; 5 | use serde::{Deserialize, Serialize}; 6 | use serde_bridge::{from_value, Value}; 7 | 8 | #[derive(Serialize, Deserialize, PartialEq, Debug)] 9 | struct TestStruct { 10 | a: bool, 11 | b: i32, 12 | c: u64, 13 | d: String, 14 | e: f64, 15 | f: Vec, 16 | g: [u16; 3], 17 | h: BTreeMap, 18 | } 19 | 20 | #[test] 21 | fn test_to_json() -> Result<()> { 22 | let raw = TestStruct { 23 | a: true, 24 | b: 1, 25 | c: 2, 26 | d: "Hello, World!".to_string(), 27 | e: 3.4, 28 | f: vec![6, 7, 8, 9, 10], 29 | g: [11, 12, 13], 30 | h: BTreeMap::from([("a".to_string(), 10.1), ("b".to_string(), 11.3)]), 31 | }; 32 | let value = Value::Struct( 33 | "TestStruct", 34 | indexmap! { 35 | "a" => Value::Bool(true), 36 | "b" => Value::I32(1), 37 | "c" => Value::U64(2), 38 | "d" => Value::Str("Hello, World!".to_string()), 39 | "e" => Value::F64(3.4), 40 | "f" => Value::Seq(vec![ 41 | Value::U8(6), 42 | Value::U8(7), 43 | Value::U8(8), 44 | Value::U8(9), 45 | Value::U8(10), 46 | ]), 47 | "g" => Value::Tuple(vec![ 48 | Value::U16(11), 49 | Value::U16(12), 50 | Value::U16(13), 51 | ]), 52 | "h" => Value::Map( 53 | indexmap! { 54 | Value::Str("a".to_string()) => Value::F32(10.1), 55 | Value::Str("b".to_string()) => Value::F32(11.3), 56 | } 57 | ) 58 | }, 59 | ); 60 | 61 | assert_eq!(serde_json::to_string(&raw)?, serde_json::to_string(&value)?); 62 | 63 | Ok(()) 64 | } 65 | 66 | #[test] 67 | fn test_from_json() -> Result<()> { 68 | let json = r#"{ 69 | "a": true, 70 | "b": 1, 71 | "c": 2, 72 | "d": "Hello, World!", 73 | "e": 3.4, 74 | "f": [6,7,8,9,10], 75 | "g": [11,12,13], 76 | "h": { 77 | "a": 10.1, 78 | "b": 11.3 79 | } 80 | }"#; 81 | 82 | let raw: TestStruct = serde_json::from_str(json)?; 83 | let value: Value = serde_json::from_str(json)?; 84 | 85 | assert_eq!(raw, from_value(value)?); 86 | 87 | Ok(()) 88 | } 89 | -------------------------------------------------------------------------------- /src/value.rs: -------------------------------------------------------------------------------- 1 | use std::hash::{Hash, Hasher}; 2 | 3 | use indexmap::IndexMap; 4 | 5 | /// Value is the internal represents of serde's data format. 6 | /// 7 | /// Value is the one-to-one map to [serde's data format](https://serde.rs/data-model.html). 8 | /// Theoretically, `Value` can be converted from/to any serde format. 9 | /// 10 | /// `Value` is a inter data represents which means: 11 | /// 12 | /// `Value` should be constructed or consumed by `into_value` or `from_value`. 13 | /// 14 | /// - `t.into_value()` -> `Value` 15 | /// - `into_value(t)` -> `Value` 16 | /// - `T::from_value(v)` -> `T` 17 | /// - `from_value(v)` -> `T` 18 | /// 19 | /// `Value` also implements [`serde::Serialize`](https://docs.serde.rs/serde/trait.Serialize.html) and [`serde::Deserialize`](https://docs.serde.rs/serde/trait.Deserialize.html). 20 | /// `Serialize` and `Deserialize` on `Value` that converted from `T` will be the same with `T`. 21 | /// 22 | /// # Examples 23 | /// 24 | /// ## Conversion between `T` and `Value` 25 | /// 26 | /// ``` 27 | /// use anyhow::Result; 28 | /// use serde_bridge::{from_value, into_value, FromValue, IntoValue, Value}; 29 | /// 30 | /// fn main() -> Result<()> { 31 | /// let v = bool::from_value(Value::Bool(true))?; 32 | /// assert!(v); 33 | /// 34 | /// let v: bool = from_value(Value::Bool(true))?; 35 | /// assert!(v); 36 | /// 37 | /// let v = true.into_value()?; 38 | /// assert_eq!(v, Value::Bool(true)); 39 | /// 40 | /// let v = into_value(true)?; 41 | /// assert_eq!(v, Value::Bool(true)); 42 | /// 43 | /// Ok(()) 44 | /// } 45 | /// ``` 46 | /// 47 | /// ## Transparent Serialize and Deserialize 48 | /// 49 | /// ``` 50 | /// use anyhow::Result; 51 | /// use serde_bridge::{from_value, into_value, FromValue, IntoValue, Value}; 52 | /// use serde_json; 53 | /// 54 | /// fn main() -> Result<()> { 55 | /// let raw = serde_json::to_string(&true)?; 56 | /// let value = serde_json::to_string(&true.into_value()?)?; 57 | /// assert_eq!(raw, value); 58 | /// 59 | /// let raw: bool = serde_json::from_str("true")?; 60 | /// let value: Value = serde_json::from_str("true")?; 61 | /// assert_eq!(raw, bool::from_value(value)?); 62 | /// 63 | /// Ok(()) 64 | /// } 65 | /// ``` 66 | #[derive(Debug, Clone, PartialEq)] 67 | pub enum Value { 68 | /// primitive types for `bool`: `false`/`true` 69 | Bool(bool), 70 | /// primitive types for `i8` 71 | I8(i8), 72 | /// primitive types for `i16` 73 | I16(i16), 74 | /// primitive types for `i32` 75 | I32(i32), 76 | /// primitive types for `i64` 77 | I64(i64), 78 | /// primitive types for `i128` 79 | I128(i128), 80 | /// primitive types for `u8` 81 | U8(u8), 82 | /// primitive types for `u16` 83 | U16(u16), 84 | /// primitive types for `u32` 85 | U32(u32), 86 | /// primitive types for `u64` 87 | U64(u64), 88 | /// primitive types for `u128` 89 | U128(u128), 90 | /// primitive types for `f32` 91 | F32(f32), 92 | /// primitive types for `f64` 93 | F64(f64), 94 | /// primitive types for `char` 95 | Char(char), 96 | /// string type 97 | /// 98 | /// UTF-8 bytes with a length and no null terminator. May contain 0-bytes. 99 | Str(String), 100 | /// byte array 101 | /// 102 | /// Similar to strings, during deserialization byte arrays can be transient, owned, or borrowed. 103 | Bytes(Vec), 104 | /// `None` part of an `Option` 105 | None, 106 | /// `Some` part of an `Option` 107 | /// 108 | /// # Note 109 | /// 110 | /// We use `Box` here to workaround recursive data type. 111 | Some(Box), 112 | /// The type of `()` in Rust. 113 | /// 114 | /// It represents an anonymous value containing no data. 115 | Unit, 116 | /// For example `struct Unit` or `PhantomData`. 117 | /// 118 | /// It represents a named value containing no data. 119 | UnitStruct(&'static str), 120 | /// For example the `E::A` and `E::B` in `enum E { A, B }`. 121 | UnitVariant { 122 | name: &'static str, 123 | variant_index: u32, 124 | variant: &'static str, 125 | }, 126 | /// For example struct `Millimeters(u8)`. 127 | NewtypeStruct(&'static str, Box), 128 | /// For example the `E::N` in `enum E { N(u8) }`. 129 | /// 130 | /// # Note 131 | /// 132 | /// We use `Box` here to workaround recursive data type. 133 | NewtypeVariant { 134 | name: &'static str, 135 | variant_index: u32, 136 | variant: &'static str, 137 | value: Box, 138 | }, 139 | /// A variably sized heterogeneous sequence of values, for example `Vec` or `HashSet` 140 | Seq(Vec), 141 | /// A statically sized heterogeneous sequence of values for which the length will be known at deserialization time without looking at the serialized data. 142 | /// 143 | /// For example `(u8,)` or `(String, u64, Vec)` or `[u64; 10]`. 144 | Tuple(Vec), 145 | /// A named tuple, for example `struct Rgb(u8, u8, u8)`. 146 | TupleStruct(&'static str, Vec), 147 | /// For example the `E::T` in `enum E { T(u8, u8) }`. 148 | TupleVariant { 149 | name: &'static str, 150 | variant_index: u32, 151 | variant: &'static str, 152 | fields: Vec, 153 | }, 154 | /// A variably sized heterogeneous key-value pairing, for example `BTreeMap` 155 | Map(IndexMap), 156 | /// A statically sized heterogeneous key-value pairing in which the keys are compile-time 157 | /// constant strings and will be known at deserialization time without looking at the 158 | /// serialized data. 159 | /// 160 | /// For example `struct S { r: u8, g: u8, b: u8 }`. 161 | Struct(&'static str, IndexMap<&'static str, Value>), 162 | /// For example the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }`. 163 | StructVariant { 164 | name: &'static str, 165 | variant_index: u32, 166 | variant: &'static str, 167 | fields: IndexMap<&'static str, Value>, 168 | }, 169 | } 170 | 171 | impl Eq for Value {} 172 | 173 | /// Implement Hash for Value so that we can use value as hash key. 174 | /// 175 | /// ## Notes 176 | /// 177 | /// Not all variants supports hash. 178 | /// 179 | /// ## FIXME 180 | /// 181 | /// does this implementation correct? 182 | #[allow(clippy::derived_hash_with_manual_eq)] 183 | impl Hash for Value { 184 | fn hash(&self, state: &mut H) { 185 | // Write current enum discriminant into state. 186 | std::mem::discriminant(self).hash(state); 187 | match self { 188 | Value::Bool(v) => v.hash(state), 189 | Value::I8(v) => v.hash(state), 190 | Value::I16(v) => v.hash(state), 191 | Value::I32(v) => v.hash(state), 192 | Value::I64(v) => v.hash(state), 193 | Value::I128(v) => v.hash(state), 194 | Value::U8(v) => v.hash(state), 195 | Value::U16(v) => v.hash(state), 196 | Value::U32(v) => v.hash(state), 197 | Value::U64(v) => v.hash(state), 198 | Value::U128(v) => v.hash(state), 199 | Value::F32(_) => panic!("f32 is not hashable"), 200 | Value::F64(_) => panic!("f64 is not hashable"), 201 | Value::Char(v) => v.hash(state), 202 | Value::Str(v) => v.hash(state), 203 | Value::Bytes(v) => v.hash(state), 204 | Value::None => {} 205 | Value::Some(v) => v.hash(state), 206 | Value::Unit => {} 207 | Value::UnitStruct(v) => v.hash(state), 208 | Value::UnitVariant { 209 | name, 210 | variant_index, 211 | variant, 212 | } => { 213 | name.hash(state); 214 | variant_index.hash(state); 215 | variant.hash(state); 216 | } 217 | Value::NewtypeStruct(name, value) => { 218 | name.hash(state); 219 | value.hash(state); 220 | } 221 | Value::NewtypeVariant { 222 | name, 223 | variant_index, 224 | variant, 225 | value, 226 | } => { 227 | name.hash(state); 228 | variant_index.hash(state); 229 | variant.hash(state); 230 | value.hash(state); 231 | } 232 | Value::Seq(v) => v.hash(state), 233 | Value::Tuple(v) => v.hash(state), 234 | Value::TupleStruct(name, fields) => { 235 | name.hash(state); 236 | fields.hash(state); 237 | } 238 | Value::TupleVariant { 239 | name, 240 | variant_index, 241 | variant, 242 | fields, 243 | } => { 244 | name.hash(state); 245 | variant_index.hash(state); 246 | variant.hash(state); 247 | fields.hash(state); 248 | } 249 | Value::Map(v) => { 250 | for e in v { 251 | e.hash(state) 252 | } 253 | } 254 | Value::Struct(name, fields) => { 255 | name.hash(state); 256 | for e in fields { 257 | e.hash(state) 258 | } 259 | } 260 | Value::StructVariant { 261 | name, 262 | variant_index, 263 | variant, 264 | fields, 265 | } => { 266 | name.hash(state); 267 | variant_index.hash(state); 268 | variant.hash(state); 269 | for e in fields { 270 | e.hash(state) 271 | } 272 | } 273 | } 274 | } 275 | } 276 | 277 | #[cfg(test)] 278 | mod tests { 279 | use super::*; 280 | 281 | #[test] 282 | fn test_enum_size() { 283 | println!("Size is {}", std::mem::size_of::()); 284 | } 285 | } 286 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 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 2021 Datafuse Labs 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. -------------------------------------------------------------------------------- /src/ser.rs: -------------------------------------------------------------------------------- 1 | use indexmap::IndexMap; 2 | use serde::ser::{ 3 | SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple, 4 | SerializeTupleStruct, SerializeTupleVariant, 5 | }; 6 | use serde::{ser, Serialize}; 7 | 8 | use crate::{Error, Value}; 9 | 10 | /// Convert `T: Serialize` into [`Value`]. 11 | /// 12 | /// # Examples 13 | /// 14 | /// ``` 15 | /// use serde_bridge::{into_value, Value}; 16 | /// # use anyhow::Result; 17 | /// # fn main() -> Result<()>{ 18 | /// let v = into_value(true)?; 19 | /// # assert_eq!(v, Value::Bool(true)); 20 | /// # Ok(()) 21 | /// # } 22 | /// ``` 23 | pub fn into_value(v: impl Serialize) -> Result { 24 | v.serialize(Serializer) 25 | } 26 | 27 | /// Convert `T: Serialize` into [`Value`]. 28 | /// 29 | /// # Examples 30 | /// 31 | /// ``` 32 | /// use serde_bridge::{IntoValue, Value}; 33 | /// # use anyhow::Result; 34 | /// # fn main() -> Result<()>{ 35 | /// let v = true.into_value()?; 36 | /// # assert_eq!(v, Value::Bool(true)); 37 | /// # Ok(()) 38 | /// # } 39 | /// ``` 40 | pub trait IntoValue { 41 | fn into_value(self) -> Result; 42 | } 43 | 44 | impl IntoValue for T 45 | where 46 | T: Serialize, 47 | { 48 | fn into_value(self) -> Result { 49 | into_value(self) 50 | } 51 | } 52 | 53 | /// Implement transparent [`serde::Serialize`](https://docs.serde.rs/serde/trait.Serialize.html) for [`Value`]. 54 | /// 55 | /// `Serialize` on `Value` that converted from `T` will be the same with `T`. 56 | impl serde::Serialize for Value { 57 | fn serialize(&self, s: S) -> Result 58 | where 59 | S: serde::Serializer, 60 | { 61 | match self { 62 | Value::Bool(v) => s.serialize_bool(*v), 63 | Value::I8(v) => s.serialize_i8(*v), 64 | Value::I16(v) => s.serialize_i16(*v), 65 | Value::I32(v) => s.serialize_i32(*v), 66 | Value::I64(v) => s.serialize_i64(*v), 67 | Value::I128(v) => s.serialize_i128(*v), 68 | Value::U8(v) => s.serialize_u8(*v), 69 | Value::U16(v) => s.serialize_u16(*v), 70 | Value::U32(v) => s.serialize_u32(*v), 71 | Value::U64(v) => s.serialize_u64(*v), 72 | Value::U128(v) => s.serialize_u128(*v), 73 | Value::F32(v) => s.serialize_f32(*v), 74 | Value::F64(v) => s.serialize_f64(*v), 75 | Value::Char(v) => s.serialize_char(*v), 76 | Value::Str(v) => s.serialize_str(v), 77 | Value::Bytes(v) => s.serialize_bytes(v), 78 | Value::None => s.serialize_none(), 79 | Value::Some(v) => s.serialize_some(v), 80 | Value::Unit => s.serialize_unit(), 81 | Value::UnitStruct(name) => s.serialize_unit_struct(name), 82 | Value::UnitVariant { 83 | name, 84 | variant_index, 85 | variant, 86 | } => s.serialize_unit_variant(name, *variant_index, variant), 87 | Value::NewtypeStruct(name, value) => s.serialize_newtype_struct(name, value), 88 | Value::NewtypeVariant { 89 | name, 90 | variant_index, 91 | variant, 92 | value, 93 | } => s.serialize_newtype_variant(name, *variant_index, variant, value), 94 | Value::Seq(v) => { 95 | let mut seq = s.serialize_seq(Some(v.len()))?; 96 | for i in v { 97 | seq.serialize_element(i)?; 98 | } 99 | seq.end() 100 | } 101 | Value::Tuple(v) => { 102 | let mut tuple = s.serialize_tuple(v.len())?; 103 | for i in v { 104 | tuple.serialize_element(i)?; 105 | } 106 | tuple.end() 107 | } 108 | Value::TupleStruct(name, fields) => { 109 | let mut se = s.serialize_tuple_struct(name, fields.len())?; 110 | for i in fields { 111 | se.serialize_field(i)?; 112 | } 113 | se.end() 114 | } 115 | Value::TupleVariant { 116 | name, 117 | variant_index, 118 | variant, 119 | fields, 120 | } => { 121 | let mut se = 122 | s.serialize_tuple_variant(name, *variant_index, variant, fields.len())?; 123 | for i in fields { 124 | se.serialize_field(i)?; 125 | } 126 | se.end() 127 | } 128 | Value::Map(map) => { 129 | let mut se = s.serialize_map(Some(map.len()))?; 130 | for (k, v) in map { 131 | se.serialize_entry(k, v)?; 132 | } 133 | se.end() 134 | } 135 | Value::Struct(name, fields) => { 136 | let mut se = s.serialize_struct(name, fields.len())?; 137 | for (k, v) in fields { 138 | se.serialize_field(k, v)?; 139 | } 140 | se.end() 141 | } 142 | Value::StructVariant { 143 | name, 144 | variant_index, 145 | variant, 146 | fields, 147 | } => { 148 | let mut se = 149 | s.serialize_struct_variant(name, *variant_index, variant, fields.len())?; 150 | for (k, v) in fields { 151 | se.serialize_field(k, v)?; 152 | } 153 | se.end() 154 | } 155 | } 156 | } 157 | } 158 | 159 | struct Serializer; 160 | 161 | impl serde::Serializer for Serializer { 162 | type Ok = Value; 163 | type Error = Error; 164 | type SerializeSeq = SeqSerializer; 165 | type SerializeTuple = TupleSerializer; 166 | type SerializeTupleStruct = TupleStructSerializer; 167 | type SerializeTupleVariant = TupleVariantSerializer; 168 | type SerializeMap = MapSerializer; 169 | type SerializeStruct = StructSerializer; 170 | type SerializeStructVariant = StructVariantSerializer; 171 | 172 | fn serialize_bool(self, v: bool) -> Result { 173 | Ok(Value::Bool(v)) 174 | } 175 | 176 | fn serialize_i8(self, v: i8) -> Result { 177 | Ok(Value::I8(v)) 178 | } 179 | 180 | fn serialize_i16(self, v: i16) -> Result { 181 | Ok(Value::I16(v)) 182 | } 183 | 184 | fn serialize_i32(self, v: i32) -> Result { 185 | Ok(Value::I32(v)) 186 | } 187 | 188 | fn serialize_i64(self, v: i64) -> Result { 189 | Ok(Value::I64(v)) 190 | } 191 | 192 | fn serialize_u8(self, v: u8) -> Result { 193 | Ok(Value::U8(v)) 194 | } 195 | 196 | fn serialize_u16(self, v: u16) -> Result { 197 | Ok(Value::U16(v)) 198 | } 199 | 200 | fn serialize_u32(self, v: u32) -> Result { 201 | Ok(Value::U32(v)) 202 | } 203 | 204 | fn serialize_u64(self, v: u64) -> Result { 205 | Ok(Value::U64(v)) 206 | } 207 | 208 | fn serialize_f32(self, v: f32) -> Result { 209 | Ok(Value::F32(v)) 210 | } 211 | 212 | fn serialize_f64(self, v: f64) -> Result { 213 | Ok(Value::F64(v)) 214 | } 215 | 216 | fn serialize_char(self, v: char) -> Result { 217 | Ok(Value::Char(v)) 218 | } 219 | 220 | fn serialize_str(self, v: &str) -> Result { 221 | Ok(Value::Str(v.to_string())) 222 | } 223 | 224 | fn serialize_bytes(self, v: &[u8]) -> Result { 225 | Ok(Value::Bytes(v.to_vec())) 226 | } 227 | 228 | fn serialize_none(self) -> Result { 229 | Ok(Value::None) 230 | } 231 | 232 | fn serialize_some(self, value: &T) -> Result { 233 | Ok(Value::Some(Box::new(value.serialize(Serializer)?))) 234 | } 235 | 236 | fn serialize_unit(self) -> Result { 237 | Ok(Value::Unit) 238 | } 239 | 240 | fn serialize_unit_struct(self, name: &'static str) -> Result { 241 | Ok(Value::UnitStruct(name)) 242 | } 243 | 244 | fn serialize_unit_variant( 245 | self, 246 | name: &'static str, 247 | variant_index: u32, 248 | variant: &'static str, 249 | ) -> Result { 250 | Ok(Value::UnitVariant { 251 | name, 252 | variant_index, 253 | variant, 254 | }) 255 | } 256 | 257 | fn serialize_newtype_struct( 258 | self, 259 | name: &'static str, 260 | value: &T, 261 | ) -> Result { 262 | Ok(Value::NewtypeStruct( 263 | name, 264 | Box::new(value.serialize(Serializer)?), 265 | )) 266 | } 267 | 268 | fn serialize_newtype_variant( 269 | self, 270 | name: &'static str, 271 | variant_index: u32, 272 | variant: &'static str, 273 | value: &T, 274 | ) -> Result { 275 | Ok(Value::NewtypeVariant { 276 | name, 277 | variant_index, 278 | variant, 279 | value: Box::new(value.serialize(Serializer)?), 280 | }) 281 | } 282 | 283 | fn serialize_seq(self, len: Option) -> Result { 284 | Ok(SeqSerializer::new(len)) 285 | } 286 | 287 | fn serialize_tuple(self, len: usize) -> Result { 288 | Ok(TupleSerializer::new(len)) 289 | } 290 | 291 | fn serialize_tuple_struct( 292 | self, 293 | name: &'static str, 294 | len: usize, 295 | ) -> Result { 296 | Ok(TupleStructSerializer::new(name, len)) 297 | } 298 | 299 | fn serialize_tuple_variant( 300 | self, 301 | name: &'static str, 302 | variant_index: u32, 303 | variant: &'static str, 304 | len: usize, 305 | ) -> Result { 306 | Ok(TupleVariantSerializer::new( 307 | name, 308 | variant_index, 309 | variant, 310 | len, 311 | )) 312 | } 313 | 314 | fn serialize_map(self, len: Option) -> Result { 315 | Ok(MapSerializer::new(len)) 316 | } 317 | 318 | fn serialize_struct( 319 | self, 320 | name: &'static str, 321 | len: usize, 322 | ) -> Result { 323 | Ok(StructSerializer::new(name, len)) 324 | } 325 | 326 | fn serialize_struct_variant( 327 | self, 328 | name: &'static str, 329 | variant_index: u32, 330 | variant: &'static str, 331 | len: usize, 332 | ) -> Result { 333 | Ok(StructVariantSerializer::new( 334 | name, 335 | variant_index, 336 | variant, 337 | len, 338 | )) 339 | } 340 | } 341 | 342 | struct SeqSerializer { 343 | elements: Vec, 344 | } 345 | 346 | impl SeqSerializer { 347 | pub fn new(len: Option) -> Self { 348 | Self { 349 | elements: Vec::with_capacity(len.unwrap_or_default()), 350 | } 351 | } 352 | } 353 | 354 | impl ser::SerializeSeq for SeqSerializer { 355 | type Ok = Value; 356 | type Error = Error; 357 | 358 | fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> { 359 | self.elements.push(value.serialize(Serializer)?); 360 | 361 | Ok(()) 362 | } 363 | 364 | fn end(self) -> Result { 365 | Ok(Value::Seq(self.elements)) 366 | } 367 | } 368 | 369 | struct TupleSerializer { 370 | elements: Vec, 371 | } 372 | 373 | impl TupleSerializer { 374 | pub fn new(len: usize) -> Self { 375 | Self { 376 | elements: Vec::with_capacity(len), 377 | } 378 | } 379 | } 380 | 381 | impl ser::SerializeTuple for TupleSerializer { 382 | type Ok = Value; 383 | type Error = Error; 384 | 385 | fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> { 386 | self.elements.push(value.serialize(Serializer)?); 387 | 388 | Ok(()) 389 | } 390 | 391 | fn end(self) -> Result { 392 | Ok(Value::Tuple(self.elements)) 393 | } 394 | } 395 | 396 | struct TupleStructSerializer { 397 | name: &'static str, 398 | fields: Vec, 399 | } 400 | 401 | impl TupleStructSerializer { 402 | pub fn new(name: &'static str, len: usize) -> Self { 403 | Self { 404 | name, 405 | fields: Vec::with_capacity(len), 406 | } 407 | } 408 | } 409 | 410 | impl ser::SerializeTupleStruct for TupleStructSerializer { 411 | type Ok = Value; 412 | type Error = Error; 413 | 414 | fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> { 415 | self.fields.push(value.serialize(Serializer)?); 416 | 417 | Ok(()) 418 | } 419 | 420 | fn end(self) -> Result { 421 | Ok(Value::TupleStruct(self.name, self.fields)) 422 | } 423 | } 424 | 425 | struct TupleVariantSerializer { 426 | name: &'static str, 427 | variant_index: u32, 428 | variant: &'static str, 429 | fields: Vec, 430 | } 431 | 432 | impl TupleVariantSerializer { 433 | pub fn new(name: &'static str, variant_index: u32, variant: &'static str, len: usize) -> Self { 434 | Self { 435 | name, 436 | variant_index, 437 | variant, 438 | fields: Vec::with_capacity(len), 439 | } 440 | } 441 | } 442 | 443 | impl ser::SerializeTupleVariant for TupleVariantSerializer { 444 | type Ok = Value; 445 | type Error = Error; 446 | 447 | fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> { 448 | self.fields.push(value.serialize(Serializer)?); 449 | 450 | Ok(()) 451 | } 452 | 453 | fn end(self) -> Result { 454 | Ok(Value::TupleVariant { 455 | name: self.name, 456 | variant_index: self.variant_index, 457 | variant: self.variant, 458 | fields: self.fields, 459 | }) 460 | } 461 | } 462 | 463 | struct MapSerializer { 464 | cache_key: Option, 465 | entries: IndexMap, 466 | } 467 | 468 | impl MapSerializer { 469 | pub fn new(len: Option) -> Self { 470 | Self { 471 | cache_key: None, 472 | entries: IndexMap::with_capacity(len.unwrap_or_default()), 473 | } 474 | } 475 | } 476 | 477 | impl ser::SerializeMap for MapSerializer { 478 | type Ok = Value; 479 | type Error = Error; 480 | 481 | fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> { 482 | debug_assert!( 483 | self.cache_key.is_none(), 484 | "value for the last entry is missing" 485 | ); 486 | self.cache_key = Some(key.serialize(Serializer)?); 487 | 488 | Ok(()) 489 | } 490 | 491 | fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error> { 492 | let key = self 493 | .cache_key 494 | .take() 495 | .expect("key for current entry is missing"); 496 | self.entries.insert(key, value.serialize(Serializer)?); 497 | 498 | Ok(()) 499 | } 500 | 501 | fn end(self) -> Result { 502 | Ok(Value::Map(self.entries)) 503 | } 504 | } 505 | 506 | struct StructSerializer { 507 | name: &'static str, 508 | fields: IndexMap<&'static str, Value>, 509 | } 510 | 511 | impl StructSerializer { 512 | pub fn new(name: &'static str, len: usize) -> Self { 513 | Self { 514 | name, 515 | fields: IndexMap::with_capacity(len), 516 | } 517 | } 518 | } 519 | 520 | impl ser::SerializeStruct for StructSerializer { 521 | type Ok = Value; 522 | type Error = Error; 523 | 524 | fn serialize_field( 525 | &mut self, 526 | key: &'static str, 527 | value: &T, 528 | ) -> Result<(), Self::Error> { 529 | self.fields.insert(key, value.serialize(Serializer)?); 530 | 531 | Ok(()) 532 | } 533 | 534 | fn end(self) -> Result { 535 | Ok(Value::Struct(self.name, self.fields)) 536 | } 537 | } 538 | 539 | struct StructVariantSerializer { 540 | name: &'static str, 541 | variant_index: u32, 542 | variant: &'static str, 543 | fields: IndexMap<&'static str, Value>, 544 | } 545 | 546 | impl StructVariantSerializer { 547 | pub fn new(name: &'static str, variant_index: u32, variant: &'static str, len: usize) -> Self { 548 | Self { 549 | name, 550 | variant_index, 551 | variant, 552 | fields: IndexMap::with_capacity(len), 553 | } 554 | } 555 | } 556 | 557 | impl ser::SerializeStructVariant for StructVariantSerializer { 558 | type Ok = Value; 559 | type Error = Error; 560 | 561 | fn serialize_field( 562 | &mut self, 563 | key: &'static str, 564 | value: &T, 565 | ) -> Result<(), Self::Error> { 566 | self.fields.insert(key, value.serialize(Serializer)?); 567 | 568 | Ok(()) 569 | } 570 | 571 | fn end(self) -> Result { 572 | Ok(Value::StructVariant { 573 | name: self.name, 574 | variant_index: self.variant_index, 575 | variant: self.variant, 576 | fields: self.fields, 577 | }) 578 | } 579 | } 580 | 581 | #[cfg(test)] 582 | mod tests { 583 | use anyhow::Result; 584 | use indexmap::indexmap; 585 | 586 | use super::*; 587 | 588 | #[derive(serde::Serialize)] 589 | struct TestStruct { 590 | a: bool, 591 | b: i32, 592 | c: u64, 593 | d: String, 594 | e: f64, 595 | } 596 | 597 | #[test] 598 | fn test_to_value() { 599 | assert_eq!(into_value(128).expect("must success"), Value::I32(128)); 600 | assert_eq!(into_value(128_u64).expect("must success"), Value::U64(128)); 601 | 602 | assert_eq!( 603 | into_value(TestStruct { 604 | a: true, 605 | b: 1, 606 | c: 2, 607 | d: "Hello, World!".to_string(), 608 | e: 4.5 609 | }) 610 | .expect("must success"), 611 | Value::Struct( 612 | "TestStruct", 613 | indexmap! { 614 | "a" => Value::Bool(true), 615 | "b" => Value::I32(1), 616 | "c" => Value::U64(2), 617 | "d" => Value::Str("Hello, World!".to_string()), 618 | "e" => Value::F64(4.5) 619 | } 620 | ) 621 | ) 622 | } 623 | 624 | #[test] 625 | fn test_serialize() -> Result<()> { 626 | let raw = TestStruct { 627 | a: true, 628 | b: 1, 629 | c: 2, 630 | d: "Hello, World!".to_string(), 631 | e: 4.5, 632 | }; 633 | let value = Value::Struct( 634 | "TestStruct", 635 | indexmap! { 636 | "a" => Value::Bool(true), 637 | "b" => Value::I32(1), 638 | "c" => Value::U64(2), 639 | "d" => Value::Str("Hello, World!".to_string()), 640 | "e" => Value::F64(4.5) 641 | }, 642 | ); 643 | 644 | assert_eq!(serde_json::to_string(&raw)?, serde_json::to_string(&value)?); 645 | 646 | Ok(()) 647 | } 648 | } 649 | -------------------------------------------------------------------------------- /src/de.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::Formatter; 2 | use std::vec::IntoIter; 3 | 4 | use anyhow::anyhow; 5 | use indexmap::IndexMap; 6 | use serde::de::{DeserializeOwned, DeserializeSeed, MapAccess, SeqAccess, Visitor}; 7 | use serde::{de, Deserialize}; 8 | 9 | use crate::{Error, Value}; 10 | 11 | /// Convert [`Value`] into `T: DeserializeOwned`. 12 | /// 13 | /// # Examples 14 | /// 15 | /// ``` 16 | /// use serde_bridge::{from_value, Value}; 17 | /// # use anyhow::Result; 18 | /// # fn main() -> Result<()> { 19 | /// let v: bool = from_value(Value::Bool(true))?; 20 | /// # assert!(v); 21 | /// # Ok(()) 22 | /// # } 23 | /// ``` 24 | pub fn from_value(v: Value) -> Result { 25 | T::deserialize(Deserializer(v)) 26 | } 27 | 28 | /// Convert [`Value`] into `T: DeserializeOwned`. 29 | /// 30 | /// # Examples 31 | /// 32 | /// ``` 33 | /// use serde_bridge::{FromValue, Value}; 34 | /// # use anyhow::Result; 35 | /// # fn main() -> Result<()>{ 36 | /// let v = bool::from_value(Value::Bool(true))?; 37 | /// # assert!(v); 38 | /// # Ok(()) 39 | /// # } 40 | /// ``` 41 | pub trait FromValue { 42 | fn from_value(v: Value) -> Result 43 | where 44 | Self: Sized; 45 | } 46 | 47 | impl FromValue for T 48 | where 49 | T: DeserializeOwned, 50 | { 51 | fn from_value(v: Value) -> Result { 52 | from_value(v) 53 | } 54 | } 55 | 56 | struct ValueVisitor; 57 | 58 | impl<'de> Visitor<'de> for ValueVisitor { 59 | type Value = Value; 60 | 61 | fn expecting(&self, f: &mut Formatter) -> std::fmt::Result { 62 | write!(f, "expecting visitor") 63 | } 64 | 65 | fn visit_bool(self, v: bool) -> Result 66 | where 67 | E: de::Error, 68 | { 69 | Ok(Value::Bool(v)) 70 | } 71 | 72 | fn visit_i8(self, v: i8) -> Result 73 | where 74 | E: de::Error, 75 | { 76 | Ok(Value::I8(v)) 77 | } 78 | 79 | fn visit_i16(self, v: i16) -> Result 80 | where 81 | E: de::Error, 82 | { 83 | Ok(Value::I16(v)) 84 | } 85 | 86 | fn visit_i32(self, v: i32) -> Result 87 | where 88 | E: de::Error, 89 | { 90 | Ok(Value::I32(v)) 91 | } 92 | 93 | fn visit_i64(self, v: i64) -> Result 94 | where 95 | E: de::Error, 96 | { 97 | Ok(Value::I64(v)) 98 | } 99 | 100 | fn visit_u8(self, v: u8) -> Result 101 | where 102 | E: de::Error, 103 | { 104 | Ok(Value::U8(v)) 105 | } 106 | 107 | fn visit_u16(self, v: u16) -> Result 108 | where 109 | E: de::Error, 110 | { 111 | Ok(Value::U16(v)) 112 | } 113 | 114 | fn visit_u32(self, v: u32) -> Result 115 | where 116 | E: de::Error, 117 | { 118 | Ok(Value::U32(v)) 119 | } 120 | 121 | fn visit_u64(self, v: u64) -> Result 122 | where 123 | E: de::Error, 124 | { 125 | Ok(Value::U64(v)) 126 | } 127 | 128 | fn visit_f32(self, v: f32) -> Result 129 | where 130 | E: de::Error, 131 | { 132 | Ok(Value::F32(v)) 133 | } 134 | 135 | fn visit_f64(self, v: f64) -> Result 136 | where 137 | E: de::Error, 138 | { 139 | Ok(Value::F64(v)) 140 | } 141 | 142 | fn visit_char(self, v: char) -> Result 143 | where 144 | E: de::Error, 145 | { 146 | Ok(Value::Char(v)) 147 | } 148 | 149 | fn visit_str(self, v: &str) -> Result 150 | where 151 | E: de::Error, 152 | { 153 | Ok(Value::Str(v.to_string())) 154 | } 155 | 156 | fn visit_borrowed_str(self, v: &'de str) -> Result 157 | where 158 | E: de::Error, 159 | { 160 | Ok(Value::Str(v.to_string())) 161 | } 162 | 163 | fn visit_string(self, v: String) -> Result 164 | where 165 | E: de::Error, 166 | { 167 | Ok(Value::Str(v)) 168 | } 169 | 170 | fn visit_bytes(self, v: &[u8]) -> Result 171 | where 172 | E: de::Error, 173 | { 174 | Ok(Value::Bytes(v.to_vec())) 175 | } 176 | 177 | fn visit_borrowed_bytes(self, v: &'de [u8]) -> Result 178 | where 179 | E: de::Error, 180 | { 181 | Ok(Value::Bytes(v.to_vec())) 182 | } 183 | 184 | fn visit_byte_buf(self, v: Vec) -> Result 185 | where 186 | E: de::Error, 187 | { 188 | Ok(Value::Bytes(v)) 189 | } 190 | 191 | fn visit_none(self) -> Result 192 | where 193 | E: de::Error, 194 | { 195 | Ok(Value::None) 196 | } 197 | 198 | fn visit_some(self, d: D) -> Result 199 | where 200 | D: serde::Deserializer<'de>, 201 | { 202 | Ok(Value::Some(Box::new(d.deserialize_any(ValueVisitor)?))) 203 | } 204 | 205 | fn visit_unit(self) -> Result 206 | where 207 | E: de::Error, 208 | { 209 | Ok(Value::Unit) 210 | } 211 | 212 | fn visit_newtype_struct(self, d: D) -> Result 213 | where 214 | D: serde::Deserializer<'de>, 215 | { 216 | Ok(Value::NewtypeStruct( 217 | "", 218 | Box::new(d.deserialize_any(ValueVisitor)?), 219 | )) 220 | } 221 | 222 | fn visit_seq(self, mut seq: A) -> Result 223 | where 224 | A: SeqAccess<'de>, 225 | { 226 | let mut vec = Vec::new(); 227 | while let Some(v) = seq.next_element()? { 228 | vec.push(v); 229 | } 230 | Ok(Value::Seq(vec)) 231 | } 232 | 233 | fn visit_map(self, mut map: A) -> Result 234 | where 235 | A: MapAccess<'de>, 236 | { 237 | let mut im = IndexMap::new(); 238 | while let Some((k, v)) = map.next_entry()? { 239 | im.insert(k, v); 240 | } 241 | Ok(Value::Map(im)) 242 | } 243 | } 244 | 245 | impl<'de> Deserialize<'de> for Value { 246 | fn deserialize(d: D) -> Result 247 | where 248 | D: serde::Deserializer<'de>, 249 | { 250 | d.deserialize_any(ValueVisitor) 251 | } 252 | } 253 | 254 | pub struct Deserializer(Value); 255 | 256 | impl<'de> serde::Deserializer<'de> for Deserializer { 257 | type Error = Error; 258 | 259 | fn deserialize_any(self, vis: V) -> Result 260 | where 261 | V: Visitor<'de>, 262 | { 263 | match &self.0 { 264 | Value::Bool(_) => self.deserialize_bool(vis), 265 | Value::I8(_) => self.deserialize_i8(vis), 266 | Value::I16(_) => self.deserialize_i16(vis), 267 | Value::I32(_) => self.deserialize_i32(vis), 268 | Value::I64(_) => self.deserialize_i64(vis), 269 | Value::I128(_) => self.deserialize_i128(vis), 270 | Value::U8(_) => self.deserialize_u8(vis), 271 | Value::U16(_) => self.deserialize_u16(vis), 272 | Value::U32(_) => self.deserialize_u32(vis), 273 | Value::U64(_) => self.deserialize_u64(vis), 274 | Value::U128(_) => self.deserialize_u128(vis), 275 | Value::F32(_) => self.deserialize_f32(vis), 276 | Value::F64(_) => self.deserialize_f64(vis), 277 | Value::Char(_) => self.deserialize_char(vis), 278 | Value::Str(_) => self.deserialize_string(vis), 279 | Value::Bytes(_) => self.deserialize_byte_buf(vis), 280 | Value::None => self.deserialize_option(vis), 281 | Value::Some(_) => self.deserialize_option(vis), 282 | Value::Unit => self.deserialize_unit(vis), 283 | Value::Map(_) => self.deserialize_map(vis), 284 | Value::Seq(_) => self.deserialize_seq(vis), 285 | Value::Struct(_, _) => self.deserialize_map(vis), 286 | v => unimplemented!("deserialize_any for {:?}", v), 287 | } 288 | } 289 | 290 | fn deserialize_bool(self, vis: V) -> Result 291 | where 292 | V: Visitor<'de>, 293 | { 294 | match self.0 { 295 | Value::Bool(v) => vis.visit_bool(v), 296 | v => Err(Error(anyhow!("invalid type: {:?}", v))), 297 | } 298 | } 299 | 300 | fn deserialize_i8(self, vis: V) -> Result 301 | where 302 | V: Visitor<'de>, 303 | { 304 | match self.0 { 305 | Value::I8(v) => vis.visit_i8(v), 306 | Value::I16(v) => vis.visit_i8(i8::try_from(v)?), 307 | Value::I32(v) => vis.visit_i8(i8::try_from(v)?), 308 | Value::I64(v) => vis.visit_i8(i8::try_from(v)?), 309 | Value::I128(v) => vis.visit_i8(i8::try_from(v)?), 310 | Value::U8(v) => vis.visit_i8(i8::try_from(v)?), 311 | Value::U16(v) => vis.visit_i8(i8::try_from(v)?), 312 | Value::U32(v) => vis.visit_i8(i8::try_from(v)?), 313 | Value::U64(v) => vis.visit_i8(i8::try_from(v)?), 314 | Value::U128(v) => vis.visit_i8(i8::try_from(v)?), 315 | v => Err(Error(anyhow!("invalid type: {:?}, expect i8", v))), 316 | } 317 | } 318 | 319 | fn deserialize_i16(self, vis: V) -> Result 320 | where 321 | V: Visitor<'de>, 322 | { 323 | match self.0 { 324 | Value::I8(v) => vis.visit_i16(i16::from(v)), 325 | Value::I16(v) => vis.visit_i16(v), 326 | Value::I32(v) => vis.visit_i16(i16::try_from(v)?), 327 | Value::I64(v) => vis.visit_i16(i16::try_from(v)?), 328 | Value::I128(v) => vis.visit_i16(i16::try_from(v)?), 329 | Value::U8(v) => vis.visit_i16(i16::from(v)), 330 | Value::U16(v) => vis.visit_i16(i16::try_from(v)?), 331 | Value::U32(v) => vis.visit_i16(i16::try_from(v)?), 332 | Value::U64(v) => vis.visit_i16(i16::try_from(v)?), 333 | Value::U128(v) => vis.visit_i16(i16::try_from(v)?), 334 | v => Err(Error(anyhow!("invalid type: {:?}, expect i16", v))), 335 | } 336 | } 337 | 338 | fn deserialize_i32(self, vis: V) -> Result 339 | where 340 | V: Visitor<'de>, 341 | { 342 | match self.0 { 343 | Value::I8(v) => vis.visit_i32(i32::from(v)), 344 | Value::I16(v) => vis.visit_i32(i32::from(v)), 345 | Value::I32(v) => vis.visit_i32(v), 346 | Value::I64(v) => vis.visit_i32(i32::try_from(v)?), 347 | Value::I128(v) => vis.visit_i32(i32::try_from(v)?), 348 | Value::U8(v) => vis.visit_i32(i32::from(v)), 349 | Value::U16(v) => vis.visit_i32(i32::from(v)), 350 | Value::U32(v) => vis.visit_i32(i32::try_from(v)?), 351 | Value::U64(v) => vis.visit_i32(i32::try_from(v)?), 352 | Value::U128(v) => vis.visit_i32(i32::try_from(v)?), 353 | v => Err(Error(anyhow!("invalid type: {:?}", v))), 354 | } 355 | } 356 | 357 | fn deserialize_i64(self, vis: V) -> Result 358 | where 359 | V: Visitor<'de>, 360 | { 361 | match self.0 { 362 | Value::I8(v) => vis.visit_i64(i64::from(v)), 363 | Value::I16(v) => vis.visit_i64(i64::from(v)), 364 | Value::I32(v) => vis.visit_i64(i64::from(v)), 365 | Value::I64(v) => vis.visit_i64(v), 366 | Value::I128(v) => vis.visit_i64(i64::try_from(v)?), 367 | Value::U8(v) => vis.visit_i64(i64::from(v)), 368 | Value::U16(v) => vis.visit_i32(i32::from(v)), 369 | Value::U32(v) => vis.visit_i64(i64::from(v)), 370 | Value::U64(v) => vis.visit_i64(i64::try_from(v)?), 371 | Value::U128(v) => vis.visit_i64(i64::try_from(v)?), 372 | v => Err(Error(anyhow!("invalid type: {:?}, expect i64", v))), 373 | } 374 | } 375 | 376 | fn deserialize_u8(self, vis: V) -> Result 377 | where 378 | V: Visitor<'de>, 379 | { 380 | match self.0 { 381 | Value::I8(v) => vis.visit_u8(u8::try_from(v)?), 382 | Value::I16(v) => vis.visit_u8(u8::try_from(v)?), 383 | Value::I32(v) => vis.visit_u8(u8::try_from(v)?), 384 | Value::I64(v) => vis.visit_u8(u8::try_from(v)?), 385 | Value::I128(v) => vis.visit_u8(u8::try_from(v)?), 386 | Value::U8(v) => vis.visit_u8(v), 387 | Value::U16(v) => vis.visit_u8(u8::try_from(v)?), 388 | Value::U32(v) => vis.visit_u8(u8::try_from(v)?), 389 | Value::U64(v) => vis.visit_u8(u8::try_from(v)?), 390 | Value::U128(v) => vis.visit_u8(u8::try_from(v)?), 391 | v => Err(Error(anyhow!("invalid type: {:?}, expect u8", v))), 392 | } 393 | } 394 | 395 | fn deserialize_u16(self, vis: V) -> Result 396 | where 397 | V: Visitor<'de>, 398 | { 399 | match self.0 { 400 | Value::I8(v) => vis.visit_u16(u16::try_from(v)?), 401 | Value::I16(v) => vis.visit_u16(u16::try_from(v)?), 402 | Value::I32(v) => vis.visit_u16(u16::try_from(v)?), 403 | Value::I64(v) => vis.visit_u16(u16::try_from(v)?), 404 | Value::I128(v) => vis.visit_u16(u16::try_from(v)?), 405 | Value::U8(v) => vis.visit_u16(u16::from(v)), 406 | Value::U16(v) => vis.visit_u16(v), 407 | Value::U32(v) => vis.visit_u16(u16::try_from(v)?), 408 | Value::U64(v) => vis.visit_u16(u16::try_from(v)?), 409 | Value::U128(v) => vis.visit_u16(u16::try_from(v)?), 410 | v => Err(Error(anyhow!("invalid type: {:?}, expect u16", v))), 411 | } 412 | } 413 | 414 | fn deserialize_u32(self, vis: V) -> Result 415 | where 416 | V: Visitor<'de>, 417 | { 418 | match self.0 { 419 | Value::I8(v) => vis.visit_u32(u32::try_from(v)?), 420 | Value::I16(v) => vis.visit_u32(u32::try_from(v)?), 421 | Value::I32(v) => vis.visit_u32(u32::try_from(v)?), 422 | Value::I64(v) => vis.visit_u32(u32::try_from(v)?), 423 | Value::I128(v) => vis.visit_u32(u32::try_from(v)?), 424 | Value::U8(v) => vis.visit_u32(u32::from(v)), 425 | Value::U16(v) => vis.visit_u32(u32::from(v)), 426 | Value::U32(v) => vis.visit_u32(v), 427 | Value::U64(v) => vis.visit_u32(u32::try_from(v)?), 428 | Value::U128(v) => vis.visit_u32(u32::try_from(v)?), 429 | v => Err(Error(anyhow!("invalid type: {:?}, expect u32", v))), 430 | } 431 | } 432 | 433 | fn deserialize_u64(self, vis: V) -> Result 434 | where 435 | V: Visitor<'de>, 436 | { 437 | match self.0 { 438 | Value::I8(v) => vis.visit_u64(u64::try_from(v)?), 439 | Value::I16(v) => vis.visit_u64(u64::try_from(v)?), 440 | Value::I32(v) => vis.visit_u64(u64::try_from(v)?), 441 | Value::I64(v) => vis.visit_u64(u64::try_from(v)?), 442 | Value::I128(v) => vis.visit_u64(u64::try_from(v)?), 443 | Value::U8(v) => vis.visit_u64(u64::from(v)), 444 | Value::U16(v) => vis.visit_u64(u64::from(v)), 445 | Value::U32(v) => vis.visit_u64(u64::from(v)), 446 | Value::U64(v) => vis.visit_u64(v), 447 | Value::U128(v) => vis.visit_u64(u64::try_from(v)?), 448 | v => Err(Error(anyhow!("invalid type: {:?}, expect u64", v))), 449 | } 450 | } 451 | 452 | fn deserialize_f32(self, vis: V) -> Result 453 | where 454 | V: Visitor<'de>, 455 | { 456 | match self.0 { 457 | Value::F32(v) => vis.visit_f32(v), 458 | Value::F64(v) => vis.visit_f32(v as f32), 459 | v => Err(Error(anyhow!("invalid type: {:?}, expect f32", v))), 460 | } 461 | } 462 | 463 | fn deserialize_f64(self, vis: V) -> Result 464 | where 465 | V: Visitor<'de>, 466 | { 467 | match self.0 { 468 | Value::F32(v) => vis.visit_f64(f64::from(v)), 469 | Value::F64(v) => vis.visit_f64(v), 470 | v => Err(Error(anyhow!("invalid type: {:?}, expect f64", v))), 471 | } 472 | } 473 | 474 | fn deserialize_char(self, vis: V) -> Result 475 | where 476 | V: Visitor<'de>, 477 | { 478 | match self.0 { 479 | Value::Char(v) => vis.visit_char(v), 480 | v => Err(Error(anyhow!("invalid type: {:?}, expect char", v))), 481 | } 482 | } 483 | 484 | fn deserialize_str(self, vis: V) -> Result 485 | where 486 | V: Visitor<'de>, 487 | { 488 | match self.0 { 489 | Value::Str(v) => vis.visit_string(v), 490 | v => Err(Error(anyhow!("invalid type: {:?}, expect str", v))), 491 | } 492 | } 493 | 494 | fn deserialize_string(self, vis: V) -> Result 495 | where 496 | V: Visitor<'de>, 497 | { 498 | match self.0 { 499 | Value::Str(v) => vis.visit_string(v), 500 | v => Err(Error(anyhow!("invalid type: {:?}, expect string", v))), 501 | } 502 | } 503 | 504 | fn deserialize_bytes(self, vis: V) -> Result 505 | where 506 | V: Visitor<'de>, 507 | { 508 | match self.0 { 509 | Value::Bytes(v) => vis.visit_byte_buf(v), 510 | v => Err(Error(anyhow!("invalid type: {:?}, expect bytes", v))), 511 | } 512 | } 513 | 514 | fn deserialize_byte_buf(self, vis: V) -> Result 515 | where 516 | V: Visitor<'de>, 517 | { 518 | match self.0 { 519 | Value::Bytes(v) => vis.visit_byte_buf(v), 520 | v => Err(Error(anyhow!("invalid type: {:?}, expect bytes_buf", v))), 521 | } 522 | } 523 | 524 | fn deserialize_option(self, vis: V) -> Result 525 | where 526 | V: Visitor<'de>, 527 | { 528 | match self.0 { 529 | Value::None => vis.visit_none(), 530 | Value::Some(v) => vis.visit_some(Deserializer(*v)), 531 | v => Err(Error(anyhow!("invalid type: {:?}, expect option", v))), 532 | } 533 | } 534 | 535 | fn deserialize_unit(self, vis: V) -> Result 536 | where 537 | V: Visitor<'de>, 538 | { 539 | match self.0 { 540 | Value::Unit => vis.visit_unit(), 541 | v => Err(Error(anyhow!("invalid type: {:?}, expect unit", v))), 542 | } 543 | } 544 | 545 | fn deserialize_unit_struct(self, name: &'static str, vis: V) -> Result 546 | where 547 | V: Visitor<'de>, 548 | { 549 | match self.0 { 550 | Value::UnitStruct(vn) if vn == name => vis.visit_unit(), 551 | v => Err(Error(anyhow!("invalid type: {:?}, expect unit struct", v))), 552 | } 553 | } 554 | 555 | fn deserialize_newtype_struct( 556 | self, 557 | name: &'static str, 558 | vis: V, 559 | ) -> Result 560 | where 561 | V: Visitor<'de>, 562 | { 563 | match self.0 { 564 | Value::NewtypeStruct(vn, vv) if vn == name => { 565 | vis.visit_newtype_struct(Deserializer(*vv)) 566 | } 567 | v => Err(Error(anyhow!( 568 | "invalid type: {:?}, expect newtype struct", 569 | v 570 | ))), 571 | } 572 | } 573 | 574 | fn deserialize_seq(self, vis: V) -> Result 575 | where 576 | V: Visitor<'de>, 577 | { 578 | match self.0 { 579 | Value::Tuple(v) => vis.visit_seq(SeqAccessor::new(v)), 580 | Value::Seq(v) => vis.visit_seq(SeqAccessor::new(v)), 581 | v => Err(Error(anyhow!("invalid type: {:?}, expect seq", v))), 582 | } 583 | } 584 | 585 | fn deserialize_tuple(self, len: usize, vis: V) -> Result 586 | where 587 | V: Visitor<'de>, 588 | { 589 | match self.0 { 590 | Value::Tuple(v) if len == v.len() => vis.visit_seq(SeqAccessor::new(v)), 591 | Value::Seq(v) if len == v.len() => vis.visit_seq(SeqAccessor::new(v)), 592 | v => Err(Error(anyhow!("invalid type: {:?}, expect tuple", v))), 593 | } 594 | } 595 | 596 | fn deserialize_tuple_struct( 597 | self, 598 | name: &'static str, 599 | len: usize, 600 | vis: V, 601 | ) -> Result 602 | where 603 | V: Visitor<'de>, 604 | { 605 | match self.0 { 606 | Value::TupleStruct(vn, vf) if name == vn && len == vf.len() => { 607 | vis.visit_seq(SeqAccessor::new(vf)) 608 | } 609 | v => Err(Error(anyhow!("invalid type: {:?}, expect tuple struct", v))), 610 | } 611 | } 612 | 613 | fn deserialize_map(self, vis: V) -> Result 614 | where 615 | V: Visitor<'de>, 616 | { 617 | match self.0 { 618 | Value::Map(v) => vis.visit_map(MapAccessor::new(v)), 619 | v => Err(Error(anyhow!("invalid type: {:?}, expect map", v))), 620 | } 621 | } 622 | 623 | fn deserialize_struct( 624 | self, 625 | name: &'static str, 626 | fields: &'static [&'static str], 627 | vis: V, 628 | ) -> Result 629 | where 630 | V: Visitor<'de>, 631 | { 632 | match self.0 { 633 | Value::Struct(vn, mut vf) if vn == name => { 634 | let mut vs = Vec::with_capacity(fields.len()); 635 | for key in fields { 636 | // Use `remove` instead of `get` & `clone` here. 637 | // - As serde will make sure to not access the same field twice. 638 | // - The order of key is not needed to preserve during deserialize. 639 | match vf.shift_remove(key) { 640 | Some(v) => vs.push(v), 641 | None => return Err(Error(anyhow!("field not exist"))), 642 | } 643 | } 644 | vis.visit_seq(SeqAccessor::new(vs)) 645 | } 646 | Value::Map(fields) => vis.visit_map(MapAccessor::new(fields)), 647 | v => Err(Error(anyhow!("invalid type: {:?}, expect struct", v))), 648 | } 649 | } 650 | 651 | fn deserialize_enum( 652 | self, 653 | name: &'static str, 654 | variants: &'static [&'static str], 655 | vis: V, 656 | ) -> Result 657 | where 658 | V: Visitor<'de>, 659 | { 660 | vis.visit_enum(EnumAccessor::new(name, variants, self.0)) 661 | } 662 | 663 | fn deserialize_identifier(self, vis: V) -> Result 664 | where 665 | V: Visitor<'de>, 666 | { 667 | self.deserialize_str(vis) 668 | } 669 | 670 | fn deserialize_ignored_any(self, vis: V) -> Result 671 | where 672 | V: Visitor<'de>, 673 | { 674 | self.deserialize_any(vis) 675 | } 676 | } 677 | 678 | impl From for Deserializer { 679 | fn from(v: Value) -> Self { 680 | Self(v) 681 | } 682 | } 683 | 684 | struct SeqAccessor { 685 | elements: IntoIter, 686 | } 687 | 688 | impl SeqAccessor { 689 | fn new(elements: Vec) -> Self { 690 | Self { 691 | elements: elements.into_iter(), 692 | } 693 | } 694 | } 695 | 696 | impl<'de> de::SeqAccess<'de> for SeqAccessor { 697 | type Error = Error; 698 | 699 | fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> 700 | where 701 | T: DeserializeSeed<'de>, 702 | { 703 | match self.elements.next() { 704 | None => Ok(None), 705 | Some(v) => Ok(Some(seed.deserialize(Deserializer(v))?)), 706 | } 707 | } 708 | } 709 | 710 | struct MapAccessor { 711 | cache_value: Option, 712 | entries: indexmap::map::IntoIter, 713 | } 714 | 715 | impl MapAccessor { 716 | fn new(entries: IndexMap) -> Self { 717 | Self { 718 | cache_value: None, 719 | entries: entries.into_iter(), 720 | } 721 | } 722 | } 723 | impl<'de> de::MapAccess<'de> for MapAccessor { 724 | type Error = Error; 725 | 726 | fn next_key_seed(&mut self, seed: K) -> Result, Self::Error> 727 | where 728 | K: DeserializeSeed<'de>, 729 | { 730 | debug_assert!( 731 | self.cache_value.is_none(), 732 | "value for the last entry is not deserialized" 733 | ); 734 | 735 | match self.entries.next() { 736 | None => Ok(None), 737 | Some((k, v)) => { 738 | self.cache_value = Some(v); 739 | Ok(Some(seed.deserialize(Deserializer(k))?)) 740 | } 741 | } 742 | } 743 | 744 | fn next_value_seed(&mut self, seed: V) -> Result 745 | where 746 | V: DeserializeSeed<'de>, 747 | { 748 | let value = self 749 | .cache_value 750 | .take() 751 | .expect("value for current entry is missing"); 752 | seed.deserialize(Deserializer(value)) 753 | } 754 | } 755 | 756 | struct EnumAccessor { 757 | name: &'static str, 758 | variants: &'static [&'static str], 759 | value: Value, 760 | } 761 | 762 | impl EnumAccessor { 763 | fn new(name: &'static str, variants: &'static [&'static str], value: Value) -> Self { 764 | Self { 765 | name, 766 | variants, 767 | value, 768 | } 769 | } 770 | } 771 | 772 | impl<'de> de::EnumAccess<'de> for EnumAccessor { 773 | type Error = Error; 774 | type Variant = VariantAccessor; 775 | 776 | fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> 777 | where 778 | V: DeserializeSeed<'de>, 779 | { 780 | let value = match &self.value { 781 | Value::UnitVariant { 782 | name: vn, 783 | variant_index: vvi, 784 | variant: vv, 785 | } if &self.name == vn && &self.variants[*vvi as usize] == vv => { 786 | seed.deserialize(Deserializer(Value::Str(vv.to_string())))? 787 | } 788 | Value::TupleVariant { 789 | name: vn, 790 | variant_index: vvi, 791 | variant: vv, 792 | .. 793 | } if &self.name == vn && &self.variants[*vvi as usize] == vv => { 794 | seed.deserialize(Deserializer(Value::Str(vv.to_string())))? 795 | } 796 | Value::StructVariant { 797 | name: vn, 798 | variant_index: vvi, 799 | variant: vv, 800 | .. 801 | } if &self.name == vn && &self.variants[*vvi as usize] == vv => { 802 | seed.deserialize(Deserializer(Value::Str(vv.to_string())))? 803 | } 804 | Value::NewtypeVariant { 805 | name: vn, 806 | variant_index: vvi, 807 | variant: vv, 808 | .. 809 | } if &self.name == vn && &self.variants[*vvi as usize] == vv => { 810 | seed.deserialize(Deserializer(Value::Str(vv.to_string())))? 811 | } 812 | _ => return Err(Error(anyhow!("invalid type"))), 813 | }; 814 | 815 | Ok((value, VariantAccessor::new(self.value))) 816 | } 817 | } 818 | 819 | struct VariantAccessor { 820 | value: Value, 821 | } 822 | 823 | impl VariantAccessor { 824 | fn new(value: Value) -> Self { 825 | Self { value } 826 | } 827 | } 828 | 829 | impl<'de> de::VariantAccess<'de> for VariantAccessor { 830 | type Error = Error; 831 | 832 | fn unit_variant(self) -> Result<(), Self::Error> { 833 | match self.value { 834 | Value::UnitVariant { .. } => Ok(()), 835 | _ => Err(Error(anyhow!("invalid type"))), 836 | } 837 | } 838 | 839 | fn newtype_variant_seed(self, seed: T) -> Result 840 | where 841 | T: DeserializeSeed<'de>, 842 | { 843 | match self.value { 844 | Value::NewtypeVariant { value, .. } => Ok(seed.deserialize(Deserializer(*value))?), 845 | _ => Err(Error(anyhow!("invalid type"))), 846 | } 847 | } 848 | 849 | fn tuple_variant(self, len: usize, vis: V) -> Result 850 | where 851 | V: Visitor<'de>, 852 | { 853 | match self.value { 854 | Value::TupleVariant { fields, .. } if len == fields.len() => { 855 | vis.visit_seq(SeqAccessor::new(fields)) 856 | } 857 | _ => Err(Error(anyhow!("invalid type"))), 858 | } 859 | } 860 | 861 | fn struct_variant( 862 | self, 863 | fields: &'static [&'static str], 864 | vis: V, 865 | ) -> Result 866 | where 867 | V: Visitor<'de>, 868 | { 869 | match self.value { 870 | Value::Struct(_, mut vf) => { 871 | let mut vs = Vec::with_capacity(fields.len()); 872 | for key in fields { 873 | // Use `remove` instead of `get` & `clone` here. 874 | // - As serde will make sure to not access the same field twice. 875 | // - The order of key is not needed to preserve during deserialize. 876 | match vf.shift_remove(key) { 877 | Some(v) => vs.push(v), 878 | None => return Err(Error(anyhow!("field not exist"))), 879 | } 880 | } 881 | vis.visit_seq(SeqAccessor::new(vs)) 882 | } 883 | _ => Err(Error(anyhow!("invalid type"))), 884 | } 885 | } 886 | } 887 | 888 | #[cfg(test)] 889 | mod tests { 890 | use anyhow::Result; 891 | use indexmap::indexmap; 892 | 893 | use super::*; 894 | use crate::de::from_value; 895 | 896 | #[derive(Debug, PartialEq, serde::Deserialize)] 897 | struct TestStruct { 898 | a: bool, 899 | b: i32, 900 | c: u64, 901 | d: String, 902 | e: f64, 903 | } 904 | 905 | #[test] 906 | fn test_from_value() { 907 | let v: bool = from_value(Value::Bool(true)).expect("must success"); 908 | assert!(v); 909 | 910 | let v: TestStruct = from_value(Value::Struct( 911 | "TestStruct", 912 | indexmap! { 913 | "a" => Value::Bool(true), 914 | "b" => Value::I32(1), 915 | "c" => Value::U64(2), 916 | "d" => Value::Str("Hello, World!".to_string()), 917 | "e" => Value::F64(4.5) 918 | }, 919 | )) 920 | .expect("must success"); 921 | assert_eq!( 922 | v, 923 | TestStruct { 924 | a: true, 925 | b: 1, 926 | c: 2, 927 | d: "Hello, World!".to_string(), 928 | e: 4.5 929 | } 930 | ) 931 | } 932 | 933 | #[test] 934 | fn test_deserialize() -> Result<()> { 935 | let content = r#"{ 936 | "a": true, 937 | "b": 1, 938 | "c": 2, 939 | "d": "Hello, World!", 940 | "e": 4.5 941 | }"#; 942 | let raw: TestStruct = serde_json::from_str(content)?; 943 | let value: Value = serde_json::from_str(content)?; 944 | println!("{:?}", value); 945 | 946 | assert_eq!(TestStruct::from_value(value)?, raw); 947 | 948 | Ok(()) 949 | } 950 | } 951 | --------------------------------------------------------------------------------