[go: up one dir, main page]

mongodb 0.3.9

A native MongoDB driver developed under MongoDB labs.
Documentation
use bson::{Bson, Document};
use json::options::FromValue;
use mongodb::coll::options::{AggregateOptions, CountOptions, FindOneAndDeleteOptions,
                             FindOneAndUpdateOptions, FindOptions};
use serde_json::Map;

pub enum Arguments {
    Aggregate {
        pipeline: Vec<Document>,
        options: AggregateOptions,
        out: bool,
    },
    Count {
        filter: Option<Document>,
        options: CountOptions,
    },
    Delete { filter: Document, many: bool },
    Distinct {
        field_name: String,
        filter: Option<Document>,
    },
    Find {
        filter: Option<Document>,
        options: FindOptions,
    },
    FindOneAndDelete {
        filter: Document,
        options: FindOneAndDeleteOptions,
    },
    FindOneAndReplace {
        filter: Document,
        replacement: Document,
        options: FindOneAndUpdateOptions,
    },
    FindOneAndUpdate {
        filter: Document,
        update: Document,
        options: FindOneAndUpdateOptions,
    },
    InsertOne { document: Document },
    InsertMany { documents: Vec<Document> },
    ReplaceOne {
        filter: Document,
        replacement: Document,
        upsert: bool,
    },
    Update {
        filter: Document,
        update: Document,
        upsert: bool,
        many: bool,
    },
}

impl Arguments {
    pub fn aggregate_from_json(object: &Map<String, Value>) -> Result<Arguments, String> {
        let options = AggregateOptions::from_json(object);

        let f = |x| Some(Bson::from_json(x));

        let array = val_or_err!(object.get("pipeline").and_then(f),
                                   Some(Bson::Array(arr)) => arr,
                                   "`aggregate` requires pipeline array");

        let mut docs = vec![];
        let mut out = false;

        for bson in array {
            let doc = match bson {
                Bson::Document(doc) => {
                    out = out || doc.contains_key("$out");
                    doc
                }
                _ => return Err(String::from("aggregate pipeline can only contain documents")),
            };

            docs.push(doc);
        }

        Ok(Arguments::Aggregate {
            pipeline: docs,
            options: options,
            out: out,
        })
    }

    pub fn count_from_json(object: &Map<String, Value>) -> Arguments {
        let options = CountOptions::from_json(object);

        let f = |x| Some(Bson::from_json(x));
        let filter = match object.get("filter").and_then(f) {
            Some(Bson::Document(doc)) => Some(doc),
            _ => None,
        };

        Arguments::Count {
            filter: filter,
            options: options,
        }
    }

    pub fn delete_from_json(object: &Map<String, Value>, many: bool) -> Result<Arguments, String> {
        let f = |x| Some(Bson::from_json(x));
        let document = val_or_err!(object.get("filter").and_then(f),
                                   Some(Bson::Document(doc)) => doc,
                                   "`delete` requires document");

        Ok(Arguments::Delete {
            filter: document,
            many: many,
        })
    }

    pub fn distinct_from_json(object: &Map<String, Value>) -> Result<Arguments, String> {
        let f = |x| Some(Bson::from_json(x));
        let field_name = val_or_err!(object.get("fieldName").and_then(f),
                                     Some(Bson::String(ref s)) => s.to_owned(),
                                     "`distinct` requires field name");

        let f = |x| Some(Bson::from_json(x));
        let filter = match object.get("filter").and_then(f) {
            Some(Bson::Document(doc)) => Some(doc),
            _ => None,
        };

        Ok(Arguments::Distinct {
            field_name: field_name,
            filter: filter,
        })
    }

    pub fn find_from_json(object: &Map<String, Value>) -> Arguments {
        let options = FindOptions::from_json(object);

        let f = |x| Some(Bson::from_json(x));
        let filter = match object.get("filter").and_then(f) {
            Some(Bson::Document(doc)) => Some(doc),
            _ => None,
        };

        Arguments::Find {
            filter: filter,
            options: options,
        }
    }

    pub fn find_one_and_delete_from_json(object: &Map<String, Value>) -> Result<Arguments, String> {
        let options = FindOneAndDeleteOptions::from_json(object);

        let f = |x| Some(Bson::from_json(x));
        let filter = val_or_err!(object.get("filter").and_then(f),
                                 Some(Bson::Document(doc)) => doc,
                                 "`find_one_and_delete` requires filter document");

        Ok(Arguments::FindOneAndDelete {
            filter: filter,
            options: options,
        })
    }

