hsemail-2.2.1: Parsec parsers for the Internet Message format (e-mail)

Copyright | (c) 2007-2019 Peter Simons
License | BSD3
Maintainer | simons@cryp.to
Stability | provisional
Portability | portable
Safe Haskell | Safe-Inferred
Language | Haskell2010

Text.Parsec.Rfc2822

Contents

- Useful parser combinators
  - Primitive Tokens (section 3.2.1)
  - Quoted characters (section 3.2.2)
  - Folding white space and comments (section 3.2.3)
  - Atom (section 3.2.4)
  - Quoted strings (section 3.2.5)
- Miscellaneous tokens (section 3.2.6)
- Date and Time Specification (section 3.3)
- Address Specification (section 3.4)
  - Addr-spec specification (section 3.4.1)
- Overall message syntax (section 3.5)
- Field definitions (section 3.6)
  - The origination date field (section 3.6.1)
  - Originator fields (section 3.6.2)
  - Destination address fields (section 3.6.3)
  - Identification fields (section 3.6.4)
  - Informational fields (section 3.6.5)
  - Resent fields (section 3.6.6)
  - Trace fields (section 3.6.7)
  - Optional fields (section 3.6.8)
- Miscellaneous obsolete tokens (section 4.1)
- Obsolete folding white space (section 4.2)
- Obsolete Date and Time (section 4.3)
- Obsolete Addressing (section 4.4)
- Obsolete header fields (section 4.5)
  - Obsolete origination date field (section 4.5.1)
  - Obsolete originator fields (section 4.5.2)
  - Obsolete destination address fields (section 4.5.3)
  - Obsolete identification fields (section 4.5.4)
  - Obsolete informational fields (section 4.5.5)
  - Obsolete resent fields (section 4.5.6)
  - Obsolete trace fields (section 4.5.7)

Description

This module provides parsers for the grammar defined in RFC2822, "Internet Message Format", http://www.faqs.org/rfcs/rfc2822.html.

Synopsis

- maybeOption :: Stream s m Char => ParsecT s u m a -> ParsecT s u m (Maybe a)
- unfold :: Stream s m Char => ParsecT s u m a -> ParsecT s u m a
- header :: Stream s m Char => String -> ParsecT s u m a -> ParsecT s u m a
- obs_header :: Stream s m Char => String -> ParsecT s u m a -> ParsecT s u m a
- no_ws_ctl :: Stream s m Char => ParsecT s u m Char
- text :: Stream s m Char => ParsecT s u m Char
- specials :: Stream s m Char => ParsecT s u m Char
- quoted_pair :: Stream s m Char => ParsecT s u m String
- fws :: Stream s m Char => ParsecT s u m String
- ctext :: Stream s m Char => ParsecT s u m Char
- comment :: Stream s m Char => ParsecT s u m String
- cfws :: Stream s m Char => ParsecT s u m String
- atext :: Stream s m Char => ParsecT s u m Char
- atom :: Stream s m Char => ParsecT s u m String
- dot_atom :: Stream s m Char => ParsecT s u m String
- dot_atom_text :: Stream s m Char => ParsecT s u m String
- qtext :: Stream s m Char => ParsecT s u m Char
- qcontent :: Stream s m Char => ParsecT s u m String
- quoted_string :: Stream s m Char => ParsecT s u m String
- word :: Stream s m Char => ParsecT s u m String
- phrase :: Stream s m Char => ParsecT s u m [String]
- utext :: Stream s m Char => ParsecT s u m Char
- unstructured :: Stream s m Char => ParsecT s u m String
- date_time :: Stream s m Char => ParsecT s u m ZonedTime
- day_of_week :: Stream s m Char => ParsecT s u m DayOfWeek
- day_name :: Stream s m Char => ParsecT s u m DayOfWeek
- date :: Stream s m Char => ParsecT s u m Day
- year :: Stream s m Char => ParsecT s u m Int
- month :: Stream s m Char => ParsecT s u m Int
- month_name :: Stream s m Char => ParsecT s u m Int
- day_of_month :: Stream s m Char => ParsecT s u m Int
- day :: Stream s m Char => ParsecT s u m Int
- time :: Stream s m Char => ParsecT s u m (TimeOfDay, TimeZone)
- time_of_day :: Stream s m Char => ParsecT s u m TimeOfDay
- hour :: Stream s m Char => ParsecT s u m Int
- minute :: Stream s m Char => ParsecT s u m Int
- second :: Stream s m Char => ParsecT s u m Int
- zone :: Stream s m Char => ParsecT s u m TimeZone
- data NameAddr = NameAddr {
  - nameAddr_name :: Maybe String
  - nameAddr_addr :: String
  }
