use std::io::{Read, Write};
use futures_util::{AsyncReadExt, AsyncWriteExt};
use super::Cursor;
use crate::{
bson::{Bson, Document},
error::Result,
gridfs::{
GridFsBucket as AsyncGridFsBucket,
GridFsDownloadStream as AsyncGridFsDownloadStream,
GridFsUploadStream as AsyncGridFsUploadStream,
},
options::{
GridFsDownloadByNameOptions,
GridFsFindOptions,
GridFsUploadOptions,
ReadConcern,
SelectionCriteria,
WriteConcern,
},
runtime,
};
pub use crate::gridfs::FilesCollectionDocument;
pub struct GridFsBucket {
async_bucket: AsyncGridFsBucket,
}
impl GridFsBucket {
pub(crate) fn new(async_bucket: AsyncGridFsBucket) -> Self {
Self { async_bucket }
}
pub fn read_concern(&self) -> Option<&ReadConcern> {
self.async_bucket.read_concern()
}
pub fn write_concern(&self) -> Option<&WriteConcern> {
self.async_bucket.write_concern()
}
pub fn selection_criteria(&self) -> Option<&SelectionCriteria> {
self.async_bucket.selection_criteria()
}
pub fn delete(&self, id: Bson) -> Result<()> {
runtime::block_on(self.async_bucket.delete(id))
}
pub fn find(
&self,
filter: Document,
options: impl Into<Option<GridFsFindOptions>>,
) -> Result<Cursor<FilesCollectionDocument>> {
runtime::block_on(self.async_bucket.find(filter, options)).map(Cursor::new)
}
pub fn rename(&self, id: Bson, new_filename: impl AsRef<str>) -> Result<()> {
runtime::block_on(self.async_bucket.rename(id, new_filename))
}
pub fn drop(&self) -> Result<()> {
runtime::block_on(self.async_bucket.drop())
}
}
pub struct GridFsDownloadStream {
async_stream: AsyncGridFsDownloadStream,
}
impl Read for GridFsDownloadStream {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
runtime::block_on(self.async_stream.read(buf))
}
}
impl GridFsDownloadStream {
fn new(async_stream: AsyncGridFsDownloadStream) -> Self {
Self { async_stream }
}
}
impl GridFsBucket {
pub fn open_download_stream(&self, id: Bson) -> Result<GridFsDownloadStream> {
runtime::block_on(self.async_bucket.open_download_stream(id)).map(GridFsDownloadStream::new)
}
pub fn open_download_stream_by_name(
&self,
filename: impl AsRef<str>,
options: impl Into<Option<GridFsDownloadByNameOptions>>,
) -> Result<GridFsDownloadStream> {
runtime::block_on(
self.async_bucket
.open_download_stream_by_name(filename, options),
)
.map(GridFsDownloadStream::new)
}
}
pub struct GridFsUploadStream {
async_stream: AsyncGridFsUploadStream,
}
impl GridFsUploadStream {
pub fn id(&self) -> &Bson {
self.async_stream.id()
}
pub fn close(&mut self) -> std::io::Result<()> {
runtime::block_on(self.async_stream.close())
}
pub fn abort(&mut self) -> Result<()> {
runtime::block_on(self.async_stream.abort())
}
}
impl Write for GridFsUploadStream {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
runtime::block_on(self.async_stream.write(buf))
}
fn flush(&mut self) -> std::io::Result<()> {
runtime::block_on(self.async_stream.flush())
}
}
impl GridFsBucket {
pub fn open_upload_stream(
&self,
filename: impl AsRef<str>,
options: impl Into<Option<GridFsUploadOptions>>,
) -> GridFsUploadStream {
let async_stream = self.async_bucket.open_upload_stream(filename, options);
GridFsUploadStream { async_stream }
}
pub fn open_upload_stream_with_id(
&self,
id: Bson,
filename: impl AsRef<str>,
options: impl Into<Option<GridFsUploadOptions>>,
) -> GridFsUploadStream {
let async_stream = self
.async_bucket
.open_upload_stream_with_id(id, filename, options);
GridFsUploadStream { async_stream }
}
}