-instance Show Message where
- show m =
- concat [ if (length (headers m) == 0) then "" else (intercalate "\n" (headers m)) ++ "\n",
- "Subject: " ++ (subject m) ++ "\n",
- "From: " ++ (from m) ++ "\n",
- "To: " ++ (to m) ++ "\n",
- "\n",
- (body m) ]
-
-
-sendmail :: Message -> IO (String, String, ExitCode)
-sendmail message = do
+
+instance Default Message where
+ -- | Construct a message with all of its fields set to their
+ -- default values.
+ --
+ def = Message default_headers def def def def
+
+
+-- | Print a 'Message' in roughly RFC-compliant form. This form is
+-- sufficient for handing the message off to sendmail (or compatible).
+--
+-- Examples:
+--
+-- >>> let hs = default_headers
+-- >>> let s = "Save up to 20% on garbage!"
+-- >>> let b = "Just kidding, now you have a virus!"
+-- >>> let f = "savings5000@impenetrable.example"
+-- >>> let t = "everyone@everywhere.example"
+-- >>> let msg = Message hs s b f t
+-- >>> putStrLn $ to_rfc822 msg
+-- MIME-Version: 1.0
+-- Content-Type: text/plain; charset=UTF-8
+-- Content-Transfer-Encoding: 8bit
+-- Subject: Save up to 20% on garbage!
+-- From: savings5000@impenetrable.example
+-- To: everyone@everywhere.example
+-- <BLANKLINE>
+-- Just kidding, now you have a virus!
+--
+to_rfc822 :: Message -> String
+to_rfc822 m =
+ concat [ formatted_headers,
+ "Subject: " ++ (subject m) ++ "\n",
+ "From: " ++ (from m) ++ "\n",
+ "To: " ++ (to m) ++ "\n",
+ "\n",
+ (body m) ]
+ where
+ formatted_headers =
+ if null (headers m)
+ then ""
+ else unlines (headers m)
+
+
+
+-- | Constructs a 'String' in RFC822 date format for the current
+-- date/time.
+--
+rfc822_now :: IO String
+rfc822_now =
+ liftM (formatTime defaultTimeLocale rfc822DateFormat) getZonedTime
+
+
+
+
+-- | Takes a message as an argument, and passes it to the system's
+-- sendmail (or compatible) binary.
+--
+sendmail :: FilePath -> Message -> IO (String, String, ExitCode)
+sendmail sendmail_path message = do
+ -- The arguments we pass to sendmail "on the command line"