- address :: Stream s m Char => ParsecT s u m [NameAddr]
- mailbox :: Stream s m Char => ParsecT s u m NameAddr
- name_addr :: Stream s m Char => ParsecT s u m NameAddr
- angle_addr :: Stream s m Char => ParsecT s u m String
- group :: Stream s m Char => ParsecT s u m [NameAddr]
- display_name :: Stream s m Char => ParsecT s u m String
- mailbox_list :: Stream s m Char => ParsecT s u m [NameAddr]
- address_list :: Stream s m Char => ParsecT s u m [NameAddr]
- addr_spec :: Stream s m Char => ParsecT s u m String
- local_part :: Stream s m Char => ParsecT s u m String
- domain :: Stream s m Char => ParsecT s u m String
- domain_literal :: Stream s m Char => ParsecT s u m String
- dcontent :: Stream s m Char => ParsecT s u m String
- dtext :: Stream s m Char => ParsecT s u m Char
- data GenericMessage a = Message [Field] a
- message :: (Monoid s, Stream s m Char) => ParsecT s u m (GenericMessage s)
- body :: (Monoid s, Monad m) => ParsecT s u m s
- data Field
  - = OptionalField String String
  - | From [NameAddr]
  - | Sender NameAddr
  - | ReturnPath String
  - | ReplyTo [NameAddr]
  - | To [NameAddr]
  - | Cc [NameAddr]
  - | Bcc [NameAddr]
  - | MessageID String
  - | InReplyTo [String]
  - | References [String]
  - | Subject String
  - | Comments String
  - | Keywords [[String]]
  - | Date ZonedTime
  - | ResentDate ZonedTime
  - | ResentFrom [NameAddr]
  - | ResentSender NameAddr
  - | ResentTo [NameAddr]
  - | ResentCc [NameAddr]
  - | ResentBcc [NameAddr]
  - | ResentMessageID String
  - | ResentReplyTo [NameAddr]
  - | Received ([(String, String)], ZonedTime)
  - | ObsReceived [(String, String)]
- fields :: Stream s m Char => ParsecT s u m [Field]
- orig_date :: Stream s m Char => ParsecT s u m ZonedTime
- from :: Stream s m Char => ParsecT s u m [NameAddr]
- sender :: Stream s m Char => ParsecT s u m NameAddr
- reply_to :: Stream s m Char => ParsecT s u m [NameAddr]
- to :: Stream s m Char => ParsecT s u m [NameAddr]
- cc :: Stream s m Char => ParsecT s u m [NameAddr]
- bcc :: Stream s m Char => ParsecT s u m [NameAddr]
- message_id :: Stream s m Char => ParsecT s u m String
- in_reply_to :: Stream s m Char => ParsecT s u m [String]
- references :: Stream s m Char => ParsecT s u m [String]
- msg_id :: Stream s m Char => ParsecT s u m String
- id_left :: Stream s m Char => ParsecT s u m String
- id_right :: Stream s m Char => ParsecT s u m String
- no_fold_quote :: Stream s m Char => ParsecT s u m String
- no_fold_literal :: Stream s m Char => ParsecT s u m String
- subject :: Stream s m Char => ParsecT s u m String
- comments :: Stream s m Char => ParsecT s u m String
- keywords :: Stream s m Char => ParsecT s u m [[String]]
- resent_date :: Stream s m Char => ParsecT s u m ZonedTime
- resent_from :: Stream s m Char => ParsecT s u m [NameAddr]
- resent_sender :: Stream s m Char => ParsecT s u m NameAddr
- resent_to :: Stream s m Char => ParsecT s u m [NameAddr]
- resent_cc :: Stream s m Char => ParsecT s u m [NameAddr]
- resent_bcc :: Stream s m Char => ParsecT s u m [NameAddr]
- resent_msg_id :: Stream s m Char => ParsecT s u m String
- return_path :: Stream s m Char => ParsecT s u m String
- path :: Stream s m Char => ParsecT s u m String
- received :: Stream s m Char => ParsecT s u m ([(String, String)], ZonedTime)
- name_val_list :: Stream s m Char => ParsecT s u m [(String, String)]
- name_val_pair :: Stream s m Char => ParsecT s u m (String, String)
- item_name :: Stream s m Char => ParsecT s u m String
- item_value :: Stream s m Char => ParsecT s u m String
- optional_field :: Stream s m Char => ParsecT s u m (String, String)
- field_name :: Stream s m Char => ParsecT s u m String
- ftext :: Stream s m Char => ParsecT s u m Char
- obs_qp :: Stream s m Char => ParsecT s u m String
- obs_text :: Stream s m Char => ParsecT s u m String
- obs_char :: Stream s m Char => ParsecT s u m Char
- obs_utext :: Stream s m Char => ParsecT s u m String
- obs_phrase :: Stream s m Char => ParsecT s u m [String]
- obs_phrase_list :: Stream s m Char => ParsecT s u m [String]
- obs_fws :: Stream s m Char => ParsecT s u m String
- obs_day_of_week :: Stream s m Char => ParsecT s u m DayOfWeek
- obs_year :: Stream s m Char => ParsecT s u m Int
- obs_month :: Stream s m Char => ParsecT s u m Int
- obs_day :: Stream s m Char => ParsecT s u m Int
- obs_hour :: Stream s m Char => ParsecT s u m Int
- obs_minute :: Stream s m Char => ParsecT s u m Int
- obs_second :: Stream s m Char => ParsecT s u m Int
- obs_zone :: Stream s m Char => ParsecT s u m TimeZone
- obs_angle_addr :: Stream s m Char => ParsecT s u m String
- obs_route :: Stream s m Char => ParsecT s u m [String]
- obs_domain_list :: Stream s m Char => ParsecT s u m [String]
- obs_local_part :: Stream s m Char => ParsecT s u m String
- obs_domain :: Stream s m Char => ParsecT s u m String
- obs_mbox_list :: Stream s m Char => ParsecT s u m [NameAddr]
- obs_addr_list :: Stream s m Char => ParsecT s u m [NameAddr]
- obs_fields :: Stream s m Char => ParsecT s u m [Field]
- obs_orig_date :: Stream s m Char => ParsecT s u m ZonedTime
- obs_from :: Stream s m Char => ParsecT s u m [NameAddr]
- obs_sender :: Stream s m Char => ParsecT s u m NameAddr
- obs_reply_to :: Stream s m Char => ParsecT s u m [NameAddr]
- obs_to :: Stream s m Char => ParsecT s u m [NameAddr]
- obs_cc :: Stream s m Char => ParsecT s u m [NameAddr]
- obs_bcc :: Stream s m Char => ParsecT s u m [NameAddr]
- obs_message_id :: Stream s m Char => ParsecT s u m String
- obs_in_reply_to :: Stream s m Char => ParsecT s u m [String]
- obs_references :: Stream s m Char => ParsecT s u m [String]
- obs_id_left :: Stream s m Char => ParsecT s u m String
- obs_id_right :: Stream s m Char => ParsecT s u m String
- obs_subject :: Stream s m Char => ParsecT s u m String
- obs_comments :: Stream s m Char => ParsecT s u m String
- obs_keywords :: Stream s m Char => ParsecT s u m [String]
- obs_resent_from :: Stream s m Char => ParsecT s u m [NameAddr]
- obs_resent_send :: Stream s m Char => ParsecT s u m NameAddr
- obs_resent_date :: Stream s m Char => ParsecT s u m ZonedTime
- obs_resent_to :: Stream s m Char => ParsecT s u m [NameAddr]
- obs_resent_cc :: Stream s m Char => ParsecT s u m [NameAddr]
- obs_resent_bcc :: Stream s m Char => ParsecT s u m [NameAddr]
- obs_resent_mid :: Stream s m Char => ParsecT s u m String
- obs_resent_reply :: Stream s m Char => ParsecT s u m [NameAddr]
- obs_return :: Stream s m Char => ParsecT s u m String
- obs_received :: Stream s m Char => ParsecT s u m [(String, String)]
- obs_path :: Stream s m Char => ParsecT s u m String
- obs_optional :: Stream s m Char => ParsecT s u m (String, String)

