WithSecureLabs / mongo-rs

A higher-level wrapper on top of the official bson & mongodb crates.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

no field on type Update when using serde

Bernie opened this issue · comments

Hi, I am trying to use Mongo and Bson derived traits while having some of the fields remain handled by serde in order to have customized serialization/de-serialization for that field.

I have a very basic example here:

#[derive(Debug, Serialize, Deserialize)]
pub struct MySerdeType {
    embedded_attr: String
}

#[derive(Debug, Bson, Mongo)]
#[mongo(collection = "my_docs", field, filter, update)]
pub struct MyDoc {
    mongo_attr: String,
    #[mongo(serde)]
    #[bson(serde)]
    serde_attr: MySerdeType
}

Unfortunately, this fails to compile due to 'no field serde_attr on type my_doc::Update'.

If I remove the update attribute, then this compiles, but the model will not implement the AsUpdate or Update traits. Is this expected? Thanks!

Hi Bernie,

Thanks for raising this and providing a replication example, good spot. This is due to a lack of derive testing. I believe I have a fix and am going to get that pushed live now with a patch bump. I have tested it with the following example:

use mongod::{AsFilter, AsUpdate, Bson, Comparator, Mongo};
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
pub struct MySerdeType {
    embedded_attr: String,
}

#[derive(Debug, Bson, Mongo)]
#[mongo(collection = "my_docs", field, filter, update)]
pub struct MyDoc {
    mongo_attr: String,
    #[bson(serde)]
    serde_attr: MySerdeType,
}

#[tokio::main]
async fn main() {
    let client = mongod::Client::new();
    let doc = MyDoc {
        mongo_attr: "foo".to_owned(),
        serde_attr: MySerdeType {
            embedded_attr: "bar".to_owned(),
        },
    };
    let result = client.insert(vec![doc]).await.unwrap();
    println!("(index: oid) {:?}", result);

    let mut filter = MyDoc::filter();
    filter.mongo_attr = Some(Comparator::Eq("foo".to_owned()));
    let mut update = MyDoc::update();
    update.serde_attr = Some(MySerdeType {
        embedded_attr: "updated".to_owned(),
    });
    let updates = mongod::Updates {
        set: Some(update),
        ..Default::default()
    };
    let updated = client.update::<MyDoc, _, _>(filter, updates).await.unwrap();
    println!("updated {} documents", updated);

    let mut filter = MyDoc::filter();
    filter.mongo_attr = Some(Comparator::Eq("foo".to_owned()));
    let result = client.find_one::<MyDoc, _>(filter).await.unwrap();
    println!("(index: oid) {:?}", result);
}