1

尝试使用 r2d2-mongodb 和 actix_web 将传入数据存储到 mongo 中。

#[derive(Serialize, Deserialize, Debug)]
struct Weight {
    desc: String,
    grams: u32,
}

fn store_weights(weights: web::Json<Vec<Weight>>, db: web::Data<Pool<MongodbConnectionManager>>) -> Result<String> {
    let conn = db.get().unwrap();
    let coll = conn.collection("weights");
    for weight in weights.iter() {
        coll.insert_one(weight.into(), None).unwrap();
    }
    Ok(String::from("ok"))
}

我似乎无法理解我需要什么/如何将重量转换为与insert_one. 上面的代码错误成error[E0277]: the trait bound 'bson::ordered::OrderedDocument: std::convert::From<&api::weight::Weight>' is not satisfied

4

1 回答 1

1

签名insert_one是:

pub fn insert_one(
    &self, 
    doc: Document, 
    options: impl Into<Option<InsertOneOptions>>
) -> Result<InsertOneResult>

Documentbson::Document的别名bson::ordered::OrderedDocument

您的类型Weight没有实现 trait Into<Document>,这是weight::into(). 您可以实现它,但更惯用的方法是将Serialize特征与 一起使用bson::to_bson

fn store_weights(weights: Vec<Weight>) -> Result<&'static str, Box<dyn std::error::Error>> {
    let conn = db.get()?;
    let coll = conn.collection("weights");

    for weight in weights.iter() {
        let document = match bson::to_bson(weight)? {
            Document(doc) => doc,
            _ => unreachable!(), // Weight should always serialize to a document
        };
        coll.insert_one(document, None)?;
    }

    Ok("ok")
}

笔记:

  1. to_bson返回一个枚举, Bson, 可以是Array, Boolean,Document等。我们match用来确保它是Document.

  2. 我使用了返回类型?而不是展开。Result确保错误Into<Error>适合您的Result类型。

  3. 返回而不是为每个请求&'static str分配一个新的。String

于 2019-12-29T22:01:03.973 回答