# Useful parser combinators

maybeOption :: Stream s m Char => ParsecT s u m a -> ParsecT s u m (Maybe a) Source #

Return `Nothing` if the given parser doesn't match. This combinator is included in the latest parsec distribution as `optionMaybe`, but ghc-6.6.1 apparently doesn't have it.

unfold :: Stream s m Char => ParsecT s u m a -> ParsecT s u m a Source #

`unfold` `=` `between (optional cfws) (optional cfws)`

header :: Stream s m Char => String -> ParsecT s u m a -> ParsecT s u m a Source #

Construct a parser for a message header line from the header's name and a parser for the body.

obs_header :: Stream s m Char => String -> ParsecT s u m a -> ParsecT s u m a Source #

Like `header`, but allows the obsolete white-space rules.

## Primitive Tokens (section 3.2.1)

no_ws_ctl :: Stream s m Char => ParsecT s u m Char Source #

Match any US-ASCII non-whitespace control character.

text :: Stream s m Char => ParsecT s u m Char Source #

Match any US-ASCII character except for `r`, `n`.

specials :: Stream s m Char => ParsecT s u m Char Source #

Match any of the RFC's "special" characters: `()<>[]:;@,.\"`.

## Quoted characters (section 3.2.2)

quoted_pair :: Stream s m Char => ParsecT s u m String Source #

Match a "quoted pair". All characters matched by `text` may be quoted. Note that the parsers returns both characters, the backslash and the actual content.

## Folding white space and comments (section 3.2.3)

fws :: Stream s m Char => ParsecT s u m String Source #

Match "folding whitespace". That is any combination of `wsp` and `crlf` followed by `wsp`.

ctext :: Stream s m Char => ParsecT s u m Char Source #

Match any non-whitespace, non-control character except for "`(`", "`)`", and "`\`". This is used to describe the legal content of `comment`s.

Note: This parser accepts 8-bit characters, even though this is not legal according to the RFC. Unfortunately, 8-bit content in comments has become fairly common in the real world, so we'll just accept the fact.

comment :: Stream s m Char => ParsecT s u m String Source #

Match a "comments". That is any combination of `ctext`, `quoted_pair`s, and `fws` between brackets. Comments may nest.

cfws :: Stream s m Char => ParsecT s u m String Source #

Match any combination of `fws` and `comments`.

## Atom (section 3.2.4)

atext :: Stream s m Char => ParsecT s u m Char Source #

Match any US-ASCII character except for control characters, `specials`, or space. `atom` and `dot_atom` are made up of this.

atom :: Stream s m Char => ParsecT s u m String Source #

Match one or more `atext` characters and skip any preceding or trailing `cfws`.

dot_atom :: Stream s m Char => ParsecT s u m String Source #

Match `dot_atom_text` and skip any preceding or trailing `cfws`.

dot_atom_text :: Stream s m Char => ParsecT s u m String Source #

Match two or more `atext`s interspersed by dots.

## Quoted strings (section 3.2.5)

qtext :: Stream s m Char => ParsecT s u m Char Source #

