near / borsh-rs

Rust implementation of Binary Object Representation Serializer for Hashing
https://borsh.io/
Apache License 2.0
306 stars 67 forks source link

Extract `alloc` feature (2.0 candidate) #281

Open dj8yfo opened 7 months ago

dj8yfo commented 7 months ago

While working on an embedded app, it was discovered, that it's not possible to use borsh crate when global_allocator is not defined. One possible solution in such cases is to define global_allocator , another is to extract alloc feature and to use borsh with default_features = false .

std = ["alloc"]
# Provide impls for types in the Rust core allocation and collections library
# including String, Box<T>, Vec<T>, and Cow<T>. This is a subset of std but may
# be enabled without depending on all of std.
alloc = []

Below is superficial description of changes required:

// from
enum Repr {
    Simple(ErrorKind),
    Custom(Custom),
}

impl Error {
    pub fn new<T: Into<String>>(kind: ErrorKind, error: T) -> Error {
        Self::_new(kind, error.into())
    }

    fn _new(kind: ErrorKind, error: String) -> Error {
        Error {
            repr: Repr::Custom(Custom { kind, error }),
        }
    }
}
// to
enum Repr {
    Simple(ErrorKind),
}
impl Error {

}

For reference an example of replicating a subset of borsh without dependency on alloc crate is provided.

dj8yfo commented 3 months ago

original motivation to create this issue was kind of resolved by https://github.com/LedgerHQ/ledger-device-rust-sdk/pull/155, but the heap on the device was still not quite usable on the device with smallest capabilities, as mentioned in comment

With the mentioned tiniest target platform being a concrete example of environment imposing specific requirements, most likely an endeavor to resolve this issue will only make sense together with changing the signature of BorshDeserialize:

fn deserialize(...) -> Result<Self>;
to 
fn deserialize(..., &mut self) -> Result<()>;