cached_db 0.2.2

A NoSQL database with a built in cache layer.
Documentation
use std::io::Write;

use bson::{Bson, Document};

use crate::internal;

use super::collection;

pub fn update_one(
    path: &String,
    col: String,
    filter: Document,
    update: Document,
) -> Result<Option<Document>, Box<dyn std::error::Error + Send + Sync>> {
    internal::ensure_folder(path);

    let data = collection::get(path, col.clone());

    let mut doc = match data {
        Ok(doc) => doc,
        Err(_) => Document::new(),
    };

    let docs = match doc.get(&col) {
        Some(Bson::Array(docs)) => docs.clone(),
        _ => return Err("Collection not found".into()),
    };

    for (index, d) in docs.iter().enumerate() {
        if let Bson::Document(d) = d {
            if document_matches_filter(d, &filter) {
                let mut new_data = d.clone();

                for (key, value) in &update {
                    new_data.insert(key, value);
                }

                let mut new_docs = docs.clone();
                new_docs[index] = Bson::Document(new_data.clone());

                doc.insert(&col, new_docs);

                let mut file = std::fs::File::create(format!("{}/{}.bson", path, &col))?;
                file.write_all(bson::to_vec(&doc)?.as_slice())?;

                return Ok(Some(new_data));
            }
        }
    }

    Err("Not found".into())
}

fn document_matches_filter(doc: &Document, filter: &Document) -> bool {
    for (key, value) in filter {
        if doc.get(key) != Some(value) {
            return false;
        }
    }

    true
}