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
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
// This file was generated by gir (https://github.com/gtk-rs/gir @ fe7a6ff+)
// from gir-files (https://github.com/gtk-rs/gir-files @ b215ee8)
// DO NOT EDIT

use Format;
use Message;
use Object;
use ParserOptions;
use Stream;
use ffi;
use glib::object::IsA;
use glib::translate::*;
use glib_ffi;
use gobject_ffi;
use std::mem;
use std::ptr;

glib_wrapper! {
    /// A MIME parser context.
    ///
    /// # Implements
    ///
    /// [`ParserExt`](trait.ParserExt.html)
    pub struct Parser(Object<ffi::GMimeParser, ffi::GMimeParserClass>);

    match fn {
        get_type => || ffi::g_mime_parser_get_type(),
    }
}

impl Parser {
    /// Creates a new parser object.
    ///
    /// # Returns
    ///
    /// a new parser object.
    pub fn new() -> Parser {
        unsafe {
            from_glib_full(ffi::g_mime_parser_new())
        }
    }

    /// Creates a new parser object preset to parse `stream`.
    /// ## `stream`
    /// raw message or part stream
    ///
    /// # Returns
    ///
    /// a new parser object.
    pub fn new_with_stream<P: IsA<Stream>>(stream: &P) -> Parser {
        unsafe {
            from_glib_full(ffi::g_mime_parser_new_with_stream(stream.to_glib_none().0))
        }
    }
}

impl Default for Parser {
    fn default() -> Self {
        Self::new()
    }
}

/// Trait containing all `Parser` methods.
///
/// # Implementors
///
/// [`Parser`](struct.Parser.html)
pub trait ParserExt {
    /// Constructs a MIME message from `self`.
    /// ## `options`
    /// a `ParserOptions` or `None`
    ///
    /// # Returns
    ///
    /// a MIME message or `None` on fail.
    fn construct_message<'a, P: Into<Option<&'a ParserOptions>>>(&self, options: P) -> Option<Message>;

    /// Constructs a MIME part from `self`.
    /// ## `options`
    /// a `ParserOptions` or `None`
    ///
    /// # Returns
    ///
    /// a MIME part based on `self` or `None` on
    /// fail.
    fn construct_part<'a, P: Into<Option<&'a ParserOptions>>>(&self, options: P) -> Option<Object>;

    /// Tests the end-of-stream indicator for `self`'s internal stream.
    ///
    /// # Returns
    ///
    /// `true` on EOS or `false` otherwise.
    fn eos(&self) -> bool;

    /// Gets the format that the parser is set to parse.
    ///
    /// # Returns
    ///
    /// the format that the parser is set to parse.
    fn get_format(&self) -> Format;

    /// Gets the stream offset of the beginning of the headers of the most
    /// recently parsed message.
    ///
    /// # Returns
    ///
    /// the offset of the beginning of the headers of the most
    /// recently parsed message or %-1 on error.
    fn get_headers_begin(&self) -> i64;

    /// Gets the stream offset of the end of the headers of the most
    /// recently parsed message.
    ///
    /// # Returns
    ///
    /// the offset of the end of the headers of the most recently
    /// parsed message or %-1 on error.
    fn get_headers_end(&self) -> i64;

    /// Gets the mbox-style From-line of the most recently parsed message
    /// (gotten from `ParserExt::construct_message`).
    ///
    /// # Returns
    ///
    /// the mbox-style From-line of the most recently parsed
    /// message or `None` on error.
    fn get_mbox_marker(&self) -> Option<String>;

    /// Gets the offset of the most recently parsed mbox-style From-line
    /// (gotten from `ParserExt::construct_message`).
    ///
    /// # Returns
    ///
    /// the offset of the most recently parsed mbox-style From-line
    /// or %-1 on error.
    fn get_mbox_marker_offset(&self) -> i64;

    /// Gets whether or not the underlying stream is persistent.
    ///
    /// # Returns
    ///
    /// `true` if the `self` will leave the content on disk or
    /// `false` if it will load the content into memory.
    fn get_persist_stream(&self) -> bool;

    /// Gets whether or not `self` is set to use Content-Length for
    /// determining the offset of the end of the message.
    ///
    /// # Returns
    ///
    /// whether or not `self` is set to use Content-Length for
    /// determining the offset of the end of the message.
    fn get_respect_content_length(&self) -> bool;

    /// Initializes `self` to use `stream`.
    ///
    /// WARNING: Initializing a parser with a stream is comparable to
    /// selling your soul (`stream`) to the devil (`self`). You are
    /// basically giving the parser complete control of the stream, this
    /// means that you had better not touch the stream so long as the
    /// parser is still using it. This means no reading, writing, seeking,
    /// or resetting of the stream. Anything that will/could change the
    /// current stream's offset is PROHIBITED.
    ///
    /// It is also recommended that you not use `StreamExt::tell`
    /// because it will not necessarily give you the current `self` offset
    /// since `self` handles its own internal read-ahead buffer. Instead,
    /// it is recommended that you use `ParserExt::tell` if you have a
    /// reason to need the current offset of the `self`.
    /// ## `stream`
    /// raw message or part stream
    fn init_with_stream<P: IsA<Stream>>(&self, stream: &P);