Match any non-whitespace, non-control US-ASCII character except for "`\`" and "`"`".

qcontent :: Stream s m Char => ParsecT s u m String Source #

Match either `qtext` or `quoted_pair`.

quoted_string :: Stream s m Char => ParsecT s u m String Source #

Match any number of `qcontent` between double quotes. Any `cfws` preceding or following the "atom" is skipped automatically.

# Miscellaneous tokens (section 3.2.6)

word :: Stream s m Char => ParsecT s u m String Source #

Match either `atom` or `quoted_string`.

phrase :: Stream s m Char => ParsecT s u m [String] Source #

Match either one or more `word`s or an `obs_phrase`.

utext :: Stream s m Char => ParsecT s u m Char Source #

Match any non-whitespace, non-control US-ASCII character except for "`\`" and "`"`".

unstructured :: Stream s m Char => ParsecT s u m String Source #

Match any number of `utext` tokens.

"Unstructured text" is used in free text fields such as `subject`. Please note that any comments or whitespace that prefaces or follows the actual `utext` is included in the returned string.

# Date and Time Specification (section 3.3)

date_time :: Stream s m Char => ParsecT s u m ZonedTime Source #

Parse a date and time specification of the form

      Thu, 19 Dec 2002 20:35:46 +0200

where the weekday specification "`Thu,`" is optional. The parser returns an appropriate `ZonedTime`

TODO: Nor will the `date_time` parser perform any consistency checking. It will accept

    >>> parseTest date_time "Wed, 30 Apr 2002 13:12 +0100"
    2002-04-30 13:12:00 +0100

day_of_week :: Stream s m Char => ParsecT s u m DayOfWeek Source #

This parser matches a `day_name` or an `obs_day_of_week` (optionally wrapped in folding whitespace) and return the appropriate `DayOfWeek` value.

day_name :: Stream s m Char => ParsecT s u m DayOfWeek Source #

This parser recognizes abbreviated weekday names ("`Mon`", "`Tue`",...).

date :: Stream s m Char => ParsecT s u m Day Source #

This parser will match a date of the form "`dd:mm:yyyy`" and return a tripple of the form (Int,Month,Int) - corresponding to (year,month,day).

year :: Stream s m Char => ParsecT s u m Int Source #

This parser will match a four digit number and return its integer value. No range checking is performed.

month :: Stream s m Char => ParsecT s u m Int Source #

This parser will match a `month_name`, optionally wrapped in folding whitespace, or an `obs_month` and return its `Month` value.

month_name :: Stream s m Char => ParsecT s u m Int Source #

This parser will the abbreviated month names ("`Jan`", "`Feb`", ...) and return the appropriate `Int` value in the range of (1,12).

day_of_month :: Stream s m Char => ParsecT s u m Int Source #

day :: Stream s m Char => ParsecT s u m Int Source #

Match a 1 or 2-digit number (day of month), recognizing both standard and obsolete folding syntax.

time :: Stream s m Char => ParsecT s u m (TimeOfDay, TimeZone) Source #

This parser will match a `time_of_day` specification followed by a `zone`. It returns the tuple (TimeOfDay,Int) corresponding to the return values of either parser.

time_of_day :: Stream s m Char => ParsecT s u m TimeOfDay Source #

This parser will match a time-of-day specification of "`hh:mm`" or "`hh:mm:ss`" and return the corrsponding time as a `TimeOfDay`.

    >>> parseTest (time_of_day <* eof) "12:03:23"
    12:03:23
    >>> parseTest (time_of_day <* eof) "99:99:99"
    parse error at (line 1, column 3):unknown parse error

hour :: Stream s m Char => ParsecT s u m Int Source #

This parser matches a two-digit number in the range (0,24) and returns its integer value.

    >>> parseTest hour "034"
    3
    >>> parseTest hour "99"
    parse error at (line 1, column 3):unknown parse error

minute :: Stream s m Char => ParsecT s u m Int Source #

This parser will match a two-digit number in the range (0,60) and return its integer value.

    >>> parseTest minute "34"
    34
    >>> parseTest minute "61"
    parse error at (line 1, column 3):unknown parse error
    >>> parseTest (minute <* eof) "034"
    parse error at (line 1, column 3):
    unexpected '4'
    expecting end of input

second :: Stream s m Char => ParsecT s u m Int Source #

This parser will match a two-digit number in the range (0,60) and return its integer value.

    >>> parseTest second "34"
    34

zone :: Stream s m Char => ParsecT s u m TimeZone Source #

This parser will match a timezone specification of the form "`+hhmm`" or "`-hhmm`" and return the zone's offset to UTC in seconds as an integer. `obs_zone` is matched as well.

# Address Specification (section 3.4)

data NameAddr Source #

A NameAddr is composed of an optional realname a mandatory e-mail `address`.

Constructors

NameAddr |

Fields

- nameAddr_name :: Maybe String
- nameAddr_addr :: String

#### Instances

Instances details

Show NameAddr Source # |
Instance details Defined in Text.Parsec.Rfc2822 Methods showsPrec :: Int -> NameAddr -> ShowS Source # show :: NameAddr -> String Source # showList :: [NameAddr] -> ShowS Source #
Eq NameAddr Source # |
Instance details Defined in Text.Parsec.Rfc2822 Methods (==) :: NameAddr -> NameAddr -> Bool Source # (/=) :: NameAddr -> NameAddr -> Bool Source #

address :: Stream s m Char => ParsecT s u m [NameAddr] Source #

