├── .github └── workflows │ └── test.yaml ├── .gitignore ├── Cargo.toml ├── LICENSE ├── README.md ├── renovate.json ├── serde_watson ├── Cargo.toml ├── README.md └── src │ ├── de.rs │ ├── error.rs │ ├── lib.rs │ ├── ser.rs │ └── value.rs ├── watson_examples ├── Cargo.toml └── examples │ ├── basic.rs │ └── run_vm.rs └── watson_rs ├── Cargo.toml ├── README.md └── src ├── error.rs ├── language ├── conversion.rs └── mod.rs ├── lexer.rs ├── lib.rs ├── serializer.rs ├── unlexer.rs └── vm.rs /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | # Based on https://github.com/actions-rs/meta/blob/master/recipes/quickstart.md 2 | 3 | on: [push, pull_request] 4 | 5 | name: Test 6 | 7 | jobs: 8 | check: 9 | name: Check 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout sources 13 | uses: actions/checkout@v3 14 | 15 | - name: Install stable toolchain 16 | uses: actions-rs/toolchain@v1 17 | with: 18 | profile: minimal 19 | toolchain: stable 20 | override: true 21 | 22 | - name: Run cargo check 23 | uses: actions-rs/cargo@v1 24 | with: 25 | command: check 26 | 27 | test: 28 | name: Test Suite 29 | runs-on: ubuntu-latest 30 | steps: 31 | - name: Checkout sources 32 | uses: actions/checkout@v3 33 | 34 | - name: Install stable toolchain 35 | uses: actions-rs/toolchain@v1 36 | with: 37 | profile: minimal 38 | toolchain: stable 39 | override: true 40 | 41 | - name: Run cargo test 42 | uses: actions-rs/cargo@v1 43 | with: 44 | command: test 45 | 46 | lints: 47 | name: Lints 48 | runs-on: ubuntu-latest 49 | steps: 50 | - name: Checkout sources 51 | uses: actions/checkout@v3 52 | 53 | - name: Install stable toolchain 54 | uses: actions-rs/toolchain@v1 55 | with: 56 | profile: minimal 57 | toolchain: stable 58 | override: true 59 | components: rustfmt, clippy 60 | 61 | - name: Run cargo fmt 62 | uses: actions-rs/cargo@v1 63 | with: 64 | command: fmt 65 | args: --all -- --check 66 | 67 | - name: Run cargo clippy 68 | uses: actions-rs/cargo@v1 69 | with: 70 | command: clippy 71 | args: -- -D warnings -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/rust 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=rust 4 | 5 | ### Rust ### 6 | # Generated by Cargo 7 | # will have compiled files and executables 8 | debug/ 9 | target/ 10 | 11 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 12 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 13 | Cargo.lock 14 | 15 | # These are backup files generated by rustfmt 16 | **/*.rs.bk 17 | 18 | # MSVC Windows builds of rustc generate these, which store debugging information 19 | *.pdb 20 | 21 | # End of https://www.toptal.com/developers/gitignore/api/rust 22 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | 3 | members = [ 4 | "watson_rs", 5 | "serde_watson", 6 | "watson_examples", 7 | ] -------------------------------------------------------------------------------- /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 [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | watson_rs/README.md -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /serde_watson/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "serde_watson" 3 | version = "0.1.0" 4 | edition = "2021" 5 | authors = ["Genta Kamitani "] 6 | license = "Apache-2.0" 7 | description = "Rust implementation for Wasted but Amazing Turing-incomplete Stack-based Object Notation (WATSON)" 8 | repository = "https://github.com/genkami/watson-rs" 9 | categories = ["encoding"] 10 | 11 | [dependencies] 12 | serde = "1.0.138" 13 | watson_rs = { version = "0.1.0", path = "../watson_rs" } 14 | 15 | [dev-dependencies] 16 | serde_test = "1.0.137" 17 | serde = { version = "1.0.138", features = ["derive"] } -------------------------------------------------------------------------------- /serde_watson/README.md: -------------------------------------------------------------------------------- 1 | # serde_watson 2 | 3 | [![Test](https://github.com/genkami/watson-rs/actions/workflows/test.yaml/badge.svg)](https://github.com/genkami/watson-rs/actions/workflows/test.yaml) 4 | [![serde_watson at crates.io](https://img.shields.io/crates/v/serde_watson.svg)](https://crates.io/crates/serde_watson) 5 | [![serde_watson at docs.rs](https://docs.rs/serde_watson/badge.svg)](https://docs.rs/serde_watson) 6 | 7 | Serde support for esoteric configuration language [WATSON](https://github.com/genkami/watson). 8 | 9 | ## Usage 10 | 11 | Add the following to your `Cargo.toml`: 12 | 13 | ```toml 14 | [dependencies] 15 | serde_watson = "0.1.0" 16 | ``` 17 | 18 | ## Examples 19 | 20 | ### Basic Usage 21 | 22 | ```rust 23 | use std::io; 24 | 25 | use serde::Serialize; 26 | use serde_watson::ser::Serializer; 27 | 28 | #[derive(Serialize)] 29 | struct Transaction { 30 | id: u64, 31 | from: String, 32 | to: String, 33 | amount: f64, 34 | } 35 | 36 | fn main() -> serde_watson::Result<()> { 37 | let tx = Transaction { 38 | id: 0xabcd1234, 39 | from: "Motoaki Tanigo".to_owned(), 40 | to: "Oozora Subaru".to_owned(), 41 | amount: 123.45, 42 | }; 43 | let mut ser = Serializer::from_writer(io::stdout()); 44 | tx.serialize(&mut ser)?; 45 | Ok(()) 46 | } 47 | ``` 48 | 49 | You can run the example above by running `cargo run --example basic` in the [watson_example](https://github.com/genkami/watson-rs/tree/main/watson_examples) directory. 50 | 51 | ``` 52 | $ cargo run --example basic 53 | Finished dev [unoptimized + debuginfo] target(s) in 0.08s 54 | Running `target/debug/examples/basic` 55 | ~?SShkShaaakShaaaaakShaaaaaak-SShaakShaaaaakShaaaaaak-SShaakShaaaakShaaaaakShaaa 56 | aaaaaakShaaaaaaaaaaaakShaaaaaaaaaaaaaaaakShaaaaaaaaaaaaaaaaaakShaaaaaaaaaaaaaaaa 57 | aaakShaaaaaaaaaaaaaaaaaaaaaakShaaaaaaaaaaaaaaaaaaaaaaakShaaaaaaaaaaaaaaaaaaaaaaa 58 | akShaaaaaaaaaaaaaaaaaaaaaaaaakShaaaaaaaaaaaaaaaaaaaaaaaaaaakShaaaaaaaaaaaaaaaaaa 59 | aaaaaaaaaaakShaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakig$BBubaBubbaBubbbbbaBubbbbbba!BBu 60 | baBubbbbaBubbbbbaBubbbbbba!BBuaBubaBubbaBubbbaBubbbbbaBubbbbbba!BBuaBubbaBubbbaB 61 | ubbbbbaBubbbbbba!?SShkShaakShaaakShaaaaaak-SShkShakShaakShaaakShaaaaakShaaaaaak- 62 | SShaakShaaaakShaaaaakShaaaaaak-SShkShakShaakShaaakShaaaaakShaaaaaak-SShkShaaaaak 63 | Shaaaaaak-SShkShakShaaakShaaaaakShaaaaaak-SShkShaaakShaaaaakShaaaaaak-SShaaaaak- 64 | SShaakShaaaakShaaaaaak-SShkShaaaaakShaaaaaak-SShakShaakShaaakShaaaaakShaaaaaak-S 65 | ShkShaaakShaaaaakShaaaaaak-SShkShakShaakShaaaaakShaaaaaak-SShkShakShaakShaaakSha 66 | aaaakShaaaaaak-g$BBubbaBubbbbaBubbbbbaBubbbbbba!BBuaBubaBubbaBubbbaBubbbbbaBubbb 67 | bbba!?SShkShakShaakShaaakShaaaaaak-SShkShakShaakShaaakShaaaaakShaaaaaak-SShakSha 68 | aakShaaaakShaaaaakShaaaaaak-SShkShakShaakShaaakShaaaaakShaaaaaak-SShakShaaaakSha 69 | aaaakShaaaaaak-SShkShaaaaakShaaaaaak-SShaaaaak-SShkShakShaaaakShaaaaaak-SShkShaa 70 | kShaaaakShaaaaakShaaaaaak-SShakShaaaaakShaaaaaak-SShkShaaaaakShaaaaaak-SShakShaa 71 | aakShaaaaakShaaaaaak-SShkShaakShaaaakShaaaaakShaaaaaak-g$BBuaBubbbbbaBubbbbbba!B 72 | BuaBubbaBubbbaBubbbbbaBubbbbbba!BBuaBubaBubbaBubbbaBubbbbbaBubbbbbba!BBuaBubbaBu 73 | bbbbaBubbbbbaBubbbbbba!BBubaBubbaBubbbaBubbbbbaBubbbbbba!BBubbaBubbbbaBubbbbbaBu 74 | bbbbbba!BBuaBubbaBubbbaBubbbbbbaBubbbbbbbaBubbbbbbbbbbaBubbbbbbbbbbbaBubbbbbbbbb 75 | bbbbbaBubbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbb 76 | bbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbb 77 | bbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbbb 78 | bbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaB 79 | ubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 80 | baBubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 81 | bbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbb 82 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaB 83 | ubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbb 84 | bbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaBu 85 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbb 86 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 87 | bbbbbbbbbbbbbbaiM 88 | ``` 89 | 90 | You can verify the output using the [WATSON CLI](https://github.com/genkami/watson/blob/main/doc/cli.md). 91 | 92 | ``` 93 | $ cargo run --example basic | watson decode -t json 94 | Finished dev [unoptimized + debuginfo] target(s) in 0.05s 95 | Running `target/debug/examples/basic` 96 | {"amount":123.45,"from":"Motoaki Tanigo","id":2882343476,"to":"Oozora Subaru"} 97 | ``` -------------------------------------------------------------------------------- /serde_watson/src/de.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | use serde::de; 4 | use watson_rs::lexer; 5 | use watson_rs::vm; 6 | 7 | use crate::error::{Error, ErrorKind, Result}; 8 | 9 | /// Deserializes an `str` into a WATSON value. 10 | pub fn from_str(s: &str) -> Result { 11 | from_reader(s.as_bytes()) 12 | } 13 | 14 | /// Reads a WATSON value from the given reader. 15 | pub fn from_reader(reader: R) -> Result 16 | where 17 | R: io::Read, 18 | { 19 | let lx = lexer::Lexer::new(reader); 20 | let mut vm = vm::VM::new(); 21 | vm.execute_all(lx)?; 22 | let top = vm.into_top().map(Ok).unwrap_or_else(|| { 23 | Err(watson_rs::error::Error { 24 | kind: watson_rs::error::ErrorKind::EmptyStack, 25 | location: watson_rs::Location::unknown(), 26 | source: None, 27 | }) 28 | })?; 29 | Ok(top) 30 | } 31 | 32 | /// Deserializer implements serde::de::Deserializer for WATSON encoding. 33 | /// 34 | /// Since WATSON format can't be deserialized incrementally, we do not provide deserializers that 35 | /// borrows an `str` or `io::Read`. Use this deserializer in combination with `from_str` or `from_reader` 36 | /// if you want to deserialize WATSON values directly from these sources. 37 | pub struct Deserializer<'de> { 38 | value: &'de watson_rs::Value, 39 | } 40 | 41 | impl<'de> Deserializer<'de> { 42 | /// Returns a new `Deserializer` that reads from `value`. 43 | pub fn new(value: &'de watson_rs::Value) -> Self { 44 | Deserializer { value } 45 | } 46 | 47 | /// Borrows an `str` from `Value::String`. 48 | fn borrow_str(&self, visitor: &V) -> Result<&'de str> 49 | where 50 | V: de::Visitor<'de>, 51 | { 52 | match self.value { 53 | watson_rs::Value::String(bytes) => try_borrow_str(bytes, visitor), 54 | _ => Err(self.invalid_type(visitor)), 55 | } 56 | } 57 | 58 | fn invalid_type(&self, exp: &dyn de::Expected) -> Error { 59 | invalid_type(self.ty(), exp) 60 | } 61 | 62 | fn ty(&self) -> de::Unexpected<'_> { 63 | use watson_rs::Value::*; 64 | match *self.value { 65 | Int(n) => de::Unexpected::Signed(n), 66 | Uint(n) => de::Unexpected::Unsigned(n), 67 | Float(f) => de::Unexpected::Float(f), 68 | String(ref bs) => de::Unexpected::Bytes(bs.as_slice()), 69 | Object(_) => de::Unexpected::Map, 70 | Array(_) => de::Unexpected::Seq, 71 | Bool(b) => de::Unexpected::Bool(b), 72 | Nil => de::Unexpected::Unit, 73 | } 74 | } 75 | } 76 | 77 | impl<'a, 'de> de::Deserializer<'de> for &'a Deserializer<'de> { 78 | type Error = Error; 79 | 80 | fn deserialize_any(self, visitor: V) -> Result 81 | where 82 | V: de::Visitor<'de>, 83 | { 84 | use watson_rs::Value::*; 85 | match *self.value { 86 | Int(_) => self.deserialize_i64(visitor), 87 | Uint(_) => self.deserialize_u64(visitor), 88 | Float(_) => self.deserialize_f64(visitor), 89 | String(_) => self.deserialize_bytes(visitor), 90 | Object(_) => self.deserialize_map(visitor), 91 | Array(_) => self.deserialize_seq(visitor), 92 | Bool(_) => self.deserialize_bool(visitor), 93 | Nil => self.deserialize_unit(visitor), 94 | } 95 | } 96 | 97 | fn deserialize_bool(self, visitor: V) -> Result 98 | where 99 | V: de::Visitor<'de>, 100 | { 101 | match self.value { 102 | &watson_rs::Value::Bool(b) => visitor.visit_bool(b), 103 | _ => Err(self.invalid_type(&visitor)), 104 | } 105 | } 106 | 107 | fn deserialize_i8(self, visitor: V) -> Result 108 | where 109 | V: de::Visitor<'de>, 110 | { 111 | match self.value { 112 | &watson_rs::Value::Int(n) => visitor.visit_i64(n), 113 | _ => Err(self.invalid_type(&visitor)), 114 | } 115 | } 116 | 117 | fn deserialize_i16(self, visitor: V) -> Result 118 | where 119 | V: de::Visitor<'de>, 120 | { 121 | match self.value { 122 | &watson_rs::Value::Int(n) => visitor.visit_i64(n), 123 | _ => Err(self.invalid_type(&visitor)), 124 | } 125 | } 126 | 127 | fn deserialize_i32(self, visitor: V) -> Result 128 | where 129 | V: de::Visitor<'de>, 130 | { 131 | match self.value { 132 | &watson_rs::Value::Int(n) => visitor.visit_i64(n), 133 | _ => Err(self.invalid_type(&visitor)), 134 | } 135 | } 136 | 137 | fn deserialize_i64(self, visitor: V) -> Result 138 | where 139 | V: de::Visitor<'de>, 140 | { 141 | match self.value { 142 | &watson_rs::Value::Int(n) => visitor.visit_i64(n), 143 | _ => Err(self.invalid_type(&visitor)), 144 | } 145 | } 146 | 147 | fn deserialize_u8(self, visitor: V) -> Result 148 | where 149 | V: de::Visitor<'de>, 150 | { 151 | match self.value { 152 | &watson_rs::Value::Uint(n) => visitor.visit_u64(n), 153 | _ => Err(self.invalid_type(&visitor)), 154 | } 155 | } 156 | 157 | fn deserialize_u16(self, visitor: V) -> Result 158 | where 159 | V: de::Visitor<'de>, 160 | { 161 | match self.value { 162 | &watson_rs::Value::Uint(n) => visitor.visit_u64(n), 163 | _ => Err(self.invalid_type(&visitor)), 164 | } 165 | } 166 | 167 | fn deserialize_u32(self, visitor: V) -> Result 168 | where 169 | V: de::Visitor<'de>, 170 | { 171 | match self.value { 172 | &watson_rs::Value::Uint(n) => visitor.visit_u64(n), 173 | _ => Err(self.invalid_type(&visitor)), 174 | } 175 | } 176 | 177 | fn deserialize_u64(self, visitor: V) -> Result 178 | where 179 | V: de::Visitor<'de>, 180 | { 181 | match self.value { 182 | &watson_rs::Value::Uint(n) => visitor.visit_u64(n), 183 | _ => Err(self.invalid_type(&visitor)), 184 | } 185 | } 186 | 187 | fn deserialize_f32(self, visitor: V) -> Result 188 | where 189 | V: de::Visitor<'de>, 190 | { 191 | match self.value { 192 | &watson_rs::Value::Float(f) => visitor.visit_f64(f), 193 | _ => Err(self.invalid_type(&visitor)), 194 | } 195 | } 196 | 197 | fn deserialize_f64(self, visitor: V) -> Result 198 | where 199 | V: de::Visitor<'de>, 200 | { 201 | match self.value { 202 | &watson_rs::Value::Float(f) => visitor.visit_f64(f), 203 | _ => Err(self.invalid_type(&visitor)), 204 | } 205 | } 206 | 207 | fn deserialize_char(self, visitor: V) -> Result 208 | where 209 | V: de::Visitor<'de>, 210 | { 211 | let mut chars = self.borrow_str(&visitor)?.chars(); 212 | match chars.next() { 213 | None => Err(invalid_value("empty byte sequence", &visitor)), 214 | Some(c) => { 215 | if chars.next().is_some() { 216 | Err(invalid_value( 217 | "string consisting of more than one characters", 218 | &visitor, 219 | )) 220 | } else { 221 | visitor.visit_char(c) 222 | } 223 | } 224 | } 225 | } 226 | 227 | fn deserialize_str(self, visitor: V) -> Result 228 | where 229 | V: de::Visitor<'de>, 230 | { 231 | let s = self.borrow_str(&visitor)?; 232 | visitor.visit_borrowed_str(s) 233 | } 234 | 235 | fn deserialize_string(self, visitor: V) -> Result 236 | where 237 | V: de::Visitor<'de>, 238 | { 239 | let s = self.borrow_str(&visitor)?; 240 | visitor.visit_string(s.to_owned()) 241 | } 242 | 243 | fn deserialize_bytes(self, visitor: V) -> Result 244 | where 245 | V: de::Visitor<'de>, 246 | { 247 | match self.value { 248 | watson_rs::Value::String(bytes) => visitor.visit_borrowed_bytes(bytes.as_slice()), 249 | _ => Err(self.invalid_type(&visitor)), 250 | } 251 | } 252 | 253 | fn deserialize_byte_buf(self, visitor: V) -> Result 254 | where 255 | V: de::Visitor<'de>, 256 | { 257 | match self.value { 258 | watson_rs::Value::String(bytes) => visitor.visit_byte_buf(bytes.clone()), 259 | _ => Err(self.invalid_type(&visitor)), 260 | } 261 | } 262 | 263 | fn deserialize_option(self, visitor: V) -> Result 264 | where 265 | V: de::Visitor<'de>, 266 | { 267 | match self.value { 268 | &watson_rs::Value::Nil => visitor.visit_none(), 269 | _ => visitor.visit_some(self), 270 | } 271 | } 272 | 273 | fn deserialize_unit(self, visitor: V) -> Result 274 | where 275 | V: de::Visitor<'de>, 276 | { 277 | match self.value { 278 | &watson_rs::Value::Nil => visitor.visit_unit(), 279 | _ => Err(self.invalid_type(&visitor)), 280 | } 281 | } 282 | 283 | fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result 284 | where 285 | V: de::Visitor<'de>, 286 | { 287 | self.deserialize_unit(visitor) 288 | } 289 | 290 | fn deserialize_newtype_struct(self, _name: &'static str, visitor: V) -> Result 291 | where 292 | V: de::Visitor<'de>, 293 | { 294 | visitor.visit_newtype_struct(self) 295 | } 296 | 297 | fn deserialize_seq(self, visitor: V) -> Result 298 | where 299 | V: de::Visitor<'de>, 300 | { 301 | match self.value { 302 | watson_rs::Value::Array(vec) => visitor.visit_seq(SeqAccess::new(vec)), 303 | _ => Err(self.invalid_type(&visitor)), 304 | } 305 | } 306 | 307 | fn deserialize_tuple(self, _len: usize, visitor: V) -> Result 308 | where 309 | V: de::Visitor<'de>, 310 | { 311 | self.deserialize_seq(visitor) 312 | } 313 | 314 | fn deserialize_tuple_struct( 315 | self, 316 | _name: &'static str, 317 | _len: usize, 318 | visitor: V, 319 | ) -> Result 320 | where 321 | V: de::Visitor<'de>, 322 | { 323 | self.deserialize_seq(visitor) 324 | } 325 | 326 | fn deserialize_map(self, visitor: V) -> Result 327 | where 328 | V: de::Visitor<'de>, 329 | { 330 | match self.value { 331 | watson_rs::Value::Object(map) => visitor.visit_map(MapAccess::new(map)), 332 | _ => Err(self.invalid_type(&visitor)), 333 | } 334 | } 335 | 336 | fn deserialize_struct( 337 | self, 338 | _name: &'static str, 339 | _fields: &'static [&'static str], 340 | visitor: V, 341 | ) -> Result 342 | where 343 | V: de::Visitor<'de>, 344 | { 345 | match *self.value { 346 | watson_rs::Value::Array(ref vec) => visitor.visit_seq(SeqAccess::new(vec)), 347 | watson_rs::Value::Object(ref map) => visitor.visit_map(MapAccess::new(map)), 348 | _ => Err(self.invalid_type(&visitor)), 349 | } 350 | } 351 | 352 | fn deserialize_enum( 353 | self, 354 | _name: &'static str, 355 | _variants: &'static [&'static str], 356 | visitor: V, 357 | ) -> Result 358 | where 359 | V: de::Visitor<'de>, 360 | { 361 | match *self.value { 362 | watson_rs::Value::String(ref name) => visitor.visit_enum(UnitVariantAccess::new(name)), 363 | watson_rs::Value::Object(ref map) => visitor.visit_enum(NonUnitVariantAccess::new(map)), 364 | _ => Err(self.invalid_type(&visitor)), 365 | } 366 | } 367 | 368 | fn deserialize_identifier(self, visitor: V) -> Result 369 | where 370 | V: de::Visitor<'de>, 371 | { 372 | self.deserialize_str(visitor) 373 | } 374 | 375 | fn deserialize_ignored_any(self, visitor: V) -> Result 376 | where 377 | V: de::Visitor<'de>, 378 | { 379 | visitor.visit_unit() 380 | } 381 | } 382 | 383 | struct SeqAccess<'de> { 384 | arr: &'de Vec, 385 | next: usize, 386 | } 387 | 388 | impl<'de> SeqAccess<'de> { 389 | fn new(arr: &'de Vec) -> Self { 390 | SeqAccess { arr, next: 0 } 391 | } 392 | } 393 | 394 | impl<'de> de::SeqAccess<'de> for SeqAccess<'de> { 395 | type Error = Error; 396 | 397 | fn next_element_seed(&mut self, seed: T) -> Result> 398 | where 399 | T: de::DeserializeSeed<'de>, 400 | { 401 | if self.arr.len() <= self.next { 402 | Ok(None) 403 | } else { 404 | let i = self.next; 405 | self.next += 1; 406 | let next_elem = seed.deserialize(&Deserializer::new(&self.arr[i]))?; 407 | Ok(Some(next_elem)) 408 | } 409 | } 410 | } 411 | 412 | struct MapAccess<'de> { 413 | it: std::collections::hash_map::Iter<'de, watson_rs::Bytes, watson_rs::Value>, 414 | next_value: Option<&'de watson_rs::Value>, 415 | } 416 | 417 | impl<'de> MapAccess<'de> { 418 | fn new(map: &'de watson_rs::Map) -> Self { 419 | MapAccess { 420 | it: map.iter(), 421 | next_value: None, 422 | } 423 | } 424 | } 425 | 426 | impl<'de> de::MapAccess<'de> for MapAccess<'de> { 427 | type Error = Error; 428 | 429 | fn next_key_seed(&mut self, seed: K) -> Result> 430 | where 431 | K: de::DeserializeSeed<'de>, 432 | { 433 | if self.next_value.is_some() { 434 | return Err(error(ErrorKind::UnexpectedMapValue)); 435 | } 436 | match self.it.next() { 437 | None => Ok(None), 438 | Some((k, v)) => { 439 | self.next_value = Some(v); 440 | let next_key = seed.deserialize(MapKeyDeserializer::new(k))?; 441 | Ok(Some(next_key)) 442 | } 443 | } 444 | } 445 | 446 | fn next_value_seed(&mut self, seed: V) -> Result 447 | where 448 | V: de::DeserializeSeed<'de>, 449 | { 450 | match self.next_value.take() { 451 | None => Err(error(ErrorKind::UnexpectedMapKey)), 452 | Some(v) => seed.deserialize(&Deserializer::new(v)), 453 | } 454 | } 455 | } 456 | 457 | struct MapKeyDeserializer<'de> { 458 | key: &'de watson_rs::Bytes, 459 | } 460 | 461 | impl<'de> MapKeyDeserializer<'de> { 462 | fn new(k: &'de watson_rs::Bytes) -> Self { 463 | MapKeyDeserializer { key: k } 464 | } 465 | } 466 | 467 | impl<'de> MapKeyDeserializer<'de> { 468 | fn invalid_type(&self, exp: &dyn de::Expected) -> Error { 469 | invalid_type(de::Unexpected::Bytes(self.key.as_slice()), exp) 470 | } 471 | 472 | fn to_array(&self, exp: &dyn de::Expected) -> Result<[u8; N]> { 473 | self.key 474 | .as_slice() 475 | .try_into() 476 | .map_err(|_| self.invalid_type(exp)) 477 | } 478 | } 479 | 480 | impl<'de> de::Deserializer<'de> for MapKeyDeserializer<'de> { 481 | type Error = Error; 482 | 483 | fn deserialize_any(self, visitor: V) -> Result 484 | where 485 | V: de::Visitor<'de>, 486 | { 487 | self.deserialize_bytes(visitor) 488 | } 489 | 490 | fn deserialize_bool(self, visitor: V) -> Result 491 | where 492 | V: de::Visitor<'de>, 493 | { 494 | match self.to_array::<1>(&visitor)? { 495 | [0] => visitor.visit_bool(false), 496 | [1] => visitor.visit_bool(true), 497 | _ => Err(self.invalid_type(&visitor)), 498 | } 499 | } 500 | 501 | fn deserialize_i8(self, visitor: V) -> Result 502 | where 503 | V: de::Visitor<'de>, 504 | { 505 | let n = i8::from_be_bytes(self.to_array(&visitor)?); 506 | visitor.visit_i8(n) 507 | } 508 | 509 | fn deserialize_i16(self, visitor: V) -> Result 510 | where 511 | V: de::Visitor<'de>, 512 | { 513 | let n = i16::from_be_bytes(self.to_array(&visitor)?); 514 | visitor.visit_i16(n) 515 | } 516 | 517 | fn deserialize_i32(self, visitor: V) -> Result 518 | where 519 | V: de::Visitor<'de>, 520 | { 521 | let n = i32::from_be_bytes(self.to_array(&visitor)?); 522 | visitor.visit_i32(n) 523 | } 524 | 525 | fn deserialize_i64(self, visitor: V) -> Result 526 | where 527 | V: de::Visitor<'de>, 528 | { 529 | let n = i64::from_be_bytes(self.to_array(&visitor)?); 530 | visitor.visit_i64(n) 531 | } 532 | 533 | fn deserialize_u8(self, visitor: V) -> Result 534 | where 535 | V: de::Visitor<'de>, 536 | { 537 | let n = u8::from_be_bytes(self.to_array(&visitor)?); 538 | visitor.visit_u8(n) 539 | } 540 | 541 | fn deserialize_u16(self, visitor: V) -> Result 542 | where 543 | V: de::Visitor<'de>, 544 | { 545 | let n = u16::from_be_bytes(self.to_array(&visitor)?); 546 | visitor.visit_u16(n) 547 | } 548 | 549 | fn deserialize_u32(self, visitor: V) -> Result 550 | where 551 | V: de::Visitor<'de>, 552 | { 553 | let n = u32::from_be_bytes(self.to_array(&visitor)?); 554 | visitor.visit_u32(n) 555 | } 556 | 557 | fn deserialize_u64(self, visitor: V) -> Result 558 | where 559 | V: de::Visitor<'de>, 560 | { 561 | let n = u64::from_be_bytes(self.to_array(&visitor)?); 562 | visitor.visit_u64(n) 563 | } 564 | 565 | fn deserialize_f32(self, visitor: V) -> Result 566 | where 567 | V: de::Visitor<'de>, 568 | { 569 | Err(self.invalid_type(&visitor)) 570 | } 571 | 572 | fn deserialize_f64(self, visitor: V) -> Result 573 | where 574 | V: de::Visitor<'de>, 575 | { 576 | Err(self.invalid_type(&visitor)) 577 | } 578 | 579 | fn deserialize_char(self, visitor: V) -> Result 580 | where 581 | V: de::Visitor<'de>, 582 | { 583 | let s = try_borrow_str(self.key, &visitor)?; 584 | let mut chars = s.chars(); 585 | let c = chars 586 | .next() 587 | .map(Ok) 588 | .unwrap_or_else(|| Err(self.invalid_type(&visitor)))?; 589 | match chars.next() { 590 | None => visitor.visit_char(c), 591 | Some(_) => Err(self.invalid_type(&visitor)), 592 | } 593 | } 594 | 595 | fn deserialize_str(self, visitor: V) -> Result 596 | where 597 | V: de::Visitor<'de>, 598 | { 599 | let s = try_borrow_str(self.key, &visitor)?; 600 | visitor.visit_borrowed_str(s) 601 | } 602 | 603 | fn deserialize_string(self, visitor: V) -> Result 604 | where 605 | V: de::Visitor<'de>, 606 | { 607 | let s = try_borrow_str(self.key, &visitor)?; 608 | visitor.visit_string(s.to_owned()) 609 | } 610 | 611 | fn deserialize_bytes(self, visitor: V) -> Result 612 | where 613 | V: de::Visitor<'de>, 614 | { 615 | visitor.visit_borrowed_bytes(self.key.as_slice()) 616 | } 617 | 618 | fn deserialize_byte_buf(self, visitor: V) -> Result 619 | where 620 | V: de::Visitor<'de>, 621 | { 622 | visitor.visit_byte_buf(self.key.clone()) 623 | } 624 | 625 | fn deserialize_option(self, visitor: V) -> Result 626 | where 627 | V: de::Visitor<'de>, 628 | { 629 | Err(self.invalid_type(&visitor)) 630 | } 631 | 632 | fn deserialize_unit(self, visitor: V) -> Result 633 | where 634 | V: de::Visitor<'de>, 635 | { 636 | Err(self.invalid_type(&visitor)) 637 | } 638 | 639 | fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result 640 | where 641 | V: de::Visitor<'de>, 642 | { 643 | Err(self.invalid_type(&visitor)) 644 | } 645 | 646 | fn deserialize_newtype_struct(self, _name: &'static str, visitor: V) -> Result 647 | where 648 | V: de::Visitor<'de>, 649 | { 650 | visitor.visit_newtype_struct(self) 651 | } 652 | 653 | fn deserialize_seq(self, visitor: V) -> Result 654 | where 655 | V: de::Visitor<'de>, 656 | { 657 | visitor.visit_seq(MapKeySeqAccess::new(self.key)) 658 | } 659 | 660 | fn deserialize_tuple(self, _len: usize, visitor: V) -> Result 661 | where 662 | V: de::Visitor<'de>, 663 | { 664 | Err(self.invalid_type(&visitor)) 665 | } 666 | 667 | fn deserialize_tuple_struct( 668 | self, 669 | _name: &'static str, 670 | _len: usize, 671 | visitor: V, 672 | ) -> Result 673 | where 674 | V: de::Visitor<'de>, 675 | { 676 | Err(self.invalid_type(&visitor)) 677 | } 678 | 679 | fn deserialize_map(self, visitor: V) -> Result 680 | where 681 | V: de::Visitor<'de>, 682 | { 683 | Err(self.invalid_type(&visitor)) 684 | } 685 | 686 | fn deserialize_struct( 687 | self, 688 | _name: &'static str, 689 | _fields: &'static [&'static str], 690 | visitor: V, 691 | ) -> Result 692 | where 693 | V: de::Visitor<'de>, 694 | { 695 | Err(self.invalid_type(&visitor)) 696 | } 697 | 698 | fn deserialize_enum( 699 | self, 700 | _name: &'static str, 701 | _variants: &'static [&'static str], 702 | visitor: V, 703 | ) -> Result 704 | where 705 | V: de::Visitor<'de>, 706 | { 707 | visitor.visit_enum(UnitVariantAccess::new(self.key)) 708 | } 709 | 710 | fn deserialize_identifier(self, visitor: V) -> Result 711 | where 712 | V: de::Visitor<'de>, 713 | { 714 | self.deserialize_str(visitor) 715 | } 716 | 717 | fn deserialize_ignored_any(self, visitor: V) -> Result 718 | where 719 | V: de::Visitor<'de>, 720 | { 721 | visitor.visit_unit() 722 | } 723 | } 724 | 725 | struct MapKeySeqAccess<'de> { 726 | key: &'de watson_rs::Bytes, 727 | next: usize, 728 | } 729 | 730 | impl<'de> MapKeySeqAccess<'de> { 731 | fn new(key: &'de watson_rs::Bytes) -> Self { 732 | MapKeySeqAccess { key, next: 0 } 733 | } 734 | } 735 | 736 | impl<'de> de::SeqAccess<'de> for MapKeySeqAccess<'de> { 737 | type Error = Error; 738 | 739 | fn next_element_seed(&mut self, seed: T) -> Result> 740 | where 741 | T: de::DeserializeSeed<'de>, 742 | { 743 | if self.key.len() <= self.next { 744 | Ok(None) 745 | } else { 746 | let i = self.next; 747 | self.next += 1; 748 | let v = seed.deserialize(MapKeyByteDeserializer::new(self.key[i]))?; 749 | Ok(Some(v)) 750 | } 751 | } 752 | } 753 | 754 | struct MapKeyByteDeserializer { 755 | b: u8, 756 | } 757 | 758 | impl MapKeyByteDeserializer { 759 | fn new(b: u8) -> Self { 760 | MapKeyByteDeserializer { b } 761 | } 762 | 763 | fn invalid_type(&self, exp: &dyn de::Expected) -> Error { 764 | invalid_type(de::Unexpected::Unsigned(self.b as u64), exp) 765 | } 766 | } 767 | 768 | impl<'de> de::Deserializer<'de> for MapKeyByteDeserializer { 769 | type Error = Error; 770 | 771 | fn deserialize_any(self, visitor: V) -> Result 772 | where 773 | V: de::Visitor<'de>, 774 | { 775 | Err(self.invalid_type(&visitor)) 776 | } 777 | 778 | fn deserialize_bool(self, visitor: V) -> Result 779 | where 780 | V: de::Visitor<'de>, 781 | { 782 | Err(self.invalid_type(&visitor)) 783 | } 784 | 785 | fn deserialize_i8(self, visitor: V) -> Result 786 | where 787 | V: de::Visitor<'de>, 788 | { 789 | Err(self.invalid_type(&visitor)) 790 | } 791 | 792 | fn deserialize_i16(self, visitor: V) -> Result 793 | where 794 | V: de::Visitor<'de>, 795 | { 796 | Err(self.invalid_type(&visitor)) 797 | } 798 | 799 | fn deserialize_i32(self, visitor: V) -> Result 800 | where 801 | V: de::Visitor<'de>, 802 | { 803 | Err(self.invalid_type(&visitor)) 804 | } 805 | 806 | fn deserialize_i64(self, visitor: V) -> Result 807 | where 808 | V: de::Visitor<'de>, 809 | { 810 | Err(self.invalid_type(&visitor)) 811 | } 812 | 813 | fn deserialize_u8(self, visitor: V) -> Result 814 | where 815 | V: de::Visitor<'de>, 816 | { 817 | visitor.visit_u8(self.b) 818 | } 819 | 820 | fn deserialize_u16(self, visitor: V) -> Result 821 | where 822 | V: de::Visitor<'de>, 823 | { 824 | Err(self.invalid_type(&visitor)) 825 | } 826 | 827 | fn deserialize_u32(self, visitor: V) -> Result 828 | where 829 | V: de::Visitor<'de>, 830 | { 831 | Err(self.invalid_type(&visitor)) 832 | } 833 | 834 | fn deserialize_u64(self, visitor: V) -> Result 835 | where 836 | V: de::Visitor<'de>, 837 | { 838 | Err(self.invalid_type(&visitor)) 839 | } 840 | 841 | fn deserialize_f32(self, visitor: V) -> Result 842 | where 843 | V: de::Visitor<'de>, 844 | { 845 | Err(self.invalid_type(&visitor)) 846 | } 847 | 848 | fn deserialize_f64(self, visitor: V) -> Result 849 | where 850 | V: de::Visitor<'de>, 851 | { 852 | Err(self.invalid_type(&visitor)) 853 | } 854 | 855 | fn deserialize_char(self, visitor: V) -> Result 856 | where 857 | V: de::Visitor<'de>, 858 | { 859 | Err(self.invalid_type(&visitor)) 860 | } 861 | 862 | fn deserialize_str(self, visitor: V) -> Result 863 | where 864 | V: de::Visitor<'de>, 865 | { 866 | Err(self.invalid_type(&visitor)) 867 | } 868 | 869 | fn deserialize_string(self, visitor: V) -> Result 870 | where 871 | V: de::Visitor<'de>, 872 | { 873 | Err(self.invalid_type(&visitor)) 874 | } 875 | 876 | fn deserialize_bytes(self, visitor: V) -> Result 877 | where 878 | V: de::Visitor<'de>, 879 | { 880 | Err(self.invalid_type(&visitor)) 881 | } 882 | 883 | fn deserialize_byte_buf(self, visitor: V) -> Result 884 | where 885 | V: de::Visitor<'de>, 886 | { 887 | Err(self.invalid_type(&visitor)) 888 | } 889 | 890 | fn deserialize_option(self, visitor: V) -> Result 891 | where 892 | V: de::Visitor<'de>, 893 | { 894 | Err(self.invalid_type(&visitor)) 895 | } 896 | 897 | fn deserialize_unit(self, visitor: V) -> Result 898 | where 899 | V: de::Visitor<'de>, 900 | { 901 | Err(self.invalid_type(&visitor)) 902 | } 903 | 904 | fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result 905 | where 906 | V: de::Visitor<'de>, 907 | { 908 | Err(self.invalid_type(&visitor)) 909 | } 910 | 911 | fn deserialize_newtype_struct(self, _name: &'static str, visitor: V) -> Result 912 | where 913 | V: de::Visitor<'de>, 914 | { 915 | Err(self.invalid_type(&visitor)) 916 | } 917 | 918 | fn deserialize_seq(self, visitor: V) -> Result 919 | where 920 | V: de::Visitor<'de>, 921 | { 922 | Err(self.invalid_type(&visitor)) 923 | } 924 | 925 | fn deserialize_tuple(self, _len: usize, visitor: V) -> Result 926 | where 927 | V: de::Visitor<'de>, 928 | { 929 | Err(self.invalid_type(&visitor)) 930 | } 931 | 932 | fn deserialize_tuple_struct( 933 | self, 934 | _name: &'static str, 935 | _len: usize, 936 | visitor: V, 937 | ) -> Result 938 | where 939 | V: de::Visitor<'de>, 940 | { 941 | Err(self.invalid_type(&visitor)) 942 | } 943 | 944 | fn deserialize_map(self, visitor: V) -> Result 945 | where 946 | V: de::Visitor<'de>, 947 | { 948 | Err(self.invalid_type(&visitor)) 949 | } 950 | 951 | fn deserialize_struct( 952 | self, 953 | _name: &'static str, 954 | _fields: &'static [&'static str], 955 | visitor: V, 956 | ) -> Result 957 | where 958 | V: de::Visitor<'de>, 959 | { 960 | Err(self.invalid_type(&visitor)) 961 | } 962 | 963 | fn deserialize_enum( 964 | self, 965 | _name: &'static str, 966 | _variants: &'static [&'static str], 967 | visitor: V, 968 | ) -> Result 969 | where 970 | V: de::Visitor<'de>, 971 | { 972 | Err(self.invalid_type(&visitor)) 973 | } 974 | 975 | fn deserialize_identifier(self, visitor: V) -> Result 976 | where 977 | V: de::Visitor<'de>, 978 | { 979 | Err(self.invalid_type(&visitor)) 980 | } 981 | 982 | fn deserialize_ignored_any(self, visitor: V) -> Result 983 | where 984 | V: de::Visitor<'de>, 985 | { 986 | Err(self.invalid_type(&visitor)) 987 | } 988 | } 989 | 990 | struct EnumCtorDeserializer<'de> { 991 | name: &'de watson_rs::Bytes, 992 | } 993 | 994 | impl<'de> EnumCtorDeserializer<'de> { 995 | fn new(name: &'de watson_rs::Bytes) -> Self { 996 | EnumCtorDeserializer { name } 997 | } 998 | 999 | fn invalid_type(&self, exp: &dyn de::Expected) -> Error { 1000 | invalid_type(de::Unexpected::Bytes(self.name.as_slice()), exp) 1001 | } 1002 | } 1003 | 1004 | impl<'de> de::Deserializer<'de> for EnumCtorDeserializer<'de> { 1005 | type Error = Error; 1006 | 1007 | fn deserialize_any(self, visitor: V) -> Result 1008 | where 1009 | V: de::Visitor<'de>, 1010 | { 1011 | Err(self.invalid_type(&visitor)) 1012 | } 1013 | 1014 | fn deserialize_bool(self, visitor: V) -> Result 1015 | where 1016 | V: de::Visitor<'de>, 1017 | { 1018 | Err(self.invalid_type(&visitor)) 1019 | } 1020 | 1021 | fn deserialize_i8(self, visitor: V) -> Result 1022 | where 1023 | V: de::Visitor<'de>, 1024 | { 1025 | Err(self.invalid_type(&visitor)) 1026 | } 1027 | 1028 | fn deserialize_i16(self, visitor: V) -> Result 1029 | where 1030 | V: de::Visitor<'de>, 1031 | { 1032 | Err(self.invalid_type(&visitor)) 1033 | } 1034 | 1035 | fn deserialize_i32(self, visitor: V) -> Result 1036 | where 1037 | V: de::Visitor<'de>, 1038 | { 1039 | Err(self.invalid_type(&visitor)) 1040 | } 1041 | 1042 | fn deserialize_i64(self, visitor: V) -> Result 1043 | where 1044 | V: de::Visitor<'de>, 1045 | { 1046 | Err(self.invalid_type(&visitor)) 1047 | } 1048 | 1049 | fn deserialize_u8(self, visitor: V) -> Result 1050 | where 1051 | V: de::Visitor<'de>, 1052 | { 1053 | Err(self.invalid_type(&visitor)) 1054 | } 1055 | 1056 | fn deserialize_u16(self, visitor: V) -> Result 1057 | where 1058 | V: de::Visitor<'de>, 1059 | { 1060 | Err(self.invalid_type(&visitor)) 1061 | } 1062 | 1063 | fn deserialize_u32(self, visitor: V) -> Result 1064 | where 1065 | V: de::Visitor<'de>, 1066 | { 1067 | Err(self.invalid_type(&visitor)) 1068 | } 1069 | 1070 | fn deserialize_u64(self, visitor: V) -> Result 1071 | where 1072 | V: de::Visitor<'de>, 1073 | { 1074 | Err(self.invalid_type(&visitor)) 1075 | } 1076 | 1077 | fn deserialize_f32(self, visitor: V) -> Result 1078 | where 1079 | V: de::Visitor<'de>, 1080 | { 1081 | Err(self.invalid_type(&visitor)) 1082 | } 1083 | 1084 | fn deserialize_f64(self, visitor: V) -> Result 1085 | where 1086 | V: de::Visitor<'de>, 1087 | { 1088 | Err(self.invalid_type(&visitor)) 1089 | } 1090 | 1091 | fn deserialize_char(self, visitor: V) -> Result 1092 | where 1093 | V: de::Visitor<'de>, 1094 | { 1095 | Err(self.invalid_type(&visitor)) 1096 | } 1097 | 1098 | fn deserialize_str(self, visitor: V) -> Result 1099 | where 1100 | V: de::Visitor<'de>, 1101 | { 1102 | Err(self.invalid_type(&visitor)) 1103 | } 1104 | 1105 | fn deserialize_string(self, visitor: V) -> Result 1106 | where 1107 | V: de::Visitor<'de>, 1108 | { 1109 | Err(self.invalid_type(&visitor)) 1110 | } 1111 | 1112 | fn deserialize_bytes(self, visitor: V) -> Result 1113 | where 1114 | V: de::Visitor<'de>, 1115 | { 1116 | Err(self.invalid_type(&visitor)) 1117 | } 1118 | 1119 | fn deserialize_byte_buf(self, visitor: V) -> Result 1120 | where 1121 | V: de::Visitor<'de>, 1122 | { 1123 | Err(self.invalid_type(&visitor)) 1124 | } 1125 | 1126 | fn deserialize_option(self, visitor: V) -> Result 1127 | where 1128 | V: de::Visitor<'de>, 1129 | { 1130 | Err(self.invalid_type(&visitor)) 1131 | } 1132 | 1133 | fn deserialize_unit(self, visitor: V) -> Result 1134 | where 1135 | V: de::Visitor<'de>, 1136 | { 1137 | Err(self.invalid_type(&visitor)) 1138 | } 1139 | 1140 | fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result 1141 | where 1142 | V: de::Visitor<'de>, 1143 | { 1144 | Err(self.invalid_type(&visitor)) 1145 | } 1146 | 1147 | fn deserialize_newtype_struct(self, _name: &'static str, visitor: V) -> Result 1148 | where 1149 | V: de::Visitor<'de>, 1150 | { 1151 | Err(self.invalid_type(&visitor)) 1152 | } 1153 | 1154 | fn deserialize_seq(self, visitor: V) -> Result 1155 | where 1156 | V: de::Visitor<'de>, 1157 | { 1158 | Err(self.invalid_type(&visitor)) 1159 | } 1160 | 1161 | fn deserialize_tuple(self, _len: usize, visitor: V) -> Result 1162 | where 1163 | V: de::Visitor<'de>, 1164 | { 1165 | Err(self.invalid_type(&visitor)) 1166 | } 1167 | 1168 | fn deserialize_tuple_struct( 1169 | self, 1170 | _name: &'static str, 1171 | _len: usize, 1172 | visitor: V, 1173 | ) -> Result 1174 | where 1175 | V: de::Visitor<'de>, 1176 | { 1177 | Err(self.invalid_type(&visitor)) 1178 | } 1179 | 1180 | fn deserialize_map(self, visitor: V) -> Result 1181 | where 1182 | V: de::Visitor<'de>, 1183 | { 1184 | Err(self.invalid_type(&visitor)) 1185 | } 1186 | 1187 | fn deserialize_struct( 1188 | self, 1189 | _name: &'static str, 1190 | _fields: &'static [&'static str], 1191 | visitor: V, 1192 | ) -> Result 1193 | where 1194 | V: de::Visitor<'de>, 1195 | { 1196 | Err(self.invalid_type(&visitor)) 1197 | } 1198 | 1199 | fn deserialize_enum( 1200 | self, 1201 | _name: &'static str, 1202 | _variants: &'static [&'static str], 1203 | visitor: V, 1204 | ) -> Result 1205 | where 1206 | V: de::Visitor<'de>, 1207 | { 1208 | Err(self.invalid_type(&visitor)) 1209 | } 1210 | 1211 | fn deserialize_identifier(self, visitor: V) -> Result 1212 | where 1213 | V: de::Visitor<'de>, 1214 | { 1215 | let s = try_borrow_str(self.name, &visitor)?; 1216 | visitor.visit_borrowed_str(s) 1217 | } 1218 | 1219 | fn deserialize_ignored_any(self, visitor: V) -> Result 1220 | where 1221 | V: de::Visitor<'de>, 1222 | { 1223 | Err(self.invalid_type(&visitor)) 1224 | } 1225 | } 1226 | 1227 | struct UnitVariantAccess<'de> { 1228 | name: &'de watson_rs::Bytes, 1229 | } 1230 | 1231 | impl<'de> UnitVariantAccess<'de> { 1232 | fn new(name: &'de watson_rs::Bytes) -> Self { 1233 | UnitVariantAccess { name } 1234 | } 1235 | } 1236 | 1237 | impl<'de> de::EnumAccess<'de> for UnitVariantAccess<'de> { 1238 | type Error = Error; 1239 | type Variant = Self; 1240 | 1241 | fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant)> 1242 | where 1243 | V: de::DeserializeSeed<'de>, 1244 | { 1245 | let v = seed.deserialize(EnumCtorDeserializer::new(self.name))?; 1246 | Ok((v, self)) 1247 | } 1248 | } 1249 | 1250 | impl<'de> de::VariantAccess<'de> for UnitVariantAccess<'de> { 1251 | type Error = Error; 1252 | 1253 | fn unit_variant(self) -> Result<()> { 1254 | Ok(()) 1255 | } 1256 | 1257 | fn newtype_variant_seed(self, _seed: T) -> Result 1258 | where 1259 | T: de::DeserializeSeed<'de>, 1260 | { 1261 | Err(de::Error::invalid_type( 1262 | de::Unexpected::UnitVariant, 1263 | &"newtype variant", 1264 | )) 1265 | } 1266 | 1267 | fn tuple_variant(self, _len: usize, _visitor: V) -> Result 1268 | where 1269 | V: de::Visitor<'de>, 1270 | { 1271 | Err(de::Error::invalid_type( 1272 | de::Unexpected::UnitVariant, 1273 | &"tuple variant", 1274 | )) 1275 | } 1276 | 1277 | fn struct_variant(self, _fields: &'static [&'static str], _visitor: V) -> Result 1278 | where 1279 | V: de::Visitor<'de>, 1280 | { 1281 | Err(de::Error::invalid_type( 1282 | de::Unexpected::UnitVariant, 1283 | &"struct variant", 1284 | )) 1285 | } 1286 | } 1287 | 1288 | struct NonUnitVariantAccess<'de> { 1289 | map: &'de watson_rs::Map, 1290 | } 1291 | 1292 | impl<'de> NonUnitVariantAccess<'de> { 1293 | fn new(map: &'de watson_rs::Map) -> Self { 1294 | NonUnitVariantAccess { map } 1295 | } 1296 | } 1297 | 1298 | impl<'de> de::EnumAccess<'de> for NonUnitVariantAccess<'de> { 1299 | type Error = Error; 1300 | type Variant = VariantFieldAccess<'de>; 1301 | 1302 | fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant)> 1303 | where 1304 | V: de::DeserializeSeed<'de>, 1305 | { 1306 | if self.map.len() != 1 { 1307 | Err(error(ErrorKind::UnexpectedMap)) 1308 | } else { 1309 | let (k, v) = self.map.iter().next().unwrap(); 1310 | let ctor = seed.deserialize(EnumCtorDeserializer::new(k))?; 1311 | Ok((ctor, VariantFieldAccess::new(v))) 1312 | } 1313 | } 1314 | } 1315 | 1316 | struct VariantFieldAccess<'de> { 1317 | value: &'de watson_rs::Value, 1318 | } 1319 | 1320 | impl<'de> VariantFieldAccess<'de> { 1321 | fn new(v: &'de watson_rs::Value) -> Self { 1322 | VariantFieldAccess { value: v } 1323 | } 1324 | } 1325 | 1326 | impl<'de> de::VariantAccess<'de> for VariantFieldAccess<'de> { 1327 | type Error = Error; 1328 | 1329 | fn unit_variant(self) -> Result<()> { 1330 | de::Deserialize::deserialize(&Deserializer::new(self.value)) 1331 | } 1332 | 1333 | fn newtype_variant_seed(self, seed: T) -> Result 1334 | where 1335 | T: de::DeserializeSeed<'de>, 1336 | { 1337 | seed.deserialize(&Deserializer::new(self.value)) 1338 | } 1339 | 1340 | fn tuple_variant(self, _len: usize, visitor: V) -> Result 1341 | where 1342 | V: de::Visitor<'de>, 1343 | { 1344 | de::Deserializer::deserialize_seq(&Deserializer::new(self.value), visitor) 1345 | } 1346 | 1347 | fn struct_variant(self, fields: &'static [&'static str], visitor: V) -> Result 1348 | where 1349 | V: de::Visitor<'de>, 1350 | { 1351 | de::Deserializer::deserialize_struct(&Deserializer::new(self.value), "", fields, visitor) 1352 | } 1353 | } 1354 | 1355 | /* 1356 | * Helper functions 1357 | */ 1358 | 1359 | fn try_borrow_str<'de, V>(bytes: &'de watson_rs::Bytes, visitor: &V) -> Result<&'de str> 1360 | where 1361 | V: de::Visitor<'de>, 1362 | { 1363 | std::str::from_utf8(bytes.as_slice()).map_err(|_| invalid_utf8(visitor)) 1364 | } 1365 | 1366 | fn invalid_type(ty: de::Unexpected, exp: &dyn de::Expected) -> Error { 1367 | de::Error::invalid_type(ty, exp) 1368 | } 1369 | 1370 | fn invalid_utf8(exp: &dyn de::Expected) -> Error { 1371 | invalid_value("invalid UTF-8 string", exp) 1372 | } 1373 | 1374 | fn invalid_value(desc: &'static str, exp: &dyn de::Expected) -> Error { 1375 | de::Error::invalid_value(de::Unexpected::Other(desc), exp) 1376 | } 1377 | 1378 | fn error(k: ErrorKind) -> Error { 1379 | Error { 1380 | kind: k, 1381 | location: None, 1382 | source: None, 1383 | } 1384 | } 1385 | 1386 | #[cfg(test)] 1387 | mod test { 1388 | use std::fmt; 1389 | 1390 | use serde::Deserialize; 1391 | use watson_rs::Value::*; 1392 | use watson_rs::{array, object}; 1393 | 1394 | use super::*; 1395 | use crate::value::Value; 1396 | 1397 | #[test] 1398 | fn test_from_str() -> Result<()> { 1399 | assert_eq!(Int(4), from_str("BBubba")?); 1400 | Ok(()) 1401 | } 1402 | 1403 | #[test] 1404 | fn deserialize_any() { 1405 | assert_decodes(Value::new(Int(123)), &Int(123)); 1406 | assert_decodes(Value::new(Uint(456)), &Uint(456)); 1407 | assert_decodes(Value::new(Float(1.23)), &Float(1.23)); 1408 | assert_decodes(Value::new(Bool(true)), &Bool(true)); 1409 | assert_decodes( 1410 | Value::new(String(b"foo".to_vec())), 1411 | &String(b"foo".to_vec()), 1412 | ); 1413 | assert_decodes( 1414 | Value::new(array![Int(123), Uint(456)]), 1415 | &array![Int(123), Uint(456)], 1416 | ); 1417 | assert_decodes( 1418 | Value::new(object![A: Int(1), B: Bool(false)]), 1419 | &object![A: Int(1), B: Bool(false)], 1420 | ); 1421 | } 1422 | 1423 | #[test] 1424 | fn deserialize_bool() { 1425 | assert_decodes(true, &Bool(true)); 1426 | assert_decodes(false, &Bool(false)); 1427 | } 1428 | 1429 | #[test] 1430 | fn deserialize_i8() { 1431 | assert_decodes(0_i8, &Int(0)); 1432 | assert_decodes(127_i8, &Int(127)); 1433 | assert_decodes(-128_i8, &Int(-128)); 1434 | } 1435 | 1436 | #[test] 1437 | fn deserialize_i16() { 1438 | assert_decodes(0_i16, &Int(0)); 1439 | assert_decodes(1_i16, &Int(1)); 1440 | assert_decodes(32767_i16, &Int(32767)); 1441 | assert_decodes(-1_i16, &Int(-1)); 1442 | assert_decodes(-32768_i16, &Int(-32768)); 1443 | } 1444 | 1445 | #[test] 1446 | fn deserialize_i32() { 1447 | assert_decodes(0_i32, &Int(0)); 1448 | assert_decodes(1_i32, &Int(1)); 1449 | assert_decodes(2147483647_i32, &Int(2147483647)); 1450 | assert_decodes(-1_i32, &Int(-1)); 1451 | assert_decodes(-2147483647_i32, &Int(-2147483647)); 1452 | } 1453 | 1454 | #[test] 1455 | fn deserialize_i64() { 1456 | assert_decodes(0_i64, &Int(0)); 1457 | assert_decodes(1_i64, &Int(1)); 1458 | assert_decodes(9223372036854775807_i64, &Int(9223372036854775807_i64)); 1459 | assert_decodes(-1_i64, &Int(-1)); 1460 | assert_decodes(-9223372036854775808_i64, &Int(-9223372036854775808_i64)); 1461 | } 1462 | 1463 | #[test] 1464 | fn deserialize_u8() { 1465 | assert_decodes(0_u8, &Uint(0)); 1466 | assert_decodes(1_u8, &Uint(1)); 1467 | assert_decodes(255_u8, &Uint(255)); 1468 | } 1469 | 1470 | #[test] 1471 | fn deserialize_u16() { 1472 | assert_decodes(0_u16, &Uint(0)); 1473 | assert_decodes(1_u16, &Uint(1)); 1474 | assert_decodes(65535_u16, &Uint(65535)); 1475 | } 1476 | 1477 | #[test] 1478 | fn deserialize_u32() { 1479 | assert_decodes(0_u32, &Uint(0)); 1480 | assert_decodes(1_u32, &Uint(1)); 1481 | assert_decodes(4294967295_u32, &Uint(4294967295)); 1482 | } 1483 | 1484 | #[test] 1485 | fn deserialize_u64() { 1486 | assert_decodes(0_u64, &Uint(0)); 1487 | assert_decodes(1_u64, &Uint(1)); 1488 | assert_decodes(18446744073709551615_u64, &Uint(18446744073709551615)); 1489 | } 1490 | 1491 | #[test] 1492 | fn deserialize_f32() { 1493 | assert_decoded_value_satisfies(|f: f32| f.is_nan(), &Float(f64::NAN)); 1494 | assert_decoded_value_satisfies( 1495 | |f: f32| f.is_sign_positive() && f.is_infinite(), 1496 | &Float(f64::INFINITY), 1497 | ); 1498 | assert_decoded_value_satisfies( 1499 | |f: f32| f.is_sign_negative() && f.is_infinite(), 1500 | &Float(f64::NEG_INFINITY), 1501 | ); 1502 | assert_decodes(1.25_f32, &Float(1.25)); 1503 | assert_decodes(-1.25_f32, &Float(-1.25)); 1504 | } 1505 | 1506 | #[test] 1507 | fn deserialize_f64() { 1508 | assert_decoded_value_satisfies(|f: f64| f.is_nan(), &Float(f64::NAN)); 1509 | assert_decoded_value_satisfies( 1510 | |f: f64| f.is_sign_positive() && f.is_infinite(), 1511 | &Float(f64::INFINITY), 1512 | ); 1513 | assert_decoded_value_satisfies( 1514 | |f: f64| f.is_sign_negative() && f.is_infinite(), 1515 | &Float(f64::NEG_INFINITY), 1516 | ); 1517 | assert_decodes(1.25_f64, &Float(1.25)); 1518 | assert_decodes(-1.25_f64, &Float(-1.25)); 1519 | } 1520 | 1521 | #[test] 1522 | fn deserialize_char() { 1523 | assert_decodes('a', &String(b"a".to_vec())); 1524 | assert_decodes('あ', &String("あ".as_bytes().to_owned())); 1525 | } 1526 | 1527 | #[test] 1528 | fn deserialize_str() { 1529 | let v = String(b"foobar".to_vec()); 1530 | let s: &str = deserialize(&v); 1531 | assert_eq!(s, "foobar"); 1532 | } 1533 | 1534 | #[test] 1535 | fn deserialize_string() { 1536 | assert_decodes("".to_string(), &String(b"".to_vec())); 1537 | assert_decodes("abc".to_string(), &String(b"abc".to_vec())); 1538 | } 1539 | 1540 | #[test] 1541 | fn deserialize_bytes() { 1542 | let v = String(b"hello".to_vec()); 1543 | let b: &[u8] = deserialize(&v); 1544 | assert_eq!(b, &b"hello"[..]) 1545 | } 1546 | 1547 | #[test] 1548 | fn deserialize_byte_buf() { 1549 | assert_decodes(Buf(b"".to_vec()), &String(b"".to_vec())); 1550 | assert_decodes(Buf(b"goodbye".to_vec()), &String(b"goodbye".to_vec())); 1551 | } 1552 | 1553 | #[test] 1554 | fn deserialize_option() { 1555 | assert_decodes(Some(123), &Int(123)); 1556 | assert_decodes(Option::::None, &Nil); 1557 | } 1558 | 1559 | #[test] 1560 | fn deserialize_unit() { 1561 | assert_decodes((), &Nil); 1562 | } 1563 | 1564 | #[test] 1565 | fn deserialize_unit_struct() { 1566 | #[derive(Eq, PartialEq, Deserialize, Debug)] 1567 | struct S; 1568 | 1569 | assert_decodes(S, &Nil); 1570 | } 1571 | 1572 | #[test] 1573 | fn deserialize_newtype_struct() { 1574 | #[derive(Eq, PartialEq, Deserialize, Debug)] 1575 | struct S(i64); 1576 | 1577 | assert_decodes(S(123), &Int(123)); 1578 | } 1579 | 1580 | #[test] 1581 | fn deserialize_seq() { 1582 | assert_decodes(Vec::::new(), &array![]); 1583 | assert_decodes(vec![1_i32, 2_i32, 3_i32], &array![Int(1), Int(2), Int(3)]); 1584 | } 1585 | 1586 | #[test] 1587 | fn deserialize_tuple() { 1588 | assert_decodes( 1589 | (1_u32, true, "foo"), 1590 | &array![Uint(1), Bool(true), String(b"foo".to_vec())], 1591 | ); 1592 | } 1593 | 1594 | #[test] 1595 | fn deserialize_tuple_struct() { 1596 | #[derive(Eq, PartialEq, Deserialize, Debug)] 1597 | struct S(i32, (), u16); 1598 | 1599 | assert_decodes(S(123, (), 45), &array![Int(123), Nil, Uint(45)]); 1600 | } 1601 | #[test] 1602 | fn deserialize_map_key_any() { 1603 | use crate::value::Value; 1604 | use watson_rs::ToBytes; 1605 | let v = Value::deserialize(MapKeyDeserializer::new(&b"foo".to_bytes())) 1606 | .expect("deserialization error"); 1607 | assert_eq!(v, Value::new(String(b"foo".to_vec()))) 1608 | } 1609 | 1610 | #[test] 1611 | fn deserialize_map_key_bool() { 1612 | type HM = std::collections::HashMap; 1613 | 1614 | assert_decodes(HM::::new(), &object![]); 1615 | assert_decodes( 1616 | [(true, 123), (false, 456)].into_iter().collect::>(), 1617 | &object![ 1618 | [b"\x01"]: Int(123), 1619 | [b"\x00"]: Int(456), 1620 | ], 1621 | ); 1622 | } 1623 | 1624 | #[test] 1625 | fn deserialize_map_key_i8() { 1626 | type HM = std::collections::HashMap; 1627 | 1628 | assert_decodes(HM::::new(), &object![]); 1629 | assert_decodes( 1630 | [(0, 1), (1, 2), (0x7f, 3), (-1, 4)] 1631 | .into_iter() 1632 | .collect::>(), 1633 | &object![ 1634 | [b"\x00"]: Int(1), 1635 | [b"\x01"]: Int(2), 1636 | [b"\x7f"]: Int(3), 1637 | [b"\xff"]: Int(4), 1638 | ], 1639 | ); 1640 | } 1641 | 1642 | #[test] 1643 | fn deserialize_map_key_i16() { 1644 | type HM = std::collections::HashMap; 1645 | 1646 | assert_decodes(HM::::new(), &object![]); 1647 | assert_decodes( 1648 | [(0, 1), (1, 2), (0x7fff, 3), (-1, 4)] 1649 | .into_iter() 1650 | .collect::>(), 1651 | &object![ 1652 | [b"\x00\x00"]: Int(1), 1653 | [b"\x00\x01"]: Int(2), 1654 | [b"\x7f\xff"]: Int(3), 1655 | [b"\xff\xff"]: Int(4), 1656 | ], 1657 | ); 1658 | } 1659 | 1660 | #[test] 1661 | fn deserialize_map_key_i32() { 1662 | type HM = std::collections::HashMap; 1663 | 1664 | assert_decodes(HM::::new(), &object![]); 1665 | assert_decodes( 1666 | [(0, 1), (1, 2), (0x7fff_ffff, 3), (-1, 4)] 1667 | .into_iter() 1668 | .collect::>(), 1669 | &object![ 1670 | [b"\x00\x00\x00\x00"]: Int(1), 1671 | [b"\x00\x00\x00\x01"]: Int(2), 1672 | [b"\x7f\xff\xff\xff"]: Int(3), 1673 | [b"\xff\xff\xff\xff"]: Int(4), 1674 | ], 1675 | ); 1676 | } 1677 | 1678 | #[test] 1679 | fn deserialize_map_key_i64() { 1680 | type HM = std::collections::HashMap; 1681 | 1682 | assert_decodes(HM::::new(), &object![]); 1683 | assert_decodes( 1684 | [(0, 1), (1, 2), (0x7fff_ffff_ffff_ffff, 3), (-1, 4)] 1685 | .into_iter() 1686 | .collect::>(), 1687 | &object![ 1688 | [b"\x00\x00\x00\x00\x00\x00\x00\x00"]: Int(1), 1689 | [b"\x00\x00\x00\x00\x00\x00\x00\x01"]: Int(2), 1690 | [b"\x7f\xff\xff\xff\xff\xff\xff\xff"]: Int(3), 1691 | [b"\xff\xff\xff\xff\xff\xff\xff\xff"]: Int(4), 1692 | ], 1693 | ); 1694 | } 1695 | 1696 | #[test] 1697 | fn deserialize_map_key_u8() { 1698 | type HM = std::collections::HashMap; 1699 | 1700 | assert_decodes(HM::::new(), &object![]); 1701 | assert_decodes( 1702 | [(0, 1), (1, 2), (0x7f, 3), (0xff, 4)] 1703 | .into_iter() 1704 | .collect::>(), 1705 | &object![ 1706 | [b"\x00"]: Int(1), 1707 | [b"\x01"]: Int(2), 1708 | [b"\x7f"]: Int(3), 1709 | [b"\xff"]: Int(4), 1710 | ], 1711 | ); 1712 | } 1713 | 1714 | #[test] 1715 | fn deserialize_map_key_u16() { 1716 | type HM = std::collections::HashMap; 1717 | 1718 | assert_decodes(HM::::new(), &object![]); 1719 | assert_decodes( 1720 | [(0, 1), (1, 2), (0x7fff, 3), (0xffff, 4)] 1721 | .into_iter() 1722 | .collect::>(), 1723 | &object![ 1724 | [b"\x00\x00"]: Int(1), 1725 | [b"\x00\x01"]: Int(2), 1726 | [b"\x7f\xff"]: Int(3), 1727 | [b"\xff\xff"]: Int(4), 1728 | ], 1729 | ); 1730 | } 1731 | 1732 | #[test] 1733 | fn deserialize_map_key_u32() { 1734 | type HM = std::collections::HashMap; 1735 | 1736 | assert_decodes(HM::::new(), &object![]); 1737 | assert_decodes( 1738 | [(0, 1), (1, 2), (0x7fff_ffff, 3), (0xffff_ffff, 4)] 1739 | .into_iter() 1740 | .collect::>(), 1741 | &object![ 1742 | [b"\x00\x00\x00\x00"]: Int(1), 1743 | [b"\x00\x00\x00\x01"]: Int(2), 1744 | [b"\x7f\xff\xff\xff"]: Int(3), 1745 | [b"\xff\xff\xff\xff"]: Int(4), 1746 | ], 1747 | ); 1748 | } 1749 | 1750 | #[test] 1751 | fn deserialize_map_key_u64() { 1752 | type HM = std::collections::HashMap; 1753 | 1754 | assert_decodes(HM::::new(), &object![]); 1755 | assert_decodes( 1756 | [ 1757 | (0, 1), 1758 | (1, 2), 1759 | (0x7fff_ffff_ffff_ffff, 3), 1760 | (0xffff_ffff_ffff_ffff, 4), 1761 | ] 1762 | .into_iter() 1763 | .collect::>(), 1764 | &object![ 1765 | [b"\x00\x00\x00\x00\x00\x00\x00\x00"]: Int(1), 1766 | [b"\x00\x00\x00\x00\x00\x00\x00\x01"]: Int(2), 1767 | [b"\x7f\xff\xff\xff\xff\xff\xff\xff"]: Int(3), 1768 | [b"\xff\xff\xff\xff\xff\xff\xff\xff"]: Int(4), 1769 | ], 1770 | ); 1771 | } 1772 | 1773 | #[test] 1774 | fn deserialize_map_key_char() { 1775 | type HM = std::collections::HashMap; 1776 | 1777 | assert_decodes(HM::::new(), &object![]); 1778 | assert_decodes( 1779 | [('A', 1), ('ぽ', 2), ('ꙮ', 8)] 1780 | .into_iter() 1781 | .collect::>(), 1782 | &object![ 1783 | A: Int(1), 1784 | [b"\xe3\x81\xbd"]: Int(2), 1785 | [b"\xea\x99\xae"]: Int(8), 1786 | ], 1787 | ); 1788 | } 1789 | 1790 | #[test] 1791 | fn deserialize_map_key_str() { 1792 | type HM<'a, T> = std::collections::HashMap<&'a str, T>; 1793 | 1794 | assert_decodes(HM::<'_, i32>::new(), &object![]); 1795 | assert_decodes( 1796 | [("foo", 1), ("bar", 2)] 1797 | .into_iter() 1798 | .collect::>(), 1799 | &object![ 1800 | foo: Int(1), 1801 | bar: Int(2), 1802 | ], 1803 | ); 1804 | } 1805 | 1806 | #[test] 1807 | fn deserialize_map_key_string() { 1808 | type HM = std::collections::HashMap; 1809 | 1810 | assert_decodes(HM::::new(), &object![]); 1811 | assert_decodes( 1812 | [ 1813 | ("hello".to_owned(), "world".to_owned()), 1814 | ("foo".to_owned(), "bar".to_owned()), 1815 | ] 1816 | .into_iter() 1817 | .collect::>(), 1818 | &object![ 1819 | hello: String(b"world".to_vec()), 1820 | foo: String(b"bar".to_vec()), 1821 | ], 1822 | ); 1823 | } 1824 | 1825 | #[test] 1826 | fn deserialize_map_key_bytes() { 1827 | type HM<'a, T> = std::collections::HashMap<&'a [u8], T>; 1828 | 1829 | assert_decodes(HM::<'_, i32>::new(), &object![]); 1830 | assert_decodes( 1831 | [(b"foo".as_slice(), 1), (b"bar".as_slice(), 2)] 1832 | .into_iter() 1833 | .collect::>(), 1834 | &object![ 1835 | foo: Int(1), 1836 | bar: Int(2), 1837 | ], 1838 | ); 1839 | } 1840 | 1841 | #[test] 1842 | fn deserialize_map_key_byte_buf() { 1843 | type HM = std::collections::HashMap; 1844 | 1845 | assert_decodes(HM::::new(), &object![]); 1846 | assert_decodes( 1847 | [(Buf(b"foo".to_vec()), 1), (Buf(b"bar".to_vec()), 2)] 1848 | .into_iter() 1849 | .collect::>(), 1850 | &object![ 1851 | foo: Int(1), 1852 | bar: Int(2), 1853 | ], 1854 | ); 1855 | } 1856 | 1857 | #[test] 1858 | fn deserialize_map_key_newtype_struct() { 1859 | #[derive(Eq, PartialEq, Hash, Deserialize, Debug)] 1860 | struct S(std::string::String); 1861 | 1862 | type HM = std::collections::HashMap; 1863 | 1864 | assert_decodes(HM::::new(), &object![]); 1865 | assert_decodes( 1866 | [(S("foo".to_owned()), 1), (S("bar".to_owned()), 2)] 1867 | .into_iter() 1868 | .collect::>(), 1869 | &object![ 1870 | foo: Int(1), 1871 | bar: Int(2), 1872 | ], 1873 | ); 1874 | } 1875 | 1876 | #[test] 1877 | fn deserialize_map_key_u8_seq() { 1878 | use watson_rs::ToBytes; 1879 | type HM = std::collections::HashMap; 1880 | 1881 | assert_decodes(HM::::new(), &object![]); 1882 | assert_decodes( 1883 | [(b"foo".to_bytes(), 1), (b"bar".to_bytes(), 2)] 1884 | .into_iter() 1885 | .collect::>(), 1886 | &object![ 1887 | foo: Int(1), 1888 | bar: Int(2), 1889 | ], 1890 | ); 1891 | } 1892 | 1893 | #[test] 1894 | fn deserialize_map_key_enum() { 1895 | #[derive(Eq, PartialEq, Hash, Deserialize, Debug)] 1896 | enum E { 1897 | A, 1898 | B, 1899 | } 1900 | type HM = std::collections::HashMap; 1901 | 1902 | assert_decodes(HM::::new(), &object![]); 1903 | assert_decodes( 1904 | [(E::A, 1), (E::B, 2)].into_iter().collect::>(), 1905 | &object![ 1906 | A: Int(1), 1907 | B: Int(2), 1908 | ], 1909 | ); 1910 | } 1911 | 1912 | #[test] 1913 | fn deserialize_struct() { 1914 | #[derive(Eq, PartialEq, Deserialize, Debug)] 1915 | struct S { 1916 | f1: i32, 1917 | f2: bool, 1918 | } 1919 | 1920 | assert_decodes( 1921 | S { f1: 123, f2: true }, 1922 | &object![ 1923 | f1: Int(123), 1924 | f2: Bool(true), 1925 | ], 1926 | ); 1927 | assert_decodes(S { f1: 456, f2: false }, &array![Int(456), Bool(false)]); 1928 | } 1929 | 1930 | #[test] 1931 | fn deserialize_enum() { 1932 | #[derive(PartialEq, Deserialize, Debug)] 1933 | enum E { 1934 | A, 1935 | B(i32), 1936 | C(u32, bool), 1937 | D { f1: f64, f2: std::string::String }, 1938 | } 1939 | 1940 | assert_decodes(E::A, &String(b"A".to_vec())); 1941 | assert_decodes(E::A, &object![A: Nil]); 1942 | assert_decodes(E::B(123), &object![B: Int(123)]); 1943 | assert_decodes(E::C(456, true), &object![C: array![Uint(456), Bool(true)]]); 1944 | assert_decodes( 1945 | E::D { 1946 | f1: 1.25, 1947 | f2: "hey".to_owned(), 1948 | }, 1949 | &object![D: object![f1: Float(1.25), f2: String(b"hey".to_vec())]], 1950 | ); 1951 | } 1952 | 1953 | /* 1954 | * Helper functions 1955 | */ 1956 | 1957 | fn assert_decoded_value_satisfies<'de, T, F>(f: F, v: &'de watson_rs::Value) 1958 | where 1959 | T: fmt::Debug + de::Deserialize<'de>, 1960 | F: FnOnce(T) -> bool, 1961 | { 1962 | assert!(f(deserialize(v))); 1963 | } 1964 | 1965 | fn assert_decodes<'de, T>(expected: T, v: &'de watson_rs::Value) 1966 | where 1967 | T: PartialEq + fmt::Debug + de::Deserialize<'de>, 1968 | { 1969 | assert_eq!(expected, deserialize(v)); 1970 | } 1971 | 1972 | fn deserialize<'de, T>(v: &'de watson_rs::Value) -> T 1973 | where 1974 | T: fmt::Debug + de::Deserialize<'de>, 1975 | { 1976 | T::deserialize(&Deserializer::new(v)).expect("deserialization error") 1977 | } 1978 | 1979 | // The standard `de::Deserialize` implementation for `Vec` does not use `deserialize_byte_buf`. 1980 | #[derive(Eq, PartialEq, Hash, Debug)] 1981 | struct Buf(Vec); 1982 | 1983 | impl<'de> de::Deserialize<'de> for Buf { 1984 | fn deserialize(deserializer: D) -> std::result::Result 1985 | where 1986 | D: de::Deserializer<'de>, 1987 | { 1988 | deserializer.deserialize_byte_buf(BufVisitor) 1989 | } 1990 | } 1991 | 1992 | struct BufVisitor; 1993 | 1994 | impl<'de> de::Visitor<'de> for BufVisitor { 1995 | type Value = Buf; 1996 | 1997 | fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { 1998 | write!(f, "byte_buf") 1999 | } 2000 | 2001 | fn visit_byte_buf(self, v: Vec) -> std::result::Result 2002 | where 2003 | E: de::Error, 2004 | { 2005 | Ok(Buf(v)) 2006 | } 2007 | } 2008 | } 2009 | -------------------------------------------------------------------------------- /serde_watson/src/error.rs: -------------------------------------------------------------------------------- 1 | use std::error::Error as StdError; 2 | use std::fmt; 3 | 4 | use serde::{de, ser}; 5 | 6 | pub type Result = std::result::Result; 7 | 8 | /// Error represents an error when serializing to or deserializing from WATSON. 9 | #[derive(Debug)] 10 | pub struct Error { 11 | pub(crate) kind: ErrorKind, 12 | pub(crate) location: Option, 13 | pub(crate) source: Option>, 14 | } 15 | 16 | impl Error { 17 | /// Returns its `ErrorKind`. 18 | pub fn kind(&self) -> &ErrorKind { 19 | &self.kind 20 | } 21 | 22 | /// Returns an optional `Location` where the error happened. 23 | pub fn location(&self) -> Option<&watson_rs::Location> { 24 | self.location.as_ref() 25 | } 26 | } 27 | 28 | impl fmt::Display for Error { 29 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 30 | match self.location() { 31 | Some(loc) => write!(f, "{} at {}", self.kind, loc), 32 | None => write!(f, "{} at unknown location", self.kind), 33 | } 34 | } 35 | } 36 | 37 | impl StdError for Error { 38 | fn source(&self) -> Option<&(dyn StdError + 'static)> { 39 | self.source.as_deref() 40 | } 41 | } 42 | 43 | impl ser::Error for Error { 44 | fn custom(msg: T) -> Self 45 | where 46 | T: fmt::Display, 47 | { 48 | Error { 49 | kind: ErrorKind::Custom(format!("{msg}")), 50 | location: None, 51 | source: None, 52 | } 53 | } 54 | } 55 | impl de::Error for Error { 56 | fn custom(msg: T) -> Self 57 | where 58 | T: fmt::Display, 59 | { 60 | ser::Error::custom(msg) 61 | } 62 | } 63 | 64 | impl From for Error { 65 | fn from(err: watson_rs::Error) -> Self { 66 | Error { 67 | kind: ErrorKind::ExecutionError(err.kind), 68 | location: Some(err.location.clone()), 69 | source: Some(Box::new(err)), 70 | } 71 | } 72 | } 73 | 74 | impl Error { 75 | pub(crate) fn key_must_be_bytes() -> Self { 76 | Error { 77 | kind: ErrorKind::KeyMustBeBytes, 78 | location: None, 79 | source: None, 80 | } 81 | } 82 | } 83 | 84 | #[derive(Eq, PartialEq, Clone, Debug)] 85 | pub enum ErrorKind { 86 | /// Object key can't be converted into bytes. 87 | KeyMustBeBytes, 88 | 89 | /// Unexpected map key detected while deserializing. 90 | UnexpectedMapKey, 91 | 92 | /// Unexpected map value detected while deserializing. 93 | UnexpectedMapValue, 94 | 95 | /// Unexpected map detected while deserializing. 96 | UnexpectedMap, 97 | 98 | /// An error occurred during VM execution. 99 | ExecutionError(watson_rs::error::ErrorKind), 100 | 101 | /// A user-defined error. 102 | Custom(String), 103 | } 104 | 105 | impl fmt::Display for ErrorKind { 106 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 107 | match *self { 108 | ErrorKind::KeyMustBeBytes => write!(f, "Key must be bytes"), 109 | ErrorKind::UnexpectedMapKey => write!(f, "Unexpected map key"), 110 | ErrorKind::UnexpectedMapValue => write!(f, "Unexpected map value"), 111 | ErrorKind::UnexpectedMap => write!(f, "Unexpected map"), 112 | ErrorKind::ExecutionError(ref k) => k.fmt(f), 113 | ErrorKind::Custom(ref s) => write!(f, "{s}"), 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /serde_watson/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod de; 2 | pub mod error; 3 | pub mod ser; 4 | pub mod value; 5 | 6 | pub use de::{from_reader, from_str}; 7 | pub use error::{Error, ErrorKind, Result}; 8 | -------------------------------------------------------------------------------- /serde_watson/src/ser.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | use serde::ser; 4 | use watson_rs::serializer; 5 | use watson_rs::serializer::WriteInsn; 6 | use watson_rs::unlexer; 7 | use watson_rs::{Insn, Value}; 8 | 9 | use crate::error::{Error, Result}; 10 | 11 | /// Serializer implements serde::ser::Serializer for WATSON encoding. 12 | pub struct Serializer { 13 | inner: serializer::Serializer, 14 | } 15 | 16 | impl Serializer { 17 | /// Returns a new `Serializer` that writes to the given writer. 18 | pub fn new(writer: W) -> Self { 19 | Serializer { 20 | inner: serializer::Serializer::new(writer), 21 | } 22 | } 23 | 24 | /// Unwraps the inner value from this `Serializer`. 25 | pub fn into_inner(self) -> W { 26 | self.inner.into_inner() 27 | } 28 | } 29 | 30 | impl Serializer> 31 | where 32 | W: io::Write, 33 | { 34 | /// Returns a new `Serializer` that writes to the given `io::Write`. 35 | pub fn from_writer(writer: W) -> Self { 36 | Serializer { 37 | inner: serializer::Serializer::new(unlexer::Unlexer::new(writer)), 38 | } 39 | } 40 | } 41 | 42 | impl<'a, W> ser::Serializer for &'a mut Serializer 43 | where 44 | W: WriteInsn, 45 | { 46 | type Ok = (); 47 | type Error = Error; 48 | type SerializeSeq = SerializeSeq<'a, W>; 49 | type SerializeTuple = SerializeTuple<'a, W>; 50 | type SerializeTupleStruct = SerializeTupleStruct<'a, W>; 51 | type SerializeTupleVariant = SerializeTupleVariant<'a, W>; 52 | type SerializeMap = SerializeMap<'a, W>; 53 | type SerializeStruct = SerializeStruct<'a, W>; 54 | type SerializeStructVariant = SerializeStructVariant<'a, W>; 55 | 56 | fn serialize_bool(self, v: bool) -> Result<()> { 57 | self.inner.serialize(&Value::Bool(v))?; 58 | Ok(()) 59 | } 60 | 61 | fn serialize_i8(self, v: i8) -> Result<()> { 62 | self.inner.serialize(&Value::Int(v as i64))?; 63 | Ok(()) 64 | } 65 | 66 | fn serialize_i16(self, v: i16) -> Result<()> { 67 | self.inner.serialize(&Value::Int(v as i64))?; 68 | Ok(()) 69 | } 70 | 71 | fn serialize_i32(self, v: i32) -> Result<()> { 72 | self.inner.serialize(&Value::Int(v as i64))?; 73 | Ok(()) 74 | } 75 | 76 | fn serialize_i64(self, v: i64) -> Result<()> { 77 | self.inner.serialize(&Value::Int(v))?; 78 | Ok(()) 79 | } 80 | 81 | fn serialize_u8(self, v: u8) -> Result<()> { 82 | self.inner.serialize(&Value::Uint(v as u64))?; 83 | Ok(()) 84 | } 85 | 86 | fn serialize_u16(self, v: u16) -> Result<()> { 87 | self.inner.serialize(&Value::Uint(v as u64))?; 88 | Ok(()) 89 | } 90 | 91 | fn serialize_u32(self, v: u32) -> Result<()> { 92 | self.inner.serialize(&Value::Uint(v as u64))?; 93 | Ok(()) 94 | } 95 | 96 | fn serialize_u64(self, v: u64) -> Result<()> { 97 | self.inner.serialize(&Value::Uint(v))?; 98 | Ok(()) 99 | } 100 | 101 | fn serialize_f32(self, v: f32) -> Result<()> { 102 | self.inner.serialize(&Value::Float(v as f64))?; 103 | Ok(()) 104 | } 105 | 106 | fn serialize_f64(self, v: f64) -> Result<()> { 107 | self.inner.serialize(&Value::Float(v))?; 108 | Ok(()) 109 | } 110 | 111 | fn serialize_char(self, v: char) -> Result<()> { 112 | let mut buf = [0; 4]; 113 | self.serialize_str(v.encode_utf8(&mut buf)) 114 | } 115 | 116 | fn serialize_str(self, v: &str) -> Result<()> { 117 | self.serialize_bytes(v.as_bytes()) 118 | } 119 | 120 | fn serialize_bytes(self, v: &[u8]) -> Result<()> { 121 | self.inner.serialize(&Value::String(v.to_vec()))?; 122 | Ok(()) 123 | } 124 | 125 | fn serialize_none(self) -> Result<()> { 126 | self.inner.serialize(&Value::Nil)?; 127 | Ok(()) 128 | } 129 | 130 | fn serialize_some(self, value: &T) -> Result<()> 131 | where 132 | T: ?Sized + ser::Serialize, 133 | { 134 | value.serialize(self) 135 | } 136 | 137 | fn serialize_unit(self) -> Result<()> { 138 | self.inner.serialize(&Value::Nil)?; 139 | Ok(()) 140 | } 141 | 142 | fn serialize_unit_struct(self, _name: &'static str) -> Result<()> { 143 | self.inner.serialize(&Value::Nil)?; 144 | Ok(()) 145 | } 146 | 147 | fn serialize_unit_variant( 148 | self, 149 | _name: &'static str, 150 | _variant_index: u32, 151 | variant: &'static str, 152 | ) -> Result<()> { 153 | self.serialize_str(variant) 154 | } 155 | 156 | fn serialize_newtype_struct(self, name: &'static str, value: &T) -> Result<()> 157 | where 158 | T: ?Sized + ser::Serialize, 159 | { 160 | self.inner.write(Insn::Onew)?; 161 | self.serialize_str(name)?; 162 | value.serialize(&mut *self)?; 163 | self.inner.write(Insn::Oadd)?; 164 | Ok(()) 165 | } 166 | 167 | fn serialize_newtype_variant( 168 | self, 169 | _name: &'static str, 170 | _variant_index: u32, 171 | variant: &'static str, 172 | value: &T, 173 | ) -> Result<()> 174 | where 175 | T: ?Sized + ser::Serialize, 176 | { 177 | self.inner.write(Insn::Onew)?; 178 | self.serialize_str(variant)?; 179 | value.serialize(&mut *self)?; 180 | self.inner.write(Insn::Oadd)?; 181 | Ok(()) 182 | } 183 | 184 | fn serialize_seq(self, _len: Option) -> Result { 185 | self.inner.write(Insn::Anew)?; 186 | Ok(SerializeSeq { ser: self }) 187 | } 188 | 189 | fn serialize_tuple(self, _len: usize) -> Result { 190 | self.serialize_seq(None) 191 | } 192 | 193 | fn serialize_tuple_struct( 194 | self, 195 | _name: &'static str, 196 | _len: usize, 197 | ) -> Result { 198 | self.serialize_seq(None) 199 | } 200 | 201 | fn serialize_tuple_variant( 202 | self, 203 | _name: &'static str, 204 | _variant_index: u32, 205 | variant: &'static str, 206 | _len: usize, 207 | ) -> Result { 208 | self.inner.write(Insn::Onew)?; 209 | self.serialize_str(variant)?; 210 | self.serialize_seq(None) 211 | } 212 | 213 | fn serialize_map(self, _len: Option) -> Result { 214 | self.inner.write(Insn::Onew)?; 215 | Ok(SerializeMap { ser: self }) 216 | } 217 | 218 | fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { 219 | self.serialize_map(None) 220 | } 221 | 222 | fn serialize_struct_variant( 223 | self, 224 | _name: &'static str, 225 | _variant_index: u32, 226 | variant: &'static str, 227 | _len: usize, 228 | ) -> Result { 229 | self.inner.write(Insn::Onew)?; 230 | self.serialize_str(variant)?; 231 | self.serialize_map(None) 232 | } 233 | } 234 | 235 | pub struct SerializeSeq<'a, W> { 236 | ser: &'a mut Serializer, 237 | } 238 | 239 | impl<'a, W> ser::SerializeSeq for SerializeSeq<'a, W> 240 | where 241 | W: WriteInsn, 242 | { 243 | type Ok = (); 244 | type Error = Error; 245 | 246 | fn serialize_element(&mut self, value: &T) -> Result<()> 247 | where 248 | T: ?Sized + ser::Serialize, 249 | { 250 | value.serialize(&mut *self.ser)?; 251 | self.ser.inner.write(Insn::Aadd)?; 252 | Ok(()) 253 | } 254 | 255 | fn end(self) -> Result<()> { 256 | Ok(()) 257 | } 258 | } 259 | 260 | type SerializeTuple<'a, W> = SerializeSeq<'a, W>; 261 | 262 | impl<'a, W> ser::SerializeTuple for SerializeTuple<'a, W> 263 | where 264 | W: WriteInsn, 265 | { 266 | type Ok = (); 267 | type Error = Error; 268 | 269 | fn serialize_element(&mut self, value: &T) -> Result<()> 270 | where 271 | T: ?Sized + ser::Serialize, 272 | { 273 | ser::SerializeSeq::serialize_element(self, value) 274 | } 275 | 276 | fn end(self) -> Result<()> { 277 | ser::SerializeSeq::end(self) 278 | } 279 | } 280 | 281 | type SerializeTupleStruct<'a, W> = SerializeSeq<'a, W>; 282 | 283 | impl<'a, W> ser::SerializeTupleStruct for SerializeTupleStruct<'a, W> 284 | where 285 | W: WriteInsn, 286 | { 287 | type Ok = (); 288 | type Error = Error; 289 | 290 | fn serialize_field(&mut self, value: &T) -> Result<()> 291 | where 292 | T: ?Sized + ser::Serialize, 293 | { 294 | ser::SerializeSeq::serialize_element(self, value) 295 | } 296 | 297 | fn end(self) -> Result<()> { 298 | ser::SerializeSeq::end(self) 299 | } 300 | } 301 | 302 | type SerializeTupleVariant<'a, W> = SerializeSeq<'a, W>; 303 | 304 | impl<'a, W> ser::SerializeTupleVariant for SerializeTupleVariant<'a, W> 305 | where 306 | W: WriteInsn, 307 | { 308 | type Ok = (); 309 | type Error = Error; 310 | 311 | fn serialize_field(&mut self, value: &T) -> Result<()> 312 | where 313 | T: ?Sized + ser::Serialize, 314 | { 315 | ser::SerializeSeq::serialize_element(self, value) 316 | } 317 | 318 | fn end(self) -> Result<()> { 319 | self.ser.inner.write(Insn::Oadd)?; 320 | ser::SerializeSeq::end(self) 321 | } 322 | } 323 | 324 | pub struct SerializeMap<'a, W> { 325 | ser: &'a mut Serializer, 326 | } 327 | 328 | impl<'a, W> ser::SerializeMap for SerializeMap<'a, W> 329 | where 330 | W: WriteInsn, 331 | { 332 | type Ok = (); 333 | type Error = Error; 334 | 335 | fn serialize_key(&mut self, key: &T) -> Result<()> 336 | where 337 | T: ?Sized + ser::Serialize, 338 | { 339 | key.serialize(MapKeySerializer { 340 | ser: &mut *self.ser, 341 | }) 342 | } 343 | 344 | fn serialize_value(&mut self, value: &T) -> Result<()> 345 | where 346 | T: ?Sized + ser::Serialize, 347 | { 348 | value.serialize(&mut *self.ser)?; 349 | self.ser.inner.write(Insn::Oadd)?; 350 | Ok(()) 351 | } 352 | 353 | fn end(self) -> Result<()> { 354 | Ok(()) 355 | } 356 | } 357 | 358 | type SerializeStruct<'a, W> = SerializeMap<'a, W>; 359 | 360 | impl<'a, W> ser::SerializeStruct for SerializeStruct<'a, W> 361 | where 362 | W: WriteInsn, 363 | { 364 | type Ok = (); 365 | type Error = Error; 366 | 367 | fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> 368 | where 369 | T: ?Sized + ser::Serialize, 370 | { 371 | ser::SerializeMap::serialize_key(&mut *self, key)?; 372 | ser::SerializeMap::serialize_value(&mut *self, value)?; 373 | Ok(()) 374 | } 375 | 376 | fn end(self) -> Result<()> { 377 | ser::SerializeMap::end(self) 378 | } 379 | } 380 | 381 | type SerializeStructVariant<'a, W> = SerializeMap<'a, W>; 382 | 383 | impl<'a, W> ser::SerializeStructVariant for SerializeStructVariant<'a, W> 384 | where 385 | W: WriteInsn, 386 | { 387 | type Ok = (); 388 | type Error = Error; 389 | 390 | fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> 391 | where 392 | T: ?Sized + ser::Serialize, 393 | { 394 | ser::SerializeMap::serialize_entry(self, key, value) 395 | } 396 | 397 | fn end(self) -> Result<()> { 398 | self.ser.inner.write(Insn::Oadd)?; 399 | ser::SerializeMap::end(self) 400 | } 401 | } 402 | 403 | struct MapKeySerializer<'a, W> { 404 | ser: &'a mut Serializer, 405 | } 406 | 407 | impl<'a, W> ser::Serializer for MapKeySerializer<'a, W> 408 | where 409 | W: WriteInsn, 410 | { 411 | type Ok = (); 412 | type Error = Error; 413 | type SerializeSeq = SerializeMapKeySeq<'a, W>; 414 | type SerializeTuple = ser::Impossible<(), Error>; 415 | type SerializeTupleStruct = ser::Impossible<(), Error>; 416 | type SerializeTupleVariant = ser::Impossible<(), Error>; 417 | type SerializeMap = ser::Impossible<(), Error>; 418 | type SerializeStruct = ser::Impossible<(), Error>; 419 | type SerializeStructVariant = ser::Impossible<(), Error>; 420 | 421 | fn serialize_bool(self, v: bool) -> Result<()> { 422 | if v { 423 | self.ser.serialize_bytes(&[1]) 424 | } else { 425 | self.ser.serialize_bytes(&[0]) 426 | } 427 | } 428 | 429 | fn serialize_i8(self, v: i8) -> Result<()> { 430 | self.ser.serialize_bytes(&v.to_be_bytes()) 431 | } 432 | 433 | fn serialize_i16(self, v: i16) -> Result<()> { 434 | self.ser.serialize_bytes(&v.to_be_bytes()) 435 | } 436 | 437 | fn serialize_i32(self, v: i32) -> Result<()> { 438 | self.ser.serialize_bytes(&v.to_be_bytes()) 439 | } 440 | 441 | fn serialize_i64(self, v: i64) -> Result<()> { 442 | self.ser.serialize_bytes(&v.to_be_bytes()) 443 | } 444 | 445 | fn serialize_u8(self, v: u8) -> Result<()> { 446 | self.ser.serialize_bytes(&v.to_be_bytes()) 447 | } 448 | 449 | fn serialize_u16(self, v: u16) -> Result<()> { 450 | self.ser.serialize_bytes(&v.to_be_bytes()) 451 | } 452 | 453 | fn serialize_u32(self, v: u32) -> Result<()> { 454 | self.ser.serialize_bytes(&v.to_be_bytes()) 455 | } 456 | 457 | fn serialize_u64(self, v: u64) -> Result<()> { 458 | self.ser.serialize_bytes(&v.to_be_bytes()) 459 | } 460 | 461 | fn serialize_f32(self, _v: f32) -> Result<()> { 462 | Err(Error::key_must_be_bytes()) 463 | } 464 | 465 | fn serialize_f64(self, _v: f64) -> Result<()> { 466 | Err(Error::key_must_be_bytes()) 467 | } 468 | 469 | fn serialize_char(self, v: char) -> Result<()> { 470 | let mut buf = [0; 4]; 471 | self.ser.serialize_str(v.encode_utf8(&mut buf)) 472 | } 473 | 474 | fn serialize_str(self, v: &str) -> Result<()> { 475 | self.ser.serialize_str(v) 476 | } 477 | 478 | fn serialize_bytes(self, v: &[u8]) -> Result<()> { 479 | self.ser.serialize_bytes(v) 480 | } 481 | 482 | fn serialize_none(self) -> Result<()> { 483 | Err(Error::key_must_be_bytes()) 484 | } 485 | 486 | fn serialize_some(self, _value: &T) -> Result<()> 487 | where 488 | T: ?Sized + ser::Serialize, 489 | { 490 | Err(Error::key_must_be_bytes()) 491 | } 492 | 493 | fn serialize_unit(self) -> Result<()> { 494 | Err(Error::key_must_be_bytes()) 495 | } 496 | 497 | fn serialize_unit_struct(self, _name: &'static str) -> Result<()> { 498 | Err(Error::key_must_be_bytes()) 499 | } 500 | 501 | fn serialize_unit_variant( 502 | self, 503 | _name: &'static str, 504 | _variant_index: u32, 505 | variant: &'static str, 506 | ) -> Result<()> { 507 | self.ser.serialize_str(variant) 508 | } 509 | 510 | fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result<()> 511 | where 512 | T: ?Sized + ser::Serialize, 513 | { 514 | value.serialize(self) 515 | } 516 | 517 | fn serialize_newtype_variant( 518 | self, 519 | _name: &'static str, 520 | _variant_index: u32, 521 | _variant: &'static str, 522 | _value: &T, 523 | ) -> Result<()> 524 | where 525 | T: ?Sized + ser::Serialize, 526 | { 527 | Err(Error::key_must_be_bytes()) 528 | } 529 | 530 | fn serialize_seq(self, _len: Option) -> Result { 531 | self.ser.inner.write(Insn::Snew)?; 532 | Ok(SerializeMapKeySeq { 533 | ser: &mut *self.ser, 534 | }) 535 | } 536 | 537 | fn serialize_tuple(self, _len: usize) -> Result { 538 | Err(Error::key_must_be_bytes()) 539 | } 540 | 541 | fn serialize_tuple_struct( 542 | self, 543 | _name: &'static str, 544 | _len: usize, 545 | ) -> Result { 546 | Err(Error::key_must_be_bytes()) 547 | } 548 | 549 | fn serialize_tuple_variant( 550 | self, 551 | _name: &'static str, 552 | _variant_index: u32, 553 | _variant: &'static str, 554 | _len: usize, 555 | ) -> Result { 556 | Err(Error::key_must_be_bytes()) 557 | } 558 | 559 | fn serialize_map(self, _len: Option) -> Result { 560 | Err(Error::key_must_be_bytes()) 561 | } 562 | 563 | fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { 564 | Err(Error::key_must_be_bytes()) 565 | } 566 | 567 | fn serialize_struct_variant( 568 | self, 569 | _name: &'static str, 570 | _variant_index: u32, 571 | _variant: &'static str, 572 | _len: usize, 573 | ) -> Result { 574 | Err(Error::key_must_be_bytes()) 575 | } 576 | } 577 | 578 | struct SerializeMapKeySeq<'a, W> { 579 | ser: &'a mut Serializer, 580 | } 581 | 582 | impl<'a, W> ser::SerializeSeq for SerializeMapKeySeq<'a, W> 583 | where 584 | W: WriteInsn, 585 | { 586 | type Ok = (); 587 | type Error = Error; 588 | 589 | fn serialize_element(&mut self, value: &T) -> Result<()> 590 | where 591 | T: ?Sized + ser::Serialize, 592 | { 593 | value.serialize(MapKeyBytesSerializer { 594 | ser: &mut *self.ser, 595 | }) 596 | } 597 | 598 | fn end(self) -> Result<()> { 599 | Ok(()) 600 | } 601 | } 602 | 603 | struct MapKeyBytesSerializer<'a, W> { 604 | ser: &'a mut Serializer, 605 | } 606 | 607 | impl<'a, W> ser::Serializer for MapKeyBytesSerializer<'a, W> 608 | where 609 | W: WriteInsn, 610 | { 611 | type Ok = (); 612 | type Error = Error; 613 | type SerializeSeq = ser::Impossible<(), Error>; 614 | type SerializeTuple = ser::Impossible<(), Error>; 615 | type SerializeTupleStruct = ser::Impossible<(), Error>; 616 | type SerializeTupleVariant = ser::Impossible<(), Error>; 617 | type SerializeMap = ser::Impossible<(), Error>; 618 | type SerializeStruct = ser::Impossible<(), Error>; 619 | type SerializeStructVariant = ser::Impossible<(), Error>; 620 | 621 | fn serialize_bool(self, _v: bool) -> Result<()> { 622 | Err(Error::key_must_be_bytes()) 623 | } 624 | 625 | fn serialize_i8(self, _v: i8) -> Result<()> { 626 | Err(Error::key_must_be_bytes()) 627 | } 628 | 629 | fn serialize_i16(self, _v: i16) -> Result<()> { 630 | Err(Error::key_must_be_bytes()) 631 | } 632 | 633 | fn serialize_i32(self, _v: i32) -> Result<()> { 634 | Err(Error::key_must_be_bytes()) 635 | } 636 | 637 | fn serialize_i64(self, _v: i64) -> Result<()> { 638 | Err(Error::key_must_be_bytes()) 639 | } 640 | 641 | fn serialize_u8(self, v: u8) -> Result<()> { 642 | self.ser.serialize_i8(v as i8)?; 643 | self.ser.inner.write(Insn::Sadd)?; 644 | Ok(()) 645 | } 646 | 647 | fn serialize_u16(self, _v: u16) -> Result<()> { 648 | Err(Error::key_must_be_bytes()) 649 | } 650 | 651 | fn serialize_u32(self, _v: u32) -> Result<()> { 652 | Err(Error::key_must_be_bytes()) 653 | } 654 | 655 | fn serialize_u64(self, _v: u64) -> Result<()> { 656 | Err(Error::key_must_be_bytes()) 657 | } 658 | 659 | fn serialize_f32(self, _v: f32) -> Result<()> { 660 | Err(Error::key_must_be_bytes()) 661 | } 662 | 663 | fn serialize_f64(self, _v: f64) -> Result<()> { 664 | Err(Error::key_must_be_bytes()) 665 | } 666 | 667 | fn serialize_char(self, _v: char) -> Result<()> { 668 | Err(Error::key_must_be_bytes()) 669 | } 670 | 671 | fn serialize_str(self, _v: &str) -> Result<()> { 672 | Err(Error::key_must_be_bytes()) 673 | } 674 | 675 | fn serialize_bytes(self, _v: &[u8]) -> Result<()> { 676 | Err(Error::key_must_be_bytes()) 677 | } 678 | 679 | fn serialize_none(self) -> Result<()> { 680 | Err(Error::key_must_be_bytes()) 681 | } 682 | 683 | fn serialize_some(self, _value: &T) -> Result<()> 684 | where 685 | T: ?Sized + ser::Serialize, 686 | { 687 | Err(Error::key_must_be_bytes()) 688 | } 689 | 690 | fn serialize_unit(self) -> Result<()> { 691 | Err(Error::key_must_be_bytes()) 692 | } 693 | 694 | fn serialize_unit_struct(self, _name: &'static str) -> Result<()> { 695 | Err(Error::key_must_be_bytes()) 696 | } 697 | 698 | fn serialize_unit_variant( 699 | self, 700 | _name: &'static str, 701 | _variant_index: u32, 702 | _variant: &'static str, 703 | ) -> Result<()> { 704 | Err(Error::key_must_be_bytes()) 705 | } 706 | 707 | fn serialize_newtype_struct(self, _name: &'static str, _value: &T) -> Result<()> 708 | where 709 | T: ?Sized + ser::Serialize, 710 | { 711 | Err(Error::key_must_be_bytes()) 712 | } 713 | 714 | fn serialize_newtype_variant( 715 | self, 716 | _name: &'static str, 717 | _variant_index: u32, 718 | _variant: &'static str, 719 | _value: &T, 720 | ) -> Result<()> 721 | where 722 | T: ?Sized + ser::Serialize, 723 | { 724 | Err(Error::key_must_be_bytes()) 725 | } 726 | 727 | fn serialize_seq(self, _len: Option) -> Result { 728 | Err(Error::key_must_be_bytes()) 729 | } 730 | 731 | fn serialize_tuple(self, _len: usize) -> Result { 732 | Err(Error::key_must_be_bytes()) 733 | } 734 | 735 | fn serialize_tuple_struct( 736 | self, 737 | _name: &'static str, 738 | _len: usize, 739 | ) -> Result { 740 | Err(Error::key_must_be_bytes()) 741 | } 742 | 743 | fn serialize_tuple_variant( 744 | self, 745 | _name: &'static str, 746 | _variant_index: u32, 747 | _variant: &'static str, 748 | _len: usize, 749 | ) -> Result { 750 | Err(Error::key_must_be_bytes()) 751 | } 752 | 753 | fn serialize_map(self, _len: Option) -> Result { 754 | Err(Error::key_must_be_bytes()) 755 | } 756 | 757 | fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { 758 | Err(Error::key_must_be_bytes()) 759 | } 760 | 761 | fn serialize_struct_variant( 762 | self, 763 | _name: &'static str, 764 | _variant_index: u32, 765 | _variant: &'static str, 766 | _len: usize, 767 | ) -> Result { 768 | Err(Error::key_must_be_bytes()) 769 | } 770 | } 771 | 772 | #[cfg(test)] 773 | mod test { 774 | use std::fmt; 775 | 776 | use serde::ser::Serializer as SerdeSerializer; 777 | use serde::Serialize; 778 | use watson_rs::ToBytes; 779 | use watson_rs::Value::*; 780 | use watson_rs::{array, object}; 781 | 782 | use super::*; 783 | 784 | #[test] 785 | fn serialize_bool() { 786 | assert_encodes(true, Bool(true)); 787 | assert_encodes(false, Bool(false)); 788 | } 789 | 790 | #[test] 791 | fn serialize_i8() { 792 | assert_encodes(0_i8, Int(0)); 793 | assert_encodes(1_i8, Int(1)); 794 | assert_encodes(127_i8, Int(127)); 795 | assert_encodes(-1_i8, Int(-1)); 796 | assert_encodes(-128_i8, Int(-128)); 797 | } 798 | 799 | #[test] 800 | fn serialize_i16() { 801 | assert_encodes(0_i16, Int(0)); 802 | assert_encodes(1_i16, Int(1)); 803 | assert_encodes(32767_i16, Int(32767)); 804 | assert_encodes(-1_i16, Int(-1)); 805 | assert_encodes(-32768_i16, Int(-32768)); 806 | } 807 | 808 | #[test] 809 | fn serialize_i32() { 810 | assert_encodes(0_i32, Int(0)); 811 | assert_encodes(1_i32, Int(1)); 812 | assert_encodes(2147483647_i32, Int(2147483647)); 813 | assert_encodes(-1_i32, Int(-1)); 814 | assert_encodes(-2147483647_i32, Int(-2147483647)); 815 | } 816 | 817 | #[test] 818 | fn serialize_i64() { 819 | assert_encodes(0_i64, Int(0)); 820 | assert_encodes(1_i64, Int(1)); 821 | assert_encodes(9223372036854775807_i64, Int(9223372036854775807_i64)); 822 | assert_encodes(-1_i64, Int(-1)); 823 | assert_encodes(-9223372036854775808_i64, Int(-9223372036854775808_i64)); 824 | } 825 | 826 | #[test] 827 | fn serialize_u8() { 828 | assert_encodes(0_u8, Uint(0)); 829 | assert_encodes(1_u8, Uint(1)); 830 | assert_encodes(255_u8, Uint(255)); 831 | } 832 | 833 | #[test] 834 | fn serialize_u16() { 835 | assert_encodes(0_u16, Uint(0)); 836 | assert_encodes(1_u16, Uint(1)); 837 | assert_encodes(65535_u16, Uint(65535)); 838 | } 839 | 840 | #[test] 841 | fn serialize_u32() { 842 | assert_encodes(0_u32, Uint(0)); 843 | assert_encodes(1_u32, Uint(1)); 844 | assert_encodes(4294967295_u32, Uint(4294967295)); 845 | } 846 | 847 | #[test] 848 | fn serialize_u64() { 849 | assert_encodes(0_u64, Uint(0)); 850 | assert_encodes(1_u64, Uint(1)); 851 | assert_encodes(18446744073709551615_u64, Uint(18446744073709551615)); 852 | } 853 | 854 | #[test] 855 | fn serialize_f32() { 856 | assert_encodes_to_float_satisfying(f32::NAN, |f| f.is_nan()); 857 | assert_encodes_to_float_satisfying(f32::INFINITY, |f| { 858 | f.is_sign_positive() && f.is_infinite() 859 | }); 860 | assert_encodes_to_float_satisfying(f32::NEG_INFINITY, |f| { 861 | f.is_sign_negative() && f.is_infinite() 862 | }); 863 | assert_encodes(1.25_f32, Float(1.25)); 864 | assert_encodes(-1.25_f32, Float(-1.25)); 865 | } 866 | 867 | #[test] 868 | fn serialize_f64() { 869 | assert_encodes_to_float_satisfying(f64::NAN, |f| f.is_nan()); 870 | assert_encodes_to_float_satisfying(f64::INFINITY, |f| { 871 | f.is_sign_positive() && f.is_infinite() 872 | }); 873 | assert_encodes_to_float_satisfying(f64::NEG_INFINITY, |f| { 874 | f.is_sign_negative() && f.is_infinite() 875 | }); 876 | assert_encodes(1.25e67_f64, Float(1.25e67)); 877 | assert_encodes(-1.25e-67_f64, Float(-1.25e-67)); 878 | } 879 | 880 | #[test] 881 | fn serialize_char() { 882 | assert_encodes('a', String(b"a".to_vec())); 883 | assert_encodes('あ', String("あ".to_bytes())); 884 | } 885 | 886 | #[test] 887 | fn serialize_str() { 888 | assert_encodes("", String("".to_bytes())); 889 | assert_encodes("x", String("x".to_bytes())); 890 | assert_encodes("こんにちは世界", String("こんにちは世界".to_bytes())); 891 | assert_encodes("Привет, мир!", String("Привет, мир!".to_bytes())); 892 | } 893 | 894 | #[test] 895 | fn serialize_bytes() { 896 | assert_encodes_to_bytes(b"", String("".to_bytes())); 897 | assert_encodes_to_bytes(b"1", String("1".to_bytes())); 898 | assert_encodes_to_bytes(b"Hello, world!", String("Hello, world!".to_bytes())); 899 | } 900 | 901 | #[test] 902 | fn serialize_none() { 903 | assert_encodes(Option::::None, Nil); 904 | } 905 | 906 | #[test] 907 | fn serialize_some() { 908 | assert_encodes(Some(true), Bool(true)); 909 | assert_encodes(Some(123), Int(123)); 910 | } 911 | 912 | #[test] 913 | fn serialize_unit() { 914 | assert_encodes((), Nil); 915 | } 916 | 917 | #[test] 918 | fn serialize_unit_struct() { 919 | #[derive(Debug, Serialize)] 920 | struct S; 921 | 922 | assert_encodes(S, Nil); 923 | } 924 | 925 | #[test] 926 | fn serialize_unit_variant() { 927 | #[derive(Debug, Serialize)] 928 | enum E { 929 | A, 930 | B, 931 | C, 932 | } 933 | 934 | assert_encodes(E::A, String(b"A".to_vec())); 935 | assert_encodes(E::B, String(b"B".to_vec())); 936 | assert_encodes(E::C, String(b"C".to_vec())); 937 | } 938 | 939 | #[test] 940 | fn serialize_newtype_struct() { 941 | #[derive(Debug, Serialize)] 942 | struct S(i64); 943 | 944 | assert_encodes(S(123), object![S: Int(123)]) 945 | } 946 | 947 | #[test] 948 | fn serialize_newtype_variant() { 949 | #[derive(Debug, Serialize)] 950 | enum E { 951 | A(bool), 952 | } 953 | 954 | assert_encodes(E::A(false), object![A: Bool(false)]); 955 | } 956 | 957 | #[test] 958 | fn serialize_seq() { 959 | assert_encodes(vec![1, 2, 3], array![Int(1), Int(2), Int(3)]); 960 | } 961 | 962 | #[test] 963 | fn serialize_tuple() { 964 | assert_encodes( 965 | (1, true, vec![2_u8, 3_u8]), 966 | array![Int(1), Bool(true), array![Uint(2), Uint(3)]], 967 | ); 968 | } 969 | 970 | #[test] 971 | fn serialize_tuple_struct() { 972 | #[derive(Debug, Serialize)] 973 | struct T(i32, bool, &'static str); 974 | 975 | assert_encodes( 976 | T(123, true, "foo"), 977 | array![Int(123), Bool(true), String(b"foo".to_vec())], 978 | ); 979 | } 980 | 981 | #[test] 982 | fn serialize_tuple_variant() { 983 | #[derive(Debug, Serialize)] 984 | enum E { 985 | A(i32, bool), 986 | B(u64, ()), 987 | } 988 | 989 | assert_encodes(E::A(123, true), object![A: array![Int(123), Bool(true)]]); 990 | assert_encodes(E::B(456, ()), object![B: array![Uint(456), Nil]]); 991 | } 992 | 993 | #[test] 994 | fn serialize_map_key_bool() { 995 | type HM = std::collections::HashMap; 996 | 997 | assert_encodes(HM::::new(), object![]); 998 | assert_encodes( 999 | [(true, "true"), (false, "false")] 1000 | .into_iter() 1001 | .collect::>(), 1002 | object![ 1003 | [b"\x01"]: String(b"true".to_vec()), 1004 | [b"\x00"]: String(b"false".to_vec()), 1005 | ], 1006 | ) 1007 | } 1008 | 1009 | #[test] 1010 | fn serialize_map_key_i8() { 1011 | type HM = std::collections::HashMap; 1012 | 1013 | assert_encodes(HM::::new(), object![]); 1014 | assert_encodes( 1015 | [(0, "A"), (0x7f, "B"), (-0x80, "C")] 1016 | .into_iter() 1017 | .collect::>(), 1018 | object![ 1019 | [b"\x00"]: String(b"A".to_vec()), 1020 | [b"\x7f"]: String(b"B".to_vec()), 1021 | [b"\x80"]: String(b"C".to_vec()), 1022 | ], 1023 | ) 1024 | } 1025 | 1026 | #[test] 1027 | fn serialize_map_key_i16() { 1028 | type HM = std::collections::HashMap; 1029 | 1030 | assert_encodes(HM::::new(), object![]); 1031 | assert_encodes( 1032 | [(0, "A"), (0x7fff, "B"), (-0x8000, "C")] 1033 | .into_iter() 1034 | .collect::>(), 1035 | object![ 1036 | [b"\x00\x00"]: String(b"A".to_vec()), 1037 | [b"\x7f\xff"]: String(b"B".to_vec()), 1038 | [b"\x80\x00"]: String(b"C".to_vec()), 1039 | ], 1040 | ) 1041 | } 1042 | 1043 | #[test] 1044 | fn serialize_map_key_i32() { 1045 | type HM = std::collections::HashMap; 1046 | 1047 | assert_encodes(HM::::new(), object![]); 1048 | assert_encodes( 1049 | [(0, "A"), (0x7fff_ffff, "B"), (-0x8000_0000, "C")] 1050 | .into_iter() 1051 | .collect::>(), 1052 | object![ 1053 | [b"\x00\x00\x00\x00"]: String(b"A".to_vec()), 1054 | [b"\x7f\xff\xff\xff"]: String(b"B".to_vec()), 1055 | [b"\x80\x00\x00\x00"]: String(b"C".to_vec()), 1056 | ], 1057 | ) 1058 | } 1059 | 1060 | #[test] 1061 | fn serialize_map_key_i64() { 1062 | type HM = std::collections::HashMap; 1063 | 1064 | assert_encodes(HM::::new(), object![]); 1065 | assert_encodes( 1066 | [ 1067 | (0, "A"), 1068 | (0x7fff_ffff_ffff_ffff, "B"), 1069 | (-0x8000_0000_0000_0000, "C"), 1070 | ] 1071 | .into_iter() 1072 | .collect::>(), 1073 | object![ 1074 | [b"\x00\x00\x00\x00\x00\x00\x00\x00"]: String(b"A".to_vec()), 1075 | [b"\x7f\xff\xff\xff\xff\xff\xff\xff"]: String(b"B".to_vec()), 1076 | [b"\x80\x00\x00\x00\x00\x00\x00\x00"]: String(b"C".to_vec()), 1077 | ], 1078 | ) 1079 | } 1080 | 1081 | #[test] 1082 | fn serialize_map_key_u8() { 1083 | type HM = std::collections::HashMap; 1084 | 1085 | assert_encodes(HM::::new(), object![]); 1086 | assert_encodes( 1087 | [(0, "A"), (0x7f, "B"), (0xff, "C")] 1088 | .into_iter() 1089 | .collect::>(), 1090 | object![ 1091 | [b"\x00"]: String(b"A".to_vec()), 1092 | [b"\x7f"]: String(b"B".to_vec()), 1093 | [b"\xff"]: String(b"C".to_vec()), 1094 | ], 1095 | ) 1096 | } 1097 | 1098 | #[test] 1099 | fn serialize_map_key_u16() { 1100 | type HM = std::collections::HashMap; 1101 | 1102 | assert_encodes(HM::::new(), object![]); 1103 | assert_encodes( 1104 | [(0, "A"), (0x7fff, "B"), (0xffff, "C")] 1105 | .into_iter() 1106 | .collect::>(), 1107 | object![ 1108 | [b"\x00\x00"]: String(b"A".to_vec()), 1109 | [b"\x7f\xff"]: String(b"B".to_vec()), 1110 | [b"\xff\xff"]: String(b"C".to_vec()), 1111 | ], 1112 | ) 1113 | } 1114 | 1115 | #[test] 1116 | fn serialize_map_key_u32() { 1117 | type HM = std::collections::HashMap; 1118 | 1119 | assert_encodes(HM::::new(), object![]); 1120 | assert_encodes( 1121 | [(0, "A"), (0x7fff_ffff, "B"), (0xffff_ffff, "C")] 1122 | .into_iter() 1123 | .collect::>(), 1124 | object![ 1125 | [b"\x00\x00\x00\x00"]: String(b"A".to_vec()), 1126 | [b"\x7f\xff\xff\xff"]: String(b"B".to_vec()), 1127 | [b"\xff\xff\xff\xff"]: String(b"C".to_vec()), 1128 | ], 1129 | ) 1130 | } 1131 | 1132 | #[test] 1133 | fn serialize_map_key_u64() { 1134 | type HM = std::collections::HashMap; 1135 | 1136 | assert_encodes(HM::::new(), object![]); 1137 | assert_encodes( 1138 | [ 1139 | (0, "A"), 1140 | (0x7fff_ffff_ffff_ffff, "B"), 1141 | (0xffff_ffff_ffff_ffff, "C"), 1142 | ] 1143 | .into_iter() 1144 | .collect::>(), 1145 | object![ 1146 | [b"\x00\x00\x00\x00\x00\x00\x00\x00"]: String(b"A".to_vec()), 1147 | [b"\x7f\xff\xff\xff\xff\xff\xff\xff"]: String(b"B".to_vec()), 1148 | [b"\xff\xff\xff\xff\xff\xff\xff\xff"]: String(b"C".to_vec()), 1149 | ], 1150 | ) 1151 | } 1152 | 1153 | #[test] 1154 | fn serialize_map_key_char() { 1155 | type HM = std::collections::HashMap; 1156 | 1157 | assert_encodes(HM::::new(), object![]); 1158 | assert_encodes( 1159 | [('A', 1), ('B', 2), ('参', 3)] 1160 | .into_iter() 1161 | .collect::>(), 1162 | object![ 1163 | [b"A"]: Int(1), 1164 | [b"B"]: Int(2), 1165 | [b"\xe5\x8f\x82"]: Int(3), 1166 | ], 1167 | ); 1168 | } 1169 | 1170 | #[test] 1171 | fn serialize_map_key_str() { 1172 | type HM = std::collections::HashMap<&'static str, T>; 1173 | 1174 | assert_encodes(HM::::new(), object![]); 1175 | assert_encodes( 1176 | [("foo", "bar")].into_iter().collect::>(), 1177 | object![foo: String(b"bar".to_vec())], 1178 | ); 1179 | assert_encodes( 1180 | [("foo", 123), ("bar", 456), ("", 789)] 1181 | .into_iter() 1182 | .collect::>(), 1183 | object![foo: Int(123), bar: Int(456), [b""]: Int(789)], 1184 | ); 1185 | } 1186 | 1187 | #[test] 1188 | fn serialize_map_key_bytes() { 1189 | type HM = std::collections::HashMap, T>; 1190 | 1191 | assert_encodes(HM::::new(), object![]); 1192 | assert_encodes( 1193 | [("foo".to_bytes(), "bar")] 1194 | .into_iter() 1195 | .collect::>(), 1196 | object![foo: String(b"bar".to_vec())], 1197 | ); 1198 | assert_encodes( 1199 | [ 1200 | ("foo".to_bytes(), 123), 1201 | ("bar".to_bytes(), 456), 1202 | ("".to_bytes(), 789), 1203 | ] 1204 | .into_iter() 1205 | .collect::>(), 1206 | object![foo: Int(123), bar: Int(456), [b""]: Int(789)], 1207 | ); 1208 | } 1209 | 1210 | #[test] 1211 | fn serialize_map_key_unit_variant() { 1212 | #[derive(Eq, PartialEq, Hash, Debug, Serialize)] 1213 | enum Key { 1214 | A, 1215 | B, 1216 | } 1217 | type HM = std::collections::HashMap; 1218 | 1219 | assert_encodes( 1220 | [(Key::A, 123), (Key::B, 456)] 1221 | .into_iter() 1222 | .collect::>(), 1223 | object![A: Int(123), B: Int(456)], 1224 | ); 1225 | } 1226 | 1227 | #[test] 1228 | fn serialize_map_key_newtype_struct() { 1229 | #[derive(Eq, PartialEq, Hash, Debug, Serialize)] 1230 | struct Key(&'static str); 1231 | type HM = std::collections::HashMap; 1232 | 1233 | assert_encodes( 1234 | [(Key("foo"), 123), (Key("bar"), 456)] 1235 | .into_iter() 1236 | .collect::>(), 1237 | object![foo: Int(123), bar: Int(456)], 1238 | ); 1239 | } 1240 | 1241 | #[test] 1242 | fn serialize_struct() { 1243 | #[derive(Debug, Serialize)] 1244 | struct S { 1245 | f1: i32, 1246 | f2: &'static str, 1247 | f3: bool, 1248 | } 1249 | 1250 | assert_encodes( 1251 | S { 1252 | f1: 123, 1253 | f2: "abc", 1254 | f3: true, 1255 | }, 1256 | object![f1: Int(123), f2: String(b"abc".to_vec()), f3: Bool(true)], 1257 | ) 1258 | } 1259 | 1260 | #[test] 1261 | fn serialize_struct_variant() { 1262 | #[derive(Debug, Serialize)] 1263 | enum E { 1264 | S { f1: u32, f2: i32 }, 1265 | } 1266 | 1267 | assert_encodes( 1268 | E::S { f1: 123, f2: 456 }, 1269 | object![S: object![f1: Uint(123), f2: Int(456)]], 1270 | ); 1271 | } 1272 | 1273 | /* 1274 | * Helper functions 1275 | */ 1276 | 1277 | fn assert_encodes(x: T, expected: watson_rs::Value) 1278 | where 1279 | T: fmt::Debug + ser::Serialize, 1280 | { 1281 | let actual = encode_then_decode(x); 1282 | assert_eq!(actual, expected); 1283 | } 1284 | 1285 | fn assert_encodes_to_float_satisfying(x: T, pred: F) 1286 | where 1287 | T: fmt::Debug + ser::Serialize, 1288 | F: FnOnce(f64) -> bool, 1289 | { 1290 | match encode_then_decode(x) { 1291 | Float(f) => { 1292 | assert!(pred(f)); 1293 | } 1294 | actual => { 1295 | panic!("expected float but got {:?}", actual); 1296 | } 1297 | } 1298 | } 1299 | 1300 | fn assert_encodes_to_bytes(s: &[u8], expected: watson_rs::Value) { 1301 | let mut buf = vec![]; 1302 | let mut ser = Serializer::new(&mut buf); 1303 | ser.serialize_bytes(s).expect("serialization error"); 1304 | assert_eq!(decode(&mut buf.into_iter()), expected); 1305 | } 1306 | 1307 | fn encode_then_decode(x: T) -> watson_rs::Value 1308 | where 1309 | T: ser::Serialize, 1310 | { 1311 | let mut buf = vec![]; 1312 | let mut ser = Serializer::new(&mut buf); 1313 | 1314 | x.serialize(&mut ser).expect("selialization error"); 1315 | 1316 | decode(&mut buf.into_iter()) 1317 | } 1318 | 1319 | fn decode(it: &mut It) -> watson_rs::Value 1320 | where 1321 | It: Iterator, 1322 | { 1323 | let mut vm = watson_rs::VM::new(); 1324 | vm.execute_all(watson_rs::vm::SliceTokenReader::new( 1325 | &it.collect::>(), 1326 | )) 1327 | .expect("execution error"); 1328 | vm.peek_top().expect("stack should not be empty").clone() 1329 | } 1330 | } 1331 | -------------------------------------------------------------------------------- /serde_watson/src/value.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | use std::ops; 3 | 4 | use serde::de; 5 | use serde::de::{Deserialize, Deserializer, MapAccess, SeqAccess, Visitor}; 6 | use serde::ser::{Serialize, SerializeMap, SerializeSeq, Serializer}; 7 | use watson_rs::Value::*; 8 | 9 | /// Value implements Serialize and Deserialize for `value::Value`. 10 | #[derive(PartialEq, Clone, Debug)] 11 | pub struct Value { 12 | value: watson_rs::Value, 13 | } 14 | 15 | impl Value { 16 | /// Returns a new `Value`. 17 | pub fn new(v: watson_rs::Value) -> Self { 18 | Value { value: v } 19 | } 20 | 21 | /// Returns underlying `watson::Value`. 22 | pub fn into_watson(self) -> watson_rs::Value { 23 | self.value 24 | } 25 | } 26 | 27 | impl From for Value { 28 | fn from(v: watson_rs::Value) -> Self { 29 | Value::new(v) 30 | } 31 | } 32 | 33 | impl Serialize for Value { 34 | fn serialize(&self, serializer: S) -> Result 35 | where 36 | S: Serializer, 37 | { 38 | ValueRef::new(&self.value).serialize(serializer) 39 | } 40 | } 41 | 42 | impl<'de> Deserialize<'de> for Value { 43 | fn deserialize(deserializer: D) -> Result 44 | where 45 | D: Deserializer<'de>, 46 | { 47 | deserializer.deserialize_any(ValueVisitor) 48 | } 49 | } 50 | 51 | struct ValueVisitor; 52 | 53 | impl<'de> Visitor<'de> for ValueVisitor { 54 | type Value = Value; 55 | 56 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 57 | formatter.write_str("bool, integer, float, string, bytes, seq, or map") 58 | } 59 | 60 | fn visit_i64(self, v: i64) -> Result 61 | where 62 | E: de::Error, 63 | { 64 | Ok(Int(v).into()) 65 | } 66 | 67 | fn visit_u64(self, v: u64) -> Result 68 | where 69 | E: de::Error, 70 | { 71 | Ok(Uint(v).into()) 72 | } 73 | 74 | fn visit_f64(self, v: f64) -> Result 75 | where 76 | E: de::Error, 77 | { 78 | Ok(Float(v).into()) 79 | } 80 | 81 | fn visit_str(self, v: &str) -> Result 82 | where 83 | E: de::Error, 84 | { 85 | self.visit_bytes(v.as_bytes()) 86 | } 87 | 88 | fn visit_string(self, v: std::string::String) -> Result 89 | where 90 | E: de::Error, 91 | { 92 | self.visit_byte_buf(v.into_bytes()) 93 | } 94 | 95 | fn visit_bytes(self, v: &[u8]) -> Result 96 | where 97 | E: de::Error, 98 | { 99 | Ok(String(v.to_owned()).into()) 100 | } 101 | 102 | fn visit_byte_buf(self, v: Vec) -> Result 103 | where 104 | E: de::Error, 105 | { 106 | Ok(String(v).into()) 107 | } 108 | 109 | fn visit_map(self, mut access: M) -> Result 110 | where 111 | M: MapAccess<'de>, 112 | { 113 | let mut map = watson_rs::Map::with_capacity(access.size_hint().unwrap_or(0)); 114 | while let Some((key, value)) = access.next_entry::()? { 115 | map.insert(key.into_bytes(), value.into_watson()); 116 | } 117 | Ok(Object(map).into()) 118 | } 119 | 120 | fn visit_seq(self, mut access: S) -> Result 121 | where 122 | S: SeqAccess<'de>, 123 | { 124 | let mut arr = Vec::with_capacity(access.size_hint().unwrap_or(0)); 125 | while let Some(elem) = access.next_element::()? { 126 | arr.push(elem.into_watson()); 127 | } 128 | Ok(Array(arr).into()) 129 | } 130 | 131 | fn visit_bool(self, v: bool) -> Result 132 | where 133 | E: de::Error, 134 | { 135 | Ok(Bool(v).into()) 136 | } 137 | 138 | fn visit_none(self) -> Result 139 | where 140 | E: de::Error, 141 | { 142 | Ok(Nil.into()) 143 | } 144 | } 145 | 146 | pub struct ValueRef<'a> { 147 | value: &'a watson_rs::Value, 148 | } 149 | 150 | impl<'a> ValueRef<'a> { 151 | /// Returns a new `ValueRef` that points to the given `Value`. 152 | pub fn new(v: &'a watson_rs::Value) -> Self { 153 | ValueRef { value: v } 154 | } 155 | } 156 | 157 | impl<'a> AsRef for ValueRef<'a> { 158 | fn as_ref(&self) -> &watson_rs::Value { 159 | self.value 160 | } 161 | } 162 | 163 | impl<'a> ops::Deref for ValueRef<'a> { 164 | type Target = watson_rs::Value; 165 | 166 | fn deref(&self) -> &watson_rs::Value { 167 | self.value 168 | } 169 | } 170 | 171 | impl<'a> Serialize for ValueRef<'a> { 172 | fn serialize(&self, serializer: S) -> Result 173 | where 174 | S: Serializer, 175 | { 176 | match *self.value { 177 | Int(n) => serializer.serialize_i64(n), 178 | Uint(n) => serializer.serialize_u64(n), 179 | Float(f) => serializer.serialize_f64(f), 180 | String(ref s) => serializer.serialize_bytes(s), 181 | Object(ref map) => { 182 | let mut map_ser = serializer.serialize_map(Some(map.len()))?; 183 | for (k, v) in map { 184 | map_ser.serialize_entry(&BytesRef(k), &ValueRef::new(v))?; 185 | } 186 | map_ser.end() 187 | } 188 | Array(ref arr) => { 189 | let mut seq_ser = serializer.serialize_seq(Some(arr.len()))?; 190 | for i in arr { 191 | seq_ser.serialize_element(&ValueRef::new(i))?; 192 | } 193 | seq_ser.end() 194 | } 195 | Bool(b) => serializer.serialize_bool(b), 196 | Nil => serializer.serialize_none(), 197 | } 198 | } 199 | } 200 | 201 | struct BytesRef<'a>(&'a watson_rs::Bytes); 202 | 203 | impl<'a> Serialize for BytesRef<'a> { 204 | fn serialize(&self, serializer: S) -> Result 205 | where 206 | S: Serializer, 207 | { 208 | serializer.serialize_bytes(self.0) 209 | } 210 | } 211 | 212 | struct Bytes(watson_rs::Bytes); 213 | 214 | impl Bytes { 215 | fn into_bytes(self) -> watson_rs::Bytes { 216 | self.0 217 | } 218 | } 219 | 220 | impl<'de> Deserialize<'de> for Bytes { 221 | fn deserialize(deserializer: D) -> Result 222 | where 223 | D: Deserializer<'de>, 224 | { 225 | deserializer.deserialize_bytes(BytesVisitor) 226 | } 227 | } 228 | 229 | struct BytesVisitor; 230 | 231 | impl<'de> Visitor<'de> for BytesVisitor { 232 | type Value = Bytes; 233 | 234 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 235 | formatter.write_str("bytes") 236 | } 237 | 238 | fn visit_str(self, v: &str) -> Result 239 | where 240 | E: de::Error, 241 | { 242 | self.visit_bytes(v.as_bytes()) 243 | } 244 | 245 | fn visit_string(self, v: std::string::String) -> Result 246 | where 247 | E: de::Error, 248 | { 249 | self.visit_byte_buf(v.into_bytes()) 250 | } 251 | 252 | fn visit_bytes(self, v: &[u8]) -> Result 253 | where 254 | E: de::Error, 255 | { 256 | Ok(Bytes(v.to_vec())) 257 | } 258 | 259 | fn visit_byte_buf(self, v: Vec) -> Result 260 | where 261 | E: de::Error, 262 | { 263 | Ok(Bytes(v)) 264 | } 265 | } 266 | 267 | #[cfg(test)] 268 | mod test { 269 | use serde_test::{assert_tokens, Token}; 270 | use watson_rs::Map; 271 | use watson_rs::Value::*; 272 | 273 | use super::*; 274 | 275 | #[test] 276 | fn ser_de_int() { 277 | assert_tokens(&Value::new(Int(0)), &[Token::I64(0)]); 278 | assert_tokens(&Value::new(Int(123)), &[Token::I64(123)]); 279 | assert_tokens(&Value::new(Int(-123)), &[Token::I64(-123)]); 280 | } 281 | 282 | #[test] 283 | fn ser_de_uint() { 284 | assert_tokens(&Value::new(Uint(0)), &[Token::U64(0)]); 285 | assert_tokens(&Value::new(Uint(123)), &[Token::U64(123)]); 286 | assert_tokens( 287 | &Value::new(Uint(0xdead_beef_fefe_aaaa)), 288 | &[Token::U64(0xdead_beef_fefe_aaaa)], 289 | ); 290 | } 291 | 292 | #[test] 293 | fn ser_de_float() { 294 | assert_tokens(&Value::new(Float(0.0)), &[Token::F64(0.0)]); 295 | assert_tokens(&Value::new(Float(1.23e45)), &[Token::F64(1.23e45)]); 296 | assert_tokens(&Value::new(Float(6.78e-91)), &[Token::F64(6.78e-91)]); 297 | } 298 | 299 | #[test] 300 | fn ser_de_string() { 301 | assert_tokens(&Value::new(String(b"".to_vec())), &[Token::Bytes(b"")]); 302 | assert_tokens(&Value::new(String(b"a".to_vec())), &[Token::Bytes(b"a")]); 303 | assert_tokens( 304 | &Value::new(String(b"hello world!".to_vec())), 305 | &[Token::Bytes(b"hello world!")], 306 | ); 307 | } 308 | 309 | #[test] 310 | fn ser_de_object() { 311 | assert_tokens( 312 | &Value::new(Object(Map::new())), 313 | &[Token::Map { len: Some(0) }, Token::MapEnd], 314 | ); 315 | assert_tokens( 316 | &Value::new(Object( 317 | vec![(b"value".to_vec(), Int(123))].into_iter().collect(), 318 | )), 319 | &[ 320 | Token::Map { len: Some(1) }, 321 | Token::Bytes(b"value"), 322 | Token::I64(123), 323 | Token::MapEnd, 324 | ], 325 | ); 326 | } 327 | 328 | #[test] 329 | fn ser_de_array() { 330 | assert_tokens( 331 | &Value::new(Array(vec![])), 332 | &[Token::Seq { len: Some(0) }, Token::SeqEnd], 333 | ); 334 | assert_tokens( 335 | &Value::new(Array(vec![Int(123)])), 336 | &[Token::Seq { len: Some(1) }, Token::I64(123), Token::SeqEnd], 337 | ); 338 | assert_tokens( 339 | &Value::new(Array(vec![Int(123), String(b"hello".to_vec())])), 340 | &[ 341 | Token::Seq { len: Some(2) }, 342 | Token::I64(123), 343 | Token::Bytes(b"hello"), 344 | Token::SeqEnd, 345 | ], 346 | ); 347 | } 348 | 349 | #[test] 350 | fn ser_de_bool() { 351 | assert_tokens(&Value::new(Bool(true)), &[Token::Bool(true)]); 352 | assert_tokens(&Value::new(Bool(false)), &[Token::Bool(false)]); 353 | } 354 | 355 | #[test] 356 | fn ser_de_nil() { 357 | assert_tokens(&Value::new(Nil), &[Token::None]); 358 | } 359 | } 360 | -------------------------------------------------------------------------------- /watson_examples/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "watson_examples" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | watson_rs = { path = "../watson_rs" } 8 | serde_watson = { path = "../serde_watson" } 9 | serde = "1.0.138" -------------------------------------------------------------------------------- /watson_examples/examples/basic.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | use serde::Serialize; 4 | use serde_watson::ser::Serializer; 5 | 6 | #[derive(Serialize)] 7 | struct Transaction { 8 | id: u64, 9 | from: String, 10 | to: String, 11 | amount: f64, 12 | } 13 | 14 | fn main() -> serde_watson::Result<()> { 15 | let tx = Transaction { 16 | id: 0xabcd1234, 17 | from: "Motoaki Tanigo".to_owned(), 18 | to: "Oozora Subaru".to_owned(), 19 | amount: 123.45, 20 | }; 21 | let mut ser = Serializer::from_writer(io::stdout()); 22 | tx.serialize(&mut ser)?; 23 | Ok(()) 24 | } 25 | -------------------------------------------------------------------------------- /watson_examples/examples/run_vm.rs: -------------------------------------------------------------------------------- 1 | use watson_rs::vm::VM; 2 | use watson_rs::{Insn, Location, Token}; 3 | 4 | fn main() -> watson_rs::Result<()> { 5 | let mut vm = VM::new(); 6 | 7 | // Instructions are defined in https://github.com/genkami/watson/blob/main/doc/spec.md. 8 | vm.execute(token(Insn::Inew))?; // Push a signed integer `0` to the stack. 9 | vm.execute(token(Insn::Iinc))?; // Increment a value on the top of the stack. 10 | vm.execute(token(Insn::Ishl))?; // Shift a value on the top of the stack to the left by one bit. 11 | 12 | println!("result: {:?}", vm.peek_top().unwrap()); 13 | Ok(()) 14 | } 15 | 16 | fn token(insn: Insn) -> Token { 17 | Token { 18 | insn, 19 | location: Location::unknown(), 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /watson_rs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "watson_rs" 3 | version = "0.1.0" 4 | edition = "2021" 5 | authors = ["Genta Kamitani "] 6 | license = "Apache-2.0" 7 | description = "Rust implementation for Wasted but Amazing Turing-incomplete Stack-based Object Notation (WATSON)" 8 | repository = "https://github.com/genkami/watson-rs" 9 | categories = ["encoding"] 10 | 11 | [dependencies] 12 | 13 | [dev-dependencies] 14 | tempfile = "3" -------------------------------------------------------------------------------- /watson_rs/README.md: -------------------------------------------------------------------------------- 1 | # watson_rs 2 | [![Test](https://github.com/genkami/watson-rs/actions/workflows/test.yaml/badge.svg)](https://github.com/genkami/watson-rs/actions/workflows/test.yaml) 3 | [![watson_rs at crates.io](https://img.shields.io/crates/v/watson_rs.svg)](https://crates.io/crates/watson_rs) 4 | [![watson_rs at docs.rs](https://docs.rs/watson_rs/badge.svg)](https://docs.rs/watson_rs) 5 | 6 | 7 | A Rust implementation of [Wasted but Amazing Turing-incomplete Stack-based Object Notation (WATSON)](https://github.com/genkami/watson). 8 | 9 | ## Documentation 10 | * [Language specification](https://github.com/genkami/watson/blob/main/doc/spec.md) 11 | * [Original implementation](https://github.com/genkami/watson) 12 | 13 | ## Usage 14 | 15 | Add the following to your `Cargo.toml`: 16 | 17 | ```toml 18 | [dependencies] 19 | watson_rs = "0.1.0" 20 | ``` 21 | 22 | ## Examples 23 | 24 | ### Basic Usage (with serde_watson crate) 25 | 26 | ```rust 27 | use std::io; 28 | 29 | use serde::Serialize; 30 | use serde_watson::ser::Serializer; 31 | 32 | #[derive(Serialize)] 33 | struct Transaction { 34 | id: u64, 35 | from: String, 36 | to: String, 37 | amount: f64, 38 | } 39 | 40 | fn main() -> serde_watson::Result<()> { 41 | let tx = Transaction { 42 | id: 0xabcd1234, 43 | from: "Motoaki Tanigo".to_owned(), 44 | to: "Oozora Subaru".to_owned(), 45 | amount: 123.45, 46 | }; 47 | let mut ser = Serializer::from_writer(io::stdout()); 48 | tx.serialize(&mut ser)?; 49 | Ok(()) 50 | } 51 | ``` 52 | 53 | You can run the example above by running `cargo run --example basic` in the [watson_example](https://github.com/genkami/watson-rs/tree/main/watson_examples) directory. 54 | 55 | ``` 56 | $ cargo run --example basic 57 | Finished dev [unoptimized + debuginfo] target(s) in 0.08s 58 | Running `target/debug/examples/basic` 59 | ~?SShkShaaakShaaaaakShaaaaaak-SShaakShaaaaakShaaaaaak-SShaakShaaaakShaaaaakShaaa 60 | aaaaaakShaaaaaaaaaaaakShaaaaaaaaaaaaaaaakShaaaaaaaaaaaaaaaaaakShaaaaaaaaaaaaaaaa 61 | aaakShaaaaaaaaaaaaaaaaaaaaaakShaaaaaaaaaaaaaaaaaaaaaaakShaaaaaaaaaaaaaaaaaaaaaaa 62 | akShaaaaaaaaaaaaaaaaaaaaaaaaakShaaaaaaaaaaaaaaaaaaaaaaaaaaakShaaaaaaaaaaaaaaaaaa 63 | aaaaaaaaaaakShaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakig$BBubaBubbaBubbbbbaBubbbbbba!BBu 64 | baBubbbbaBubbbbbaBubbbbbba!BBuaBubaBubbaBubbbaBubbbbbaBubbbbbba!BBuaBubbaBubbbaB 65 | ubbbbbaBubbbbbba!?SShkShaakShaaakShaaaaaak-SShkShakShaakShaaakShaaaaakShaaaaaak- 66 | SShaakShaaaakShaaaaakShaaaaaak-SShkShakShaakShaaakShaaaaakShaaaaaak-SShkShaaaaak 67 | Shaaaaaak-SShkShakShaaakShaaaaakShaaaaaak-SShkShaaakShaaaaakShaaaaaak-SShaaaaak- 68 | SShaakShaaaakShaaaaaak-SShkShaaaaakShaaaaaak-SShakShaakShaaakShaaaaakShaaaaaak-S 69 | ShkShaaakShaaaaakShaaaaaak-SShkShakShaakShaaaaakShaaaaaak-SShkShakShaakShaaakSha 70 | aaaakShaaaaaak-g$BBubbaBubbbbaBubbbbbaBubbbbbba!BBuaBubaBubbaBubbbaBubbbbbaBubbb 71 | bbba!?SShkShakShaakShaaakShaaaaaak-SShkShakShaakShaaakShaaaaakShaaaaaak-SShakSha 72 | aakShaaaakShaaaaakShaaaaaak-SShkShakShaakShaaakShaaaaakShaaaaaak-SShakShaaaakSha 73 | aaaakShaaaaaak-SShkShaaaaakShaaaaaak-SShaaaaak-SShkShakShaaaakShaaaaaak-SShkShaa 74 | kShaaaakShaaaaakShaaaaaak-SShakShaaaaakShaaaaaak-SShkShaaaaakShaaaaaak-SShakShaa 75 | aakShaaaaakShaaaaaak-SShkShaakShaaaakShaaaaakShaaaaaak-g$BBuaBubbbbbaBubbbbbba!B 76 | BuaBubbaBubbbaBubbbbbaBubbbbbba!BBuaBubaBubbaBubbbaBubbbbbaBubbbbbba!BBuaBubbaBu 77 | bbbbaBubbbbbaBubbbbbba!BBubaBubbaBubbbaBubbbbbaBubbbbbba!BBubbaBubbbbaBubbbbbaBu 78 | bbbbbba!BBuaBubbaBubbbaBubbbbbbaBubbbbbbbaBubbbbbbbbbbaBubbbbbbbbbbbaBubbbbbbbbb 79 | bbbbbaBubbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbb 80 | bbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbb 81 | bbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbbb 82 | bbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaB 83 | ubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 84 | baBubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 85 | bbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbb 86 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaB 87 | ubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbb 88 | bbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaBu 89 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbb 90 | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbaBubbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 91 | bbbbbbbbbbbbbbaiM 92 | ``` 93 | 94 | You can verify the output using the [WATSON CLI](https://github.com/genkami/watson/blob/main/doc/cli.md). 95 | 96 | ``` 97 | $ cargo run --example basic | watson decode -t json 98 | Finished dev [unoptimized + debuginfo] target(s) in 0.05s 99 | Running `target/debug/examples/basic` 100 | {"amount":123.45,"from":"Motoaki Tanigo","id":2882343476,"to":"Oozora Subaru"} 101 | ``` 102 | 103 | ### Run a WATSON VM directly 104 | 105 | You can run a WATSON Virtual Machine directly by using this crate: 106 | 107 | ```rust 108 | use watson_rs::vm::VM; 109 | use watson_rs::{Insn, Location, Token}; 110 | 111 | fn main() -> watson_rs::Result<()> { 112 | let mut vm = VM::new(); 113 | 114 | // Instructions are defined in https://github.com/genkami/watson/blob/main/doc/spec.md. 115 | vm.execute(token(Insn::Inew))?; // Push a signed integer `0` to the stack. 116 | vm.execute(token(Insn::Iinc))?; // Increment a value on the top of the stack. 117 | vm.execute(token(Insn::Ishl))?; // Shift a value on the top of the stack to the left by one bit. 118 | 119 | println!("result: {:?}", vm.peek_top().unwrap()); 120 | Ok(()) 121 | } 122 | 123 | fn token(insn: Insn) -> Token { 124 | Token { 125 | insn: insn, 126 | location: Location::unknown(), 127 | } 128 | } 129 | ``` 130 | 131 | 132 | You can run the example above by running `cargo run --example run_vm` in the [watson_example](https://github.com/genkami/watson-rs/tree/main/watson_examples) directory. 133 | 134 | ``` 135 | $ cargo run --example run_vm 136 | Finished dev [unoptimized + debuginfo] target(s) in 0.12s 137 | Running `target/debug/examples/run_vm` 138 | result: Int(2) 139 | ``` -------------------------------------------------------------------------------- /watson_rs/src/error.rs: -------------------------------------------------------------------------------- 1 | use std::error; 2 | use std::fmt; 3 | use std::io; 4 | 5 | use crate::language::Location; 6 | 7 | /// The error type of the WATSON VM. 8 | #[derive(Debug)] 9 | pub struct Error { 10 | /// Represents details of the error. 11 | pub kind: ErrorKind, 12 | 13 | /// The location where the error happened. 14 | pub location: Location, 15 | 16 | /// The internal error that causes this error. 17 | pub source: Option>, 18 | } 19 | 20 | /// Details of the `Error`. 21 | #[derive(Eq, PartialEq, Copy, Clone, Debug)] 22 | pub enum ErrorKind { 23 | /// The VM tried to pop values from an empty stack. 24 | EmptyStack, 25 | 26 | /// The type of the value on the top of stack is different from the one that the instruction wants. 27 | TypeMismatch, 28 | 29 | /// An I/O error happened. 30 | IOError, 31 | } 32 | 33 | pub type Result = std::result::Result; 34 | 35 | impl Error { 36 | /// Creates a new `Error` caused by the given `io::Error`. 37 | pub fn from_io_error(e: io::Error, location: Location) -> Self { 38 | Error { 39 | kind: ErrorKind::IOError, 40 | location, 41 | source: Some(Box::new(e)), 42 | } 43 | } 44 | } 45 | 46 | impl fmt::Display for Error { 47 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 48 | write!(f, "{} at {}", self.kind, self.location) 49 | } 50 | } 51 | 52 | impl fmt::Display for ErrorKind { 53 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 54 | let msg = match self { 55 | ErrorKind::EmptyStack => "Empty stack", 56 | ErrorKind::TypeMismatch => "Type mismatch", 57 | ErrorKind::IOError => "I/O error", 58 | }; 59 | write!(f, "{msg}") 60 | } 61 | } 62 | 63 | impl std::error::Error for Error { 64 | fn source(&self) -> Option<&(dyn error::Error + 'static)> { 65 | self.source.as_deref() 66 | } 67 | } 68 | 69 | impl From for Error { 70 | fn from(e: io::Error) -> Self { 71 | Error::from_io_error(e, Location::unknown()) 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /watson_rs/src/language/conversion.rs: -------------------------------------------------------------------------------- 1 | use super::*; 2 | use Value::*; 3 | 4 | macro_rules! impl_from_int_for_value { 5 | ( $( $t:ty ),* ) => { 6 | $( 7 | impl From<$t> for Value { 8 | fn from(v: $t) -> Value { 9 | Int(v as i64) 10 | } 11 | } 12 | )* 13 | }; 14 | } 15 | 16 | impl_from_int_for_value!(i8, i16, i32, i64, i128, isize); 17 | 18 | macro_rules! impl_from_uint_for_value { 19 | ( $( $t:ty ),* ) => { 20 | $( 21 | impl From<$t> for Value { 22 | fn from(v: $t) -> Value { 23 | Uint(v as u64) 24 | } 25 | } 26 | )* 27 | }; 28 | } 29 | 30 | impl_from_uint_for_value!(u8, u16, u32, u64, u128, usize); 31 | 32 | macro_rules! impl_from_float_for_value { 33 | ( $( $t:ty ),* ) => { 34 | $( 35 | impl From<$t> for Value { 36 | fn from(v: $t) -> Value { 37 | Float(v as f64) 38 | } 39 | } 40 | )* 41 | }; 42 | } 43 | 44 | impl_from_float_for_value!(f32, f64); 45 | 46 | impl From for Value { 47 | fn from(v: Bytes) -> Value { 48 | String(v) 49 | } 50 | } 51 | 52 | impl From for Value { 53 | fn from(v: std::string::String) -> Value { 54 | String(v.into_bytes()) 55 | } 56 | } 57 | 58 | impl From for Value { 59 | fn from(v: Map) -> Value { 60 | Object(v) 61 | } 62 | } 63 | 64 | impl From> for Value { 65 | fn from(v: Vec) -> Value { 66 | Array(v) 67 | } 68 | } 69 | 70 | impl From for Value { 71 | fn from(v: bool) -> Value { 72 | Bool(v) 73 | } 74 | } 75 | 76 | impl From<()> for Value { 77 | fn from(_: ()) -> Value { 78 | Nil 79 | } 80 | } 81 | 82 | /// A type that can be converted directly from and to `Value`. 83 | /// This is different from From and Into in that the values of these these types are "identical" to `Value`. 84 | pub trait IsValue: Into { 85 | /// Converts a `Value` into its expected type. 86 | fn from_value(v: Value) -> Option; 87 | 88 | /// Converts self into a `Value`. 89 | fn into_value(self) -> Value { 90 | self.into() 91 | } 92 | } 93 | 94 | impl IsValue for Value { 95 | fn from_value(v: Value) -> Option { 96 | Some(v) 97 | } 98 | } 99 | 100 | impl IsValue for i64 { 101 | fn from_value(v: Value) -> Option { 102 | match v { 103 | Int(i) => Some(i), 104 | _ => None, 105 | } 106 | } 107 | } 108 | 109 | impl IsValue for u64 { 110 | fn from_value(v: Value) -> Option { 111 | match v { 112 | Uint(u) => Some(u), 113 | _ => None, 114 | } 115 | } 116 | } 117 | 118 | impl IsValue for f64 { 119 | fn from_value(v: Value) -> Option { 120 | match v { 121 | Float(f) => Some(f), 122 | _ => None, 123 | } 124 | } 125 | } 126 | 127 | impl IsValue for Bytes { 128 | fn from_value(v: Value) -> Option { 129 | match v { 130 | String(s) => Some(s), 131 | _ => None, 132 | } 133 | } 134 | } 135 | 136 | impl IsValue for Map { 137 | fn from_value(v: Value) -> Option { 138 | match v { 139 | Object(o) => Some(o), 140 | _ => None, 141 | } 142 | } 143 | } 144 | 145 | impl IsValue for Vec { 146 | fn from_value(v: Value) -> Option> { 147 | match v { 148 | Array(a) => Some(a), 149 | _ => None, 150 | } 151 | } 152 | } 153 | 154 | impl IsValue for bool { 155 | fn from_value(v: Value) -> Option { 156 | match v { 157 | Bool(b) => Some(b), 158 | _ => None, 159 | } 160 | } 161 | } 162 | 163 | impl IsValue for () { 164 | fn from_value(v: Value) -> Option<()> { 165 | match v { 166 | Nil => Some(()), 167 | _ => None, 168 | } 169 | } 170 | } 171 | 172 | /// A type that can be converted to `Bytes`. 173 | pub trait ToBytes { 174 | /// Converts `self` to `Bytes`. 175 | fn to_bytes(self) -> Bytes; 176 | } 177 | 178 | impl ToBytes for Bytes { 179 | fn to_bytes(self) -> Bytes { 180 | self 181 | } 182 | } 183 | 184 | impl<'a> ToBytes for &'a Bytes { 185 | fn to_bytes(self) -> Bytes { 186 | self.to_vec() 187 | } 188 | } 189 | 190 | impl ToBytes for char { 191 | fn to_bytes(self) -> Bytes { 192 | let mut buf = [0; 4]; 193 | let len = self.encode_utf8(&mut buf).len(); 194 | buf[..len].to_bytes() 195 | } 196 | } 197 | 198 | impl ToBytes for std::string::String { 199 | fn to_bytes(self) -> Bytes { 200 | self.into_bytes() 201 | } 202 | } 203 | 204 | impl<'a> ToBytes for &'a str { 205 | fn to_bytes(self) -> Bytes { 206 | self.as_bytes().to_vec() 207 | } 208 | } 209 | 210 | impl ToBytes for u8 { 211 | fn to_bytes(self) -> Bytes { 212 | vec![self] 213 | } 214 | } 215 | 216 | impl<'a> ToBytes for &'a [u8] { 217 | fn to_bytes(self) -> Bytes { 218 | self.to_vec() 219 | } 220 | } 221 | 222 | impl<'a, const N: usize> ToBytes for &'a [u8; N] { 223 | fn to_bytes(self) -> Bytes { 224 | self.to_vec() 225 | } 226 | } 227 | -------------------------------------------------------------------------------- /watson_rs/src/language/mod.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | use std::path; 3 | use std::rc::Rc; 4 | 5 | mod conversion; 6 | 7 | pub use self::conversion::{IsValue, ToBytes}; 8 | 9 | macro_rules! define_insn { 10 | ( $( ($name:ident, $achar:expr, $schar:expr) ),* ) => { 11 | /// An instruction of the WATSON Virtual Machine. 12 | /// See [the specification](https://github.com/genkami/watson/blob/main/doc/spec.md) for more details. 13 | #[derive(Eq, PartialEq, Clone, Copy, Hash, Debug)] 14 | pub enum Insn { 15 | $( $name ),* 16 | } 17 | 18 | impl Insn { 19 | /// Returns an iterator that iterates over all instructions. 20 | pub fn all() -> impl Iterator { 21 | [$( Insn::$name ),* ].into_iter() 22 | } 23 | 24 | /// Converts a byte representation into corresponding `Insn`. 25 | /// Which byte is converted to which insn depends on `Mode`. 26 | pub fn from_byte(mode: Mode, byte: u8) -> Option { 27 | match mode { 28 | Mode::A => Insn::from_byte_a(byte), 29 | Mode::S => Insn::from_byte_s(byte), 30 | } 31 | } 32 | 33 | /// Converts itself into its byte representation. 34 | /// Which insn is converted to which byte depends on `Mode`. 35 | pub fn into_byte(self, mode: Mode) -> u8 { 36 | match mode { 37 | Mode::A => self.into_byte_a(), 38 | Mode::S => self.into_byte_s(), 39 | } 40 | } 41 | 42 | fn from_byte_a(byte: u8) -> Option { 43 | match byte { 44 | $( 45 | $achar => Some(Insn::$name), 46 | )* 47 | _ => None, 48 | } 49 | } 50 | 51 | fn from_byte_s(byte: u8) -> Option { 52 | match byte { 53 | $( 54 | $schar => Some(Insn::$name), 55 | )* 56 | _ => None, 57 | } 58 | } 59 | 60 | fn into_byte_a(self) -> u8 { 61 | match self { 62 | $( 63 | Insn::$name => $achar 64 | ),* 65 | } 66 | } 67 | 68 | fn into_byte_s(self) -> u8 { 69 | match self { 70 | $( 71 | Insn::$name => $schar 72 | ),* 73 | } 74 | } 75 | } 76 | }; 77 | ( $( ($name:ident, $achar:expr, $schar:expr) ),* ,) => { 78 | define_insn!( $( ($name, $achar, $schar) ),* ); 79 | } 80 | } 81 | 82 | /// A byte array. 83 | pub type Bytes = Vec; 84 | 85 | /// A type corresponding to WATSON Object. 86 | pub type Map = std::collections::HashMap; 87 | 88 | /// A value that is defined in WATSON specification. 89 | /// See [the specification](https://github.com/genkami/watson/blob/main/doc/spec.md) for more details. 90 | #[derive(PartialEq, Clone, Debug)] 91 | pub enum Value { 92 | Int(i64), 93 | Uint(u64), 94 | Float(f64), 95 | String(Bytes), 96 | Object(Map), 97 | Array(Vec), 98 | Bool(bool), 99 | Nil, 100 | } 101 | 102 | define_insn! { 103 | (Inew, b'B', b'S'), 104 | (Iinc, b'u', b'h'), 105 | (Ishl, b'b', b'a'), 106 | (Iadd, b'a', b'k'), 107 | (Ineg, b'A', b'r'), 108 | (Isht, b'e', b'A'), 109 | (Itof, b'i', b'z'), 110 | (Itou, b'\'', b'i'), 111 | (Finf, b'q', b'm'), 112 | (Fnan, b't', b'b'), 113 | (Fneg, b'p', b'u'), 114 | (Snew, b'?', b'$'), 115 | (Sadd, b'!', b'-'), 116 | (Onew, b'~', b'+'), 117 | (Oadd, b'M', b'g'), 118 | (Anew, b'@', b'v'), 119 | (Aadd, b's', b'?'), 120 | (Bnew, b'z', b'^'), 121 | (Bneg, b'o', b'!'), 122 | (Nnew, b'.', b'y'), 123 | (Gdup, b'E', b'/'), 124 | (Gpop, b'#', b'e'), 125 | (Gswp, b'%', b':'), 126 | } 127 | 128 | /// A token of the WATSON language. 129 | #[derive(Eq, PartialEq, Clone, Debug)] 130 | pub struct Token { 131 | /// A VM instruction that the token represents. 132 | pub insn: Insn, 133 | 134 | /// Location of the instruction. 135 | pub location: Location, 136 | } 137 | 138 | /// Location where an error happened. 139 | #[derive(Eq, PartialEq, Clone, Debug)] 140 | pub struct Location { 141 | /// A byte that the WATSON VM read. 142 | pub byte: u8, 143 | 144 | /// Optional file path. 145 | pub path: Option>, 146 | 147 | /// Line number. 148 | pub line: usize, 149 | 150 | /// Column number. 151 | pub column: usize, 152 | } 153 | 154 | impl fmt::Display for Location { 155 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 156 | match self.path.as_ref() { 157 | Some(p) => { 158 | write!(f, "{}", p.to_string_lossy())?; 159 | } 160 | None => { 161 | write!(f, "unknown file")?; 162 | } 163 | } 164 | write!(f, " (line: {}, column: {})", self.line, self.column)?; 165 | if let Some(c) = char::from_u32(self.byte as u32) { 166 | write!(f, ", near the character {c}")?; 167 | } 168 | Ok(()) 169 | } 170 | } 171 | 172 | impl Location { 173 | pub fn unknown() -> Self { 174 | Location { 175 | byte: 0, 176 | path: None, 177 | line: 0, 178 | column: 0, 179 | } 180 | } 181 | } 182 | 183 | /// A "mode" of the WATSON lexer. 184 | /// See [the specification](https://github.com/genkami/watson/blob/main/doc/spec.md) for more details. 185 | #[derive(Eq, PartialEq, Ord, PartialOrd, Copy, Clone, Debug)] 186 | pub enum Mode { 187 | /// The A mode. 188 | A, 189 | /// The S mode. 190 | S, 191 | } 192 | 193 | impl Mode { 194 | /// Returns the opposite state. 195 | pub fn flip(self) -> Mode { 196 | match self { 197 | Mode::A => Mode::S, 198 | Mode::S => Mode::A, 199 | } 200 | } 201 | } 202 | 203 | /// Creates an array `Value` consisting of the arguments. 204 | #[macro_export] 205 | macro_rules! array { 206 | // To suppress unused_mut. 207 | () => { 208 | $crate::language::Value::Array(std::vec::Vec::new()) 209 | }; 210 | ( $( $elem:expr ),* $(,)? ) => {{ 211 | let mut vec = std::vec::Vec::new(); 212 | $( 213 | vec.push($elem); 214 | )* 215 | $crate::language::Value::Array(vec) 216 | }} 217 | } 218 | 219 | #[macro_export] 220 | #[doc(hidden)] 221 | macro_rules! object_key { 222 | ($key:ident) => { 223 | $crate::language::ToBytes::to_bytes(stringify!($key)) 224 | }; 225 | ([ $key:expr ]) => { 226 | $crate::language::ToBytes::to_bytes($key) 227 | }; 228 | } 229 | 230 | /// Creates an object `Value` consisting of the given key-value pairs. 231 | /// The key must be an identifier or an expression that implements `ToBytes` surrounded by `[` and `]`. 232 | /// The value must be any expression of type `Value`. 233 | #[macro_export] 234 | macro_rules! object { 235 | // To suppress unused_mut. 236 | () => { 237 | $crate::language::Value::Object($crate::language::Map::new()) 238 | }; 239 | ( $( $key:tt : $value:expr ),* $(,)? ) => {{ 240 | let mut map = $crate::language::Map::new(); 241 | $( 242 | map.insert($crate::object_key!($key), $value); 243 | )* 244 | $crate::language::Value::Object(map) 245 | }}; 246 | } 247 | 248 | #[cfg(test)] 249 | mod test { 250 | use super::*; 251 | use Value::*; 252 | 253 | // 0x21 to 0x7E 254 | const ASCII_CHARS: std::ops::RangeInclusive = b'!'..=b'~'; 255 | 256 | #[test] 257 | fn insn_from_byte_is_surjective() { 258 | fn assert_surjective(mode: Mode) { 259 | use std::collections::HashSet; 260 | 261 | let mut insns = Insn::all().collect::>(); 262 | for c in ASCII_CHARS { 263 | Insn::from_byte(mode, c).map(|insn| insns.remove(&insn)); 264 | } 265 | for insn in insns { 266 | panic!( 267 | "mode={:?}: instruction {:?} does not have matching byte characters", 268 | mode, insn 269 | ); 270 | } 271 | } 272 | 273 | assert_surjective(Mode::A); 274 | assert_surjective(Mode::S); 275 | } 276 | 277 | #[test] 278 | fn insn_from_byte_is_injective() { 279 | fn assert_injective(mode: Mode) { 280 | use std::collections::HashMap; 281 | 282 | let mut reversed = HashMap::new(); 283 | for c in ASCII_CHARS { 284 | Insn::from_byte(mode, c).map(|insn| match reversed.get(&insn) { 285 | None => { 286 | reversed.insert(insn, c); 287 | } 288 | Some(d) => { 289 | panic!( 290 | "mode={:?}: both {:?} and {:?} are converted into {:?}", 291 | mode, c, d, insn 292 | ); 293 | } 294 | }); 295 | } 296 | } 297 | 298 | assert_injective(Mode::A); 299 | assert_injective(Mode::S); 300 | } 301 | 302 | #[test] 303 | fn insn_into_byte_is_injective() { 304 | fn assert_injective(mode: Mode) { 305 | use std::collections::HashMap; 306 | 307 | let mut reversed = HashMap::new(); 308 | for i in Insn::all() { 309 | let c = i.into_byte(mode); 310 | match reversed.get(&c) { 311 | None => { 312 | reversed.insert(c, i); 313 | } 314 | Some(j) => { 315 | panic!( 316 | "mode={:?}: both {:?} and {:?} are converted into {:?}", 317 | mode, i, j, c 318 | ); 319 | } 320 | } 321 | } 322 | } 323 | 324 | assert_injective(Mode::A); 325 | assert_injective(Mode::S); 326 | } 327 | 328 | #[test] 329 | fn array_macro() { 330 | assert_eq!(array![], Array(vec![])); 331 | assert_eq!(array![Int(123)], Array(vec![Int(123)])); 332 | assert_eq!( 333 | array![Int(123), Bool(false), array![Uint(456)]], 334 | Array(vec![Int(123), Bool(false), Array(vec![Uint(456)])]) 335 | ); 336 | assert_eq!( 337 | array![ 338 | Int(123), 339 | Bool(false), 340 | array![Uint(456)], // trailing comma 341 | ], 342 | Array(vec![Int(123), Bool(false), Array(vec![Uint(456)])]) 343 | ) 344 | } 345 | 346 | #[test] 347 | fn object_macro() { 348 | assert_eq!(object![], Object([].into_iter().collect())); 349 | assert_eq!( 350 | object![x: Int(1)], 351 | Object([(b"x".to_vec(), Int(1))].into_iter().collect()) 352 | ); 353 | assert_eq!( 354 | object![[b"y"]: Int(1)], 355 | Object([(b"y".to_vec(), Int(1))].into_iter().collect()) 356 | ); 357 | assert_eq!( 358 | object![x: Int(1), y: Bool(true), ['ぬ']: object![nested: Nil]], 359 | Object( 360 | [ 361 | (b"x".to_vec(), Int(1)), 362 | (b"y".to_vec(), Bool(true)), 363 | ( 364 | "ぬ".to_string().into_bytes(), 365 | Object([(b"nested".to_vec(), Nil)].into_iter().collect()) 366 | ) 367 | ] 368 | .into_iter() 369 | .collect() 370 | ) 371 | ); 372 | assert_eq!( 373 | object![ 374 | x: Int(1), y: Bool(true), z: object![nested: Nil], // trailing comma 375 | ], 376 | Object( 377 | [ 378 | (b"x".to_vec(), Int(1)), 379 | (b"y".to_vec(), Bool(true)), 380 | ( 381 | b"z".to_vec(), 382 | Object([(b"nested".to_vec(), Nil)].into_iter().collect()) 383 | ) 384 | ] 385 | .into_iter() 386 | .collect() 387 | ) 388 | ); 389 | } 390 | } 391 | -------------------------------------------------------------------------------- /watson_rs/src/lexer.rs: -------------------------------------------------------------------------------- 1 | use std::fs; 2 | use std::io; 3 | use std::path; 4 | use std::rc::Rc; 5 | 6 | use crate::error::{Error, Result}; 7 | use crate::language::{Insn, Location, Mode, Token}; 8 | use crate::vm::ReadToken; 9 | 10 | /// A lexer of the WATSON language. 11 | pub struct Lexer { 12 | bytes: io::Bytes, 13 | 14 | mode: Mode, 15 | 16 | last_read_byte: u8, 17 | file_path: Option>, 18 | line: usize, 19 | column: usize, 20 | } 21 | 22 | /// Config configures a `Lexer`. 23 | pub struct Config { 24 | // Initial mode of a `Lexer` (defaults to `A` by the specificaton). 25 | pub initial_mode: Mode, 26 | 27 | // File path to display (not used to open a file or something). 28 | pub file_path: Option>, 29 | } 30 | 31 | impl Default for Config { 32 | fn default() -> Config { 33 | Config { 34 | initial_mode: Mode::A, 35 | file_path: None, 36 | } 37 | } 38 | } 39 | 40 | impl Config { 41 | /// Returns a new `Lexer` that reads from the given reader. 42 | pub fn build(self, reader: R) -> Lexer { 43 | Lexer { 44 | bytes: reader.bytes(), 45 | mode: self.initial_mode, 46 | last_read_byte: 0, 47 | file_path: self.file_path, 48 | line: 1, 49 | column: 0, 50 | } 51 | } 52 | 53 | /// Opens a file and builds a `Lexer` that reads from the given file. 54 | pub fn open(mut self, path: &path::Path) -> Result> { 55 | let file = fs::File::open(path)?; 56 | if self.file_path.is_none() { 57 | self.file_path = Some(path.to_path_buf().into()); 58 | } 59 | Ok(self.build(file)) 60 | } 61 | } 62 | 63 | impl Lexer { 64 | /// Opens a file and builds a `Lexer` with the default configuration. 65 | pub fn open(path: &path::Path) -> Result { 66 | Config::default().open(path) 67 | } 68 | } 69 | 70 | impl Lexer { 71 | /// Returns a new `Lexer` with the default configuration. 72 | pub fn new(reader: R) -> Self { 73 | Config::default().build(reader) 74 | } 75 | 76 | /// Returns the next byte. 77 | /// EOF is mapped to `Ok(None)`. 78 | fn next_byte(&mut self) -> Result> { 79 | match self.bytes.next() { 80 | None => Ok(None), 81 | Some(byte) => { 82 | let byte = byte.map_err(|e| Error::from_io_error(e, self.current_location()))?; 83 | self.last_read_byte = byte; 84 | if byte == b'\n' { 85 | self.line += 1; 86 | self.column = 0; 87 | } else { 88 | self.column += 1; 89 | } 90 | Ok(Some(byte)) 91 | } 92 | } 93 | } 94 | 95 | fn current_location(&self) -> Location { 96 | Location { 97 | byte: self.last_read_byte, 98 | path: self.file_path.as_ref().map(Rc::clone), 99 | line: self.line, 100 | column: self.column, 101 | } 102 | } 103 | 104 | fn advance_state(&mut self, insn: Insn) { 105 | // See https://github.com/genkami/watson/blob/main/doc/spec.md#watson-representation. 106 | if insn == Insn::Snew { 107 | self.mode = self.mode.flip(); 108 | } 109 | } 110 | } 111 | 112 | impl ReadToken for Lexer { 113 | /// Returns a next token if exists. 114 | fn read(&mut self) -> Result> { 115 | let token: Token; 116 | loop { 117 | let byte = self.next_byte()?; 118 | match byte { 119 | None => { 120 | return Ok(None); 121 | } 122 | Some(byte) => match Insn::from_byte(self.mode, byte) { 123 | None => { 124 | continue; 125 | } 126 | Some(insn) => { 127 | token = Token { 128 | insn, 129 | location: Location { 130 | byte, 131 | path: self.file_path.clone(), 132 | line: self.line, 133 | column: self.column, 134 | }, 135 | }; 136 | self.advance_state(token.insn); 137 | return Ok(Some(token)); 138 | } 139 | }, 140 | } 141 | } 142 | } 143 | } 144 | 145 | #[cfg(test)] 146 | mod test { 147 | use super::*; 148 | 149 | #[test] 150 | fn lexer_new_initial_mode_defaults_to_a() { 151 | let bytes = b"Bubba".to_vec(); 152 | let mut lexer = Lexer::new(&bytes[..]); 153 | assert_eq!( 154 | lexer.read().unwrap(), 155 | Some(Token { 156 | insn: Insn::Inew, 157 | location: Location { 158 | byte: b'B', 159 | path: None, 160 | line: 1, 161 | column: 1, 162 | }, 163 | }), 164 | ); 165 | } 166 | 167 | #[test] 168 | fn lexer_new_initial_mode_can_be_overridden() { 169 | let bytes = b"Shaak".to_vec(); 170 | let mut conf = Config::default(); 171 | conf.initial_mode = Mode::S; 172 | let mut lexer = conf.build(&bytes[..]); 173 | assert_eq!( 174 | lexer.read().unwrap(), 175 | Some(Token { 176 | insn: Insn::Inew, 177 | location: Location { 178 | byte: b'S', 179 | path: None, 180 | line: 1, 181 | column: 1, 182 | }, 183 | }), 184 | ); 185 | } 186 | 187 | #[test] 188 | fn lexer_new_file_path_defaults_to_none() { 189 | let bytes = b"Bubba".to_vec(); 190 | let mut lexer = Lexer::new(&bytes[..]); 191 | assert_eq!( 192 | lexer.read().unwrap(), 193 | Some(Token { 194 | insn: Insn::Inew, 195 | location: Location { 196 | byte: b'B', 197 | path: None, 198 | line: 1, 199 | column: 1, 200 | }, 201 | }), 202 | ); 203 | } 204 | 205 | #[test] 206 | fn lexer_file_path_can_be_overridden() { 207 | let bytes = b"Bubba".to_vec(); 208 | let path = path::Path::new("test.watson"); 209 | let mut conf = Config::default(); 210 | conf.file_path = Some(path.to_path_buf().into()); 211 | let mut lexer = conf.build(&bytes[..]); 212 | assert_eq!( 213 | lexer.read().unwrap(), 214 | Some(Token { 215 | insn: Insn::Inew, 216 | location: Location { 217 | byte: b'B', 218 | path: Some(path.to_path_buf().into()), 219 | line: 1, 220 | column: 1, 221 | }, 222 | }), 223 | ); 224 | } 225 | 226 | #[test] 227 | fn lexer_open_opens_a_file() -> Result<()> { 228 | use std::io::Write; 229 | use tempfile::NamedTempFile; 230 | 231 | let mut tempfile = NamedTempFile::new()?; 232 | tempfile.write_all(b"Bubba")?; 233 | let path = tempfile.into_temp_path(); 234 | 235 | let mut lexer = Lexer::open(&path)?; 236 | assert_eq!( 237 | lexer.read()?, 238 | Some(Token { 239 | insn: Insn::Inew, 240 | location: Location { 241 | byte: b'B', 242 | path: Some(path.to_path_buf().into()), 243 | line: 1, 244 | column: 1, 245 | }, 246 | }), 247 | ); 248 | Ok(()) 249 | } 250 | 251 | #[test] 252 | fn lexer_open_path_can_be_overridden() -> Result<()> { 253 | use std::io::Write; 254 | use tempfile::NamedTempFile; 255 | 256 | let mut tempfile = NamedTempFile::new()?; 257 | tempfile.write_all(b"Bubba")?; 258 | let path = tempfile.into_temp_path(); 259 | let path_to_display = path::Path::new("anothername.watson"); 260 | 261 | let mut conf = Config::default(); 262 | conf.file_path = Some(path_to_display.to_path_buf().into()); 263 | let mut lexer = conf.open(&path)?; 264 | assert_eq!( 265 | lexer.read()?, 266 | Some(Token { 267 | insn: Insn::Inew, 268 | location: Location { 269 | byte: b'B', 270 | path: Some(path_to_display.to_path_buf().into()), 271 | line: 1, 272 | column: 1, 273 | }, 274 | }), 275 | ); 276 | Ok(()) 277 | } 278 | 279 | #[test] 280 | fn lexer_advances_column_and_line() { 281 | let bytes = b"Bub\nba".to_vec(); 282 | let mut lexer = Lexer::new(&bytes[..]); 283 | assert_eq!( 284 | lexer.read().unwrap(), 285 | Some(Token { 286 | insn: Insn::Inew, 287 | location: Location { 288 | byte: b'B', 289 | path: None, 290 | line: 1, 291 | column: 1, 292 | }, 293 | }), 294 | ); 295 | assert_eq!( 296 | lexer.read().unwrap(), 297 | Some(Token { 298 | insn: Insn::Iinc, 299 | location: Location { 300 | byte: b'u', 301 | path: None, 302 | line: 1, 303 | column: 2, 304 | }, 305 | }), 306 | ); 307 | assert_eq!( 308 | lexer.read().unwrap(), 309 | Some(Token { 310 | insn: Insn::Ishl, 311 | location: Location { 312 | byte: b'b', 313 | path: None, 314 | line: 1, 315 | column: 3, 316 | }, 317 | }), 318 | ); 319 | 320 | // lexer hits \n here 321 | assert_eq!( 322 | lexer.read().unwrap(), 323 | Some(Token { 324 | insn: Insn::Ishl, 325 | location: Location { 326 | byte: b'b', 327 | path: None, 328 | line: 2, 329 | column: 1, 330 | }, 331 | }), 332 | ); 333 | assert_eq!( 334 | lexer.read().unwrap(), 335 | Some(Token { 336 | insn: Insn::Iadd, 337 | location: Location { 338 | byte: b'a', 339 | path: None, 340 | line: 2, 341 | column: 2, 342 | }, 343 | }), 344 | ); 345 | } 346 | 347 | #[test] 348 | fn lexer_returns_none_when_eof() { 349 | let bytes = b"Bub".to_vec(); 350 | let mut lexer = Lexer::new(&bytes[..]); 351 | 352 | assert_eq!(lexer.read().unwrap().unwrap().insn, Insn::Inew); 353 | assert_eq!(lexer.read().unwrap().unwrap().insn, Insn::Iinc); 354 | assert_eq!(lexer.read().unwrap().unwrap().insn, Insn::Ishl); 355 | assert_eq!(lexer.read().unwrap(), None); 356 | } 357 | 358 | #[test] 359 | fn lexer_changes_mode() { 360 | let bytes = b"Bu?Sh$B".to_vec(); 361 | let mut lexer = Lexer::new(&bytes[..]); 362 | assert_eq!( 363 | lexer.read().unwrap(), 364 | Some(Token { 365 | insn: Insn::Inew, 366 | location: Location { 367 | byte: b'B', 368 | path: None, 369 | line: 1, 370 | column: 1, 371 | }, 372 | }), 373 | ); 374 | assert_eq!( 375 | lexer.read().unwrap(), 376 | Some(Token { 377 | insn: Insn::Iinc, 378 | location: Location { 379 | byte: b'u', 380 | path: None, 381 | line: 1, 382 | column: 2, 383 | }, 384 | }), 385 | ); 386 | assert_eq!( 387 | lexer.read().unwrap(), 388 | Some(Token { 389 | insn: Insn::Snew, 390 | location: Location { 391 | byte: b'?', 392 | path: None, 393 | line: 1, 394 | column: 3, 395 | }, 396 | }), 397 | ); 398 | 399 | // Lexer hits `Onew`, so it changes its mode to `S`. 400 | assert_eq!( 401 | lexer.read().unwrap(), 402 | Some(Token { 403 | insn: Insn::Inew, 404 | location: Location { 405 | byte: b'S', 406 | path: None, 407 | line: 1, 408 | column: 4, 409 | }, 410 | }), 411 | ); 412 | assert_eq!( 413 | lexer.read().unwrap(), 414 | Some(Token { 415 | insn: Insn::Iinc, 416 | location: Location { 417 | byte: b'h', 418 | path: None, 419 | line: 1, 420 | column: 5, 421 | }, 422 | }), 423 | ); 424 | assert_eq!( 425 | lexer.read().unwrap(), 426 | Some(Token { 427 | insn: Insn::Snew, 428 | location: Location { 429 | byte: b'$', 430 | path: None, 431 | line: 1, 432 | column: 6, 433 | }, 434 | }), 435 | ); 436 | // Lexer hits `Onew`, so it changes its mode to `A`. 437 | assert_eq!( 438 | lexer.read().unwrap(), 439 | Some(Token { 440 | insn: Insn::Inew, 441 | location: Location { 442 | byte: b'B', 443 | path: None, 444 | line: 1, 445 | column: 7, 446 | }, 447 | }), 448 | ); 449 | } 450 | } 451 | -------------------------------------------------------------------------------- /watson_rs/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::str::FromStr; 2 | 3 | pub mod error; 4 | pub mod language; 5 | pub mod lexer; 6 | pub mod serializer; 7 | pub mod unlexer; 8 | pub mod vm; 9 | 10 | pub use error::{Error, ErrorKind, Result}; 11 | pub use language::{Bytes, Insn, IsValue, Location, Map, ToBytes, Token, Value}; 12 | pub use vm::VM; 13 | 14 | impl FromStr for Value { 15 | type Err = Error; 16 | 17 | fn from_str(s: &str) -> Result { 18 | let mut bytes = s.as_bytes(); 19 | let mut vm = vm::VM::new(); 20 | vm.execute_all(lexer::Lexer::new(&mut bytes))?; 21 | vm.into_top().map(Ok).unwrap_or_else(|| { 22 | Err(Error { 23 | kind: ErrorKind::EmptyStack, 24 | location: Location::unknown(), 25 | source: None, 26 | }) 27 | }) 28 | } 29 | } 30 | 31 | #[cfg(test)] 32 | mod test { 33 | use crate::*; 34 | 35 | use Value::*; 36 | 37 | #[test] 38 | fn parse_watson() -> Result<()> { 39 | assert_eq!("B".parse::()?, Int(0)); 40 | assert_eq!("BBubba".parse::()?, Int(4)); 41 | assert_eq!("?SShaaarrk".parse::()?, Int(8)); 42 | Ok(()) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /watson_rs/src/serializer.rs: -------------------------------------------------------------------------------- 1 | use crate::error::Result; 2 | use crate::language::{Bytes, Insn, Map, Value}; 3 | use Insn::*; 4 | use Value::*; 5 | 6 | /// A trait for objects that can be used as a sink of instructions. 7 | pub trait WriteInsn { 8 | /// Writes a single instruction. 9 | fn write(&mut self, insn: Insn) -> Result<()>; 10 | 11 | /// Writes all instructions. 12 | fn write_all(&mut self, insns: &[Insn]) -> Result<()> { 13 | for i in insns { 14 | self.write(*i)?; 15 | } 16 | Ok(()) 17 | } 18 | } 19 | 20 | impl<'a> WriteInsn for &'a mut Vec { 21 | fn write(&mut self, insn: Insn) -> Result<()> { 22 | self.push(insn); 23 | Ok(()) 24 | } 25 | } 26 | 27 | /// Serializer converts `Value` into a sequence of `Insn`s. 28 | pub struct Serializer { 29 | writer: W, 30 | } 31 | 32 | impl Serializer { 33 | /// Returns a new `Serializer`. 34 | pub fn new(writer: W) -> Self { 35 | Serializer { writer } 36 | } 37 | 38 | /// Unwraps the inner value from this `Serializer`. 39 | pub fn into_inner(self) -> W { 40 | self.writer 41 | } 42 | } 43 | 44 | /// Serialize itself can be used as a `WriteInsn`. 45 | impl WriteInsn for Serializer { 46 | fn write(&mut self, insn: Insn) -> Result<()> { 47 | self.writer.write(insn) 48 | } 49 | } 50 | 51 | impl Serializer { 52 | /// Serializes a single `Value`. 53 | pub fn serialize(&mut self, v: &Value) -> Result<()> { 54 | match *v { 55 | Int(n) => self.serialize_int(n), 56 | Uint(n) => self.serialize_uint(n), 57 | Float(f) => self.serialize_float(f), 58 | String(ref s) => self.serialize_string(s), 59 | Object(ref map) => self.serialize_object(map), 60 | Array(ref arr) => self.serialize_array(arr), 61 | Bool(b) => self.serialize_bool(b), 62 | Nil => self.serialize_nil(), 63 | } 64 | } 65 | 66 | fn serialize_int(&mut self, n: i64) -> Result<()> { 67 | let mut n = n as u64; 68 | self.write(Inew)?; 69 | let mut shift: usize = 0; 70 | while n != 0 { 71 | if n % 2 == 1 { 72 | self.write_all(&[Inew, Iinc])?; 73 | for _ in 1..=shift { 74 | self.write(Ishl)?; 75 | } 76 | self.write(Iadd)?; 77 | } 78 | n >>= 1; 79 | shift += 1; 80 | } 81 | Ok(()) 82 | } 83 | 84 | fn serialize_uint(&mut self, n: u64) -> Result<()> { 85 | self.serialize_int(n as i64)?; 86 | self.write(Itou) 87 | } 88 | 89 | fn serialize_float(&mut self, f: f64) -> Result<()> { 90 | if f.is_nan() { 91 | self.write(Fnan) 92 | } else if f.is_infinite() { 93 | self.write(Finf)?; 94 | if f.is_sign_negative() { 95 | self.write(Fneg)?; 96 | } 97 | Ok(()) 98 | } else { 99 | self.serialize_int(f.to_bits() as i64)?; 100 | self.write(Itof) 101 | } 102 | } 103 | 104 | fn serialize_string(&mut self, s: &Bytes) -> Result<()> { 105 | self.write(Snew)?; 106 | for c in s { 107 | self.serialize_int(*c as i64)?; 108 | self.write(Sadd)?; 109 | } 110 | Ok(()) 111 | } 112 | 113 | fn serialize_object(&mut self, map: &Map) -> Result<()> { 114 | self.write(Onew)?; 115 | for (k, v) in map { 116 | self.serialize_string(k)?; 117 | self.serialize(v)?; 118 | self.write(Oadd)?; 119 | } 120 | Ok(()) 121 | } 122 | 123 | fn serialize_array(&mut self, arr: &Vec) -> Result<()> { 124 | self.write(Anew)?; 125 | for i in arr { 126 | self.serialize(i)?; 127 | self.write(Aadd)?; 128 | } 129 | Ok(()) 130 | } 131 | 132 | fn serialize_bool(&mut self, b: bool) -> Result<()> { 133 | self.write(Bnew)?; 134 | if b { 135 | self.write(Bneg)?; 136 | } 137 | Ok(()) 138 | } 139 | 140 | fn serialize_nil(&mut self) -> Result<()> { 141 | self.write(Nnew) 142 | } 143 | } 144 | 145 | #[cfg(test)] 146 | mod test { 147 | use super::*; 148 | use crate::vm; 149 | use crate::{array, object}; 150 | 151 | #[test] 152 | fn serializer_int() { 153 | assert_eq!(to_insn_vec(&Int(0)), vec![Inew]); 154 | assert_eq!(to_insn_vec(&Int(1)), vec![Inew, Inew, Iinc, Iadd]); 155 | assert_eq!(to_insn_vec(&Int(2)), vec![Inew, Inew, Iinc, Ishl, Iadd]); 156 | assert_eq!( 157 | to_insn_vec(&Int(3)), 158 | vec![Inew, Inew, Iinc, Iadd, Inew, Iinc, Ishl, Iadd] 159 | ); 160 | assert_eq!( 161 | to_insn_vec(&Int(0b1010101)), 162 | vec![ 163 | Inew, // 0b0 164 | Inew, Iinc, Iadd, // 0b1 165 | Inew, Iinc, Ishl, Ishl, Iadd, // 0b101 166 | Inew, Iinc, Ishl, Ishl, Ishl, Ishl, Iadd, // 0b10101 167 | Inew, Iinc, Ishl, Ishl, Ishl, Ishl, Ishl, Ishl, Iadd, // 0b1010101 168 | ] 169 | ); 170 | assert_identical(Int(1234567890)); 171 | assert_identical(Int(-1234567890)); 172 | } 173 | 174 | #[test] 175 | fn serializer_uint() { 176 | assert_identical(Uint(0)); 177 | assert_identical(Uint(1)); 178 | assert_identical(Uint(5)); 179 | assert_identical(Uint(0xffff_ffff_ffff_ffff)); 180 | } 181 | 182 | #[test] 183 | fn serializer_float() { 184 | assert_eq!(to_insn_vec(&Float(f64::NAN)), vec![Fnan]); 185 | assert_eq!(to_insn_vec(&Float(f64::INFINITY)), vec![Finf]); 186 | assert_eq!(to_insn_vec(&Float(f64::NEG_INFINITY)), vec![Finf, Fneg]); 187 | 188 | assert_identical(Float(0.0)); 189 | assert_identical(Float(1.0)); 190 | assert_identical(Float(123.45e-67)); 191 | assert_identical(Float(8.9102e34)); 192 | } 193 | 194 | #[test] 195 | fn serializer_string() { 196 | assert_identical(String(Vec::new())); 197 | assert_identical(String(b"a".to_vec())); 198 | assert_identical(String(b"ab".to_vec())); 199 | assert_identical(String( 200 | b"qawsedrftgyhujikolp;zasxdcfvgbhnjmk,l.;qaswderftgyhujikolp;".to_vec(), 201 | )); 202 | } 203 | 204 | #[test] 205 | fn serializer_object() { 206 | assert_identical(object![]); 207 | assert_identical(object![key: Int(123)]); 208 | assert_identical(object![key: Int(123), another_key: Float(1.23)]); 209 | assert_identical(object![ 210 | key: Int(123), 211 | another_key: Float(1.23), 212 | nested_object: object![nested_key: String(b"value".to_vec())], 213 | ]); 214 | } 215 | 216 | #[test] 217 | fn serializer_array() { 218 | assert_identical(array![]); 219 | assert_identical(array![Int(1)]); 220 | assert_identical(array![Int(1), String(b"2".to_vec())]); 221 | assert_identical(array![ 222 | Int(1), 223 | String(b"2".to_vec()), 224 | array![Uint(3), String(b"nested".to_vec())], 225 | ]); 226 | } 227 | 228 | #[test] 229 | fn serializer_bool() { 230 | assert_identical(Bool(false)); 231 | assert_identical(Bool(true)); 232 | } 233 | 234 | #[test] 235 | fn serializer_nil() { 236 | assert_identical(Nil); 237 | } 238 | 239 | /* 240 | * Helper functions 241 | */ 242 | 243 | fn to_insn_vec(value: &Value) -> Vec { 244 | let mut insns = Vec::new(); 245 | Serializer::new(&mut insns).serialize(&value).unwrap(); 246 | insns 247 | } 248 | 249 | fn assert_identical(value: Value) { 250 | let mut vm = vm::VM::new(); 251 | vm.execute_all(vm::SliceTokenReader::new(&to_insn_vec(&value))) 252 | .expect("execution error"); 253 | let result = vm.peek_top().expect("stack is empty"); 254 | assert_eq!(&value, result); 255 | } 256 | } 257 | -------------------------------------------------------------------------------- /watson_rs/src/unlexer.rs: -------------------------------------------------------------------------------- 1 | use std::fs; 2 | use std::io; 3 | use std::path; 4 | 5 | use crate::error::Result; 6 | use crate::language::{Insn, Mode}; 7 | use crate::serializer::WriteInsn; 8 | 9 | const DEFAULT_CHARS_PER_LINE: usize = 80; 10 | 11 | /// `Unlexer` converts a sequence of `Insn`s to its ASCII representation. 12 | pub struct Unlexer { 13 | writer: W, 14 | 15 | mode: Mode, 16 | chars_per_line: usize, 17 | 18 | column: usize, 19 | } 20 | 21 | /// Config configures an `Unlexer`. 22 | pub struct Config { 23 | /// Initial mode of an `Unlexer` (defaults to `A` by the specification). 24 | pub initial_mode: Mode, 25 | 26 | /// An `Unlexer` emits a newline character every time it emits `chars_per_line` consecutive characters. 27 | /// If set to zero, then `Unlexer` does not emit any newline characters. 28 | pub chars_per_line: usize, 29 | } 30 | 31 | impl Default for Config { 32 | fn default() -> Config { 33 | Config { 34 | initial_mode: Mode::A, 35 | chars_per_line: DEFAULT_CHARS_PER_LINE, 36 | } 37 | } 38 | } 39 | 40 | impl Config { 41 | /// Returns a new `Unlexer` that writes to the given writer. 42 | pub fn build(self, writer: W) -> Unlexer { 43 | Unlexer { 44 | writer, 45 | mode: self.initial_mode, 46 | chars_per_line: self.chars_per_line, 47 | column: 0, 48 | } 49 | } 50 | 51 | /// Creates a file (by `fs::File::create`) and returns an `Unlexer` that writes to this file. 52 | pub fn open(self, path: &path::Path) -> Result> { 53 | let f = fs::File::create(path)?; 54 | Ok(self.build(f)) 55 | } 56 | } 57 | 58 | impl Unlexer { 59 | /// Creates a file (by `fs::File::create`) and returns an `Unlexer` that writes to this file with the default configuration. 60 | pub fn open(path: &path::Path) -> Result { 61 | Config::default().open(path) 62 | } 63 | } 64 | 65 | impl Unlexer { 66 | /// Returns a new `Unlexer` that writes to the given writer with the default configuration. 67 | pub fn new(writer: W) -> Self { 68 | Config::default().build(writer) 69 | } 70 | } 71 | 72 | impl WriteInsn for Unlexer { 73 | /// Writes a single `Insn` to its underlying writer. 74 | fn write(&mut self, insn: Insn) -> Result<()> { 75 | let mut buf = [insn.into_byte(self.mode)]; 76 | self.writer.write_all(&buf)?; 77 | self.column += 1; 78 | if 0 < self.chars_per_line && self.chars_per_line <= self.column { 79 | self.column = 0; 80 | buf[0] = b'\n'; 81 | self.writer.write_all(&buf)?; 82 | } 83 | if insn == Insn::Snew { 84 | self.mode = self.mode.flip(); 85 | } 86 | Ok(()) 87 | } 88 | } 89 | 90 | #[cfg(test)] 91 | mod test { 92 | use super::*; 93 | use Insn::*; 94 | 95 | #[test] 96 | fn unlexer_new_initial_mode_defaults_to_a() -> Result<()> { 97 | let mut buf = Vec::new(); 98 | let mut unlexer = Unlexer::new(&mut buf); 99 | unlexer.write(Insn::Inew)?; 100 | assert_eq!(buf, b"B".to_vec()); 101 | Ok(()) 102 | } 103 | 104 | #[test] 105 | fn unlexer_new_initlal_mode_is_configurable() -> Result<()> { 106 | let mut conf = Config::default(); 107 | conf.initial_mode = Mode::S; 108 | let mut buf = Vec::new(); 109 | let mut unlexer = conf.build(&mut buf); 110 | unlexer.write(Insn::Inew)?; 111 | assert_eq!(buf, b"S".to_vec()); 112 | Ok(()) 113 | } 114 | 115 | #[test] 116 | fn unlexer_open_opens_a_file() -> Result<()> { 117 | use io::BufRead; 118 | 119 | let tempdir = tempfile::tempdir()?; 120 | let path = tempdir.path().join("data.watson"); 121 | { 122 | let mut unlexer = Unlexer::open(&path)?; 123 | unlexer.write(Insn::Inew)?; 124 | } 125 | 126 | let mut lines = io::BufReader::new(fs::File::open(&path)?).lines(); 127 | assert_eq!(lines.next().unwrap().unwrap(), "B"); 128 | assert!(lines.next().is_none()); 129 | 130 | Ok(()) 131 | } 132 | 133 | #[test] 134 | fn unlexer_changes_its_mode() -> Result<()> { 135 | let mut buf = Vec::new(); 136 | let mut unlexer = Unlexer::new(&mut buf); 137 | for insn in vec![Inew, Snew, Inew, Snew, Inew] { 138 | unlexer.write(insn)?; 139 | } 140 | assert_eq!(buf, b"B?S$B".to_vec()); 141 | Ok(()) 142 | } 143 | 144 | #[test] 145 | fn unlexer_emits_newline() -> Result<()> { 146 | let mut conf = Config::default(); 147 | conf.chars_per_line = 5; 148 | let mut buf = Vec::new(); 149 | let mut unlexer = conf.build(&mut buf); 150 | 151 | for insn in vec![ 152 | Inew, Iinc, Ishl, Ishl, Iadd, Snew, Inew, Iinc, Ishl, Ishl, Iadd, Snew, Inew, 153 | ] { 154 | unlexer.write(insn)?; 155 | } 156 | assert_eq!(buf, b"Bubba\n?Shaa\nk$B".to_vec()); 157 | 158 | Ok(()) 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /watson_rs/src/vm.rs: -------------------------------------------------------------------------------- 1 | use crate::error::{Error, ErrorKind, Result}; 2 | use crate::language::{Bytes, Insn, IsValue, Location, Map, Token, Value}; 3 | use Insn::*; 4 | 5 | /// A source of tokens. 6 | pub trait ReadToken { 7 | /// Reads a single token from an underlying source. 8 | /// It should return `Ok(None)` if there is no more token. 9 | fn read(&mut self) -> Result>; 10 | } 11 | 12 | /// A token reader that reads from the given slice. 13 | pub struct SliceTokenReader<'a> { 14 | next: usize, 15 | slice: &'a [Insn], 16 | } 17 | 18 | impl<'a> SliceTokenReader<'a> { 19 | /// Returns a new reader that reads tokens from the given slice. 20 | pub fn new(slice: &'a [Insn]) -> Self { 21 | SliceTokenReader { next: 0, slice } 22 | } 23 | } 24 | 25 | impl<'a> ReadToken for SliceTokenReader<'a> { 26 | fn read(&mut self) -> Result> { 27 | if self.slice.len() <= self.next { 28 | Ok(None) 29 | } else { 30 | let insn = self.slice[self.next]; 31 | self.next += 1; 32 | Ok(Some(Token { 33 | insn, 34 | location: Location::unknown(), 35 | })) 36 | } 37 | } 38 | } 39 | 40 | /// A stack of the WATSON VM. 41 | /// See [the specification](https://github.com/genkami/watson/blob/main/doc/spec.md) for more details. 42 | pub struct Stack { 43 | vec: Vec, 44 | } 45 | 46 | impl Stack { 47 | pub fn new() -> Self { 48 | Stack { vec: Vec::new() } 49 | } 50 | 51 | /// Returns a StackOps that can manipulate the stack on behalf of the instruction given by the token. 52 | pub fn operate_as(&mut self, token: Token) -> StackOps<'_> { 53 | StackOps { stack: self, token } 54 | } 55 | 56 | /// Returns a value on the top of the stack without consuming it. 57 | pub fn peek_top(&self) -> Option<&Value> { 58 | let len = self.vec.len(); 59 | if len == 0 { 60 | None 61 | } else { 62 | Some(&self.vec[len - 1]) 63 | } 64 | } 65 | } 66 | 67 | impl Default for Stack { 68 | fn default() -> Self { 69 | Stack::new() 70 | } 71 | } 72 | 73 | /// StackOps does operations on a stack on behalf of some instruction. 74 | pub struct StackOps<'a> { 75 | stack: &'a mut Stack, 76 | token: Token, 77 | } 78 | 79 | impl<'a> StackOps<'a> { 80 | /// Pushes a value onto the stack. 81 | pub fn push(&mut self, v: Value) { 82 | self.stack.vec.push(v); 83 | } 84 | 85 | /// Pops a value from the stack. 86 | pub fn pop(&mut self) -> Result { 87 | match self.stack.vec.pop() { 88 | Some(x) => Ok(x), 89 | None => Err(Error { 90 | kind: ErrorKind::EmptyStack, 91 | location: self.token.location.clone(), 92 | source: None, 93 | }), 94 | } 95 | } 96 | 97 | /// Pops a value from the stack, applies f to it, then pushes the result. 98 | pub fn apply1(&mut self, f: F) -> Result<()> 99 | where 100 | T1: IsValue, 101 | R: IsValue, 102 | F: FnOnce(T1) -> R, 103 | { 104 | let v1 = self.pop()?; 105 | let result = f(self.claim(v1)?); 106 | self.push(result.into_value()); 107 | Ok(()) 108 | } 109 | 110 | /// Pops two values from the stack, applies f to them, then pushes the result. 111 | /// The leftmost argument corresponds to the top of the stack. 112 | pub fn apply2(&mut self, f: F) -> Result<()> 113 | where 114 | T1: IsValue, 115 | T2: IsValue, 116 | R: IsValue, 117 | F: FnOnce(T1, T2) -> R, 118 | { 119 | let v1 = self.pop()?; 120 | let v2 = self.pop()?; 121 | let result = f(self.claim(v1)?, self.claim(v2)?); 122 | self.push(result.into_value()); 123 | Ok(()) 124 | } 125 | 126 | /// Pops three values from the stack, applies f to them, then pushes the result. 127 | /// The leftmost argument corresponds to the top of the stack. 128 | pub fn apply3(&mut self, f: F) -> Result<()> 129 | where 130 | T1: IsValue, 131 | T2: IsValue, 132 | T3: IsValue, 133 | R: IsValue, 134 | F: FnOnce(T1, T2, T3) -> R, 135 | { 136 | let v1 = self.pop()?; 137 | let v2 = self.pop()?; 138 | let v3 = self.pop()?; 139 | let result = f(self.claim(v1)?, self.claim(v2)?, self.claim(v3)?); 140 | self.push(result.into_value()); 141 | Ok(()) 142 | } 143 | 144 | fn claim(&self, v: Value) -> Result { 145 | match T::from_value(v) { 146 | Some(x) => Ok(x), 147 | None => Err(Error { 148 | kind: ErrorKind::TypeMismatch, 149 | location: self.token.location.clone(), 150 | source: None, 151 | }), 152 | } 153 | } 154 | } 155 | 156 | /// A WATSON Virturl Machine. 157 | /// See [the specification](https://github.com/genkami/watson/blob/main/doc/spec.md) for more details. 158 | pub struct VM { 159 | stack: Stack, 160 | } 161 | 162 | impl VM { 163 | /// Returns a new `VM`. 164 | pub fn new() -> Self { 165 | VM { 166 | stack: Stack::new(), 167 | } 168 | } 169 | 170 | /// Executes a single instruction. 171 | pub fn execute(&mut self, t: Token) -> Result<()> { 172 | let mut ops = self.stack.operate_as(t.clone()); 173 | 174 | fn push(ops: &mut StackOps, x: T) -> Result<()> { 175 | ops.push(x.into_value()); 176 | Ok(()) 177 | } 178 | 179 | // See https://github.com/genkami/watson/blob/main/doc/spec.md#instructions. 180 | match t.insn { 181 | Inew => push(&mut ops, 0_i64), 182 | Iinc => ops.apply1(|x: i64| x + 1), 183 | Ishl => ops.apply1(|x: i64| x << 1), 184 | Iadd => ops.apply2(|y: i64, x: i64| x + y), 185 | Ineg => ops.apply1(|x: i64| -x), 186 | Isht => ops.apply2(|y: i64, x: i64| x << y), 187 | Itof => ops.apply1(|x: i64| f64::from_bits(x as u64)), 188 | Itou => ops.apply1(|x: i64| x as u64), 189 | Finf => push(&mut ops, f64::INFINITY), 190 | Fnan => push(&mut ops, f64::NAN), 191 | Fneg => ops.apply1(|x: f64| -x), 192 | Snew => push(&mut ops, Vec::::new()), 193 | Sadd => ops.apply2(|x: i64, mut s: Bytes| { 194 | s.push(x as u8); 195 | s 196 | }), 197 | Onew => push(&mut ops, Map::new()), 198 | Oadd => ops.apply3(|v: Value, k: Bytes, mut o: Map| { 199 | o.insert(k, v); 200 | o 201 | }), 202 | Anew => push(&mut ops, Vec::::new()), 203 | Aadd => ops.apply2(|v: Value, mut a: Vec| { 204 | a.push(v); 205 | a 206 | }), 207 | Bnew => push(&mut ops, false), 208 | Bneg => ops.apply1(|b: bool| !b), 209 | Nnew => push(&mut ops, ()), 210 | Gdup => { 211 | let v = ops.pop()?; 212 | ops.push(v.clone()); 213 | ops.push(v); 214 | Ok(()) 215 | } 216 | Gpop => { 217 | ops.pop()?; 218 | Ok(()) 219 | } 220 | Gswp => { 221 | let v1 = ops.pop()?; 222 | let v2 = ops.pop()?; 223 | ops.push(v1); 224 | ops.push(v2); 225 | Ok(()) 226 | } 227 | } 228 | } 229 | 230 | /// Executes all instructions sequentially from the given reader. 231 | pub fn execute_all(&mut self, mut reader: R) -> Result<()> 232 | where 233 | R: ReadToken, 234 | { 235 | while let Some(token) = reader.read()? { 236 | self.execute(token)?; 237 | } 238 | Ok(()) 239 | } 240 | 241 | /// Returns a `Value` on the top of the stack. 242 | pub fn peek_top(&self) -> Option<&Value> { 243 | self.stack.peek_top() 244 | } 245 | 246 | /// Converts itself into a value on the top of its stack. 247 | pub fn into_top(mut self) -> Option { 248 | self.stack.vec.pop() 249 | } 250 | 251 | /// Borrows its stack mutably for debug purpose. 252 | pub fn borrow_stack_mut(&mut self) -> &mut Stack { 253 | &mut self.stack 254 | } 255 | } 256 | 257 | impl Default for VM { 258 | fn default() -> Self { 259 | VM::new() 260 | } 261 | } 262 | 263 | #[cfg(test)] 264 | mod test { 265 | use std::fmt; 266 | 267 | use super::*; 268 | use crate::language::Location; 269 | use crate::{array, object}; 270 | use Value::*; 271 | 272 | #[test] 273 | fn stack_push_and_pop() -> Result<()> { 274 | test_ops(|mut ops| { 275 | assert_error_kind_is(ops.pop(), ErrorKind::EmptyStack); 276 | Ok(()) 277 | })?; 278 | 279 | test_ops(|mut ops| { 280 | ops.push(Int(1)); 281 | ops.push(Int(2)); 282 | ops.push(Int(3)); 283 | assert_eq!(ops.pop()?, Int(3)); 284 | assert_eq!(ops.pop()?, Int(2)); 285 | assert_eq!(ops.pop()?, Int(1)); 286 | assert_error_kind_is(ops.pop(), ErrorKind::EmptyStack); 287 | Ok(()) 288 | })?; 289 | 290 | Ok(()) 291 | } 292 | 293 | #[test] 294 | fn stack_apply1() -> Result<()> { 295 | fn incr(x: i64) -> i64 { 296 | x + 1 297 | } 298 | 299 | // insufficient stack 300 | test_ops(|mut ops| { 301 | assert_error_kind_is(ops.apply1(incr), ErrorKind::EmptyStack); 302 | Ok(()) 303 | })?; 304 | 305 | // type mismatch 306 | test_ops(|mut ops| { 307 | ops.push(Nil); 308 | assert_error_kind_is(ops.apply1(incr), ErrorKind::TypeMismatch); 309 | Ok(()) 310 | })?; 311 | 312 | // ok 313 | test_ops(|mut ops| { 314 | ops.push(Int(456)); 315 | ops.apply1(incr)?; 316 | assert_eq!(ops.pop()?, Int(457)); 317 | Ok(()) 318 | })?; 319 | 320 | Ok(()) 321 | } 322 | 323 | #[test] 324 | fn stack_apply2() -> Result<()> { 325 | fn sub(x: i64, y: i64) -> i64 { 326 | x - y 327 | } 328 | 329 | // insufficient stack 330 | test_ops(|mut ops| { 331 | assert_error_kind_is(ops.apply2(sub), ErrorKind::EmptyStack); 332 | Ok(()) 333 | })?; 334 | 335 | // insufficient stack (only 1 item) 336 | test_ops(|mut ops| { 337 | ops.push(Int(5)); 338 | assert_error_kind_is(ops.apply2(sub), ErrorKind::EmptyStack); 339 | Ok(()) 340 | })?; 341 | 342 | // type mismatch (first arg) 343 | test_ops(|mut ops| { 344 | ops.push(Int(5)); 345 | ops.push(Nil); 346 | assert_error_kind_is(ops.apply2(sub), ErrorKind::TypeMismatch); 347 | Ok(()) 348 | })?; 349 | 350 | // type mismatch (second arg) 351 | test_ops(|mut ops| { 352 | ops.push(Nil); 353 | ops.push(Int(5)); 354 | assert_error_kind_is(ops.apply2(sub), ErrorKind::TypeMismatch); 355 | Ok(()) 356 | })?; 357 | 358 | // ok 359 | test_ops(|mut ops| { 360 | ops.push(Int(3)); 361 | ops.push(Int(5)); 362 | ops.apply2(sub)?; 363 | assert_eq!(ops.pop()?, Int(2)); 364 | Ok(()) 365 | })?; 366 | 367 | Ok(()) 368 | } 369 | 370 | #[test] 371 | fn stack_apply3() -> Result<()> { 372 | fn affine(a: i64, x: i64, b: i64) -> i64 { 373 | a * x + b 374 | } 375 | 376 | // insufficient stack 377 | test_ops(|mut ops| { 378 | assert_error_kind_is(ops.apply3(affine), ErrorKind::EmptyStack); 379 | Ok(()) 380 | })?; 381 | 382 | // insufficient stack (only 1 item) 383 | test_ops(|mut ops| { 384 | ops.push(Int(5)); 385 | assert_error_kind_is(ops.apply3(affine), ErrorKind::EmptyStack); 386 | Ok(()) 387 | })?; 388 | 389 | // insufficient stack (only 2 items) 390 | test_ops(|mut ops| { 391 | ops.push(Int(4)); 392 | ops.push(Int(5)); 393 | assert_error_kind_is(ops.apply3(affine), ErrorKind::EmptyStack); 394 | Ok(()) 395 | })?; 396 | 397 | // type mismatch (first arg) 398 | test_ops(|mut ops| { 399 | ops.push(Int(3)); 400 | ops.push(Int(4)); 401 | ops.push(Nil); 402 | assert_error_kind_is(ops.apply3(affine), ErrorKind::TypeMismatch); 403 | Ok(()) 404 | })?; 405 | 406 | // type mismatch (second arg) 407 | test_ops(|mut ops| { 408 | ops.push(Int(3)); 409 | ops.push(Nil); 410 | ops.push(Int(5)); 411 | assert_error_kind_is(ops.apply3(affine), ErrorKind::TypeMismatch); 412 | Ok(()) 413 | })?; 414 | 415 | // type mismatch (third arg) 416 | test_ops(|mut ops| { 417 | ops.push(Nil); 418 | ops.push(Int(4)); 419 | ops.push(Int(5)); 420 | assert_error_kind_is(ops.apply3(affine), ErrorKind::TypeMismatch); 421 | Ok(()) 422 | })?; 423 | 424 | // ok 425 | test_ops(|mut ops| { 426 | ops.push(Int(3)); 427 | ops.push(Int(4)); 428 | ops.push(Int(5)); 429 | ops.apply3(affine)?; 430 | assert_eq!(ops.pop()?, Int(5 * 4 + 3)); 431 | Ok(()) 432 | })?; 433 | 434 | Ok(()) 435 | } 436 | 437 | #[test] 438 | fn vm_execute_inew() -> Result<()> { 439 | let mut vm = VM::new(); 440 | 441 | assert_eq!(vm.peek_top(), None); 442 | vm.execute(new_token(Inew))?; 443 | assert_eq!(vm.peek_top(), Some(&Int(0))); 444 | 445 | Ok(()) 446 | } 447 | 448 | #[test] 449 | fn vm_execute_iinc() -> Result<()> { 450 | let mut vm = VM::new(); 451 | let mut ops = vm.borrow_stack_mut().force_operate(); 452 | 453 | ops.push(Int(123)); 454 | vm.execute(new_token(Iinc))?; 455 | assert_eq!(vm.peek_top(), Some(&Int(124))); 456 | 457 | Ok(()) 458 | } 459 | 460 | #[test] 461 | fn vm_execute_ishl() -> Result<()> { 462 | let mut vm = VM::new(); 463 | let mut ops = vm.borrow_stack_mut().force_operate(); 464 | 465 | ops.push(Int(3)); 466 | vm.execute(new_token(Ishl))?; 467 | assert_eq!(vm.peek_top(), Some(&Int(6))); 468 | 469 | Ok(()) 470 | } 471 | 472 | #[test] 473 | fn vm_execute_iadd() -> Result<()> { 474 | let mut vm = VM::new(); 475 | let mut ops = vm.borrow_stack_mut().force_operate(); 476 | 477 | ops.push(Int(3)); 478 | ops.push(Int(4)); 479 | vm.execute(new_token(Iadd))?; 480 | assert_eq!(vm.peek_top(), Some(&Int(7))); 481 | 482 | Ok(()) 483 | } 484 | 485 | #[test] 486 | fn vm_execute_ineg() -> Result<()> { 487 | let mut vm = VM::new(); 488 | let mut ops = vm.borrow_stack_mut().force_operate(); 489 | 490 | ops.push(Int(3)); 491 | vm.execute(new_token(Ineg))?; 492 | assert_eq!(vm.peek_top(), Some(&Int(-3))); 493 | 494 | Ok(()) 495 | } 496 | 497 | #[test] 498 | fn vm_execute_isht() -> Result<()> { 499 | let mut vm = VM::new(); 500 | let mut ops = vm.borrow_stack_mut().force_operate(); 501 | 502 | ops.push(Int(3)); 503 | ops.push(Int(2)); 504 | vm.execute(new_token(Isht))?; 505 | assert_eq!(vm.peek_top(), Some(&Int(12))); 506 | 507 | Ok(()) 508 | } 509 | 510 | #[test] 511 | fn vm_execute_itof() -> Result<()> { 512 | let mut vm = VM::new(); 513 | let mut ops = vm.borrow_stack_mut().force_operate(); 514 | let f: f64 = 1.234e-56; 515 | 516 | ops.push(Int(f.to_bits() as i64)); 517 | vm.execute(new_token(Itof))?; 518 | assert_eq!(vm.peek_top(), Some(&Float(f))); 519 | 520 | Ok(()) 521 | } 522 | 523 | #[test] 524 | fn vm_execute_itou() -> Result<()> { 525 | let mut vm = VM::new(); 526 | let mut ops = vm.borrow_stack_mut().force_operate(); 527 | 528 | ops.push(Int(-1)); 529 | vm.execute(new_token(Itou))?; 530 | assert_eq!(vm.peek_top(), Some(&Uint(0xffff_ffff_ffff_ffff))); 531 | 532 | Ok(()) 533 | } 534 | 535 | #[test] 536 | fn vm_execute_finf() -> Result<()> { 537 | let mut vm = VM::new(); 538 | 539 | vm.execute(new_token(Finf))?; 540 | let top = vm.peek_top().clone(); 541 | let f = match top { 542 | Some(Float(f)) => f, 543 | _ => panic!("not a float: {:?}", top), 544 | }; 545 | assert!(f.is_infinite()); 546 | assert!(f.is_sign_positive()); 547 | 548 | Ok(()) 549 | } 550 | 551 | #[test] 552 | fn vm_execute_fnan() -> Result<()> { 553 | let mut vm = VM::new(); 554 | 555 | vm.execute(new_token(Fnan))?; 556 | let top = vm.peek_top().clone(); 557 | let f = match top { 558 | Some(Float(f)) => f, 559 | _ => panic!("not a float: {:?}", top), 560 | }; 561 | assert!(f.is_nan()); 562 | 563 | Ok(()) 564 | } 565 | 566 | #[test] 567 | fn vm_execute_fneg() -> Result<()> { 568 | let mut vm = VM::new(); 569 | let mut ops = vm.borrow_stack_mut().force_operate(); 570 | 571 | ops.push(Float(1.23)); 572 | vm.execute(new_token(Fneg))?; 573 | assert_eq!(vm.peek_top(), Some(&Float(-1.23))); 574 | 575 | Ok(()) 576 | } 577 | 578 | #[test] 579 | fn vm_execute_snew() -> Result<()> { 580 | let mut vm = VM::new(); 581 | 582 | vm.execute(new_token(Snew))?; 583 | assert_eq!(vm.peek_top(), Some(&String(Vec::new()))); 584 | 585 | Ok(()) 586 | } 587 | 588 | #[test] 589 | fn vm_execute_sadd() -> Result<()> { 590 | let mut vm = VM::new(); 591 | 592 | vm.execute(new_token(Snew))?; 593 | assert_eq!(vm.peek_top(), Some(&String(Vec::new()))); 594 | 595 | vm.borrow_stack_mut().force_operate().push(Int(b'a' as i64)); 596 | vm.execute(new_token(Sadd))?; 597 | assert_eq!(vm.peek_top(), Some(&String(b"a".to_vec()))); 598 | 599 | vm.borrow_stack_mut().force_operate().push(Int(b'b' as i64)); 600 | vm.execute(new_token(Sadd))?; 601 | assert_eq!(vm.peek_top(), Some(&String(b"ab".to_vec()))); 602 | 603 | Ok(()) 604 | } 605 | 606 | #[test] 607 | fn vm_execute_onew() -> Result<()> { 608 | let mut vm = VM::new(); 609 | 610 | vm.execute(new_token(Onew))?; 611 | assert_eq!(vm.peek_top(), Some(&object![])); 612 | 613 | Ok(()) 614 | } 615 | 616 | #[test] 617 | fn vm_execute_oadd() -> Result<()> { 618 | let mut vm = VM::new(); 619 | 620 | vm.execute(new_token(Onew))?; 621 | assert_eq!(vm.peek_top(), Some(&object![])); 622 | 623 | let mut ops = vm.borrow_stack_mut().force_operate(); 624 | ops.push(String(b"key1".to_vec())); 625 | ops.push(String(b"value1".to_vec())); 626 | vm.execute(new_token(Oadd))?; 627 | assert_eq!( 628 | vm.peek_top(), 629 | Some(&object![key1: String(b"value1".to_vec())]), 630 | ); 631 | 632 | let mut ops = vm.borrow_stack_mut().force_operate(); 633 | ops.push(String(b"key2".to_vec())); 634 | ops.push(Int(22222)); 635 | vm.execute(new_token(Oadd))?; 636 | assert_eq!( 637 | vm.peek_top(), 638 | Some(&object![ 639 | key1: String(b"value1".to_vec()), 640 | key2: Int(22222), 641 | ]), 642 | ); 643 | Ok(()) 644 | } 645 | 646 | #[test] 647 | fn vm_execute_anew() -> Result<()> { 648 | let mut vm = VM::new(); 649 | 650 | vm.execute(new_token(Anew))?; 651 | assert_eq!(vm.peek_top(), Some(&array![])); 652 | 653 | Ok(()) 654 | } 655 | 656 | #[test] 657 | fn vm_execute_aadd() -> Result<()> { 658 | let mut vm = VM::new(); 659 | 660 | vm.execute(new_token(Anew))?; 661 | assert_eq!(vm.peek_top(), Some(&array![])); 662 | 663 | vm.borrow_stack_mut().force_operate().push(Int(123)); 664 | vm.execute(new_token(Aadd))?; 665 | assert_eq!(vm.peek_top(), Some(&array![Int(123)])); 666 | 667 | vm.borrow_stack_mut() 668 | .force_operate() 669 | .push(String(b"hello".to_vec())); 670 | vm.execute(new_token(Aadd))?; 671 | assert_eq!( 672 | vm.peek_top(), 673 | Some(&array![Int(123), String(b"hello".to_vec())]), 674 | ); 675 | 676 | Ok(()) 677 | } 678 | 679 | #[test] 680 | fn vm_execute_bnew() -> Result<()> { 681 | let mut vm = VM::new(); 682 | 683 | vm.execute(new_token(Bnew))?; 684 | assert_eq!(vm.peek_top(), Some(&Bool(false))); 685 | 686 | Ok(()) 687 | } 688 | 689 | #[test] 690 | fn vm_execute_bneg() -> Result<()> { 691 | let mut vm = VM::new(); 692 | 693 | vm.execute(new_token(Bnew))?; 694 | assert_eq!(vm.peek_top(), Some(&Bool(false))); 695 | 696 | vm.execute(new_token(Bneg))?; 697 | assert_eq!(vm.peek_top(), Some(&Bool(true))); 698 | 699 | vm.execute(new_token(Bneg))?; 700 | assert_eq!(vm.peek_top(), Some(&Bool(false))); 701 | Ok(()) 702 | } 703 | 704 | #[test] 705 | fn vm_execute_nnew() -> Result<()> { 706 | let mut vm = VM::new(); 707 | 708 | vm.execute(new_token(Nnew))?; 709 | assert_eq!(vm.peek_top(), Some(&Nil)); 710 | 711 | Ok(()) 712 | } 713 | 714 | #[test] 715 | fn vm_execute_gdup() -> Result<()> { 716 | let mut vm = VM::new(); 717 | 718 | vm.borrow_stack_mut().force_operate().push(Int(123)); 719 | vm.execute(new_token(Gdup))?; 720 | 721 | let mut ops = vm.borrow_stack_mut().force_operate(); 722 | assert_eq!(ops.pop()?, Int(123)); 723 | assert_eq!(ops.pop()?, Int(123)); 724 | assert_error_kind_is(ops.pop(), ErrorKind::EmptyStack); 725 | 726 | Ok(()) 727 | } 728 | 729 | #[test] 730 | fn vm_execute_gpop() -> Result<()> { 731 | let mut vm = VM::new(); 732 | let mut ops = vm.borrow_stack_mut().force_operate(); 733 | 734 | ops.push(Int(111)); 735 | ops.push(Uint(222)); 736 | vm.execute(new_token(Gpop))?; 737 | 738 | let mut ops = vm.borrow_stack_mut().force_operate(); 739 | assert_eq!(ops.pop()?, Int(111)); 740 | assert_error_kind_is(ops.pop(), ErrorKind::EmptyStack); 741 | 742 | Ok(()) 743 | } 744 | 745 | #[test] 746 | fn vm_execute_gswp() -> Result<()> { 747 | let mut vm = VM::new(); 748 | let mut ops = vm.borrow_stack_mut().force_operate(); 749 | 750 | ops.push(Int(111)); 751 | ops.push(Uint(222)); 752 | vm.execute(new_token(Gswp))?; 753 | 754 | let mut ops = vm.borrow_stack_mut().force_operate(); 755 | assert_eq!(ops.pop()?, Int(111)); 756 | assert_eq!(ops.pop()?, Uint(222)); 757 | assert_error_kind_is(ops.pop(), ErrorKind::EmptyStack); 758 | 759 | Ok(()) 760 | } 761 | 762 | /* 763 | * Helper functions 764 | */ 765 | 766 | trait StackExt { 767 | fn force_operate(&mut self) -> StackOps; 768 | } 769 | 770 | impl StackExt for Stack { 771 | fn force_operate(&mut self) -> StackOps { 772 | self.operate_as(new_meaningless_token()) 773 | } 774 | } 775 | 776 | fn test_ops Result<()>>(f: F) -> Result<()> { 777 | let mut stack = Stack::new(); 778 | f(stack.force_operate()) 779 | } 780 | 781 | fn new_meaningless_token() -> Token { 782 | new_token(Iadd) 783 | } 784 | 785 | fn new_token(insn: Insn) -> Token { 786 | Token { 787 | insn: insn, 788 | location: Location { 789 | byte: b'X', 790 | path: None, 791 | line: 0, 792 | column: 0, 793 | }, 794 | } 795 | } 796 | 797 | fn assert_error_kind_is(res: Result, kind: ErrorKind) { 798 | assert_eq!(res.unwrap_err().kind, kind); 799 | } 800 | } 801 | --------------------------------------------------------------------------------