    pub fn find_one_and_replace_from_json(object: &Map<String, Value>) -> Result<Arguments, String> {
        let options = FindOneAndUpdateOptions::from_json(object);

        let f = |x| Some(Bson::from_json(x));
        let filter = val_or_err!(object.get("filter").and_then(f),
                                 Some(Bson::Document(doc)) => doc,
                                 "`find_one_and_update` requires filter document");

        let f = |x| Some(Bson::from_json(x));
        let replacement = val_or_err!(object.get("replacement").and_then(f),
                                 Some(Bson::Document(doc)) => doc,
                                 "`find_one_and_replace` requires replacement document");

        Ok(Arguments::FindOneAndReplace {
            filter: filter,
            replacement: replacement,
            options: options,
        })
    }

    pub fn find_one_and_update_from_json(object: &Map<String, Value>) -> Result<Arguments, String> {
        let options = FindOneAndUpdateOptions::from_json(object);

        let f = |x| Some(Bson::from_json(x));
        let filter = val_or_err!(object.get("filter").and_then(f),
                                 Some(Bson::Document(doc)) => doc,
                                 "`find_one_and_update` requires filter document");

        let f = |x| Some(Bson::from_json(x));
        let update = val_or_err!(object.get("update").and_then(f),
                                 Some(Bson::Document(doc)) => doc,
                                 "`find_one_and_update` requires update document");

        Ok(Arguments::FindOneAndUpdate {
            filter: filter,
            update: update,
            options: options,
        })
    }

    pub fn insert_many_from_json(object: &Map<String, Value>) -> Result<Arguments, String> {
        let f = |x| Some(Bson::from_json(x));

        let bsons = val_or_err!(object.get("documents").and_then(f),
                                Some(Bson::Array(arr)) => arr,
                                "`insert_many` requires documents");

        let mut docs = vec![];

        for bson in bsons.into_iter() {
            match bson {
                Bson::Document(doc) => docs.push(doc),
                _ => return Err(String::from("`insert_many` can only insert documents")),
            };
        }

        Ok(Arguments::InsertMany { documents: docs })
    }

    pub fn insert_one_from_json(object: &Map<String, Value>) -> Result<Arguments, String> {
        let f = |x| Some(Bson::from_json(x));
        let document = val_or_err!(object.get("document").and_then(f),
                                   Some(Bson::Document(doc)) => doc,
                                   "`delete_one` requires document");

        Ok(Arguments::InsertOne { document: document })
    }

    pub fn replace_one_from_json(object: &Map<String, Value>) -> Result<Arguments, String> {
        let f = |x| Some(Bson::from_json(x));
        let filter = val_or_err!(object.get("filter").and_then(f),
                                 Some(Bson::Document(doc)) => doc,
                                 "`update` requires filter document");

        let f = |x| Some(Bson::from_json(x));
        let replacement = val_or_err!(object.get("replacement").and_then(f),
                                 Some(Bson::Document(doc)) => doc,
                                 "`update` requires update document");

        let f = |x| Some(Bson::from_json(x));
        let upsert = var_match!(object.get("upsert").and_then(f),
                                Some(Bson::Boolean(b)) => b);

        Ok(Arguments::ReplaceOne {
            filter: filter,
            replacement: replacement,
            upsert: upsert,
        })
    }

    pub fn update_from_json(object: &Map<String, Value>, many: bool) -> Result<Arguments, String> {
        let f = |x| Some(Bson::from_json(x));
        let filter = val_or_err!(object.get("filter").and_then(f),
                                 Some(Bson::Document(doc)) => doc,
                                 "`update` requires filter document");

        let f = |x| Some(Bson::from_json(x));
        let update = val_or_err!(object.get("update").and_then(f),
                                 Some(Bson::Document(doc)) => doc,
                                 "`update` requires update document");

        let f = |x| Some(Bson::from_json(x));
        let upsert = var_match!(object.get("upsert").and_then(f),
                                Some(Bson::Boolean(b)) => b);

        Ok(Arguments::Update {
            filter: filter,
            update: update,
            upsert: upsert,
            many: many,
        })
    }
}