1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
use bson::Document;
use mongodb::options::{ReadConcern, ReadPreference, WriteConcern};
use std::time::Duration;
use typed_builder::TypedBuilder;

/// [Spec](https://github.com/mongodb/specifications/blob/master/source/gridfs/gridfs-spec.rst#file-upload)
#[derive(Clone, Default, TypedBuilder)]
pub struct GridFSUploadOptions {
    /**
     * The number of bytes per chunk of this file. Defaults to the
     * chunkSizeBytes in the GridFSBucketOptions.
     */
    pub(crate) chunk_size_bytes: Option<u32>,

    /**
     * User data for the 'metadata' field of the files collection document.
     * If not provided the driver MUST omit the metadata field from the
     * files collection document.
     */
    pub(crate) metadata: Option<Document>,

    /**
     * DEPRECATED: A valid MIME type. If not provided the driver MUST omit the
     * contentType field from the files collection document.
     *
     * Applications wishing to store a contentType should add a contentType field
     * to the metadata document instead.
     */
    content_type: Option<String>,

    /**
     * DEPRECATED: An array of aliases. If not provided the driver MUST omit the
     * aliases field from the files collection document.
     *
     * Applications wishing to store aliases should add an aliases field to the
     * metadata document instead.
     */
    aliases: Option<Vec<String>>,
}

/// [Spec](https://github.com/mongodb/specifications/blob/master/source/gridfs/gridfs-spec.rst#configurable-gridfsbucket-class)
#[derive(Clone, Debug, TypedBuilder)]
pub struct GridFSBucketOptions {
    /**
     * The bucket name. Defaults to 'fs'.
     */
    #[builder(default = "fs".into())]
    pub bucket_name: String,

    /**
     * The chunk size in bytes. Defaults to 255 KiB.
     */
    #[builder(default = 255 * 1024)]
    pub chunk_size_bytes: u32,

    /**
     * The write concern. Defaults to the write concern of the database.
     */
    #[builder(default)]
    pub write_concern: Option<WriteConcern>,

    /**
     * The read concern. Defaults to the read concern of the database.
     */
    #[builder(default)]
    pub read_concern: Option<ReadConcern>,

    /**
     * The read preference. Defaults to the read preference of the database.
     */
    #[builder(default)]
    pub read_preference: Option<ReadPreference>,

    /**
     * TRANSITIONAL: This option is provided for backwards compatibility.
     * It MUST be supported while a driver supports MD5 and MUST be removed
     * (or made into a no-op) when a driver removes MD5 support entirely.
     * When true, the GridFS implementation will not compute MD5 checksums
     * of uploaded files. Defaults to false.
     */
    #[builder(default = false)]
    pub disable_md5: bool,
}

impl Default for GridFSBucketOptions {
    fn default() -> Self {
        GridFSBucketOptions {
            bucket_name: "fs".into(),
            chunk_size_bytes: 255 * 1024,
            write_concern: None,
            read_concern: None,
            read_preference: None,
            disable_md5: false,
        }
    }
}

/// [Spec](https://github.com/mongodb/specifications/blob/master/source/gridfs/gridfs-spec.rst#generic-find-on-files-collection)
#[derive(Clone, Debug, Default, TypedBuilder)]
pub struct GridFSFindOptions {
    /**
     * Enables writing to temporary files on the server. When set to true, the server
     * can write temporary data to disk while executing the find operation on the files collection.
     *
     * This option is sent only if the caller explicitly provides a value. The default
     * is to not send a value. For servers < 3.2, this option is ignored and not sent
     * as allowDiskUse does not exist in the OP_QUERY wire protocol.
     *
     * @see https://docs.mongodb.com/manual/reference/command/find/
     */
    #[builder(default)]
    pub allow_disk_use: Option<bool>,

    /**
     * The number of documents to return per batch.
     */
    #[builder(default)]
    pub batch_size: Option<u32>,

    /**
     * The maximum number of documents to return.
     */
    #[builder(default)]
    pub limit: Option<i64>,

    /**
     * The maximum amount of time to allow the query to run.
     */
    #[builder(default)]
    pub max_time: Option<Duration>,

    /**
     * The server normally times out idle cursors after an inactivity period (10 minutes)
     * to prevent excess memory use. Set this option to prevent that.
     */
    #[builder(default)]
    pub no_cursor_timeout: Option<bool>,

    /**
     * The number of documents to skip before returning.
     */
    #[builder(default)]
    pub skip: i64,

    /**
     * The order by which to sort results. Defaults to not sorting.
     */
    #[builder(default)]
    pub sort: Option<Document>,
}

#[cfg(test)]
mod tests {
    use super::{GridFSBucketOptions, GridFSFindOptions};

    #[test]
    fn grid_fs_bucket_options_default() {
        let options = GridFSBucketOptions::default();
        assert_eq!(options.bucket_name, "fs");
        assert_eq!(options.chunk_size_bytes, 255 * 1024);
        assert_eq!(options.disable_md5, false);
    }
    #[test]
    fn grid_fs_bucket_options_builder_default() {
        let options = GridFSBucketOptions::builder().build();
        assert_eq!(options.bucket_name, "fs");
        assert_eq!(options.chunk_size_bytes, 255 * 1024);
        assert_eq!(options.disable_md5, false);
    }
    #[test]
    fn grid_fs_bucket_options_bucket_name() {
        let options = GridFSBucketOptions::builder()
            .bucket_name("newfs".into())
            .build();
        assert_eq!(options.bucket_name, "newfs");
    }
    #[test]
    fn grid_fs_bucket_options_chunk_size_bytes() {
        let options = GridFSBucketOptions::builder()
            .chunk_size_bytes(1023)
            .build();
        assert_eq!(options.chunk_size_bytes, 1023);
    }
    #[test]
    fn grid_fs_bucket_options_builder_chain() {
        let options = GridFSBucketOptions::builder()
            .bucket_name("newfs".into())
            .chunk_size_bytes(1023)
            .build();
        assert_eq!(options.bucket_name, "newfs");
        assert_eq!(options.chunk_size_bytes, 1023);
    }

    #[test]
    fn grid_fs_find_options_builder_chain() {
        let options = GridFSFindOptions::builder().skip(4).build();
        assert_eq!(options.skip, 4);
    }
    #[test]
    fn grid_fs_find_options_builder_default() {
        let options = GridFSFindOptions::builder().build();
        assert_eq!(options.allow_disk_use, None);
        assert_eq!(options.batch_size, None);
        assert_eq!(options.limit, None);
        assert_eq!(options.max_time, None);
        assert_eq!(options.no_cursor_timeout, None);
        assert_eq!(options.skip, 0);
        assert_eq!(options.sort, None);
    }
    #[test]
    fn grid_fs_find_options_default() {
        let options = GridFSFindOptions::default();
        assert_eq!(options.allow_disk_use, None);
        assert_eq!(options.batch_size, None);
        assert_eq!(options.limit, None);
        assert_eq!(options.max_time, None);
        assert_eq!(options.no_cursor_timeout, None);
        assert_eq!(options.skip, 0);
        assert_eq!(options.sort, None);
    }
}