| Crates.io | bson_comp |
| lib.rs | bson_comp |
| version | 0.1.0 |
| created_at | 2025-12-23 13:30:55.887374+00 |
| updated_at | 2025-12-23 13:30:55.887374+00 |
| description | A derive macro that implements `Into |
| homepage | |
| repository | https://github.com/h01-team/bson_comp |
| max_upload_size | |
| id | 2001500 |
| size | 8,925 |
Stop fighting the doc! macro. Make your types generic-compatible.
If you work with MongoDB in Rust, you've definitely hit this wall. You have a nice, strongly-typed Enum or Struct, and you just want to use it in a query.
You try to do this:
let filter = doc! { "role": Role::Admin };
And the compiler screams at you with Error E0277:
the trait bound Bson: std::convert::From<Role> is not satisfied
required for Role to implement Into<Bson>
So you end up writing this boilerplate everywhere:
// ❌ The Ugly Way
// Manual conversion every time you use it.
let filter = doc! {
"role": bson::to_bson(&Role::Admin).unwrap()
};
bson_comp (BSON Compatibility) handles that boilerplate for you. It implements Into<Bson> for your types so they fit right into the doc! macro.
// ✅ The Clean Way
let filter = doc! { "role": Role::Admin };
Add this to your Cargo.toml:
[dependencies]
bson_comp = "0.1"
serde = { version = "1.0", features = ["derive"] }
Perfect for status flags, user roles, or category types.
use serde::{Serialize, Deserialize};
use bson_comp::BsonComp;
use bson::doc;
#[derive(Serialize, Deserialize, BsonComp)]
#[serde(rename_all = "UPPERCASE")] // Optional: controls how it looks in Mongo
enum Role {
Admin,
User,
}
fn main() {
// Works natively in doc!
let query = doc! {
"role": Role::Admin,
"is_active": true
};
// Output: { "role": "ADMIN", "is_active": true }
}
Useful when embedding objects inside other documents.
use serde::Serialize;
use bson_comp::BsonComp;
use bson::doc;
#[derive(Serialize, BsonComp)]
struct Address {
city: String,
zip: u32,
}
fn main() {
let my_address = Address {
city: "New York".to_string(),
zip: 10001
};
// Embed it directly
let profile = doc! {
"username": "alice",
"address": my_address
};
}
Rust's "Orphan Rules" prevent you from implementing From<YourType> for Bson because you don't own the bson crate.
However, the doc! macro accepts anything that implements Into<Bson>. Since Into is a generic trait, you are allowed to implement it for your own types.
This macro simply generates:
impl Into<bson::Bson> for YourType {
fn into(self) -> bson::Bson {
bson::to_bson(&self).expect("Failed to serialize type for BSON macro")
}
}
serde::Serialize.MIT. Enjoy clean code.