I need help using Rust’s u128
data type via MongoDB’s Rust driver. Please find my minimal example below:
use mongodb::{bson::{doc},
options::{ClientOptions, ServerApi, ServerApiVersion},
Client};
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize, Serialize)]
struct Book {
id : u128,
title : String,
author: String,
}
#[tokio::main]
async fn main() -> mongodb::error::Result<()> {
// create client options
let uri = "mongodb://localhost:27017";
let mut client_options = ClientOptions::parse(uri).await?;
// set server API
let server_api = ServerApi::builder().version(ServerApiVersion::V1).build();
client_options.server_api = Some(server_api);
client_options.app_name = Some("Books".to_string());
// create new client, connect to server
let client = Client::with_options(client_options)?;
// get handle to 'passports' database
let db = client.database("books");
// obtain handle to (strongly typed) collection in database
let collection = db.collection::<Book>("books");
let books = vec![
Book {
id: u128::pow(2,64),
title: "The Grapes of Wrath".to_string(),
author: "John Steinbeck".to_string(),
},
Book {
id: u128::pow(2,64)+1,
title: "To Kill a Mockingbird".to_string(),
author: "Harper Lee".to_string(),
},
];
// insert books into (strongly typed) collection
// @note No manual conversion to BSON is necessary
collection.insert_many(books, None).await?;
Ok(())
}
When I try to compile and run this code with cargo run
it fails with the following error message:
Compiling mongodb_dr v0.1.0 (/Users/username/repo/git/rustwerk/mongodb_dr)
Finished dev [unoptimized + debuginfo] target(s) in 0.84s
Running `target/debug/mongodb_dr`
Error: Error { kind: BsonSerialization(SerializationError { message: "u128 is not supported" }), labels: {}, wire_version: Some(17), source: None }
Any help would be much appreciated.
2
Answers
Another good alternative can be using Rust's UUID crate. It generates "unique 128-bit value, stored as 16 octets, and regularly formatted as a hex string in five groups", e.g.:
To use UUIDs instead of
u128
please modify the above code:Do not forget to add a dependency for the UUID crate into your
Cargo.toml
file:There are no 128-bit integers in the BSON spec, so you need to choose an intermediate type to represent it in a BSON-compatible type.
I’m not sure if MongoDB has any guidance for unserializable types, but just for BSON’s purposes, you can use the binary type, which is represented in the library as
Binary
andRawBinaryRef
.You can use Serde’s
with
attribute to define custom serialization logic. It accepts a module withserialize
anddeserialize
functions, which replace the default serialization functions.I’ve used
Generic
as the binary subtype (U128_SUBTYPE
in the code above), but you could use a custom one for more robustness.I didn’t want to serialize it as an array because it is not very space-efficient (see the note at the bottom of the spec). Other good formats would be two
u64
s, or a hexadecimal string.Related: