mongodb 0.9.1

The official MongoDB driver for Rust (currently in alpha)
Documentation
#[cfg(test)]
mod test;

use std::collections::HashMap;

use bson::{bson, doc, Document};

use crate::{
    bson_util,
    cmap::{Command, CommandResponse, StreamDescription},
    error::{ErrorKind, Result},
    operation::{append_options, Operation, WriteResponseBody},
    options::InsertManyOptions,
    results::InsertManyResult,
    Namespace,
};

#[derive(Debug)]
pub(crate) struct Insert {
    ns: Namespace,
    documents: Vec<Document>,
    options: Option<InsertManyOptions>,
}

impl Insert {
    pub(crate) fn new(
        ns: Namespace,
        documents: Vec<Document>,
        options: Option<InsertManyOptions>,
    ) -> Self {
        Self {
            ns,
            options,
            documents: documents
                .into_iter()
                .map(|mut d| {
                    bson_util::add_id(&mut d);
                    d
                })
                .collect(),
        }
    }
}

impl Operation for Insert {
    type O = InsertManyResult;
    const NAME: &'static str = "insert";

    fn build(&self, description: &StreamDescription) -> Result<Command> {
        let mut body = doc! {
            Self::NAME: self.ns.coll.clone(),
            "documents": bson_util::to_bson_array(&self.documents),
        };
        append_options(&mut body, self.options.as_ref())?;

        let ordered = self
            .options
            .as_ref()
            .and_then(|options| options.ordered)
            .unwrap_or(true);
        body.insert("ordered", ordered);

        Ok(Command::new(
            Self::NAME.to_string(),
            self.ns.db.clone(),
            body,
        ))
    }

    fn handle_response(&self, response: CommandResponse) -> Result<Self::O> {
        let body: WriteResponseBody = response.body()?;
        body.validate()?;

        let mut map = HashMap::new();
        for (i, doc) in self.documents.iter().enumerate() {
            map.insert(
                i,
                doc.get("_id")
                    .ok_or_else(|| ErrorKind::ResponseError {
                        message: "missing _id in inserted document".to_string(),
                    })?
                    .clone(),
            );
        }
        Ok(InsertManyResult { inserted_ids: map })
    }
}