Parse a single `mailbox` or an address `group` and return the address(es).

mailbox :: Stream s m Char => ParsecT s u m NameAddr Source #

Parse a `name_addr` or an `addr_spec` and return the address.

name_addr :: Stream s m Char => ParsecT s u m NameAddr Source #

Parse an `angle_addr`, optionally prefaced with a `display_name`, and return the address.

angle_addr :: Stream s m Char => ParsecT s u m String Source #

Parse an `angle_addr` or an `obs_angle_addr` and return the address.

group :: Stream s m Char => ParsecT s u m [NameAddr] Source #

Parse a "group" of addresses. That is a `display_name`, followed by a colon, optionally followed by a `mailbox_list`, followed by a semicolon. The found address(es) are returned - what may be none. Here is an example:

    >>> parse group "" "my group: user1@example.org, user2@example.org;"
    Right [NameAddr {nameAddr_name = Nothing, nameAddr_addr = "user1@example.org"},NameAddr {nameAddr_name = Nothing, nameAddr_addr = "user2@example.org"}]

display_name :: Stream s m Char => ParsecT s u m String Source #

Parse and return a `phrase`.

mailbox_list :: Stream s m Char => ParsecT s u m [NameAddr] Source #

Parse a list of `mailbox` addresses, every two addresses being separated by a comma, and return the list of found address(es).

address_list :: Stream s m Char => ParsecT s u m [NameAddr] Source #

Parse a list of `address` addresses, every two addresses being separated by a comma, and return the list of found address(es).

## Addr-spec specification (section 3.4.1)

addr_spec :: Stream s m Char => ParsecT s u m String Source #

Parse an "address specification". That is a `local_part`, followed by an "`@`" character, followed by a `domain`. Return the complete address as `String`, ignoring any whitespace or any comments.

local_part :: Stream s m Char => ParsecT s u m String Source #

Parse and return a "local part" of an `addr_spec`. That is either a `dot_atom` or a `quoted_string`.

domain :: Stream s m Char => ParsecT s u m String Source #

Parse and return a "domain part" of an `addr_spec`. That is either a `dot_atom` or a `domain_literal`.

domain_literal :: Stream s m Char => ParsecT s u m String Source #

Parse a "domain literal". That is a "`[`" character, followed by any amount of `dcontent`, followed by a terminating "`]`" character. The complete string is returned verbatim.

dcontent :: Stream s m Char => ParsecT s u m String Source #

Parse and return any characters that are legal in a `domain_literal`. That is `dtext` or a `quoted_pair`.

dtext :: Stream s m Char => ParsecT s u m Char Source #

Parse and return any ASCII characters except "`[`", "`]`", and "`\`".

# Overall message syntax (section 3.5)

data GenericMessage a Source #

This data type represents a parsed Internet Message as defined in this RFC. It consists of an arbitrary number of header lines, represented in the `Field` data type, and a message body, which may be empty.

Constructors

Message [Field] a |

#### Instances

Instances details

Show a => Show (GenericMessage a) Source # |
Instance details Defined in Text.Parsec.Rfc2822 Methods showsPrec :: Int -> GenericMessage a -> ShowS Source # show :: GenericMessage a -> String Source # showList :: [GenericMessage a] -> ShowS Source #

message :: (Monoid s, Stream s m Char) => ParsecT s u m (GenericMessage s) Source #

Parse a complete message as defined by this RFC and it broken down into the separate header fields and the message body. Header lines, which contain syntax errors, will not cause the parser to abort. Rather, these headers will appear as `OptionalField`s (which are unparsed) in the resulting `Message`. A message must be really, really badly broken for this parser to fail.

This behaviour was chosen because it is impossible to predict what the user of this module considers to be a fatal error; traditionally, parsers are very forgiving when it comes to Internet messages.

If you want to implement a really strict parser, you'll have to put the appropriate parser together yourself. You'll find that this is rather easy to do. Refer to the `fields` parser for further details.

body :: (Monoid s, Monad m) => ParsecT s u m s Source #

A message body is just an unstructured sequence of characters.

# Field definitions (section 3.6)

data Field Source #

This data type represents any of the header fields defined in this RFC. Each of the various instances contains with the return value of the corresponding parser.

Constructors

OptionalField String String |
From [NameAddr] |
Sender NameAddr |
ReturnPath String |
ReplyTo [NameAddr] |
To [NameAddr] |
Cc [NameAddr] |
Bcc [NameAddr] |
MessageID String |
InReplyTo [String] |
References [String] |
Subject String |
Comments String |
Keywords [[String]] |
Date ZonedTime |
ResentDate ZonedTime |
ResentFrom [NameAddr] |
ResentSender NameAddr |
ResentTo [NameAddr] |
ResentCc [NameAddr] |
ResentBcc [NameAddr] |
ResentMessageID String |
ResentReplyTo [NameAddr] |
Received ([(String, String)], ZonedTime) |
ObsReceived [(String, String)] |

#### Instances

Instances details

Show Field Source # |
Instance details Defined in Text.Parsec.Rfc2822 Methods showsPrec :: Int -> Field -> ShowS Source # show :: Field -> String Source # showList :: [Field] -> ShowS Source #

fields :: Stream s m Char => ParsecT s u m [Field] Source #

