#derive #borsh

borsh-derive-internal

Binary Object Representation Serializer for Hashing

31 releases

0.11.0 Jun 2, 2023
0.10.3 Mar 22, 2023
0.10.2 Feb 14, 2023
0.9.3 Feb 4, 2022
0.2.10 Nov 27, 2019

#1599 in Encoding

Download history 104882/week @ 2023-05-26 126931/week @ 2023-06-02 123939/week @ 2023-06-09 129299/week @ 2023-06-16 133949/week @ 2023-06-23 126260/week @ 2023-06-30 153207/week @ 2023-07-07 127515/week @ 2023-07-14 139367/week @ 2023-07-21 131648/week @ 2023-07-28 130342/week @ 2023-08-04 135582/week @ 2023-08-11 151625/week @ 2023-08-18 154657/week @ 2023-08-25 154825/week @ 2023-09-01 137719/week @ 2023-09-08

626,403 downloads per month
Used in 1,350 crates (via borsh-derive)

Apache-2.0

25KB
483 lines

Borsh in Rust   Latest Version borsh: rustc 1.55+ License Apache-2.0 badge License MIT badge

borsh-rs is Rust implementation of the Borsh binary serialization format.

Borsh stands for Binary Object Representation Serializer for Hashing. It is meant to be used in security-critical projects as it prioritizes consistency, safety, speed, and comes with a strict specification.

Example

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:

#[derive(BorshSerialize, BorshDeserialize)]
#[borsh_init(init)]
struct Message {
    message: String,
    timestamp: u64,
    public_key: CryptoKey,
    signature: CryptoSignature
    hash: CryptoHash
}

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);
    }
}

borsh_skip allows to skip serializing/deserializing fields, assuming they implement Default trait, similary to #[serde(skip)].

#[derive(BorshSerialize, BorshDeserialize)]
struct A {
    x: u64,
    #[borsh_skip]
    y: f32,
}

Releasing

The versions of all public crates in this repository are collectively managed by a single version in the workspace manifest.

So, to publish a new version of all the crates, you can do so by simply bumping that to the next "patch" version and submit a PR.

We have CI Infrastructure put in place to automate the process of publishing all crates once a version change has merged into master.

However, before you release, make sure the CHANGELOG is up to date and that the [Unreleased] section is present but empty.

License

This repository is distributed under the terms of both the MIT license and the Apache License (Version 2.0). See LICENSE-MIT and LICENSE-APACHE for details.

Dependencies

~1MB
~31K SLoC