Search code examples
rustbson

How to convert bson::Bson to Vec<u8> in rust?


I am trying to get a byte array of a non-document bson object value:

When attempting this:

let value: bson::Bson = bson::Bson::String(String::from("heya"));
bson::to_vec(&value).unwrap();

Then this error is produced:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: SerializationError { message: "attempted to encode a non-document type at the top level: String" }', ****\src\**\mod.rs:83:43
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

... I don't have a document and the documentation is un-clear that this can't be done and isn't clear as to how to achieve this.


Solution

  • Outside of a document, it isn't obvious what serializing a string as BSON should mean. Ordinarily, BSON would store the following data in order:

    • Type
    • Key + \0
    • Length
    • String + \0

    So if you want just the value, it's the string itself. If you want the value plus the null terminator, it's the previous part plus the null byte. If you want the length, value, and null terminator, then it's the length (including null byte), then all the previous parts. You can see this in bson here. None of these are valid BSON since they are not contained within a document, and don't even include the key or type, so their utility is limited.

    The bson crate doesn't expose this functionality, so you'll have to copy/write it in your own code. However, they are quite simple.

    If you are trying to get something that's valid BSON, you could put it in a simple document:

    bson::doc! { "0": value }