    /// Sets the format that the parser should expect the stream to be in.
    /// ## `format`
    /// a `Format`
    fn set_format(&self, format: Format);

    //fn set_header_regex<P: Into<Option</*Unimplemented*/Fundamental: Pointer>>>(&self, regex: &str, header_cb: /*Unknown conversion*//*Unimplemented*/ParserHeaderRegexFunc, user_data: P);

    /// Sets whether or not the `self`'s underlying stream is persistent.
    ///
    /// If `persist` is `true`, the `self` will attempt to construct
    /// messages/parts whose content will remain on disk rather than being
    /// loaded into memory so as to reduce memory usage. This is the default.
    ///
    /// If `persist` is `false`, the `self` will always load message content
    /// into memory.
    ///
    /// Note: This attribute only serves as a hint to the `self`. If the
    /// underlying stream does not support seeking, then this attribute
    /// will be ignored.
    ///
    /// By default, this feature is enabled if the underlying stream is seekable.
    /// ## `persist`
    /// persist attribute
    fn set_persist_stream(&self, persist: bool);

    /// Sets whether or not `self` should respect Content-Length headers
    /// when deciding where to look for the start of the next message. Only
    /// used when the parser is also set to scan for From-lines.
    ///
    /// Most notably useful when parsing broken Solaris mbox files (See
    /// http://www.jwz.org/doc/content-length.html for details).
    ///
    /// By default, this feature is disabled.
    /// ## `respect_content_length`
    /// `true` if the parser should use Content-Length headers or `false` otherwise.
    fn set_respect_content_length(&self, respect_content_length: bool);

    /// Gets the current stream offset from the parser's internal stream.
    ///
    /// # Returns
    ///
    /// the current stream offset from the parser's internal stream
    /// or %-1 on error.
    fn tell(&self) -> i64;
}

impl<O: IsA<Parser>> ParserExt for O {
    fn construct_message<'a, P: Into<Option<&'a ParserOptions>>>(&self, options: P) -> Option<Message> {
        let options = options.into();
        unsafe {
            from_glib_full(ffi::g_mime_parser_construct_message(self.to_glib_none().0, mut_override(options.to_glib_none().0)))
        }
    }

    fn construct_part<'a, P: Into<Option<&'a ParserOptions>>>(&self, options: P) -> Option<Object> {
        let options = options.into();
        unsafe {
            from_glib_full(ffi::g_mime_parser_construct_part(self.to_glib_none().0, mut_override(options.to_glib_none().0)))
        }
    }

    fn eos(&self) -> bool {
        unsafe {
            from_glib(ffi::g_mime_parser_eos(self.to_glib_none().0))
        }
    }

    fn get_format(&self) -> Format {
        unsafe {
            from_glib(ffi::g_mime_parser_get_format(self.to_glib_none().0))
        }
    }

    fn get_headers_begin(&self) -> i64 {
        unsafe {
            ffi::g_mime_parser_get_headers_begin(self.to_glib_none().0)
        }
    }

    fn get_headers_end(&self) -> i64 {
        unsafe {
            ffi::g_mime_parser_get_headers_end(self.to_glib_none().0)
        }
    }

    fn get_mbox_marker(&self) -> Option<String> {
        unsafe {
            from_glib_full(ffi::g_mime_parser_get_mbox_marker(self.to_glib_none().0))
        }
    }

    fn get_mbox_marker_offset(&self) -> i64 {
        unsafe {
            ffi::g_mime_parser_get_mbox_marker_offset(self.to_glib_none().0)
        }
    }

    fn get_persist_stream(&self) -> bool {
        unsafe {
            from_glib(ffi::g_mime_parser_get_persist_stream(self.to_glib_none().0))
        }
    }

    fn get_respect_content_length(&self) -> bool {
        unsafe {
            from_glib(ffi::g_mime_parser_get_respect_content_length(self.to_glib_none().0))
        }
    }

    fn init_with_stream<P: IsA<Stream>>(&self, stream: &P) {
        unsafe {
            ffi::g_mime_parser_init_with_stream(self.to_glib_none().0, stream.to_glib_none().0);
        }
    }

    fn set_format(&self, format: Format) {
        unsafe {
            ffi::g_mime_parser_set_format(self.to_glib_none().0, format.to_glib());
        }
    }

    //fn set_header_regex<P: Into<Option</*Unimplemented*/Fundamental: Pointer>>>(&self, regex: &str, header_cb: /*Unknown conversion*//*Unimplemented*/ParserHeaderRegexFunc, user_data: P) {
    //    unsafe { TODO: call ffi::g_mime_parser_set_header_regex() }
    //}

    fn set_persist_stream(&self, persist: bool) {
        unsafe {
            ffi::g_mime_parser_set_persist_stream(self.to_glib_none().0, persist.to_glib());
        }
    }

    fn set_respect_content_length(&self, respect_content_length: bool) {
        unsafe {
            ffi::g_mime_parser_set_respect_content_length(self.to_glib_none().0, respect_content_length.to_glib());
        }
    }

    fn tell(&self) -> i64 {
        unsafe {
            ffi::g_mime_parser_tell(self.to_glib_none().0)
        }
    }
}