This parser will parse an arbitrary number of header fields as defined in this RFC. For each field, an appropriate `Field` value is created, all of them making up the `Field` list that this parser returns.

If you look at the implementation of this parser, you will find that it uses Parsec's `try` modifier around all of the fields. The idea behind this is that fields, which contain syntax errors, fall back to the catch-all `optional_field`. Thus, this parser will hardly ever return a syntax error -- what conforms with the idea that any message that can possibly be accepted should be.

## The origination date field (section 3.6.1)

orig_date :: Stream s m Char => ParsecT s u m ZonedTime Source #

Parse a "`Date:`" header line and return the date it contains a `CalendarTime`.

## Originator fields (section 3.6.2)

from :: Stream s m Char => ParsecT s u m [NameAddr] Source #

Parse a "`From:`" header line and return the `mailbox_list` address(es) contained in it.

sender :: Stream s m Char => ParsecT s u m NameAddr Source #

Parse a "`Sender:`" header line and return the `mailbox` address contained in it.

reply_to :: Stream s m Char => ParsecT s u m [NameAddr] Source #

Parse a "`Reply-To:`" header line and return the `address_list` address(es) contained in it.

## Destination address fields (section 3.6.3)

to :: Stream s m Char => ParsecT s u m [NameAddr] Source #

Parse a "`To:`" header line and return the `address_list` address(es) contained in it.

cc :: Stream s m Char => ParsecT s u m [NameAddr] Source #

Parse a "`Cc:`" header line and return the `address_list` address(es) contained in it.

bcc :: Stream s m Char => ParsecT s u m [NameAddr] Source #

Parse a "`Bcc:`" header line and return the `address_list` address(es) contained in it.

## Identification fields (section 3.6.4)

message_id :: Stream s m Char => ParsecT s u m String Source #

Parse a "`Message-Id:`" header line and return the `msg_id` contained in it.

in_reply_to :: Stream s m Char => ParsecT s u m [String] Source #

Parse a "`In-Reply-To:`" header line and return the list of `msg_id`s contained in it.

references :: Stream s m Char => ParsecT s u m [String] Source #

Parse a "`References:`" header line and return the list of `msg_id`s contained in it.

msg_id :: Stream s m Char => ParsecT s u m String Source #

Parse a "`message ID:`" and return it. A message ID is almost identical to an `angle_addr`, but with stricter rules about folding and whitespace.

id_left :: Stream s m Char => ParsecT s u m String Source #

Parse a "left ID" part of a `msg_id`. This is almost identical to the `local_part` of an e-mail address, but with stricter rules about folding and whitespace.

id_right :: Stream s m Char => ParsecT s u m String Source #

Parse a "right ID" part of a `msg_id`. This is almost identical to the `domain` of an e-mail address, but with stricter rules about folding and whitespace.

no_fold_quote :: Stream s m Char => ParsecT s u m String Source #

Parse one or more occurrences of `qtext` or `quoted_pair` and return the concatenated string. This makes up the `id_left` of a `msg_id`.

no_fold_literal :: Stream s m Char => ParsecT s u m String Source #

Parse one or more occurrences of `dtext` or `quoted_pair` and return the concatenated string. This makes up the `id_right` of a `msg_id`.

## Informational fields (section 3.6.5)

subject :: Stream s m Char => ParsecT s u m String Source #

Parse a "`Subject:`" header line and return its contents verbatim. Please note that all whitespace and/or comments are preserved, i.e. the result of parsing `"Subject: foo"` is `" foo"`, not `"foo"`.

comments :: Stream s m Char => ParsecT s u m String Source #

Parse a "`Comments:`" header line and return its contents verbatim. Please note that all whitespace and/or comments are preserved, i.e. the result of parsing `"Comments: foo"` is `" foo"`, not `"foo"`.

keywords :: Stream s m Char => ParsecT s u m [[String]] Source #

Parse a "`Keywords:`" header line and return the list of `phrase`s found. Please not that each phrase is again a list of `atom`s, as returned by the `phrase` parser.

## Resent fields (section 3.6.6)

resent_date :: Stream s m Char => ParsecT s u m ZonedTime Source #

Parse a "`Resent-Date:`" header line and return the date it contains as `ZonedTime`.

resent_from :: Stream s m Char => ParsecT s u m [NameAddr] Source #

Parse a "`Resent-From:`" header line and return the `mailbox_list` address(es) contained in it.

resent_sender :: Stream s m Char => ParsecT s u m NameAddr Source #

Parse a "`Resent-Sender:`" header line and return the `mailbox_list` address(es) contained in it.

resent_to :: Stream s m Char => ParsecT s u m [NameAddr] Source #

Parse a "`Resent-To:`" header line and return the `mailbox` address contained in it.

resent_cc :: Stream s m Char => ParsecT s u m [NameAddr] Source #

Parse a "`Resent-Cc:`" header line and return the `address_list` address(es) contained in it.

resent_bcc :: Stream s m Char => ParsecT s u m [NameAddr] Source #

Parse a "`Resent-Bcc:`" header line and return the `address_list` address(es) contained in it. (This list may be empty.)

resent_msg_id :: Stream s m Char => ParsecT s u m String Source #

Parse a "`Resent-Message-ID:`" header line and return the `msg_id` contained in it.

## Trace fields (section 3.6.7)

return_path :: Stream s m Char => ParsecT s u m String Source #

