DennyHiu
DennyHiu

Reputation: 6110

Save Nested Struct with Rust mongodb returns error the trait `From<T>` is not implemented for `Bson`

I have a struct to model an Item. But some of its field depends of other struct. And I want to save this nested object into mongodb with MongoDB Rust Driver. (https://github.com/mongodb/mongo-rust-driver)

     use mongodb::bson::doc;
     use serde::{Deserialize, Serialize};

     #[derive(Serialize, Deserialize, Debug)]
     struct CustomUnit {
         pub unit: String,
         pub multiplier: f64,
     }

     // Item depends on CustomUnit struct above. Nested object, JSON-like
     struct Item {
        pub name: String,
        pub qty: f64,
        pub unit: CustomUnit ,
     }

     // declare an item and an unit
     let my_unit = CustomUnit {unit: "BOX".to_string(), multiplier: 12.0};
     let a = Item {name: "FOO Item".to_string(), qty: 10.0, unit: my_unit};

     // later in the code I extracted the value for each field
     let name = a.name.clone();
     let qty = a.qty;
     let unit = a.unit;

     let doc = doc! {
        "name": name.clone(),
        "qty": qty,
        "unit": unit,
    };

    // throws an error: "the trait `From<CustomUnit>` is not implemented for `Bson`"
    db.collection(COLL).insert_one(doc, None).await
    

this displays an error message:

_^ the trait `From<CustomUnit>` is not implemented for `Bson`
= help: the following implementations were found:
         <Bson as From<&T>>
         <Bson as From<&[T]>>
         <Bson as From<&str>>
         <Bson as From<Regex>>
       and 19 others
= note: required by `std::convert::From::from`
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

How to implement this From<CustomUnit> for Bson trait ?

impl From<CustomUnit> for Bson {
    fn from(unit: CustomUnit) -> Self {
       // what to do here ? and how to return a Bson document ?
       // there's no explanation in rust-mongodb manual
    }
}

Upvotes: 1

Views: 1703

Answers (1)

DennyHiu
DennyHiu

Reputation: 6110

Since doc! internally converts each field into Binary JSON (BSON). doc! converts known types into BSON automatically, but since unit is a user made struct, it doesn't know how to.

use mongodb::bson;

 #[derive(Serialize, Deserialize, Debug)]
 struct CustomUnit {
     pub unit: String,
     pub multiplier: f64,
 }

let doc = doc! {
    "name": name.clone(),
    "qty": qty,
    "unit": bson::to_bson(&unit).unwrap(),
};

Upvotes: 4

Related Questions