mongodb-gridfs 0.2.7

An implementation of Mongo GridFS
Documentation
//! This crate provides an implementation of Mongo GridFS on the top of mongodb's crate.
//! This implementation only use the _async/await_ version of mongodb.
//!
//! From <https://github.com/mongodb/specifications/blob/master/source/gridfs/gridfs-spec.rst>
//! > GridFS is a convention drivers use to store and retrieve BSON binary data (type “\x05”) that exceeds MongoDB’s BSON-document size limit of 16 MiB. When this data, called a user file, is written to the system, GridFS divides the file into chunks that are stored as distinct documents in a chunks collection. To retrieve a stored file, GridFS locates and returns all of its component chunks. Internally, GridFS creates a files collection document for each stored file. Files collection documents hold information about stored files, and they are stored in a files collection.
//! # Examples
//! Uploading a document:
//!  ```rust
//!  # use mongodb::Client;
//!  # use mongodb::{error::Error, Database};
//!  use mongodb_gridfs::{options::GridFSBucketOptions, GridFSBucket};
//!  # use uuid::Uuid;
//!  
//!  # fn db_name_new() -> String {
//!  #     "test_".to_owned()
//!  #         + Uuid::new_v4()
//!  #             .hyphenated()
//!  #             .encode_lower(&mut Uuid::encode_buffer())
//!  # }
//!  #
//!  # #[tokio::main]
//!  # async fn main() -> Result<(), Error> {
//!  #    let client = Client::with_uri_str(&std::env::var("MONGO_URI").unwrap_or("mongodb://localhost:27017/".to_string())).await?;
//!  #    let dbname = db_name_new();
//!  #    let db: Database = client.database(&dbname);
//!  let mut bucket = GridFSBucket::new(db.clone(), Some(GridFSBucketOptions::default()));
//!  let id = bucket
//!      .upload_from_stream("test.txt", "stream your data here".as_bytes(), None)
//!      .await?;
//!  #     println!("{}", id);
//!  #     db.drop(None).await
//!  # }
//!  ```
//!  Downloading a document:
//!  ```rust
//! # #[cfg(feature = "async-std-runtime")]
//! # use futures::stream::StreamExt;
//! # #[cfg(any(feature = "default", feature = "tokio-runtime"))]
//! use tokio_stream::StreamExt;
//! # use mongodb::Client;
//! # use mongodb::Database;
//! use mongodb_gridfs::{options::GridFSBucketOptions, GridFSBucket, GridFSError};
//! # use uuid::Uuid;
//!
//! # fn db_name_new() -> String {
//! #     "test_".to_owned()
//! #         + Uuid::new_v4()
//! #             .hyphenated()
//! #             .encode_lower(&mut Uuid::encode_buffer())
//! # }
//! #
//! # #[tokio::main]
//! # async fn main() -> Result<(), GridFSError> {
//! #     let client = Client::with_uri_str(
//! #         &std::env::var("MONGO_URI").unwrap_or("mongodb://localhost:27017/".to_string()),
//! #     )
//! #     .await?;
//! #     let dbname = db_name_new();
//! #     let db: Database = client.database(&dbname);
//! let bucket = GridFSBucket::new(db.clone(), Some(GridFSBucketOptions::default()));
//! #     let id = bucket
//! #         .clone()
//! #         .upload_from_stream("test.txt", "test data".as_bytes(), None)
//! #         .await?;
//! #     println!("{}", id);
//! #
//! let mut cursor = bucket.open_download_stream(id).await?;
//! let buffer = cursor.next().await.unwrap();
//! #     println!("{:?}", buffer);
//! #
//! #     db.drop(None).await?;
//! #     Ok(())
//! # }
//!  ```
//! # Features
//! The following features are propagated to mongodb:
//! - default
//! - async-std-runtime
//! - tokio-runtime
//! # Code Status
//! | Feature                                     | Status  | Notes                                           |
//! | ------------------------------------------- | ------- | ----------------------------------------------- |
//! | GridFSUploadOptions                         | DONE    | `contentType` and `aliases` are not implemented |
//! | GridFSBucketOption                          | DONE    | concerns not used when ensuring indexes         |
//! | GridFSFindOptions                           | DONE    |                                                 |
//! | GridFSDownloadByNameOptions                 | TODO    |                                                 |
//! | GridFSBucket                                | DONE    |                                                 |
//! | GridFSBucket . open_upload_stream           | DONE    |                                                 |
//! | GridFSBucket . open_upload_stream_with_id   |         |                                                 |
//! | GridFSBucket . upload_from_stream           | NO      | No Implementation planned                         |
//! | GridFSBucket . upload_from_stream_with_id   | NO      | No Implementation planned                         |
//! | GridFSBucket . open_download_stream         | DONE    |                                                 |
//! | GridFSBucket . download_to_stream           | NO      | No Implementation planned                         |
//! | GridFSBucket . delete                       | DONE    |                                                 |
//! | GridFSBucket . find                         | DONE    |                                                 |
//! | GridFSBucket . rename                       | DONE    |                                                 |
//! | GridFSBucket . drop                         | DONE    |                                                 |
//! | GridFSBucket . open_download_stream_by_name |         |                                                 |
//! | GridFSBucket . download_to_stream_by_name   |         |                                                 |
//! | indexes                                     | DONE   |                                                 |

pub mod bucket;
pub mod options;
use std::{
    error::Error,
    fmt::{Display, Formatter, Result},
};

pub use bucket::GridFSBucket;

#[derive(Debug)]
pub enum GridFSError {
    MongoError(mongodb::error::Error),
    FileNotFound(),
}

impl From<mongodb::error::Error> for GridFSError {
    fn from(err: mongodb::error::Error) -> GridFSError {
        GridFSError::MongoError(err)
    }
}

impl Error for GridFSError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        match self {
            GridFSError::MongoError(e) => Some(e),
            GridFSError::FileNotFound() => None,
        }
    }

    // fn backtrace(&self) -> Option<&std::backtrace::Backtrace> {
    //     None
    // }

    fn description(&self) -> &str {
        "description() is deprecated; use Display"
    }

    fn cause(&self) -> Option<&dyn Error> {
        self.source()
    }
}

impl Display for GridFSError {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        match self {
            GridFSError::MongoError(me) => write!(f, "{}", me),
            GridFSError::FileNotFound() => write!(f, "File not found"),
        }
    }
}