path :: Stream s m Char => ParsecT s u m String Source #

received :: Stream s m Char => ParsecT s u m ([(String, String)], ZonedTime) Source #

name_val_list :: Stream s m Char => ParsecT s u m [(String, String)] Source #

name_val_pair :: Stream s m Char => ParsecT s u m (String, String) Source #

item_name :: Stream s m Char => ParsecT s u m String Source #

item_value :: Stream s m Char => ParsecT s u m String Source #

## Optional fields (section 3.6.8)

optional_field :: Stream s m Char => ParsecT s u m (String, String) Source #

Parse an arbitrary header field and return a tuple containing the `field_name` and `unstructured` text of the header. The name will not contain the terminating colon.

field_name :: Stream s m Char => ParsecT s u m String Source #

Parse and return an arbitrary header field name. That is one or more `ftext` characters.

ftext :: Stream s m Char => ParsecT s u m Char Source #

Match and return any ASCII character except for control characters, whitespace, and "`:`".

# Miscellaneous obsolete tokens (section 4.1)

obs_qp :: Stream s m Char => ParsecT s u m String Source #

Match the obsolete "quoted pair" syntax, which - unlike `quoted_pair` - allowed any ASCII character to be specified when quoted. The parser will return both, the backslash and the actual character.

obs_text :: Stream s m Char => ParsecT s u m String Source #

Match the obsolete "text" syntax, which - unlike `text` - allowed "carriage returns" and "linefeeds". This is really weird; you better consult the RFC for details. The parser will return the complete string, including those special characters.

obs_char :: Stream s m Char => ParsecT s u m Char Source #

Match and return the obsolete "char" syntax, which - unlike `character` - did not allow "carriage return" and "linefeed".

obs_utext :: Stream s m Char => ParsecT s u m String Source #

Match and return the obsolete "utext" syntax, which is identical to `obs_text`.

obs_phrase :: Stream s m Char => ParsecT s u m [String] Source #

Match the obsolete "phrase" syntax, which - unlike `phrase` - allows dots between tokens.

obs_phrase_list :: Stream s m Char => ParsecT s u m [String] Source #

Match a "phrase list" syntax and return the list of `String`s that make up the phrase. In contrast to a `phrase`, the `obs_phrase_list` separates the individual words by commas. This syntax is - as you will have guessed - obsolete.

# Obsolete folding white space (section 4.2)

obs_fws :: Stream s m Char => ParsecT s u m String Source #

Parse and return an "obsolete fws" token. That is at least one `wsp` character, followed by an arbitrary number (including zero) of `crlf` followed by at least one more `wsp` character.

# Obsolete Date and Time (section 4.3)

obs_day_of_week :: Stream s m Char => ParsecT s u m DayOfWeek Source #

Parse a `day_name` but allow for the obsolete folding syntax. TODO

obs_year :: Stream s m Char => ParsecT s u m Int Source #

Parse a `year` but allow for a two-digit number (obsolete) and the obsolete folding syntax.

obs_month :: Stream s m Char => ParsecT s u m Int Source #

Parse a `month_name` but allow for the obsolete folding syntax.

obs_day :: Stream s m Char => ParsecT s u m Int Source #

Parse a `day` but allow for the obsolete folding syntax.

obs_hour :: Stream s m Char => ParsecT s u m Int Source #

Parse a `hour` but allow for the obsolete folding syntax.

obs_minute :: Stream s m Char => ParsecT s u m Int Source #

Parse a `minute` but allow for the obsolete folding syntax.

obs_second :: Stream s m Char => ParsecT s u m Int Source #

Parse a `second` but allow for the obsolete folding syntax.

obs_zone :: Stream s m Char => ParsecT s u m TimeZone Source #

Match the obsolete zone names and return the appropriate offset.

# Obsolete Addressing (section 4.4)

obs_angle_addr :: Stream s m Char => ParsecT s u m String Source #

This parser matches the "obsolete angle address" syntax, a construct that used to be called "route address" in earlier RFCs. It differs from a standard `angle_addr` in two ways: (1) it allows far more liberal insertion of folding whitespace and comments and (2) the address may contain a "route" (which this parser ignores):

    >>> parse obs_angle_addr "" "<@example1.org,@example2.org:joe@example.org>"
    Right "<joe@example.org>"

obs_route :: Stream s m Char => ParsecT s u m [String] Source #

This parser parses the "route" part of `obs_angle_addr` and returns the list of `String`s that make up this route. Relies on `obs_domain_list` for the actual parsing.

obs_domain_list :: Stream s m Char => ParsecT s u m [String] Source #

This parser parses a list of domain names, each of them prefaced with an "at". Multiple names are separated by a comma. The list of `domain`s is returned - and may be empty.

obs_local_part :: Stream s m Char => ParsecT s u m String Source #

Parse the obsolete syntax of a `local_part`, which allowed for more liberal insertion of folding whitespace and comments. The actual string is returned.

obs_domain :: Stream s m Char => ParsecT s u m String Source #

Parse the obsolete syntax of a `domain`, which allowed for more liberal insertion of folding whitespace and comments. The actual string is returned.

obs_mbox_list :: Stream s m Char => ParsecT s u m [NameAddr] Source #

