# Module Netmime

    module Netmime: sig .. end

Netmime contains high-level classes and functions to process mail and MIME messages.

Contents

- Types
- Classes

The tutorial has been moved to `Netmime_tut`. Parsers for MIME headers are now in `Netmime_header`. Parser and printers for MIME channels are now in `Netmime_channels`.

## Types

    type store = [ `File of string | `Memory ]

Specifies where to store the body of a mail message. ``Memory` means in-memory, ``File name` means in the file `name`. The body is stored in decoded form (i.e. without transfer encoding).

    exception Immutable of string

Raised if it is tried to modify a read-only value. The string denotes the function or method where the incident happened.

MIME headers and bodies are defined in two steps. First the subtype describing read access is defined (`mime_header_ro`, and `mime_body_ro`), and after that the full class type including write access is defined (`mime_header`, and `mime_body`).

The idea is that you can write functions that take an ro value as input to indicate that they do not modify the value. For example:

     let number_of_fields (h:#mime_header_ro) =
       List.length (h#fields)

This function accepts both `mime_header`, and `mime_header_ro` values as input, but the typing ensures that the function cannot mutate anything.

There is another way to ensure that a header or body is not modified. The read-only flag can be set when creating the object, and this flag causes that all trials to modify the value will raise the exception `Immutable`. Of course, such trials of mutation are only detected at run-time.

The advantage of the read-only flag is that it even works if mutation depends on a condition, but it can be ensured that this condition is never true. Furthermore, typing is much simpler (getting subtyping correct can be annoying).

    class type mime_header_ro = object .. end

This is the read-only version of a MIME header.

    class type mime_header = object .. end

A MIME header with both read and write method.

    class type mime_body_ro = object .. end

This is the read-only version of a MIME body.

    class type mime_body = object .. end

A MIME body with both read and write method.

One can consider the pair `(mime_header, mime_body)` as simple MIME message with one header and one body. Of course, this simple representation does not support multi-part messages (attachments). For that reason, the `complex_mime_message` was invented: The body can be further structured as a sequence of parts that are complex messages themselves.

For example, a mail message with an attachment is usually represented as

     (mail_header, `Parts [ (main_header, `Body main_body);
                            (att_header, `Body att_body) ] )

Here, `mail_header` is the real header of the mail message. `main_header` is the header of the main message, usually only containing the content type of `main_body`, the body of the main message. The attachment has also its own `att_header`, again usually only containing the content type, and the data of the attachment can be found in `att_body`.

Nowadays, mails have often even a more complicated structure with ``Parts` containing nested ``Parts`. As `complex_mime_message` is recursive, any kind of nesting can be easily represented.

    type complex_mime_message = mime_header * complex_mime_body

    type complex_mime_body = [ `Body of mime_body | `Parts of complex_mime_message list ]

    type complex_mime_message_ro = mime_header_ro * complex_mime_body_ro

    type complex_mime_body_ro = [ `Body of mime_body_ro
           | `Parts of complex_mime_message_ro list ]

The read-only view of a complex_mime_message

Note: ``Parts []`, i.e. ``Parts` together with an empty list, is considered as illegal. Such a value cannot be transformed into printable text.

    type mime_message = mime_header * [ `Body of mime_body ]

Simple MIME message, in a form that is compatible with complex ones.

    type mime_message_ro = mime_header_ro * [ `Body of mime_body_ro ]

Read-only variant of simple messages

## Classes

    class basic_mime_header : (string * string) list -> mime_header

An implementation of `mime_header`.

    val basic_mime_header : (string * string) list -> mime_header

Same as function

    class wrap_mime_header : #mime_header -> mime_header

Wraps the inner header

    class wrap_mime_header_ro : #mime_header_ro -> mime_header

Wraps the inner header but disallows modifications.

    val wrap_mime_header_ro : #mime_header_ro -> mime_header

Same as function

    class memory_mime_body : string -> mime_body

An implementation of `mime_body` where the value is stored in-memory.

    val memory_mime_body : string -> mime_body

Same as function

    class file_mime_body : ?fin:bool -> string -> mime_body

An implementation of `mime_body` where the value is stored in an external file.

    val file_mime_body : ?fin:bool -> string -> mime_body

Same as function

    class wrap_mime_body : #mime_body -> mime_body

Wraps the inner body

    class wrap_mime_body_ro : #mime_body_ro -> mime_body

Wraps the inner body but disallows modifications.

    val wrap_mime_body_ro : #mime_body_ro -> mime_body

Same as function

    val wrap_complex_mime_message_ro : complex_mime_message_ro -> complex_mime_message