diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 000000000..b429316bb
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,2 @@
+[*]
+indent_size = 2
diff --git a/.eslintrc.yml b/.eslintrc.yml
deleted file mode 100644
index 30b02597e..000000000
--- a/.eslintrc.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-env:
- es6: true
- node: true
-extends:
- - 'eslint:recommended'
-parserOptions:
- ecmaVersion: 2018
-rules:
- indent:
- - error
- - 4
- linebreak-style:
- - error
- - unix
- quotes:
- - error
- - single
- semi:
- - error
- - always
- no-console: off
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 36d300f2b..000000000
--- a/.gitignore
+++ /dev/null
@@ -1,25 +0,0 @@
-# Idea IDE files.
-**/.idea/
-
-# VSCode IDE files.
-**/.vscode/
-
-# Compilation files by Rust.
-**/target/
-Cargo.lock
-
-# Backup files generated by rustfmt.
-**/*.rs.bk
-
-# OS X
-**/.DS_Store/
-
-# JS modules
-**/node_modules/
-package-lock.json
-yarn.lock
-.nyc_output
-
-# Borsh schema file
-**/schema_schema.dat
-
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 8428221c8..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,50 +0,0 @@
-language: rust
-rust:
- - stable
- - beta
- - nightly-2020-05-15
- - nightly
-
-matrix:
- allow_failures:
- - rust: nightly
- fast_finish: true
-
-branches:
- only:
- - master
-
-install:
- - cargo build --verbose --manifest-path=borsh-rs/Cargo.toml
-
-script:
- - cargo build --verbose --manifest-path=borsh-rs/Cargo.toml
- - cargo test --verbose --manifest-path=borsh-rs/Cargo.toml
- - cd borsh-rs/borsh && cargo test --verbose --no-default-features
-
-addons:
- apt:
- packages:
- - libcurl4-openssl-dev
- - libelf-dev
- - libdw-dev
- - cmake
- - gcc
- - binutils-dev
- - libiberty-dev
-
-after_success: |
- cd borsh-rs
- wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz &&
- tar xzf master.tar.gz &&
- cd kcov-master &&
- mkdir build &&
- cd build &&
- cmake .. &&
- make &&
- make install DESTDIR=../../kcov-build &&
- cd ../.. &&
- rm -rf kcov-master &&
- for file in target/debug/*; do [ -x "${file}" ] || continue; mkdir -p "target/cov/$(basename $file)"; ./kcov-build/usr/local/bin/kcov --exclude-pattern=/.cargo,/usr/lib --verify "target/cov/$(basename $file)" "$file"; done &&
- bash <(curl -s https://codecov.io/bash) &&
- echo "Uploaded code coverage"
\ No newline at end of file
diff --git a/LICENSE-APACHE b/LICENSE-APACHE
deleted file mode 100644
index 263ddc774..000000000
--- a/LICENSE-APACHE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright 2019 Near
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/LICENSE-MIT.txt b/LICENSE-MIT.txt
deleted file mode 100644
index 31aa79387..000000000
--- a/LICENSE-MIT.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
index 005daaa9c..9a4b4e35f 100644
--- a/README.md
+++ b/README.md
@@ -6,102 +6,42 @@
Binary Object Representation Serializer for Hashing
-
-
-
-
-
-
-
-
-
-
+ Website
+ |
+ Join Community
+ |
+ Implementations
+ |
+ Benchmarks
+ |
+ Specification
+
Why do we need yet another serialization format? Borsh is the first serializer that prioritizes the following qualities that are crucial for security-critical projects:
-* Consistent and specified binary representation:
- * Consistent means there is a bijective mapping between objects and their binary representations. There is no two binary representations that deserialize
- into the same object. This is extremely useful for applications that use binary representation to compute hash;
- * Borsh comes with a full specification that can be used for implementations in other languages;
-* Safe. Borsh implementations use safe coding practices. In Rust, Borsh uses almost only safe code, with one exception usage of `unsafe` to avoid an exhaustion attack;
-* Speed. In Rust, Borsh achieves high performance by opting out from [Serde](https://serde.rs) which makes it faster
- than [bincode](https://github.com/servo/bincode) in some cases; which also reduces the code size.
-
-## Example
-
-```rust
-use borsh::{BorshSerialize, BorshDeserialize};
-
-#[derive(BorshSerialize, BorshDeserialize, PartialEq, Debug)]
-struct A {
- x: u64,
- y: String,
-}
-#[test]
-fn test_simple_struct() {
- let a = A {
- x: 3301,
- y: "liber primus".to_string(),
- };
- let encoded_a = a.try_to_vec().unwrap();
- let decoded_a = A::try_from_slice(&encoded_a).unwrap();
- assert_eq!(a, decoded_a);
-}
-```
-
-## Features
-
-Opting out from Serde allows borsh to have some features that currently are not available for serde-compatible serializers.
-Currently we support two features: `borsh_init` and `borsh_skip` (the former one not available in Serde).
-
-`borsh_init` allows to automatically run an initialization function right after deserialization. This adds a lot of convenience for objects that are architectured to be used as strictly immutable. Usage example:
-```rust
-#[derive(BorshSerialize, BorshDeserialize)]
-#[borsh_init(init)]
-struct Message {
- message: String,
- timestamp: u64,
- public_key: CryptoKey,
- signature: CryptoSignature
- hash: CryptoHash
-}
+- Consistent and specified binary representation:
+ - Consistent means there is a bijective mapping between objects and their binary representations. There is no two binary representations that deserialize
+ into the same object. This is extremely useful for applications that use binary representation to compute hash;
+ - Borsh comes with a full specification that can be used for implementations in other languages;
+- Safe. Borsh implementations use safe coding practices. In Rust, Borsh uses almost only safe code, with one exception usage of `unsafe` to avoid an exhaustion attack;
+- Speed. In Rust, Borsh achieves high performance by opting out from [Serde](https://serde.rs) which makes it faster
+ than [bincode](https://github.com/servo/bincode) in some cases; which also reduces the code size.
-impl Message {
- pub fn init(&mut self) {
- self.hash = CryptoHash::new().write_string(self.message).write_u64(self.timestamp);
- self.signature.verify(self.hash, self.public_key);
- }
-}
-```
+## Implementations
-`borsh_skip` allows to skip serializing/deserializing fields, assuming they implement `Default` trait, similary to `#[serde(skip)]`.
-```rust
-#[derive(BorshSerialize, BorshDeserialize)]
-struct A {
- x: u64,
- #[borsh_skip]
- y: f32,
-}
-```
+| Platform | Repository | Latest Release |
+| --------------------------------- | -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
+| Rust | [borsh-rs](https://github.com/near/borsh-rs) | |
+| TypeScript, JavaScript | [borsh-js](https://github.com/near/borsh-js) | |
+| Java, Kotlin, Scala, Clojure, etc | [borshj](https://github.com/near/borshj) | |
+| Python | [borsh-py](https://github.com/near/borsh-py) | Work-in-progress |
## Benchmarks
We measured the following benchmarks on objects that blockchain projects care about the most: blocks, block headers,
-transactions, accounts. We took object structure from the [nearprotocol](https://nearprotocol.com) blockchain.
+transactions, accounts. We took object structure from the [NEAR Protocol](https://near.org) blockchain.
We used [Criterion](https://bheisler.github.io/criterion.rs/book/index.html) for building the following graphs.
The benchmarks were run on Google Cloud [n1-standard-2 (2 vCPUs, 7.5 GB memory)](https://cloud.google.com/compute/docs/machine-types).
@@ -125,159 +65,150 @@ Block de-serialization speed vs block size in bytes:
See complete report [here](http://borsh.io/criterion/report/index.html).
## Specification
-In short, Borsh is a non self-describing binary serialization format. It is designed to serialize any objects to canonical and deterministic set of bytes.
-
-General principles:
-* integers are little endian;
-* sizes of dynamic containers are written before values as `u32`;
-* all unordered containers (hashmap/hashset) are ordered in lexicographic order by key (in tie breaker case on value);
-* structs are serialized in the order of fields in the struct;
-* enums are serialized with using `u8` for the enum ordinal and then storing data inside the enum value (if present).
-
-Formal specification:
-
-
- Informal type Rust EBNF * Pseudocode
-
- Integers
- integer_type: ["u8" | "u16" | "u32" | "u64" | "u128" | "i8" | "i16" | "i32" | "i64" | "i128" ]
- little_endian(x)
-
-
- Floats
- float_type: ["f32" | "f64" ]
- err_if_nan(x) little_endian(x as integer_type)
-
-
- Unit
- unit_type: "()" We do not write anything
-
-
- Fixed sized arrays
- array_type: '[' ident ';' literal ']'
- for el in x repr(el as ident)
-
-
- Dynamic sized array
- vec_type: "Vec<" ident '>'
- repr(len() as u32)
- for el in x
- repr(el as ident)
-
-
-
- Struct
- struct_type: "struct" ident fields repr(fields)
-
-
- Fields
- fields: [named_fields | unnamed_fields]
-
-
-
- Named fields
- named_fields: '{' ident_field0 ':' ident_type0 ',' ident_field1 ':' ident_type1 ',' ... '}'
- repr(ident_field0 as ident_type0)
- repr(ident_field1 as ident_type1)
- ...
-
-
-
- Unnamed fields
- unnamed_fields: '(' ident_type0 ',' ident_type1 ',' ... ')' repr(x.0 as type0) repr(x.1 as type1) ...
-
-
- Enum
- enum: 'enum' ident '{' variant0 ',' variant1 ',' ... '}'
- variant: ident [ fields ] ?
-
- Suppose X is the number of the variant that the enum takes.
- repr(X as u8)
- repr(x.X as fieldsX)
-
-
- HashMap hashmap: "HashMap<" ident0, ident1 ">"
- repr(x.len() as u32)
- for (k, v) in x.sorted_by_key() {
- repr(k as ident0)
- repr(v as ident1)
- }
- HashSet hashset: "HashSet<" ident ">"
- repr(x.len() as u32)
- for el in x.sorted() {
- repr(el as ident)
- }
-
- Option
- option_type: "Option<" ident '>'
- if x.is_some() {
- repr(1 as u8)
- repr(x.unwrap() as ident)
- } else {
- repr(0 as u8)
- }
-
-
-
- String
- string_type: "String"
- encoded = utf8_encoding(x) as Vec<u8>
- repr(encoded.len() as u32)
- repr(encoded as Vec<u8>)
-
-
-
-
-Note:
-* Some parts of Rust grammar are not yet formalized, like enums and variants. We backwards derive EBNF forms of Rust grammar from [syn types](https://github.com/dtolnay/syn);
-* We had to extend repetitions of EBNF and instead of defining them as `[ ident_field ':' ident_type ',' ] *` we define them as `ident_field0 ':' ident_type0 ',' ident_field1 ':' ident_type1 ',' ...` so that we can refer to individual elements in the pseudocode;
-* We use `repr()` function to denote that we are writing the representation of the given element into an imaginary buffer.
-
-## Releasing
-
-After you merged your change into the master branch and bumped the versions of all three crates it is time to officially release the new version.
-
-Make sure `borsh`, `borsh-derive` and `borsh-derive-internal` all have the new crate versions. Then navigate to each folder and run (in the given order):
-```bash
-cd ../borsh-derive-internal; cargo publish
-cd ../borsh-derive; cargo publish
-cd ../borsh; cargo publish
-```
-Make sure you are on the master branch, then tag the code and push the tag:
-```bash
-git tag -a v9.9.9 -m "My superawesome change."
-git push origin v9.9.9
-```
+In short, Borsh is a non self-describing binary serialization format. It is designed to serialize any objects to canonical and deterministic set of bytes.
-# TypeScript/JavaScript
-
-## Contributing
-
-Install dependencies:
-```bash
-yarn install
-```
+General principles:
-Continuesly build with:
-```bash
-yarn dev
-```
+- integers are little endian;
+- sizes of dynamic containers are written before values as `u32`;
+- all unordered containers (hashmap/hashset) are ordered in lexicographic order by key (in tie breaker case on value);
+- structs are serialized in the order of fields in the struct;
+- enums are serialized with using `u8` for the enum ordinal and then storing data inside the enum value (if present).
-Run tests:
-```bash
-yarn test
-```
+Formal specification:
-Run linter
-```bash
-yarn lint
-```
-## Publish
+
+
+
+ Informal type
+ Rust EBNF *
+ Pseudocode
+
+
+ Integers
+ integer_type: ["u8" | "u16" | "u32" | "u64" | "u128" | "i8" | "i16" | "i32" | "i64" | "i128" ]
+ little_endian(x)
+
+
+ Floats
+ float_type: ["f32" | "f64" ]
+
+ err_if_nan(x)
+ little_endian(x as integer_type)
+
+
+
+ Unit
+ unit_type: "()"
+ We do not write anything
+
+
+ Fixed sized arrays
+ array_type: '[' ident ';' literal ']'
+
+ for el in x {
+ repr(el as ident)
+ }
+
+
+
+ Dynamic sized array
+ vec_type: "Vec<" ident '>'
+
+ repr(len() as u32)
+ for el in x {
+ repr(el as ident)
+ }
+
+
+
+ Struct
+ struct_type: "struct" ident fields
+ repr(fields)
+
+
+ Fields
+ fields: [named_fields | unnamed_fields]
+
+
+
+ Named fields
+ named_fields: '{' ident_field0 ':' ident_type0 ',' ident_field1 ':' ident_type1 ',' ... '}'
+
+ repr(ident_field0 as ident_type0)
+ repr(ident_field1 as ident_type1)
+ ...
+
+
+
+ Unnamed fields
+ unnamed_fields: '(' ident_type0 ',' ident_type1 ',' ... ')'
+
+ repr(x.0 as type0)
+ repr(x.1 as type1)
+ ...
+
+
+
+ Enum
+
+ enum: 'enum' ident '{' variant0 ',' variant1 ',' ... '}'
+ variant: ident [ fields ] ?
+
+
+ Suppose X is the number of the variant that the enum takes.
+ repr(X as u8)
+ repr(x.X as fieldsX)
+
+
+
+ HashMap
+ hashmap: "HashMap<" ident0, ident1 ">"
+
+ repr(x.len() as u32)
+ for (k, v) in x.sorted_by_key() {
+ repr(k as ident0)
+ repr(v as ident1)
+ }
+
+
+
+ HashSet
+ hashset: "HashSet<" ident ">"
+
+ repr(x.len() as u32)
+ for el in x.sorted() {
+ repr(el as ident)
+ }
+
+
+
+ Option
+ option_type: "Option<" ident '>'
+
+ if x.is_some() {
+ repr(1 as u8)
+ repr(x.unwrap() as ident
+ } else {
+ repr(0 as u8)
+ }
+
+
+
+ String
+ string_type: "String"
+
+ encoded = utf8_encoding(x) as Vec<u8>
+ repr(encoded.len() as u32)
+ repr(encoded as Vec<u8>)
+
+
+
+
-Prepare `dist` version by running:
-```bash
-yarn build
-```
+Note:
-When publishing to npm use [np](https://github.com/sindresorhus/np).
\ No newline at end of file
+- Some parts of Rust grammar are not yet formalized, like enums and variants. We backwards derive EBNF forms of Rust grammar from [syn types](https://github.com/dtolnay/syn);
+- We had to extend repetitions of EBNF and instead of defining them as `[ ident_field ':' ident_type ',' ] *` we define them as `ident_field0 ':' ident_type0 ',' ident_field1 ':' ident_type1 ',' ...` so that we can refer to individual elements in the pseudocode;
+- We use `repr()` function to denote that we are writing the representation of the given element into an imaginary buffer.
diff --git a/borsh-rs/CHANGELOG.md b/borsh-rs/CHANGELOG.md
deleted file mode 100644
index 0707c4f2d..000000000
--- a/borsh-rs/CHANGELOG.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# Changelog
-
-## 0.8.0
-- Add no_std support.
-
-## 0.7.2
-- Implement `BorshSerialize` for reference fields (`&T`)
-
-## 0.7.1
-- Implement `BorshSerialize` for `&T` if `T` implements `BorshSerialize`.
-
-## 0.7.0
-
-- Extended `Box` implementation for `?Sized` types (`[T]`, `str`, ...).
-- Added support for `std::borrow::Cow`
-- Avoid silent integer casts since they can lead to hidden security issues.
-- Removed `Cargo.lock` as it is advised for lib crates.
-
diff --git a/borsh-rs/Cargo.toml b/borsh-rs/Cargo.toml
deleted file mode 100644
index f8bcfd1e0..000000000
--- a/borsh-rs/Cargo.toml
+++ /dev/null
@@ -1,11 +0,0 @@
-[workspace]
-members = [
-"borsh",
-"borsh-derive",
-"borsh-derive-internal",
-"borsh-schema-derive-internal",
-"benchmarks",
-]
-exclude = [
-"fuzz",
-]
diff --git a/borsh-rs/benchmarks/Cargo.toml b/borsh-rs/benchmarks/Cargo.toml
deleted file mode 100644
index 98d3bfbdc..000000000
--- a/borsh-rs/benchmarks/Cargo.toml
+++ /dev/null
@@ -1,30 +0,0 @@
-[package]
-name = "benchmarks"
-version = "0.1.0"
-authors = ["Near Inc "]
-edition = "2018"
-
-# This is somehow needed for command line arguments to work: https://github.com/bheisler/criterion.rs/issues/193#issuecomment-415740713
-[lib]
-bench = false
-
-[dependencies]
-rand_xorshift = "0.2.0"
-rand = "0.7.0"
-borsh = { path = "../borsh", default-features = false }
-serde = { version = "1.0", features = ["derive"] }
-speedy-derive = "0.5"
-speedy = "0.5"
-
-[dev-dependencies]
-criterion = "0.3.0"
-bincode = "1.1.4"
-serde_cbor = "0.10"
-
-
-[[bench]]
-name = "bench"
-harness = false
-
-[features]
-default = ["borsh/std"]
\ No newline at end of file
diff --git a/borsh-rs/benchmarks/README.md b/borsh-rs/benchmarks/README.md
deleted file mode 100644
index b12bf6345..000000000
--- a/borsh-rs/benchmarks/README.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# Borsh benchmarks
-
-To run benchmarks execute:
-
-```bash
-cargo bench
-```
-
-If you want to make a change and see how it affects the performance then
-copy `criterion` folder from `docs` into `target` folder so that you have `target/criterion`, and run the benchmarks.
-Criterion will print whether the change has statistically significant positive/negative impact based on p-values or
-whether it is within noise. Unfortunately, benchmarks related to serializing `Account` and `SignedTransaction` turned out to
-be highly volatile therefore prefer using `Block` and `BlockHeader` as the measurement of the performance change.
-We use default Criterion setting for determining statistical significance, which corresponds to 2 sigma.
-
-We run benchmarks using `n1-standard-2 (2 vCPUs, 7.5 GB memory)` on GCloud. Make sure the instance
-is not running any other heavy process.
diff --git a/borsh-rs/benchmarks/benches/bench.rs b/borsh-rs/benchmarks/benches/bench.rs
deleted file mode 100644
index 43536f4be..000000000
--- a/borsh-rs/benchmarks/benches/bench.rs
+++ /dev/null
@@ -1,180 +0,0 @@
-use benchmarks::{Account, Block, BlockHeader, Generate, SignedTransaction};
-use borsh::{BorshDeserialize, BorshSerialize};
-use rand::SeedableRng;
-use serde::{Deserialize as SerdeDeserialize, Serialize as SerdeSerialize};
-use speedy::Endianness;
-use speedy::{Readable, Writable};
-
-use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
-
-fn ser_obj(group_name: &str, num_samples: usize, c: &mut Criterion)
-where
- for<'a> T: Generate
- + BorshSerialize
- + BorshDeserialize
- + SerdeSerialize
- + SerdeDeserialize<'a>
- + Readable<'a, speedy::Endianness>
- + Writable
- + 'static,
-{
- let mut rng = rand_xorshift::XorShiftRng::from_seed([0u8; 16]);
- let mut group = c.benchmark_group(group_name);
-
- let objects: Vec<_> = (0..num_samples).map(|_| T::generate(&mut rng)).collect();
- let borsh_datas: Vec> = objects.iter().map(|t| t.try_to_vec().unwrap()).collect();
- let borsh_sizes: Vec<_> = borsh_datas.iter().map(|d| d.len()).collect();
-
- for i in 0..objects.len() {
- let size = borsh_sizes[i];
- let obj = &objects[i];
-
- let benchmark_param_display = format!("idx={}; size={}", i, size);
-
- group.throughput(Throughput::Bytes(size as u64));
- group.bench_with_input(
- BenchmarkId::new("cbor", benchmark_param_display.clone()),
- obj,
- |b, d| {
- b.iter(|| serde_cbor::to_vec(d).unwrap());
- },
- );
- group.bench_with_input(
- BenchmarkId::new("bincode", benchmark_param_display.clone()),
- obj,
- |b, d| {
- b.iter(|| bincode::serialize(d).unwrap());
- },
- );
- group.bench_with_input(
- BenchmarkId::new("borsh", benchmark_param_display.clone()),
- obj,
- |b, d| {
- b.iter(|| d.try_to_vec().unwrap());
- },
- );
- group.bench_with_input(
- BenchmarkId::new("speedy", benchmark_param_display),
- obj,
- |b, d| {
- b.iter(|| d.write_to_vec(Endianness::LittleEndian).unwrap());
- },
- );
- }
- group.finish();
-}
-
-fn de_obj(group_name: &str, num_samples: usize, c: &mut Criterion)
-where
- for<'a> T: Generate
- + BorshSerialize
- + BorshDeserialize
- + SerdeSerialize
- + SerdeDeserialize<'a>
- + Readable<'a, speedy::Endianness>
- + Writable
- + 'static,
-{
- let mut rng = rand_xorshift::XorShiftRng::from_seed([0u8; 16]);
- let mut group = c.benchmark_group(group_name);
-
- let objects: Vec<_> = (0..num_samples).map(|_| T::generate(&mut rng)).collect();
- let cbor_datas: Vec> = objects
- .iter()
- .map(|t| serde_cbor::to_vec(t).unwrap())
- .collect();
- let bincode_datas: Vec> = objects
- .iter()
- .map(|t| bincode::serialize(t).unwrap())
- .collect();
- let borsh_datas: Vec> = objects.iter().map(|t| t.try_to_vec().unwrap()).collect();
- let speedy_datas: Vec> = objects
- .iter()
- .map(|t| t.write_to_vec(Endianness::LittleEndian).unwrap())
- .collect();
-
- let borsh_sizes: Vec<_> = borsh_datas.iter().map(|d| d.len()).collect();
-
- for i in 0..objects.len() {
- let size = borsh_sizes[i];
- let cbor_data = &cbor_datas[i];
- let bincode_data = &bincode_datas[i];
- let borsh_data = &borsh_datas[i];
- let speedy_data = &speedy_datas[i];
-
- let benchmark_param_display = format!("idx={}; size={}", i, size);
-
- group.throughput(Throughput::Bytes(size as u64));
- group.bench_with_input(
- BenchmarkId::new("cbor", benchmark_param_display.clone()),
- cbor_data,
- |b, d| {
- b.iter(|| serde_cbor::from_slice::(&d).unwrap());
- },
- );
- group.bench_with_input(
- BenchmarkId::new("bincode", benchmark_param_display.clone()),
- bincode_data,
- |b, d| {
- b.iter(|| bincode::deserialize::(&d).unwrap());
- },
- );
- group.bench_with_input(
- BenchmarkId::new("borsh", benchmark_param_display.clone()),
- borsh_data,
- |b, d| {
- b.iter(|| T::try_from_slice(&d).unwrap());
- },
- );
- group.bench_with_input(
- BenchmarkId::new("speedy", benchmark_param_display),
- speedy_data,
- |b, d| {
- b.iter(|| T::read_from_buffer(Endianness::LittleEndian, &d).unwrap());
- },
- );
- }
- group.finish();
-}
-
-fn ser_account(c: &mut Criterion) {
- ser_obj::("ser_account", 10, c);
-}
-
-fn ser_transaction(c: &mut Criterion) {
- ser_obj::("ser_transaction", 10, c);
-}
-
-fn ser_header(c: &mut Criterion) {
- ser_obj::("ser_header", 10, c);
-}
-
-fn ser_block(c: &mut Criterion) {
- ser_obj::("ser_block", 10, c);
-}
-
-fn de_account(c: &mut Criterion) {
- de_obj::("de_account", 10, c);
-}
-
-fn de_transaction(c: &mut Criterion) {
- de_obj::("de_transaction", 10, c);
-}
-
-fn de_header(c: &mut Criterion) {
- de_obj::("de_header", 10, c);
-}
-
-fn de_block(c: &mut Criterion) {
- de_obj::("de_block", 10, c);
-}
-
-criterion_group!(
- ser_benches,
- ser_account,
- ser_transaction,
- ser_header,
- ser_block
-);
-criterion_group!(de_benches, de_account, de_transaction, de_header, de_block);
-criterion_main!(ser_benches, de_benches);
diff --git a/borsh-rs/benchmarks/src/lib.rs b/borsh-rs/benchmarks/src/lib.rs
deleted file mode 100644
index b2fc3dc31..000000000
--- a/borsh-rs/benchmarks/src/lib.rs
+++ /dev/null
@@ -1,759 +0,0 @@
-//! This library contains data structures used for benchmarking.
-
-use borsh::{BorshDeserialize, BorshSerialize};
-use rand::distributions::{Alphanumeric, Distribution, Standard};
-use rand::Rng;
-use serde::{Deserialize as SerdeDeserialize, Serialize as SerdeSerialize};
-extern crate speedy_derive;
-use speedy::{Context, Readable, Reader, Writable, Writer};
-
-pub trait Generate {
- fn generate(rng: &mut R) -> Self;
-}
-
-#[derive(
- BorshSerialize, BorshDeserialize, Debug, Clone, Eq, PartialEq, SerdeSerialize, SerdeDeserialize,
-)]
-pub struct CryptoHash([u8; 32]);
-impl Generate for CryptoHash {
- fn generate(rng: &mut R) -> Self {
- let mut res = [0u8; 32];
- rng.fill_bytes(&mut res);
- CryptoHash(res)
- }
-}
-
-impl<'a, C> Readable<'a, C> for CryptoHash
-where
- C: Context,
-{
- fn read_from>(reader: &mut R) -> std::result::Result {
- let mut data = [0u8; 32];
- reader.read_bytes(&mut data)?;
- Ok(Self(data))
- }
-}
-
-impl Writable for CryptoHash {
- fn write_to<'a, T: ?Sized + Writer<'a, C>>(
- &'a self,
- writer: &mut T,
- ) -> std::result::Result<(), std::io::Error> {
- writer.write_bytes(&self.0).map(|_| ())
- }
-}
-
-#[derive(
- BorshSerialize, BorshDeserialize, Debug, Clone, Eq, PartialEq, SerdeSerialize, SerdeDeserialize,
-)]
-pub struct MerkleHash([u8; 32]);
-impl Generate for MerkleHash {
- fn generate(rng: &mut R) -> Self {
- let mut res = [0u8; 32];
- rng.fill_bytes(&mut res);
- MerkleHash(res)
- }
-}
-
-impl<'a, C> Readable<'a, C> for MerkleHash
-where
- C: Context,
-{
- fn read_from>(reader: &mut R) -> std::result::Result {
- let mut data = [0u8; 32];
- reader.read_bytes(&mut data)?;
- Ok(Self(data))
- }
-}
-
-impl Writable for MerkleHash {
- fn write_to<'a, T: ?Sized + Writer<'a, C>>(
- &'a self,
- writer: &mut T,
- ) -> std::result::Result<(), std::io::Error> {
- writer.write_bytes(&self.0).map(|_| ())
- }
-}
-
-#[derive(
- BorshSerialize, BorshDeserialize, Debug, Clone, Eq, PartialEq, SerdeSerialize, SerdeDeserialize,
-)]
-pub struct Signature([u8; 32]);
-impl Generate for Signature {
- fn generate(rng: &mut R) -> Self {
- let mut res = [0u8; 32];
- rng.fill_bytes(&mut res);
- Signature(res)
- }
-}
-
-impl<'a, C> Readable<'a, C> for Signature
-where
- C: Context,
-{
- fn read_from>(reader: &mut R) -> std::result::Result {
- let mut data = [0u8; 32];
- reader.read_bytes(&mut data)?;
- Ok(Self(data))
- }
-}
-
-impl Writable for Signature {
- fn write_to<'a, T: ?Sized + Writer<'a, C>>(
- &'a self,
- writer: &mut T,
- ) -> std::result::Result<(), std::io::Error> {
- writer.write_bytes(&self.0).map(|_| ())
- }
-}
-
-#[derive(
- BorshSerialize, BorshDeserialize, Debug, Clone, Eq, PartialEq, SerdeSerialize, SerdeDeserialize,
-)]
-pub struct PublicKey([u8; 32]);
-impl Generate for PublicKey {
- fn generate(rng: &mut R) -> Self {
- let mut res = [0u8; 32];
- rng.fill_bytes(&mut res);
- PublicKey(res)
- }
-}
-
-impl<'a, C> Readable<'a, C> for PublicKey
-where
- C: Context,
-{
- fn read_from>(reader: &mut R) -> std::result::Result {
- let mut data = [0u8; 32];
- reader.read_bytes(&mut data)?;
- Ok(Self(data))
- }
-}
-
-impl Writable for PublicKey {
- fn write_to<'a, T: ?Sized + Writer<'a, C>>(
- &'a self,
- writer: &mut T,
- ) -> std::result::Result<(), std::io::Error> {
- writer.write_bytes(&self.0).map(|_| ())
- }
-}
-
-#[derive(
- BorshSerialize,
- BorshDeserialize,
- Debug,
- Clone,
- Eq,
- PartialEq,
- SerdeSerialize,
- SerdeDeserialize,
- Readable,
- Writable,
-)]
-pub struct AccountId(String);
-impl Generate for String {
- fn generate(rng: &mut R) -> Self {
- let len: usize = rng.gen_range(5, 200);
- rng.sample_iter(&Alphanumeric).take(len).collect::()
- }
-}
-
-impl Generate for AccountId {
- fn generate(rng: &mut R) -> Self {
- AccountId(String::generate(rng))
- }
-}
-
-pub type Balance = u64;
-
-#[derive(
- BorshSerialize,
- BorshDeserialize,
- Debug,
- Clone,
- Eq,
- PartialEq,
- SerdeSerialize,
- SerdeDeserialize,
- Readable,
- Writable,
-)]
-pub struct ValidatorStake {
- pub account_id: AccountId,
- pub public_key: PublicKey,
- pub amount: Balance,
-}
-
-impl Generate for ValidatorStake {
- fn generate(rng: &mut R) -> Self {
- Self {
- account_id: AccountId::generate(rng),
- public_key: PublicKey::generate(rng),
- amount: u64::generate(rng),
- }
- }
-}
-
-pub type BlockIndex = u64;
-pub type Weight = u64;
-
-pub fn generate_vec_primitives(rng: &mut R, min_number: usize, max_number: usize) -> Vec
-where
- Standard: Distribution,
- R: rand::Rng,
-{
- let num: usize = rng.gen_range(min_number, max_number + 1);
- let mut res = vec![];
- for _ in 0..num {
- res.push(rng.gen());
- }
- res
-}
-
-pub fn generate_vec(
- rng: &mut R,
- min_number: usize,
- max_number: usize,
-) -> Vec {
- let num: usize = rng.gen_range(min_number, max_number + 1);
- let mut res = vec![];
- for _ in 0..num {
- res.push(T::generate(rng));
- }
- res
-}
-
-#[derive(
- BorshSerialize,
- BorshDeserialize,
- Debug,
- Clone,
- Eq,
- PartialEq,
- SerdeSerialize,
- SerdeDeserialize,
- Readable,
- Writable,
-)]
-pub struct BlockHeaderInner {
- pub height: BlockIndex,
- pub epoch_hash: CryptoHash,
- pub prev_hash: CryptoHash,
- pub prev_state_root: MerkleHash,
- pub tx_root: MerkleHash,
- pub timestamp: u64,
- pub approval_mask: Vec,
- pub approval_sigs: Vec,
- pub total_weight: Weight,
- pub validator_proposals: Vec,
-}
-
-impl Generate for BlockHeaderInner {
- fn generate(rng: &mut R) -> Self {
- Self {
- height: u64::generate(rng),
- epoch_hash: CryptoHash::generate(rng),
- prev_hash: CryptoHash::generate(rng),
- prev_state_root: MerkleHash::generate(rng),
- tx_root: MerkleHash::generate(rng),
- timestamp: u64::generate(rng),
- approval_mask: generate_vec_primitives(rng, 2, 1000),
- approval_sigs: generate_vec(rng, 2, 1000),
- total_weight: u64::generate(rng),
- validator_proposals: generate_vec(rng, 2, 1000),
- }
- }
-}
-
-#[derive(
- BorshSerialize,
- BorshDeserialize,
- Debug,
- Clone,
- Eq,
- PartialEq,
- SerdeSerialize,
- SerdeDeserialize,
- Readable,
- Writable,
-)]
-pub struct BlockHeader {
- pub inner: BlockHeaderInner,
- pub signature: Signature,
- pub hash: CryptoHash,
-}
-
-impl Generate for BlockHeader {
- fn generate(rng: &mut R) -> Self {
- Self {
- inner: BlockHeaderInner::generate(rng),
- signature: Signature::generate(rng),
- hash: CryptoHash::generate(rng),
- }
- }
-}
-
-#[derive(
- BorshSerialize,
- BorshDeserialize,
- Debug,
- Clone,
- Eq,
- PartialEq,
- SerdeSerialize,
- SerdeDeserialize,
- Readable,
- Writable,
-)]
-pub struct Block {
- pub header: BlockHeader,
- pub transactions: Vec,
-}
-
-impl Generate for Block {
- fn generate(rng: &mut R) -> Self {
- Self {
- header: BlockHeader::generate(rng),
- transactions: generate_vec(rng, 0, 1000),
- }
- }
-}
-
-#[derive(
- BorshSerialize,
- BorshDeserialize,
- Debug,
- Clone,
- Eq,
- PartialEq,
- SerdeSerialize,
- SerdeDeserialize,
- Readable,
- Writable,
-)]
-pub struct SignedTransaction {
- transaction: Transaction,
- signature: Signature,
- hash: CryptoHash,
-}
-
-impl Generate for SignedTransaction {
- fn generate(rng: &mut R) -> Self {
- Self {
- transaction: Transaction::generate(rng),
- signature: Signature::generate(rng),
- hash: CryptoHash::generate(rng),
- }
- }
-}
-
-pub type Nonce = u64;
-
-#[derive(
- BorshSerialize,
- BorshDeserialize,
- Debug,
- Clone,
- Eq,
- PartialEq,
- SerdeSerialize,
- SerdeDeserialize,
- Readable,
- Writable,
-)]
-pub struct Transaction {
- signer_id: AccountId,
- public_key: PublicKey,
- nonce: Nonce,
- receiver_id: AccountId,
- actions: Vec,
-}
-
-impl Generate for Transaction {
- fn generate(rng: &mut R) -> Self {
- Self {
- signer_id: AccountId::generate(rng),
- public_key: PublicKey::generate(rng),
- nonce: u64::generate(rng),
- receiver_id: AccountId::generate(rng),
- actions: generate_vec(rng, 1, 10),
- }
- }
-}
-
-#[derive(
- BorshSerialize,
- BorshDeserialize,
- Debug,
- Clone,
- Eq,
- PartialEq,
- SerdeSerialize,
- SerdeDeserialize,
- Readable,
- Writable,
-)]
-pub enum Action {
- CreateAccount(CreateAccountAction),
- DeployContract(DeployContractAction),
- FunctionCall(FunctionCallAction),
- Transfer(TransferAction),
- Stake(StakeAction),
- AddKey(AddKeyAction),
- DeleteKey(DeleteKeyAction),
- DeleteAccount(DeleteAccountAction),
-}
-
-impl Generate for Action {
- fn generate(rng: &mut R) -> Self {
- use Action::*;
- // Deploy contract action is 1000 times less frequent than other actions.
- if u64::generate(rng) % 1000 == 0 {
- DeployContract(DeployContractAction::generate(rng))
- } else {
- match u64::generate(rng) % 7 {
- 0 => CreateAccount(CreateAccountAction::generate(rng)),
- 1 => FunctionCall(FunctionCallAction::generate(rng)),
- 2 => Transfer(TransferAction::generate(rng)),
- 3 => Stake(StakeAction::generate(rng)),
- 4 => AddKey(AddKeyAction::generate(rng)),
- 5 => DeleteKey(DeleteKeyAction::generate(rng)),
- 6 => DeleteAccount(DeleteAccountAction::generate(rng)),
- _ => unimplemented!(),
- }
- }
- }
-}
-
-#[derive(
- BorshSerialize,
- BorshDeserialize,
- Debug,
- Clone,
- Eq,
- PartialEq,
- SerdeSerialize,
- SerdeDeserialize,
- Readable,
- Writable,
-)]
-pub struct CreateAccountAction {}
-impl Generate for CreateAccountAction {
- fn generate(_rng: &mut R) -> Self {
- Self {}
- }
-}
-
-#[derive(
- BorshSerialize,
- BorshDeserialize,
- Debug,
- Clone,
- Eq,
- PartialEq,
- SerdeSerialize,
- SerdeDeserialize,
- Readable,
- Writable,
-)]
-pub struct DeployContractAction {
- code: Vec,
-}
-
-pub fn generate_vec_u8(rng: &mut R, min_number: usize, max_number: usize) -> Vec {
- let num: usize = rng.gen_range(min_number, max_number + 1);
- let mut res = vec![0u8; num];
- rng.fill_bytes(&mut res);
- res
-}
-
-impl Generate for DeployContractAction {
- fn generate(rng: &mut R) -> Self {
- Self {
- // Between 20KiB and 1MiB.
- code: generate_vec_u8(rng, 20 * 2usize.pow(10), 2usize.pow(20)),
- }
- }
-}
-
-pub type Gas = u64;
-
-#[derive(
- BorshSerialize,
- BorshDeserialize,
- Debug,
- Clone,
- Eq,
- PartialEq,
- SerdeSerialize,
- SerdeDeserialize,
- Readable,
- Writable,
-)]
-pub struct FunctionCallAction {
- method_name: String,
- args: Vec,
- gas: Gas,
- deposit: Balance,
-}
-
-impl Generate for FunctionCallAction {
- fn generate(rng: &mut R) -> Self {
- Self {
- method_name: String::generate(rng),
- args: generate_vec_u8(rng, 0, 1000),
- gas: u64::generate(rng),
- deposit: u64::generate(rng),
- }
- }
-}
-#[derive(
- BorshSerialize,
- BorshDeserialize,
- Debug,
- Clone,
- Eq,
- PartialEq,
- SerdeSerialize,
- SerdeDeserialize,
- Readable,
- Writable,
-)]
-pub struct TransferAction {
- deposit: Balance,
-}
-impl Generate for TransferAction {
- fn generate(rng: &mut R) -> Self {
- Self {
- deposit: u64::generate(rng),
- }
- }
-}
-
-#[derive(
- BorshSerialize,
- BorshDeserialize,
- Debug,
- Clone,
- Eq,
- PartialEq,
- SerdeSerialize,
- SerdeDeserialize,
- Readable,
- Writable,
-)]
-pub struct StakeAction {
- stake: Balance,
- public_key: PublicKey,
-}
-
-impl Generate for StakeAction {
- fn generate(rng: &mut R) -> Self {
- Self {
- stake: u64::generate(rng),
- public_key: PublicKey::generate(rng),
- }
- }
-}
-
-#[derive(
- BorshSerialize,
- BorshDeserialize,
- Debug,
- Clone,
- Eq,
- PartialEq,
- SerdeSerialize,
- SerdeDeserialize,
- Readable,
- Writable,
-)]
-pub struct AddKeyAction {
- public_key: PublicKey,
- access_key: AccessKey,
-}
-
-impl Generate for AddKeyAction {
- fn generate(rng: &mut R) -> Self {
- Self {
- public_key: PublicKey::generate(rng),
- access_key: AccessKey::generate(rng),
- }
- }
-}
-
-#[derive(
- BorshSerialize,
- BorshDeserialize,
- Debug,
- Clone,
- Eq,
- PartialEq,
- SerdeSerialize,
- SerdeDeserialize,
- Readable,
- Writable,
-)]
-pub struct DeleteKeyAction {
- public_key: PublicKey,
-}
-
-impl Generate for DeleteKeyAction {
- fn generate(rng: &mut R) -> Self {
- Self {
- public_key: PublicKey::generate(rng),
- }
- }
-}
-
-#[derive(
- BorshSerialize,
- BorshDeserialize,
- Debug,
- Clone,
- Eq,
- PartialEq,
- SerdeSerialize,
- SerdeDeserialize,
- Readable,
- Writable,
-)]
-pub struct DeleteAccountAction {
- beneficiary_id: AccountId,
-}
-
-impl Generate for DeleteAccountAction {
- fn generate(rng: &mut R) -> Self {
- Self {
- beneficiary_id: AccountId::generate(rng),
- }
- }
-}
-
-#[derive(
- BorshSerialize,
- BorshDeserialize,
- Debug,
- Clone,
- Eq,
- PartialEq,
- SerdeSerialize,
- SerdeDeserialize,
- Readable,
- Writable,
-)]
-pub struct AccessKey {
- nonce: Nonce,
- permission: AccessKeyPermission,
-}
-
-impl Generate for AccessKey {
- fn generate(rng: &mut R) -> Self {
- Self {
- nonce: u64::generate(rng),
- permission: AccessKeyPermission::generate(rng),
- }
- }
-}
-
-#[derive(
- BorshSerialize,
- BorshDeserialize,
- Debug,
- Clone,
- Eq,
- PartialEq,
- SerdeSerialize,
- SerdeDeserialize,
- Readable,
- Writable,
-)]
-pub enum AccessKeyPermission {
- FunctionCall(FunctionCallPermission),
- FullAccess,
-}
-
-impl Generate for AccessKeyPermission {
- fn generate(rng: &mut R) -> Self {
- if u64::generate(rng) % 2 == 0 {
- AccessKeyPermission::FunctionCall(FunctionCallPermission::generate(rng))
- } else {
- AccessKeyPermission::FullAccess
- }
- }
-}
-
-#[derive(
- BorshSerialize,
- BorshDeserialize,
- Debug,
- Clone,
- Eq,
- PartialEq,
- SerdeSerialize,
- SerdeDeserialize,
- Readable,
- Writable,
-)]
-pub struct FunctionCallPermission {
- allowance: Option,
- receiver_id: AccountId,
- method_names: Vec,
-}
-
-fn generate_option(rng: &mut R) -> Option {
- if u64::generate(rng) % 2 == 0 {
- None
- } else {
- Some(T::generate(rng))
- }
-}
-
-impl Generate for u64 {
- fn generate(rng: &mut R) -> Self {
- rng.next_u64()
- }
-}
-
-impl Generate for FunctionCallPermission {
- fn generate(rng: &mut R) -> Self {
- Self {
- allowance: generate_option(rng),
- receiver_id: AccountId::generate(rng),
- method_names: generate_vec(rng, 0, 10),
- }
- }
-}
-
-#[derive(
- BorshSerialize,
- BorshDeserialize,
- Debug,
- Clone,
- Eq,
- PartialEq,
- SerdeSerialize,
- SerdeDeserialize,
- Readable,
- Writable,
-)]
-pub struct Account {
- pub amount: Balance,
- pub staked: Balance,
- pub code_hash: CryptoHash,
- pub storage_usage: u64,
- pub storage_paid_at: u64,
-}
-
-impl Generate for Account {
- fn generate(rng: &mut R) -> Self {
- Self {
- amount: u64::generate(rng),
- staked: u64::generate(rng),
- code_hash: CryptoHash::generate(rng),
- storage_usage: u64::generate(rng),
- storage_paid_at: u64::generate(rng),
- }
- }
-}
diff --git a/borsh-rs/borsh-derive-internal/Cargo.toml b/borsh-rs/borsh-derive-internal/Cargo.toml
deleted file mode 100644
index 57cee6fb3..000000000
--- a/borsh-rs/borsh-derive-internal/Cargo.toml
+++ /dev/null
@@ -1,18 +0,0 @@
-[package]
-name = "borsh-derive-internal"
-version = "0.8.0"
-authors = ["Near Inc "]
-edition = "2018"
-license = "Apache-2.0"
-readme = "README.md"
-categories = ["encoding", "network-programming"]
-repository = "https://github.com/nearprotocol/borsh"
-homepage = "http://borsh.io"
-description = """
-Binary Object Representation Serializer for Hashing
-"""
-
-[dependencies]
-proc-macro2 = "1"
-syn = {version = "1", features = ["full", "fold"] }
-quote = "1"
diff --git a/borsh-rs/borsh-derive-internal/README.md b/borsh-rs/borsh-derive-internal/README.md
deleted file mode 120000
index fe8400541..000000000
--- a/borsh-rs/borsh-derive-internal/README.md
+++ /dev/null
@@ -1 +0,0 @@
-../../README.md
\ No newline at end of file
diff --git a/borsh-rs/borsh-derive-internal/src/attribute_helpers.rs b/borsh-rs/borsh-derive-internal/src/attribute_helpers.rs
deleted file mode 100644
index 9ed895b4b..000000000
--- a/borsh-rs/borsh-derive-internal/src/attribute_helpers.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-use syn::spanned::Spanned;
-use syn::{Attribute, Error, Meta, NestedMeta, Path};
-use quote::ToTokens;
-
-pub fn contains_skip(attrs: &[Attribute]) -> bool {
- for attr in attrs.iter() {
- if let Ok(Meta::Path(path)) = attr.parse_meta() {
- if path.to_token_stream().to_string().as_str() == "borsh_skip" {
- return true;
- }
- }
- }
- false
-}
-
-pub fn contains_initialize_with(attrs: &[Attribute]) -> syn::Result> {
- for attr in attrs.iter() {
- if let Ok(Meta::List(meta_list)) = attr.parse_meta() {
- if meta_list.path.to_token_stream().to_string().as_str() == "borsh_init" {
- if meta_list.nested.len() != 1 {
- return Err(Error::new(
- meta_list.span(),
- "borsh_init requires exactly one initialization method.",
- ));
- }
- let nested_meta = meta_list.nested.iter().next().unwrap();
- if let NestedMeta::Meta(Meta::Path(path)) = nested_meta {
- return Ok(Some(path.clone()));
- }
- }
- }
- }
- Ok(None)
-}
diff --git a/borsh-rs/borsh-derive-internal/src/enum_de.rs b/borsh-rs/borsh-derive-internal/src/enum_de.rs
deleted file mode 100644
index 61e3a0734..000000000
--- a/borsh-rs/borsh-derive-internal/src/enum_de.rs
+++ /dev/null
@@ -1,113 +0,0 @@
-use core::convert::TryFrom;
-
-use quote::quote;
-use syn::export::TokenStream2;
-use syn::{Fields, Ident, ItemEnum, WhereClause};
-
-use crate::attribute_helpers::{contains_initialize_with, contains_skip};
-
-pub fn enum_de(input: &ItemEnum, cratename: Ident) -> syn::Result {
- let name = &input.ident;
- let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
- let mut where_clause = where_clause.map_or_else(
- || WhereClause {
- where_token: Default::default(),
- predicates: Default::default(),
- },
- Clone::clone,
- );
- let init_method = contains_initialize_with(&input.attrs)?;
- let mut variant_arms = TokenStream2::new();
- for (variant_idx, variant) in input.variants.iter().enumerate() {
- let variant_idx = u8::try_from(variant_idx).expect("up to 256 enum variants are supported");
- let variant_ident = &variant.ident;
- let mut variant_header = TokenStream2::new();
- match &variant.fields {
- Fields::Named(fields) => {
- for field in &fields.named {
- let field_name = field.ident.as_ref().unwrap();
- if contains_skip(&field.attrs) {
- variant_header.extend(quote! {
- #field_name: Default::default(),
- });
- } else {
- let field_type = &field.ty;
- where_clause.predicates.push(syn::parse2(quote! {
- #field_type: #cratename::BorshDeserialize
- }).unwrap());
-
- variant_header.extend(quote! {
- #field_name: #cratename::BorshDeserialize::deserialize(buf)?,
- });
- }
- }
- variant_header = quote! { { #variant_header }};
- }
- Fields::Unnamed(fields) => {
- for field in fields.unnamed.iter() {
- if contains_skip(&field.attrs) {
- variant_header.extend(quote! { Default::default(), });
- } else {
- let field_type = &field.ty;
- where_clause.predicates.push(syn::parse2(quote! {
- #field_type: #cratename::BorshDeserialize
- }).unwrap());
-
- variant_header
- .extend(quote! { #cratename::BorshDeserialize::deserialize(buf)?, });
- }
- }
- variant_header = quote! { ( #variant_header )};
- }
- Fields::Unit => {}
- }
- variant_arms.extend(quote! {
- #variant_idx => #name::#variant_ident #variant_header ,
- });
- }
- let variant_idx = quote! {
- let variant_idx: u8 = #cratename::BorshDeserialize::deserialize(buf)?;
- };
- if let Some(method_ident) = init_method {
- Ok(quote! {
- impl #impl_generics #cratename::de::BorshDeserialize for #name #ty_generics #where_clause {
- fn deserialize(buf: &mut &[u8]) -> core::result::Result {
- #variant_idx
- let mut return_value = match variant_idx {
- #variant_arms
- _ => {
- let msg = #cratename::maybestd::format!("Unexpected variant index: {:?}", variant_idx);
-
- return Err(#cratename::maybestd::io::Error::new(
- #cratename::maybestd::io::ErrorKind::InvalidInput,
- msg,
- ));
- }
- };
- return_value.#method_ident();
- Ok(return_value)
- }
- }
- })
- } else {
- Ok(quote! {
- impl #impl_generics #cratename::de::BorshDeserialize for #name #ty_generics #where_clause {
- fn deserialize(buf: &mut &[u8]) -> core::result::Result {
- #variant_idx
- let return_value = match variant_idx {
- #variant_arms
- _ => {
- let msg = #cratename::maybestd::format!("Unexpected variant index: {:?}", variant_idx);
-
- return Err(#cratename::maybestd::io::Error::new(
- #cratename::maybestd::io::ErrorKind::InvalidInput,
- msg,
- ));
- }
- };
- Ok(return_value)
- }
- }
- })
- }
-}
diff --git a/borsh-rs/borsh-derive-internal/src/enum_ser.rs b/borsh-rs/borsh-derive-internal/src/enum_ser.rs
deleted file mode 100644
index e81ebe159..000000000
--- a/borsh-rs/borsh-derive-internal/src/enum_ser.rs
+++ /dev/null
@@ -1,90 +0,0 @@
-use core::convert::TryFrom;
-
-use quote::quote;
-use syn::export::{Span, TokenStream2};
-use syn::{Fields, Ident, ItemEnum, WhereClause};
-
-use crate::attribute_helpers::contains_skip;
-
-pub fn enum_ser(input: &ItemEnum, cratename: Ident) -> syn::Result {
- let name = &input.ident;
- let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
- let mut where_clause = where_clause.map_or_else(
- || WhereClause {
- where_token: Default::default(),
- predicates: Default::default(),
- },
- Clone::clone,
- );
- let mut body = TokenStream2::new();
- for (variant_idx, variant) in input.variants.iter().enumerate() {
- let variant_idx = u8::try_from(variant_idx).expect("up to 256 enum variants are supported");
- let variant_ident = &variant.ident;
- let mut variant_header = TokenStream2::new();
- let mut variant_body = TokenStream2::new();
- match &variant.fields {
- Fields::Named(fields) => {
- for field in &fields.named {
- let field_name = field.ident.as_ref().unwrap();
- if contains_skip(&field.attrs) {
- variant_header.extend(quote! { _#field_name, });
- continue;
- } else {
- let field_type = &field.ty;
- where_clause.predicates.push(syn::parse2(quote! {
- #field_type: #cratename::ser::BorshSerialize
- }).unwrap());
- variant_header.extend(quote! { #field_name, });
- }
- variant_body.extend(quote! {
- #cratename::BorshSerialize::serialize(#field_name, writer)?;
- })
- }
- variant_header = quote! { { #variant_header }};
- }
- Fields::Unnamed(fields) => {
- for (field_idx, field) in fields.unnamed.iter().enumerate() {
- let field_idx =
- u32::try_from(field_idx).expect("up to 2^32 fields are supported");
- if contains_skip(&field.attrs) {
- let field_ident =
- Ident::new(format!("_id{}", field_idx).as_str(), Span::call_site());
- variant_header.extend(quote! { #field_ident, });
- continue;
- } else {
- let field_type = &field.ty;
- where_clause.predicates.push(syn::parse2(quote! {
- #field_type: #cratename::ser::BorshSerialize
- }).unwrap());
-
- let field_ident =
- Ident::new(format!("id{}", field_idx).as_str(), Span::call_site());
- variant_header.extend(quote! { #field_ident, });
- variant_body.extend(quote! {
- #cratename::BorshSerialize::serialize(#field_ident, writer)?;
- })
- }
- }
- variant_header = quote! { ( #variant_header )};
- }
- Fields::Unit => {}
- }
- body.extend(quote!(
- #name::#variant_ident #variant_header => {
- let variant_idx: u8 = #variant_idx;
- writer.write_all(&variant_idx.to_le_bytes())?;
- #variant_body
- }
- ))
- }
- Ok(quote! {
- impl #impl_generics #cratename::ser::BorshSerialize for #name #ty_generics #where_clause {
- fn serialize(&self, writer: &mut W) -> core::result::Result<(), #cratename::maybestd::io::Error> {
- match self {
- #body
- }
- Ok(())
- }
- }
- })
-}
diff --git a/borsh-rs/borsh-derive-internal/src/lib.rs b/borsh-rs/borsh-derive-internal/src/lib.rs
deleted file mode 100644
index e01b99c85..000000000
--- a/borsh-rs/borsh-derive-internal/src/lib.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-#![recursion_limit = "128"]
-
-mod attribute_helpers;
-mod enum_de;
-mod enum_ser;
-mod struct_de;
-mod struct_ser;
-mod union_de;
-mod union_ser;
-
-pub use enum_de::enum_de;
-pub use enum_ser::enum_ser;
-pub use struct_de::struct_de;
-pub use struct_ser::struct_ser;
-pub use union_de::union_de;
-pub use union_ser::union_ser;
diff --git a/borsh-rs/borsh-derive-internal/src/struct_de.rs b/borsh-rs/borsh-derive-internal/src/struct_de.rs
deleted file mode 100644
index 71a53b077..000000000
--- a/borsh-rs/borsh-derive-internal/src/struct_de.rs
+++ /dev/null
@@ -1,79 +0,0 @@
-use crate::attribute_helpers::{contains_initialize_with, contains_skip};
-use quote::quote;
-use syn::export::TokenStream2;
-use syn::{Fields, Ident, ItemStruct, WhereClause};
-
-pub fn struct_de(input: &ItemStruct, cratename: Ident) -> syn::Result {
- let name = &input.ident;
- let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
- let mut where_clause = where_clause.map_or_else(
- || WhereClause {
- where_token: Default::default(),
- predicates: Default::default(),
- },
- Clone::clone,
- );
- let init_method = contains_initialize_with(&input.attrs)?;
- let return_value = match &input.fields {
- Fields::Named(fields) => {
- let mut body = TokenStream2::new();
- for field in &fields.named {
- let field_name = field.ident.as_ref().unwrap();
- let delta = if contains_skip(&field.attrs) {
- quote! {
- #field_name: Default::default(),
- }
- } else {
- let field_type = &field.ty;
- where_clause.predicates.push(syn::parse2(quote! {
- #field_type: #cratename::BorshDeserialize
- }).unwrap());
-
- quote! {
- #field_name: #cratename::BorshDeserialize::deserialize(buf)?,
- }
- };
- body.extend(delta);
- }
- quote! {
- Self { #body }
- }
- }
- Fields::Unnamed(fields) => {
- let mut body = TokenStream2::new();
- for _ in 0..fields.unnamed.len() {
- let delta = quote! {
- #cratename::BorshDeserialize::deserialize(buf)?,
- };
- body.extend(delta);
- }
- quote! {
- Self( #body )
- }
- }
- Fields::Unit => {
- quote! {
- Self {}
- }
- }
- };
- if let Some(method_ident) = init_method {
- Ok(quote! {
- impl #impl_generics #cratename::de::BorshDeserialize for #name #ty_generics #where_clause {
- fn deserialize(buf: &mut &[u8]) -> core::result::Result {
- let mut return_value = #return_value;
- return_value.#method_ident();
- Ok(return_value)
- }
- }
- })
- } else {
- Ok(quote! {
- impl #impl_generics #cratename::de::BorshDeserialize for #name #ty_generics #where_clause {
- fn deserialize(buf: &mut &[u8]) -> core::result::Result {
- Ok(#return_value)
- }
- }
- })
- }
-}
diff --git a/borsh-rs/borsh-derive-internal/src/struct_ser.rs b/borsh-rs/borsh-derive-internal/src/struct_ser.rs
deleted file mode 100644
index 1048c2f94..000000000
--- a/borsh-rs/borsh-derive-internal/src/struct_ser.rs
+++ /dev/null
@@ -1,150 +0,0 @@
-use core::convert::TryFrom;
-
-use quote::quote;
-use syn::export::{Span, TokenStream2};
-use syn::{Fields, Ident, Index, ItemStruct, WhereClause};
-
-use crate::attribute_helpers::contains_skip;
-
-pub fn struct_ser(input: &ItemStruct, cratename: Ident) -> syn::Result {
- let name = &input.ident;
- let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
- let mut where_clause = where_clause.map_or_else(
- || WhereClause {
- where_token: Default::default(),
- predicates: Default::default(),
- },
- Clone::clone,
- );
- let mut body = TokenStream2::new();
- match &input.fields {
- Fields::Named(fields) => {
- for field in &fields.named {
- if contains_skip(&field.attrs) {
- continue;
- }
- let field_name = field.ident.as_ref().unwrap();
- let delta = quote! {
- #cratename::BorshSerialize::serialize(&self.#field_name, writer)?;
- };
- body.extend(delta);
-
- let field_type = &field.ty;
- where_clause.predicates.push(syn::parse2(quote! {
- #field_type: #cratename::ser::BorshSerialize
- }).unwrap());
- }
- }
- Fields::Unnamed(fields) => {
- for field_idx in 0..fields.unnamed.len() {
- let field_idx = Index {
- index: u32::try_from(field_idx).expect("up to 2^32 fields are supported"),
- span: Span::call_site(),
- };
- let delta = quote! {
- #cratename::BorshSerialize::serialize(&self.#field_idx, writer)?;
- };
- body.extend(delta);
- }
- }
- Fields::Unit => {}
- }
- Ok(quote! {
- impl #impl_generics #cratename::ser::BorshSerialize for #name #ty_generics #where_clause {
- fn serialize(&self, writer: &mut W) -> core::result::Result<(), #cratename::maybestd::io::Error> {
- #body
- Ok(())
- }
- }
- })
-}
-
-// Rustfmt removes comas.
-#[rustfmt::skip]
-#[cfg(test)]
-mod tests {
- use super::*;
-
- fn assert_eq(expected: TokenStream2, actual: TokenStream2) {
- assert_eq!(expected.to_string(), actual.to_string())
- }
-
- #[test]
- fn simple_struct() {
- let item_struct: ItemStruct = syn::parse2(quote!{
- struct A {
- x: u64,
- y: String,
- }
- }).unwrap();
-
- let actual = struct_ser(&item_struct, Ident::new("borsh", Span::call_site())).unwrap();
- let expected = quote!{
- impl borsh::ser::BorshSerialize for A
- where
- u64: borsh::ser::BorshSerialize,
- String: borsh::ser::BorshSerialize
- {
- fn serialize(&self, writer: &mut W) -> core::result::Result<(), borsh::maybestd::io::Error> {
- borsh::BorshSerialize::serialize(&self.x, writer)?;
- borsh::BorshSerialize::serialize(&self.y, writer)?;
- Ok(())
- }
- }
- };
- assert_eq(expected, actual);
- }
-
- #[test]
- fn simple_generics() {
- let item_struct: ItemStruct = syn::parse2(quote!{
- struct A {
- x: HashMap,
- y: String,
- }
- }).unwrap();
-
- let actual = struct_ser(&item_struct, Ident::new("borsh", Span::call_site())).unwrap();
- let expected = quote!{
- impl borsh::ser::BorshSerialize for A
- where
- HashMap: borsh::ser::BorshSerialize,
- String: borsh::ser::BorshSerialize
- {
- fn serialize(&self, writer: &mut W) -> core::result::Result<(), borsh::maybestd::io::Error> {
- borsh::BorshSerialize::serialize(&self.x, writer)?;
- borsh::BorshSerialize::serialize(&self.y, writer)?;
- Ok(())
- }
- }
- };
- assert_eq(expected, actual);
- }
-
- #[test]
- fn bound_generics() {
- let item_struct: ItemStruct = syn::parse2(quote!{
- struct A where V: Value {
- x: HashMap,
- y: String,
- }
- }).unwrap();
-
- let actual = struct_ser(&item_struct, Ident::new("borsh", Span::call_site())).unwrap();
- let expected = quote!{
- impl borsh::ser::BorshSerialize for A
- where
- V: Value,
- HashMap: borsh::ser::BorshSerialize,
- String: borsh::ser::BorshSerialize
- {
- fn serialize(&self, writer: &mut W) -> core::result::Result<(), borsh::maybestd::io::Error> {
- borsh::BorshSerialize::serialize(&self.x, writer)?;
- borsh::BorshSerialize::serialize(&self.y, writer)?;
- Ok(())
- }
- }
- };
- assert_eq(expected, actual);
- }
-}
diff --git a/borsh-rs/borsh-derive-internal/src/union_de.rs b/borsh-rs/borsh-derive-internal/src/union_de.rs
deleted file mode 100644
index 66248169f..000000000
--- a/borsh-rs/borsh-derive-internal/src/union_de.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-use syn::export::TokenStream2;
-use syn::{Ident, ItemUnion};
-
-pub fn union_de(_input: &ItemUnion, _cratename: Ident) -> syn::Result {
- unimplemented!()
-}
diff --git a/borsh-rs/borsh-derive-internal/src/union_ser.rs b/borsh-rs/borsh-derive-internal/src/union_ser.rs
deleted file mode 100644
index 3109f6dbe..000000000
--- a/borsh-rs/borsh-derive-internal/src/union_ser.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-use syn::export::TokenStream2;
-use syn::{Ident, ItemUnion};
-
-pub fn union_ser(_input: &ItemUnion, _cratename: Ident) -> syn::Result {
- unimplemented!()
-}
diff --git a/borsh-rs/borsh-derive/Cargo.toml b/borsh-rs/borsh-derive/Cargo.toml
deleted file mode 100644
index f5faa2f58..000000000
--- a/borsh-rs/borsh-derive/Cargo.toml
+++ /dev/null
@@ -1,22 +0,0 @@
-[package]
-name = "borsh-derive"
-version = "0.8.0"
-authors = ["Near Inc "]
-edition = "2018"
-license = "Apache-2.0"
-readme = "README.md"
-categories = ["encoding", "network-programming"]
-repository = "https://github.com/nearprotocol/borsh"
-homepage = "http://borsh.io"
-description = """
-Binary Object Representation Serializer for Hashing
-"""
-
-[lib]
-proc-macro = true
-
-[dependencies]
-borsh-derive-internal = { path = "../borsh-derive-internal", version="0.8.0"}
-borsh-schema-derive-internal = { path = "../borsh-schema-derive-internal", version="0.8.0"}
-syn = {version = "1", features = ["full", "fold"] }
-proc-macro-crate = "0.1.5"
diff --git a/borsh-rs/borsh-derive/README.md b/borsh-rs/borsh-derive/README.md
deleted file mode 120000
index fe8400541..000000000
--- a/borsh-rs/borsh-derive/README.md
+++ /dev/null
@@ -1 +0,0 @@
-../../README.md
\ No newline at end of file
diff --git a/borsh-rs/borsh-derive/src/lib.rs b/borsh-rs/borsh-derive/src/lib.rs
deleted file mode 100644
index 459b975d1..000000000
--- a/borsh-rs/borsh-derive/src/lib.rs
+++ /dev/null
@@ -1,79 +0,0 @@
-extern crate proc_macro;
-use borsh_derive_internal::*;
-use borsh_schema_derive_internal::*;
-use proc_macro::TokenStream;
-use proc_macro_crate::crate_name;
-use syn::export::Span;
-use syn::{Ident, ItemEnum, ItemStruct, ItemUnion};
-
-#[proc_macro_derive(BorshSerialize, attributes(borsh_skip))]
-pub fn borsh_serialize(input: TokenStream) -> TokenStream {
- let cratename = Ident::new(
- &crate_name("borsh").unwrap_or("borsh".to_string()),
- Span::call_site(),
- );
-
- let res = if let Ok(input) = syn::parse::(input.clone()) {
- struct_ser(&input, cratename)
- } else if let Ok(input) = syn::parse::(input.clone()) {
- enum_ser(&input, cratename)
- } else if let Ok(input) = syn::parse::(input.clone()) {
- union_ser(&input, cratename)
- } else {
- // Derive macros can only be defined on structs, enums, and unions.
- unreachable!()
- };
- TokenStream::from(match res {
- Ok(res) => res,
- Err(err) => err.to_compile_error(),
- })
-}
-
-#[proc_macro_derive(BorshDeserialize, attributes(borsh_skip, borsh_init))]
-pub fn borsh_deserialize(input: TokenStream) -> TokenStream {
- let cratename = Ident::new(
- &crate_name("borsh").unwrap_or("borsh".to_string()),
- Span::call_site(),
- );
-
- let res = if let Ok(input) = syn::parse::(input.clone()) {
- struct_de(&input, cratename)
- } else if let Ok(input) = syn::parse::(input.clone()) {
- enum_de(&input, cratename)
- } else if let Ok(input) = syn::parse::(input.clone()) {
- union_de(&input, cratename)
- } else {
- // Derive macros can only be defined on structs, enums, and unions.
- unreachable!()
- };
- TokenStream::from(match res {
- Ok(res) => res,
- Err(err) => err.to_compile_error(),
- })
-}
-
-#[proc_macro_derive(BorshSchema, attributes(borsh_skip))]
-pub fn borsh_schema(input: TokenStream) -> TokenStream {
- let cratename = Ident::new(
- &crate_name("borsh").unwrap_or("borsh".to_string()),
- Span::call_site(),
- );
-
- let res = if let Ok(input) = syn::parse::(input.clone()) {
- process_struct(&input, cratename)
- } else if let Ok(input) = syn::parse::(input.clone()) {
- process_enum(&input, cratename)
- } else if let Ok(_) = syn::parse::(input.clone()) {
- Err(syn::Error::new(
- Span::call_site(),
- "Borsh schema does not support unions yet.",
- ))
- } else {
- // Derive macros can only be defined on structs, enums, and unions.
- unreachable!()
- };
- TokenStream::from(match res {
- Ok(res) => res,
- Err(err) => err.to_compile_error(),
- })
-}
diff --git a/borsh-rs/borsh-schema-derive-internal/Cargo.toml b/borsh-rs/borsh-schema-derive-internal/Cargo.toml
deleted file mode 100644
index 9134140ae..000000000
--- a/borsh-rs/borsh-schema-derive-internal/Cargo.toml
+++ /dev/null
@@ -1,17 +0,0 @@
-[package]
-name = "borsh-schema-derive-internal"
-version = "0.8.0"
-authors = ["Near Inc "]
-edition = "2018"
-license = "Apache-2.0"
-categories = ["encoding", "network-programming"]
-repository = "https://github.com/nearprotocol/borsh"
-homepage = "http://borsh.io"
-description = """
-Schema Generator for Borsh
-"""
-
-[dependencies]
-proc-macro2 = "1"
-syn = {version = "1", features = ["full", "fold"] }
-quote = "1"
diff --git a/borsh-rs/borsh-schema-derive-internal/src/enum_schema.rs b/borsh-rs/borsh-schema-derive-internal/src/enum_schema.rs
deleted file mode 100644
index bdea772c7..000000000
--- a/borsh-rs/borsh-schema-derive-internal/src/enum_schema.rs
+++ /dev/null
@@ -1,326 +0,0 @@
-use crate::helpers::declaration;
-use quote::quote;
-use syn::export::{Span, ToTokens, TokenStream2};
-use syn::{
- parse_quote, AttrStyle, Attribute, Field, Fields, FieldsUnnamed, Ident, ItemEnum, ItemStruct,
- Visibility,
-};
-
-pub fn process_enum(input: &ItemEnum, cratename: Ident) -> syn::Result {
- let name = &input.ident;
- let name_str = name.to_token_stream().to_string();
- let generics = &input.generics;
- let (impl_generics, ty_generics, _) = generics.split_for_impl();
- // Generate function that returns the name of the type.
- let (declaration, where_clause) = declaration(&name_str, &input.generics, cratename.clone());
-
- // Generate function that returns the schema for variants.
- // Definitions of the variants.
- let mut variants_defs = vec![];
- // Definitions of the anonymous structs used in variants.
- let mut anonymous_defs = TokenStream2::new();
- // Recursive calls to `add_definitions_recursively`.
- let mut add_recursive_defs = TokenStream2::new();
- for variant in &input.variants {
- let variant_name_str = variant.ident.to_token_stream().to_string();
- let full_variant_name_str = format!("{}{}", name_str, variant_name_str);
- let full_variant_ident = Ident::new(full_variant_name_str.as_str(), Span::call_site());
- let mut anonymous_struct = ItemStruct {
- attrs: vec![],
- vis: Visibility::Inherited,
- struct_token: Default::default(),
- ident: full_variant_ident.clone(),
- generics: (*generics).clone(),
- fields: variant.fields.clone(),
- semi_token: Some(Default::default()),
- };
- let generic_params = generics
- .type_params()
- .fold(TokenStream2::new(), |acc, generic| {
- let ident = &generic.ident;
- quote! {
- #acc
- #ident ,
- }
- });
- if !generic_params.is_empty() {
- let attr = Attribute {
- pound_token: Default::default(),
- style: AttrStyle::Outer,
- bracket_token: Default::default(),
- path: parse_quote! {borsh_skip},
- tokens: Default::default(),
- };
- // Whether we should convert the struct from unit struct to regular struct.
- let mut unit_to_regular = false;
- match &mut anonymous_struct.fields {
- Fields::Named(named) => {
- named.named.push(Field {
- attrs: vec![attr.clone()],
- vis: Visibility::Inherited,
- ident: Some(Ident::new("borsh_schema_phantom_data", Span::call_site())),
- colon_token: None,
- ty: parse_quote! {::core::marker::PhantomData<(#generic_params)>},
- });
- }
- Fields::Unnamed(unnamed) => {
- unnamed.unnamed.push(Field {
- attrs: vec![attr.clone()],
- vis: Visibility::Inherited,
- ident: None,
- colon_token: None,
- ty: parse_quote! {::core::marker::PhantomData<(#generic_params)>},
- });
- }
- Fields::Unit => {
- unit_to_regular = true;
- }
- }
- if unit_to_regular {
- let mut fields = FieldsUnnamed {
- paren_token: Default::default(),
- unnamed: Default::default(),
- };
- fields.unnamed.push(Field {
- attrs: vec![attr],
- vis: Visibility::Inherited,
- ident: None,
- colon_token: None,
- ty: parse_quote! {::core::marker::PhantomData<(#generic_params)>},
- });
- anonymous_struct.fields = Fields::Unnamed(fields);
- }
- }
- anonymous_defs.extend(quote! {
- #[derive(#cratename::BorshSchema)]
- #anonymous_struct
- });
- add_recursive_defs.extend(quote! {
- <#full_variant_ident #ty_generics>::add_definitions_recursively(definitions);
- });
- variants_defs.push(quote! {
- (#variant_name_str.to_string(), <#full_variant_ident #ty_generics>::declaration())
- });
- }
-
- let type_definitions = quote! {
- fn add_definitions_recursively(definitions: &mut #cratename::maybestd::collections::HashMap<#cratename::schema::Declaration, #cratename::schema::Definition>) {
- #anonymous_defs
- #add_recursive_defs
- let variants = #cratename::maybestd::vec![#(#variants_defs),*];
- let definition = #cratename::schema::Definition::Enum{variants};
- Self::add_definition(Self::declaration(), definition, definitions);
- }
- };
- let where_clause = if !where_clause.is_empty() {
- quote! { where #(#where_clause),*}
- } else {
- TokenStream2::new()
- };
- Ok(quote! {
- impl #impl_generics #cratename::BorshSchema for #name #ty_generics #where_clause {
- fn declaration() -> #cratename::schema::Declaration {
- #declaration
- }
- #type_definitions
- }
- })
-}
-
-// Rustfmt removes comas.
-#[rustfmt::skip]
-#[cfg(test)]
-mod tests {
- use super::*;
-
- fn assert_eq(expected: TokenStream2, actual: TokenStream2) {
- assert_eq!(expected.to_string(), actual.to_string())
- }
-
- #[test]
- fn simple_enum() {
- let item_enum: ItemEnum = syn::parse2(quote!{
- enum A {
- Bacon,
- Eggs
- }
- }).unwrap();
-
- let actual = process_enum(&item_enum, Ident::new("borsh", Span::call_site())).unwrap();
- let expected = quote!{
- impl borsh::BorshSchema for A {
- fn declaration() -> borsh::schema::Declaration {
- "A".to_string()
- }
- fn add_definitions_recursively(
- definitions: &mut borsh::maybestd::collections::HashMap<
- borsh::schema::Declaration,
- borsh::schema::Definition
- >
- ) {
- #[derive(borsh :: BorshSchema)]
- struct ABacon;
- #[derive(borsh :: BorshSchema)]
- struct AEggs;
- ::add_definitions_recursively(definitions);
- ::add_definitions_recursively(definitions);
- let variants = borsh::maybestd::vec![
- ("Bacon".to_string(), ::declaration()),
- ("Eggs".to_string(), ::declaration())
- ];
- let definition = borsh::schema::Definition::Enum { variants };
- Self::add_definition(Self::declaration(), definition, definitions);
- }
- }
- };
- assert_eq(expected, actual);
- }
-
- #[test]
- fn single_field_enum() {
- let item_enum: ItemEnum = syn::parse2(quote! {
- enum A {
- Bacon,
- }
- }).unwrap();
-
- let actual = process_enum(&item_enum, Ident::new("borsh", Span::call_site())).unwrap();
- let expected = quote!{
- impl borsh::BorshSchema for A {
- fn declaration() -> borsh::schema::Declaration {
- "A".to_string()
- }
- fn add_definitions_recursively(
- definitions: &mut borsh::maybestd::collections::HashMap<
- borsh::schema::Declaration,
- borsh::schema::Definition
- >
- ) {
- #[derive(borsh :: BorshSchema)]
- struct ABacon;
- ::add_definitions_recursively(definitions);
- let variants = borsh::maybestd::vec![("Bacon".to_string(), ::declaration())];
- let definition = borsh::schema::Definition::Enum { variants };
- Self::add_definition(Self::declaration(), definition, definitions);
- }
- }
- };
- assert_eq(expected, actual);
- }
-
- #[test]
- fn complex_enum() {
- let item_enum: ItemEnum = syn::parse2(quote! {
- enum A {
- Bacon,
- Eggs,
- Salad(Tomatoes, Cucumber, Oil),
- Sausage{wrapper: Wrapper, filling: Filling},
- }
- }).unwrap();
-
- let actual = process_enum(&item_enum, Ident::new("borsh", Span::call_site())).unwrap();
- let expected = quote!{
- impl borsh::BorshSchema for A {
- fn declaration() -> borsh::schema::Declaration {
- "A".to_string()
- }
- fn add_definitions_recursively(
- definitions: &mut borsh::maybestd::collections::HashMap<
- borsh::schema::Declaration,
- borsh::schema::Definition
- >
- ) {
- #[derive(borsh :: BorshSchema)]
- struct ABacon;
- #[derive(borsh :: BorshSchema)]
- struct AEggs;
- #[derive(borsh :: BorshSchema)]
- struct ASalad(Tomatoes, Cucumber, Oil);
- #[derive(borsh :: BorshSchema)]
- struct ASausage {
- wrapper: Wrapper,
- filling: Filling
- }
- ::add_definitions_recursively(definitions);
- ::add_definitions_recursively(definitions);
- ::add_definitions_recursively(definitions);
- ::add_definitions_recursively(definitions);
- let variants = borsh::maybestd::vec![
- ("Bacon".to_string(), ::declaration()),
- ("Eggs".to_string(), ::declaration()),
- ("Salad".to_string(), ::declaration()),
- ("Sausage".to_string(), ::declaration())
- ];
- let definition = borsh::schema::Definition::Enum { variants };
- Self::add_definition(Self::declaration(), definition, definitions);
- }
- }
- };
- assert_eq(expected, actual);
- }
-
- #[test]
- fn complex_enum_generics() {
- let item_enum: ItemEnum = syn::parse2(quote! {
- enum A {
- Bacon,
- Eggs,
- Salad(Tomatoes, C, Oil),
- Sausage{wrapper: W, filling: Filling},
- }
- }).unwrap();
-
- let actual = process_enum(&item_enum, Ident::new("borsh", Span::call_site())).unwrap();
- let expected = quote!{
- impl borsh::BorshSchema for A
- where
- C: borsh::BorshSchema,
- W: borsh::BorshSchema
- {
- fn declaration() -> borsh::schema::Declaration {
- let params = borsh::maybestd::vec![::declaration(), ::declaration()];
- format!(r#"{}<{}>"#, "A", params.join(", "))
- }
- fn add_definitions_recursively(
- definitions: &mut borsh::maybestd::collections::HashMap<
- borsh::schema::Declaration,
- borsh::schema::Definition
- >
- ) {
- #[derive(borsh :: BorshSchema)]
- struct ABacon(#[borsh_skip] ::core::marker::PhantomData<(C, W)>);
- #[derive(borsh :: BorshSchema)]
- struct AEggs(#[borsh_skip] ::core::marker::PhantomData<(C, W)>);
- #[derive(borsh :: BorshSchema)]
- struct ASalad(
- Tomatoes,
- C,
- Oil,
- #[borsh_skip] ::core::marker::PhantomData<(C, W)>
- );
- #[derive(borsh :: BorshSchema)]
- struct ASausage {
- wrapper: W,
- filling: Filling,
- #[borsh_skip]
- borsh_schema_phantom_data: ::core::marker::PhantomData<(C, W)>
- }
- >::add_definitions_recursively(definitions);
- >::add_definitions_recursively(definitions);
- >::add_definitions_recursively(definitions);
- >::add_definitions_recursively(definitions);
- let variants = borsh::maybestd::vec![
- ("Bacon".to_string(), >::declaration()),
- ("Eggs".to_string(), >::declaration()),
- ("Salad".to_string(), >::declaration()),
- ("Sausage".to_string(), >::declaration())
- ];
- let definition = borsh::schema::Definition::Enum { variants };
- Self::add_definition(Self::declaration(), definition, definitions);
- }
- }
- };
- assert_eq(expected, actual);
- }
-}
diff --git a/borsh-rs/borsh-schema-derive-internal/src/helpers.rs b/borsh-rs/borsh-schema-derive-internal/src/helpers.rs
deleted file mode 100644
index 87781ec05..000000000
--- a/borsh-rs/borsh-schema-derive-internal/src/helpers.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-use quote::{quote, ToTokens};
-use syn::export::TokenStream2;
-use syn::{Attribute, Generics, Meta, Ident};
-
-pub fn contains_skip(attrs: &[Attribute]) -> bool {
- for attr in attrs.iter() {
- if let Ok(Meta::Path(path)) = attr.parse_meta() {
- if path.to_token_stream().to_string().as_str() == "borsh_skip" {
- return true;
- }
- }
- }
- false
-}
-
-pub fn declaration(ident_str: &String, generics: &Generics, cratename: Ident) -> (TokenStream2, Vec) {
- let (_, _, where_clause_generics) = generics.split_for_impl();
- // Generate function that returns the name of the type.
- let mut declaration_params = vec![];
- let mut where_clause = vec![];
- if let Some(where_clause_generics) = where_clause_generics {
- let where_clause_generics = &where_clause_generics.predicates;
- where_clause.push(quote! {#where_clause_generics});
- }
- for type_param in generics.type_params() {
- let type_param_name = &type_param.ident;
- declaration_params.push(quote! {
- <#type_param_name>::declaration()
- });
- where_clause.push(quote! {
- #type_param_name: #cratename::BorshSchema
- });
- }
- let result = if declaration_params.is_empty() {
- quote! {
- #ident_str.to_string()
- }
- } else {
- quote! {
- let params = #cratename::maybestd::vec![#(#declaration_params),*];
- format!(r#"{}<{}>"#, #ident_str, params.join(", "))
- }
- };
- (result, where_clause)
-}
diff --git a/borsh-rs/borsh-schema-derive-internal/src/lib.rs b/borsh-rs/borsh-schema-derive-internal/src/lib.rs
deleted file mode 100644
index b75c1ee6a..000000000
--- a/borsh-rs/borsh-schema-derive-internal/src/lib.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-#![recursion_limit = "128"]
-
-mod helpers;
-
-mod enum_schema;
-mod struct_schema;
-pub use enum_schema::process_enum;
-pub use struct_schema::process_struct;
diff --git a/borsh-rs/borsh-schema-derive-internal/src/struct_schema.rs b/borsh-rs/borsh-schema-derive-internal/src/struct_schema.rs
deleted file mode 100644
index e624fb489..000000000
--- a/borsh-rs/borsh-schema-derive-internal/src/struct_schema.rs
+++ /dev/null
@@ -1,382 +0,0 @@
-use crate::helpers::{contains_skip, declaration};
-use quote::quote;
-use syn::export::{ToTokens, TokenStream2};
-use syn::{Fields, ItemStruct, Ident};
-
-
-pub fn process_struct(input: &ItemStruct, cratename: Ident) -> syn::Result {
- let name = &input.ident;
- let name_str = name.to_token_stream().to_string();
- let generics = &input.generics;
- let (impl_generics, ty_generics, _) = generics.split_for_impl();
- // Generate function that returns the name of the type.
- let (declaration, mut where_clause) = declaration(&name_str, &input.generics, cratename.clone());
-
- // Generate function that returns the schema of required types.
- let mut fields_vec = vec![];
- let mut struct_fields = TokenStream2::new();
- let mut add_definitions_recursively_rec = TokenStream2::new();
- match &input.fields {
- Fields::Named(fields) => {
- for field in &fields.named {
- if contains_skip(&field.attrs) {
- continue;
- }
- let field_name = field.ident.as_ref().unwrap().to_token_stream().to_string();
- let field_type = &field.ty;
- fields_vec.push(quote! {
- (#field_name.to_string(), <#field_type>::declaration())
- });
- add_definitions_recursively_rec.extend(quote! {
- <#field_type>::add_definitions_recursively(definitions);
- });
- where_clause.push(quote! {
- #field_type: #cratename::BorshSchema
- });
- }
- if !fields_vec.is_empty() {
- struct_fields = quote! {
- let fields = #cratename::schema::Fields::NamedFields(#cratename::maybestd::vec![#(#fields_vec),*]);
- };
- }
- }
- Fields::Unnamed(fields) => {
- for field in &fields.unnamed {
- if contains_skip(&field.attrs) {
- continue;
- }
- let field_type = &field.ty;
- fields_vec.push(quote! {
- <#field_type>::declaration()
- });
- add_definitions_recursively_rec.extend(quote! {
- <#field_type>::add_definitions_recursively(definitions);
- });
- where_clause.push(quote! {
- #field_type: #cratename::BorshSchema
- });
- }
- if !fields_vec.is_empty() {
- struct_fields = quote! {
- let fields = #cratename::schema::Fields::UnnamedFields(#cratename::maybestd::vec![#(#fields_vec),*]);
- };
- }
- }
- Fields::Unit => {}
- }
-
- if fields_vec.is_empty() {
- struct_fields = quote! {
- let fields = #cratename::schema::Fields::Empty;
- };
- }
-
- let add_definitions_recursively = quote! {
- fn add_definitions_recursively(definitions: &mut #cratename::maybestd::collections::HashMap<#cratename::schema::Declaration, #cratename::schema::Definition>) {
- #struct_fields
- let definition = #cratename::schema::Definition::Struct { fields };
- Self::add_definition(Self::declaration(), definition, definitions);
- #add_definitions_recursively_rec
- }
- };
- let where_clause = if !where_clause.is_empty() {
- quote! { where #(#where_clause),*}
- } else {
- TokenStream2::new()
- };
- Ok(quote! {
- impl #impl_generics #cratename::BorshSchema for #name #ty_generics #where_clause {
- fn declaration() -> #cratename::schema::Declaration {
- #declaration
- }
- #add_definitions_recursively
- }
- })
-}
-
-// Rustfmt removes comas.
-#[rustfmt::skip::macros(quote)]
-#[cfg(test)]
-mod tests {
- use super::*;
-
- fn assert_eq(expected: TokenStream2, actual: TokenStream2) {
- assert_eq!(expected.to_string(), actual.to_string())
- }
-
- #[test]
- fn unit_struct() {
- let item_struct: ItemStruct = syn::parse2(quote!{
- struct A;
- })
- .unwrap();
-
- let actual = process_struct(&item_struct, Ident::new("borsh", proc_macro2::Span::call_site())).unwrap();
- let expected = quote!{
- impl borsh::BorshSchema for A
- {
- fn declaration() -> borsh::schema::Declaration {
- "A".to_string()
- }
- fn add_definitions_recursively(definitions: &mut borsh::maybestd::collections::HashMap) {
- let fields = borsh::schema::Fields::Empty;
- let definition = borsh::schema::Definition::Struct { fields };
- Self::add_definition(Self::declaration(), definition, definitions);
- }
- }
- };
- assert_eq(expected, actual);
- }
-
- #[test]
- fn wrapper_struct() {
- let item_struct: ItemStruct = syn::parse2(quote!{
- struct A(T);
- })
- .unwrap();
-
- let actual = process_struct(&item_struct, Ident::new("borsh", proc_macro2::Span::call_site())).unwrap();
- let expected = quote!{
- impl borsh::BorshSchema for A
- where
- T: borsh::BorshSchema,
- T: borsh::BorshSchema
- {
- fn declaration() -> borsh::schema::Declaration {
- let params = borsh::maybestd::vec![::declaration()];
- format!(r#"{}<{}>"#, "A", params.join(", "))
- }
- fn add_definitions_recursively(
- definitions: &mut borsh::maybestd::collections::HashMap<
- borsh::schema::Declaration,
- borsh::schema::Definition
- >
- ) {
- let fields = borsh::schema::Fields::UnnamedFields(borsh::maybestd::vec![::declaration()]);
- let definition = borsh::schema::Definition::Struct { fields };
- Self::add_definition(Self::declaration(), definition, definitions);
- ::add_definitions_recursively(definitions);
- }
- }
- };
- assert_eq(expected, actual);
- }
-
- #[test]
- fn tuple_struct() {
- let item_struct: ItemStruct = syn::parse2(quote!{
- struct A(u64, String);
- })
- .unwrap();
-
- let actual = process_struct(&item_struct, Ident::new("borsh", proc_macro2::Span::call_site())).unwrap();
- let expected = quote!{
- impl borsh::BorshSchema for A
- where
- u64: borsh::BorshSchema,
- String: borsh::BorshSchema
- {
- fn declaration() -> borsh::schema::Declaration {
- "A".to_string()
- }
- fn add_definitions_recursively(
- definitions: &mut borsh::maybestd::collections::HashMap<
- borsh::schema::Declaration,
- borsh::schema::Definition
- >
- ) {
- let fields = borsh::schema::Fields::UnnamedFields(borsh::maybestd::vec![
- ::declaration(),
- ::declaration()
- ]);
- let definition = borsh::schema::Definition::Struct { fields };
- Self::add_definition(Self::declaration(), definition, definitions);
- ::add_definitions_recursively(definitions);
- ::add_definitions_recursively(definitions);
- }
- }
- };
- assert_eq(expected, actual);
- }
-
- #[test]
- fn tuple_struct_params() {
- let item_struct: ItemStruct = syn::parse2(quote!{
- struct A(K, V);
- })
- .unwrap();
-
- let actual = process_struct(&item_struct, Ident::new("borsh", proc_macro2::Span::call_site())).unwrap();
- let expected = quote!{
- impl borsh::BorshSchema for A
- where
- K: borsh::BorshSchema,
- V: borsh::BorshSchema,
- K: borsh::BorshSchema,
- V: borsh::BorshSchema
- {
- fn declaration() -> borsh::schema::Declaration {
- let params = borsh::maybestd::vec![::declaration(), ::declaration()];
- format!(r#"{}<{}>"#, "A", params.join(", "))
- }
- fn add_definitions_recursively(
- definitions: &mut borsh::maybestd::collections::HashMap<
- borsh::schema::Declaration,
- borsh::schema::Definition
- >
- ) {
- let fields =
- borsh::schema::Fields::UnnamedFields(borsh::maybestd::vec![::declaration(), ::declaration()]);
- let definition = borsh::schema::Definition::Struct { fields };
- Self::add_definition(Self::declaration(), definition, definitions);
- ::add_definitions_recursively(definitions);
- ::add_definitions_recursively(definitions);
- }
- }
- };
- assert_eq(expected, actual);
- }
-
- #[test]
- fn simple_struct() {
- let item_struct: ItemStruct = syn::parse2(quote!{
- struct A {
- x: u64,
- y: String,
- }
- })
- .unwrap();
-
- let actual = process_struct(&item_struct, Ident::new("borsh", proc_macro2::Span::call_site())).unwrap();
- let expected = quote!{
- impl borsh::BorshSchema for A
- where
- u64: borsh::BorshSchema,
- String: borsh::BorshSchema
- {
- fn declaration() -> borsh::schema::Declaration {
- "A".to_string()
- }
- fn add_definitions_recursively(
- definitions: &mut borsh::maybestd::collections::HashMap<
- borsh::schema::Declaration,
- borsh::schema::Definition
- >
- ) {
- let fields = borsh::schema::Fields::NamedFields(borsh::maybestd::vec![
- ("x".to_string(), ::declaration()),
- ("y".to_string(), ::declaration())
- ]);
- let definition = borsh::schema::Definition::Struct { fields };
- Self::add_definition(Self::declaration(), definition, definitions);
- ::add_definitions_recursively(definitions);
- ::add_definitions_recursively(definitions);
- }
- }
- };
- assert_eq(expected, actual);
- }
-
- #[test]
- fn simple_generics() {
- let item_struct: ItemStruct = syn::parse2(quote!{
- struct A {
- x: HashMap,
- y: String,
- }
- })
- .unwrap();
-
- let actual = process_struct(&item_struct, Ident::new("borsh", proc_macro2::Span::call_site())).unwrap();
- let expected = quote!{
- impl borsh::BorshSchema for A
- where
- K: borsh::BorshSchema,
- V: borsh::BorshSchema,
- HashMap: borsh::BorshSchema,
- String: borsh::BorshSchema
- {
- fn declaration() -> borsh::schema::Declaration {
- let params = borsh::maybestd::vec![::declaration(), ::declaration()];
- format!(r#"{}<{}>"#, "A", params.join(", "))
- }
- fn add_definitions_recursively(
- definitions: &mut borsh::maybestd::collections::HashMap<
- borsh::schema::Declaration,
- borsh::schema::Definition
- >
- ) {
- let fields = borsh::schema::Fields::NamedFields(borsh::maybestd::vec![
- ("x".to_string(), >::declaration()),
- ("y".to_string(), ::declaration())
- ]);
- let definition = borsh::schema::Definition::Struct { fields };
- Self::add_definition(Self::declaration(), definition, definitions);
- >::add_definitions_recursively(definitions);
- ::add_definitions_recursively(definitions);
- }
- }
- };
- assert_eq(expected, actual);
- }
-
- #[test]
- fn tuple_struct_whole_skip() {
- let item_struct: ItemStruct = syn::parse2(quote!{
- struct A(#[borsh_skip] String);
- })
- .unwrap();
-
- let actual = process_struct(&item_struct, Ident::new("borsh", proc_macro2::Span::call_site())).unwrap();
- let expected = quote!{
- impl borsh::BorshSchema for A {
- fn declaration() -> borsh::schema::Declaration {
- "A".to_string()
- }
- fn add_definitions_recursively(
- definitions: &mut borsh::maybestd::collections::HashMap<
- borsh::schema::Declaration,
- borsh::schema::Definition
- >
- ) {
- let fields = borsh::schema::Fields::Empty;
- let definition = borsh::schema::Definition::Struct { fields };
- Self::add_definition(Self::declaration(), definition, definitions);
- }
- }
- };
- assert_eq(expected, actual);
- }
-
- #[test]
- fn tuple_struct_partial_skip() {
- let item_struct: ItemStruct = syn::parse2(quote!{
- struct A(#[borsh_skip] u64, String);
- })
- .unwrap();
-
- let actual = process_struct(&item_struct, Ident::new("borsh", proc_macro2::Span::call_site())).unwrap();
- let expected = quote!{
- impl borsh::BorshSchema for A
- where
- String: borsh::BorshSchema
- {
- fn declaration() -> borsh::schema::Declaration {
- "A".to_string()
- }
- fn add_definitions_recursively(
- definitions: &mut borsh::maybestd::collections::HashMap<
- borsh::schema::Declaration,
- borsh::schema::Definition
- >
- ) {
- let fields = borsh::schema::Fields::UnnamedFields(borsh::maybestd::vec![::declaration()]);
- let definition = borsh::schema::Definition::Struct { fields };
- Self::add_definition(Self::declaration(), definition, definitions);
- ::add_definitions_recursively(definitions);
- }
- }
- };
- assert_eq(expected, actual);
- }
-}
diff --git a/borsh-rs/borsh/Cargo.toml b/borsh-rs/borsh/Cargo.toml
deleted file mode 100644
index dde5ee7f7..000000000
--- a/borsh-rs/borsh/Cargo.toml
+++ /dev/null
@@ -1,29 +0,0 @@
-[package]
-name = "borsh"
-version = "0.8.0"
-authors = ["Near Inc "]
-edition = "2018"
-license = "Apache-2.0"
-readme = "README.md"
-categories = ["encoding", "network-programming"]
-repository = "https://github.com/nearprotocol/borsh"
-homepage = "http://borsh.io"
-description = """
-Binary Object Representation Serializer for Hashing
-"""
-
-[lib]
-name = "borsh"
-path = "src/lib.rs"
-
-[[bin]]
-name = "generate_schema_schema"
-path = "src/generate_schema_schema.rs"
-
-[dependencies]
-borsh-derive = { path = "../borsh-derive", version = "0.8.0" }
-hashbrown = "0.9.1"
-
-[features]
-default = ["std"]
-std = []
diff --git a/borsh-rs/borsh/README.md b/borsh-rs/borsh/README.md
deleted file mode 120000
index fe8400541..000000000
--- a/borsh-rs/borsh/README.md
+++ /dev/null
@@ -1 +0,0 @@
-../../README.md
\ No newline at end of file
diff --git a/borsh-rs/borsh/src/de/hint.rs b/borsh-rs/borsh/src/de/hint.rs
deleted file mode 100644
index 7af550cef..000000000
--- a/borsh-rs/borsh/src/de/hint.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-#[inline]
-pub fn cautious(hint: u32) -> usize {
- let el_size = core::mem::size_of::() as u32;
- core::cmp::max(core::cmp::min(hint, 4096 / el_size), 1) as usize
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- pub fn test_cautious_u8() {
- assert_eq!(cautious::(10), 10);
- }
-}
diff --git a/borsh-rs/borsh/src/de/mod.rs b/borsh-rs/borsh/src/de/mod.rs
deleted file mode 100644
index ec3c75eed..000000000
--- a/borsh-rs/borsh/src/de/mod.rs
+++ /dev/null
@@ -1,528 +0,0 @@
-use core::{
- convert::TryInto,
- hash::Hash,
- mem::{forget, size_of}
-};
-
-use crate::maybestd::{
- io::{Error, ErrorKind, Result},
- borrow::{
- Cow,
- ToOwned,
- Borrow
- },
- collections::{BTreeMap, HashMap, HashSet},
- format,
- string::{String, ToString},
- vec::Vec,
- boxed::Box
-};
-
-
-mod hint;
-
-const ERROR_NOT_ALL_BYTES_READ: &str = "Not all bytes read";
-const ERROR_UNEXPECTED_LENGTH_OF_INPUT: &str = "Unexpected length of input";
-
-/// A data-structure that can be de-serialized from binary format by NBOR.
-pub trait BorshDeserialize: Sized {
- /// Deserializes this instance from a given slice of bytes.
- /// Updates the buffer to point at the remaining bytes.
- fn deserialize(buf: &mut &[u8]) -> Result;
-
- /// Deserialize this instance from a slice of bytes.
- fn try_from_slice(v: &[u8]) -> Result {
- let mut v_mut = v;
- let result = Self::deserialize(&mut v_mut)?;
- if !v_mut.is_empty() {
- return Err(Error::new(
- ErrorKind::InvalidData,
- ERROR_NOT_ALL_BYTES_READ,
- ));
- }
- Ok(result)
- }
-
- /// Whether Self is u8.
- /// NOTE: `Vec` is the most common use-case for serialization and deserialization, it's
- /// worth handling it as a special case to improve performance.
- /// It's a workaround for specific `Vec` implementation versus generic `Vec`
- /// implementation. See https://github.com/rust-lang/rfcs/pull/1210 for details.
- #[inline]
- fn is_u8() -> bool {
- false
- }
-}
-
-impl BorshDeserialize for u8 {
- #[inline]
- fn deserialize(buf: &mut &[u8]) -> Result {
- if buf.is_empty() {
- return Err(Error::new(
- ErrorKind::InvalidInput,
- ERROR_UNEXPECTED_LENGTH_OF_INPUT,
- ));
- }
- let res = buf[0];
- *buf = &buf[1..];
- Ok(res)
- }
-
- #[inline]
- fn is_u8() -> bool {
- true
- }
-}
-
-macro_rules! impl_for_integer {
- ($type: ident) => {
- impl BorshDeserialize for $type {
- #[inline]
- fn deserialize(buf: &mut &[u8]) -> Result {
- if buf.len() < size_of::<$type>() {
- return Err(Error::new(
- ErrorKind::InvalidInput,
- ERROR_UNEXPECTED_LENGTH_OF_INPUT,
- ));
- }
- let res = $type::from_le_bytes(buf[..size_of::<$type>()].try_into().unwrap());
- *buf = &buf[size_of::<$type>()..];
- Ok(res)
- }
- }
- };
-}
-
-impl_for_integer!(i8);
-impl_for_integer!(i16);
-impl_for_integer!(i32);
-impl_for_integer!(i64);
-impl_for_integer!(i128);
-impl_for_integer!(u16);
-impl_for_integer!(u32);
-impl_for_integer!(u64);
-impl_for_integer!(u128);
-
-// Note NaNs have a portability issue. Specifically, signalling NaNs on MIPS are quiet NaNs on x86,
-// and vice-versa. We disallow NaNs to avoid this issue.
-macro_rules! impl_for_float {
- ($type: ident, $int_type: ident) => {
- impl BorshDeserialize for $type {
- #[inline]
- fn deserialize(buf: &mut &[u8]) -> Result {
- if buf.len() < size_of::<$type>() {
- return Err(Error::new(
- ErrorKind::InvalidInput,
- ERROR_UNEXPECTED_LENGTH_OF_INPUT,
- ));
- }
- let res = $type::from_bits($int_type::from_le_bytes(
- buf[..size_of::<$int_type>()].try_into().unwrap(),
- ));
- *buf = &buf[size_of::<$int_type>()..];
- if res.is_nan() {
- return Err(Error::new(
- ErrorKind::InvalidInput,
- "For portability reasons we do not allow to deserialize NaNs.",
- ));
- }
- Ok(res)
- }
- }
- };
-}
-
-impl_for_float!(f32, u32);
-impl_for_float!(f64, u64);
-
-impl BorshDeserialize for bool {
- #[inline]
- fn deserialize(buf: &mut &[u8]) -> Result {
- if buf.is_empty() {
- return Err(Error::new(
- ErrorKind::InvalidInput,
- ERROR_UNEXPECTED_LENGTH_OF_INPUT,
- ));
- }
- let b = buf[0];
- *buf = &buf[1..];
- if b == 0 {
- Ok(false)
- } else if b == 1 {
- Ok(true)
- } else {
- let msg = format!("Invalid bool representation: {}", b);
-
- Err(Error::new(
- ErrorKind::InvalidInput,
- msg,
- ))
- }
- }
-}
-
-
-
-impl BorshDeserialize for Option
-where
- T: BorshDeserialize,
-{
- #[inline]
- fn deserialize(buf: &mut &[u8]) -> Result {
- if buf.is_empty() {
- return Err(Error::new(
- ErrorKind::InvalidInput,
- ERROR_UNEXPECTED_LENGTH_OF_INPUT,
- ));
- }
- let flag = buf[0];
- *buf = &buf[1..];
- if flag == 0 {
- Ok(None)
- } else if flag == 1 {
- Ok(Some(T::deserialize(buf)?))
- } else {
- let msg = format!(
- "Invalid Option representation: {}. The first byte must be 0 or 1",
- flag
- );
-
- Err(Error::new(
- ErrorKind::InvalidInput,
- msg,
- ))
- }
- }
-}
-
-impl BorshDeserialize for core::result::Result
-where
- T: BorshDeserialize,
- E: BorshDeserialize,
-{
- #[inline]
- fn deserialize(buf: &mut &[u8]) -> Result {
- if buf.is_empty() {
- return Err(Error::new(
- ErrorKind::InvalidInput,
- ERROR_UNEXPECTED_LENGTH_OF_INPUT,
- ));
- }
- let flag = buf[0];
- *buf = &buf[1..];
- if flag == 0 {
- Ok(Err(E::deserialize(buf)?))
- } else if flag == 1 {
- Ok(Ok(T::deserialize(buf)?))
- } else {
- let msg = format!(
- "Invalid Result representation: {}. The first byte must be 0 or 1",
- flag
- );
-
- Err(Error::new(
- ErrorKind::InvalidInput,
- msg,
- ))
- }
- }
-}
-
-impl BorshDeserialize for String {
- #[inline]
- fn deserialize(buf: &mut &[u8]) -> Result {
- String::from_utf8(Vec::::deserialize(buf)?)
- .map_err(|err| {
- let msg = err.to_string();
- Error::new(ErrorKind::InvalidData, msg)
- })
- }
-}
-
-impl BorshDeserialize for Vec
-where
- T: BorshDeserialize,
-{
- #[inline]
- fn deserialize(buf: &mut &[u8]) -> Result {
- let len = u32::deserialize(buf)?;
- if len == 0 {
- Ok(Vec::new())
- } else if T::is_u8() && size_of::() == size_of::() {
- let len = len.try_into().map_err(|_| ErrorKind::InvalidInput)?;
- if buf.len() < len {
- return Err(Error::new(
- ErrorKind::InvalidInput,
- ERROR_UNEXPECTED_LENGTH_OF_INPUT,
- ));
- }
- let result = buf[..len].to_vec();
- *buf = &buf[len..];
- // See comment from https://doc.rust-lang.org/std/mem/fn.transmute.html
- // The no-copy, unsafe way, still using transmute, but not UB.
- // This is equivalent to the original, but safer, and reuses the
- // same `Vec` internals. Therefore, the new inner type must have the
- // exact same size, and the same alignment, as the old type.
- //
- // The size of the memory should match because `size_of::() == size_of::()`.
- //
- // `T::is_u8()` is a workaround for not being able to implement `Vec` separately.
- let result = unsafe {
- // Ensure the original vector is not dropped.
- let mut v_clone = core::mem::ManuallyDrop::new(result);
- Vec::from_raw_parts(
- v_clone.as_mut_ptr() as *mut T,
- v_clone.len(),
- v_clone.capacity(),
- )
- };
- Ok(result)
- } else if size_of::() == 0 {
- let mut result = Vec::new();
- result.push(T::deserialize(buf)?);
-
- let p = result.as_mut_ptr();
- unsafe {
- forget(result);
- let len = len.try_into().map_err(|_| ErrorKind::InvalidInput)?;
- let result = Vec::from_raw_parts(p, len, len);
- Ok(result)
- }
- } else {
- // TODO(16): return capacity allocation when we can safely do that.
- let mut result = Vec::with_capacity(hint::cautious::(len));
- for _ in 0..len {
- result.push(T::deserialize(buf)?);
- }
- Ok(result)
- }
- }
-}
-
-impl BorshDeserialize for Cow<'_, T>
-where
- T: ToOwned + ?Sized,
- T::Owned: BorshDeserialize,
-{
- #[inline]
- fn deserialize(buf: &mut &[u8]) -> Result {
- Ok(Cow::Owned(BorshDeserialize::deserialize(buf)?))
- }
-}
-
-
-impl BorshDeserialize for HashSet
-where
- T: BorshDeserialize + Eq + Hash,
-{
- #[inline]
- fn deserialize(buf: &mut &[u8]) -> Result {
- let vec = >::deserialize(buf)?;
- Ok(vec.into_iter().collect::>())
- }
-}
-
-
-impl BorshDeserialize for HashMap
-where
- K: BorshDeserialize + Eq + Hash,
- V: BorshDeserialize,
-{
- #[inline]
- fn deserialize(buf: &mut &[u8]) -> Result {
- let len = u32::deserialize(buf)?;
- // TODO(16): return capacity allocation when we can safely do that.
- let mut result = HashMap::new();
- for _ in 0..len {
- let key = K::deserialize(buf)?;
- let value = V::deserialize(buf)?;
- result.insert(key, value);
- }
- Ok(result)
- }
-}
-
-
-impl BorshDeserialize for BTreeMap
-where
- K: BorshDeserialize + Ord + core::hash::Hash,
- V: BorshDeserialize,
-{
- #[inline]
- fn deserialize(buf: &mut &[u8]) -> Result {
- let len = u32::deserialize(buf)?;
- let mut result = BTreeMap::new();
- for _ in 0..len {
- let key = K::deserialize(buf)?;
- let value = V::deserialize(buf)?;
- result.insert(key, value);
- }
- Ok(result)
- }
-}
-
-#[cfg(feature = "std")]
-impl BorshDeserialize for std::net::SocketAddr {
- #[inline]
- fn deserialize(buf: &mut &[u8]) -> Result {
- let kind = u8::deserialize(buf)?;
- match kind {
- 0 => std::net::SocketAddrV4::deserialize(buf).map(std::net::SocketAddr::V4),
- 1 => std::net::SocketAddrV6::deserialize(buf).map(std::net::SocketAddr::V6),
- value => Err(Error::new(
- ErrorKind::InvalidInput,
- format!("Invalid SocketAddr variant: {}", value),
- )),
- }
- }
-}
-
-#[cfg(feature = "std")]
-impl BorshDeserialize for std::net::SocketAddrV4 {
- #[inline]
- fn deserialize(buf: &mut &[u8]) -> Result {
- let ip = std::net::Ipv4Addr::deserialize(buf)?;
- let port = u16::deserialize(buf)?;
- Ok(std::net::SocketAddrV4::new(ip, port))
- }
-}
-
-#[cfg(feature = "std")]
-impl BorshDeserialize for std::net::SocketAddrV6 {
- #[inline]
- fn deserialize(buf: &mut &[u8]) -> Result {
- let ip = std::net::Ipv6Addr::deserialize(buf)?;
- let port = u16::deserialize(buf)?;
- Ok(std::net::SocketAddrV6::new(ip, port, 0, 0))
- }
-}
-
-#[cfg(feature = "std")]
-impl BorshDeserialize for std::net::Ipv4Addr {
- #[inline]
- fn deserialize(buf: &mut &[u8]) -> Result {
- if buf.len() < 4 {
- return Err(Error::new(
- ErrorKind::InvalidInput,
- ERROR_UNEXPECTED_LENGTH_OF_INPUT,
- ));
- }
- let bytes: [u8; 4] = buf[..4].try_into().unwrap();
- let res = std::net::Ipv4Addr::from(bytes);
- *buf = &buf[4..];
- Ok(res)
- }
-}
-
-#[cfg(feature = "std")]
-impl BorshDeserialize for std::net::Ipv6Addr {
- #[inline]
- fn deserialize(buf: &mut &[u8]) -> Result {
- if buf.len() < 16 {
- return Err(Error::new(
- ErrorKind::InvalidInput,
- ERROR_UNEXPECTED_LENGTH_OF_INPUT,
- ));
- }
- let bytes: [u8; 16] = buf[..16].try_into().unwrap();
- let res = std::net::Ipv6Addr::from(bytes);
- *buf = &buf[16..];
- Ok(res)
- }
-}
-
-impl BorshDeserialize for Box
-where
- U: Into> + Borrow,
- T: ToOwned + ?Sized,
- T::Owned: BorshDeserialize,
-{
- fn deserialize(buf: &mut &[u8]) -> Result {
- Ok(T::Owned::deserialize(buf)?.into())
- }
-}
-
-macro_rules! impl_arrays {
- ($($len:expr)+) => {
- $(
- impl BorshDeserialize for [T; $len]
- where
- T: BorshDeserialize + Default + Copy
- {
- #[inline]
- fn deserialize(buf: &mut &[u8]) -> Result {
- let mut result = [T::default(); $len];
- if T::is_u8() && size_of::() == size_of::() {
- if buf.len() < $len {
- return Err(Error::new(
- ErrorKind::InvalidInput,
- ERROR_UNEXPECTED_LENGTH_OF_INPUT,
- ));
- }
- // The size of the memory should match because `size_of::() == size_of::()`.
- // `T::is_u8()` is a workaround for not being able to implement `[u8; *]` separately.
- result.copy_from_slice(unsafe { core::slice::from_raw_parts(buf.as_ptr() as *const T, $len) });
- *buf = &buf[$len..];
- } else {
- for i in 0..$len {
- result[i] = T::deserialize(buf)?;
- }
- }
- Ok(result)
- }
- }
- )+
- };
-}
-
-impl_arrays!(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 64 65 128 256 512 1024 2048);
-
-impl