This parser will match the obsolete syntax for a `mailbox_list`. This one is quite weird: An `obs_mbox_list` contains an arbitrary number of `mailbox`es - including none -, which are separated by commas. But you may have multiple consecutive commas without giving a `mailbox`. You may also have a valid `obs_mbox_list` that contains no `mailbox` at all. On the other hand, you must have at least one comma. The following example is valid:

    >>> parse obs_mbox_list "" ","
    Right []

But this one is not:

    >>> parse obs_mbox_list "" "joe@example.org"
    Left (line 1, column 16):
    unexpected end of input
    expecting obsolete syntax for a list of mailboxes

obs_addr_list :: Stream s m Char => ParsecT s u m [NameAddr] Source #

This parser is identical to `obs_mbox_list` but parses a list of `address`es rather than `mailbox`es. The main difference is that an `address` may contain `group`s. Please note that as of now, the parser will return a simple list of addresses; the grouping information is lost.

# Obsolete header fields (section 4.5)

obs_fields :: Stream s m Char => ParsecT s u m [Field] Source #

## Obsolete origination date field (section 4.5.1)

obs_orig_date :: Stream s m Char => ParsecT s u m ZonedTime Source #

Parse a `date` header line but allow for the obsolete folding syntax.

## Obsolete originator fields (section 4.5.2)

obs_from :: Stream s m Char => ParsecT s u m [NameAddr] Source #

Parse a `from` header line but allow for the obsolete folding syntax.

obs_sender :: Stream s m Char => ParsecT s u m NameAddr Source #

Parse a `sender` header line but allow for the obsolete folding syntax.

obs_reply_to :: Stream s m Char => ParsecT s u m [NameAddr] Source #

Parse a `reply_to` header line but allow for the obsolete folding syntax.

## Obsolete destination address fields (section 4.5.3)

obs_to :: Stream s m Char => ParsecT s u m [NameAddr] Source #

Parse a `to` header line but allow for the obsolete folding syntax.

obs_cc :: Stream s m Char => ParsecT s u m [NameAddr] Source #

Parse a `cc` header line but allow for the obsolete folding syntax.

obs_bcc :: Stream s m Char => ParsecT s u m [NameAddr] Source #

Parse a `bcc` header line but allow for the obsolete folding syntax.

## Obsolete identification fields (section 4.5.4)

obs_message_id :: Stream s m Char => ParsecT s u m String Source #

Parse a `message_id` header line but allow for the obsolete folding syntax.

obs_in_reply_to :: Stream s m Char => ParsecT s u m [String] Source #

Parse an `in_reply_to` header line but allow for the obsolete folding and the obsolete phrase syntax.

obs_references :: Stream s m Char => ParsecT s u m [String] Source #

Parse a `references` header line but allow for the obsolete folding and the obsolete phrase syntax.

obs_id_left :: Stream s m Char => ParsecT s u m String Source #

Parses the "left part" of a message ID, but allows the obsolete syntax, which is identical to a `local_part`.

obs_id_right :: Stream s m Char => ParsecT s u m String Source #

Parses the "right part" of a message ID, but allows the obsolete syntax, which is identical to a `domain`.

## Obsolete informational fields (section 4.5.5)

obs_subject :: Stream s m Char => ParsecT s u m String Source #

Parse a `subject` header line but allow for the obsolete folding syntax.

obs_comments :: Stream s m Char => ParsecT s u m String Source #

Parse a `comments` header line but allow for the obsolete folding syntax.

obs_keywords :: Stream s m Char => ParsecT s u m [String] Source #

Parse a `keywords` header line but allow for the obsolete folding syntax. Also, this parser accepts `obs_phrase_list`.

## Obsolete resent fields (section 4.5.6)

obs_resent_from :: Stream s m Char => ParsecT s u m [NameAddr] Source #

Parse a `resent_from` header line but allow for the obsolete folding syntax.

obs_resent_send :: Stream s m Char => ParsecT s u m NameAddr Source #

Parse a `resent_sender` header line but allow for the obsolete folding syntax.

obs_resent_date :: Stream s m Char => ParsecT s u m ZonedTime Source #

Parse a `resent_date` header line but allow for the obsolete folding syntax.

obs_resent_to :: Stream s m Char => ParsecT s u m [NameAddr] Source #

Parse a `resent_to` header line but allow for the obsolete folding syntax.

obs_resent_cc :: Stream s m Char => ParsecT s u m [NameAddr] Source #

Parse a `resent_cc` header line but allow for the obsolete folding syntax.

obs_resent_bcc :: Stream s m Char => ParsecT s u m [NameAddr] Source #

Parse a `resent_bcc` header line but allow for the obsolete folding syntax.

obs_resent_mid :: Stream s m Char => ParsecT s u m String Source #

Parse a `resent_msg_id` header line but allow for the obsolete folding syntax.

obs_resent_reply :: Stream s m Char => ParsecT s u m [NameAddr] Source #

Parse a `Resent-Reply-To` header line but allow for the obsolete folding syntax.

## Obsolete trace fields (section 4.5.7)

obs_return :: Stream s m Char => ParsecT s u m String Source #

obs_received :: Stream s m Char => ParsecT s u m [(String, String)] Source #

obs_path :: Stream s m Char => ParsecT s u m String Source #

Match `obs_angle_addr`.

obs_optional :: Stream s m Char => ParsecT s u m (String, String) Source #

This parser is identical to `optional_field` but allows the more liberal line-folding syntax between the "field_name" and the "field text".