Initial email header parsing
This commit is contained in:
		
							
								
								
									
										50
									
								
								src/Data/Email/Header.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/Data/Email/Header.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
			
		||||
module Data.Email.Header where
 | 
			
		||||
 | 
			
		||||
import Data.Text
 | 
			
		||||
       (Text)
 | 
			
		||||
import qualified Data.Text as T
 | 
			
		||||
 | 
			
		||||
import qualified Data.Foldable as F
 | 
			
		||||
 | 
			
		||||
import Data.Attoparsec.Text
 | 
			
		||||
 | 
			
		||||
import Data.Vector
 | 
			
		||||
       (Vector)
 | 
			
		||||
import qualified Data.Vector as V
 | 
			
		||||
 | 
			
		||||
import Data.Char
 | 
			
		||||
       (isSpace)
 | 
			
		||||
 | 
			
		||||
import Control.Applicative
 | 
			
		||||
       ((<|>))
 | 
			
		||||
 | 
			
		||||
data Header
 | 
			
		||||
  = From !Text
 | 
			
		||||
  | To !(Vector Text)
 | 
			
		||||
  deriving (Show, Eq)
 | 
			
		||||
 | 
			
		||||
decode :: Text -> Either String Header
 | 
			
		||||
decode = parseOnly parseHeader
 | 
			
		||||
  where
 | 
			
		||||
    parseHeader :: Parser Header
 | 
			
		||||
    parseHeader = parseFrom <|> parseTo
 | 
			
		||||
    parseFrom :: Parser Header
 | 
			
		||||
    parseFrom = From <$> (string "From:" *> emptySpace *> email)
 | 
			
		||||
    parseTo :: Parser Header
 | 
			
		||||
    parseTo = To <$> (string "To:" *> emptySpace *> emails)
 | 
			
		||||
    emptySpace = many' space
 | 
			
		||||
    emails :: Parser (Vector Text)
 | 
			
		||||
    emails = V.fromList <$> email `sepBy` char ','
 | 
			
		||||
    email :: Parser Text
 | 
			
		||||
    email = do
 | 
			
		||||
      _ <- many' space
 | 
			
		||||
      name <- T.pack <$> many' (notChar '@')
 | 
			
		||||
      _ <- char '@'
 | 
			
		||||
      rest <- T.pack <$> many' (satisfy (\c -> not (isSpace c) && c /= ','))
 | 
			
		||||
      pure (name <> "@" <> rest)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
encode :: Header -> Text
 | 
			
		||||
encode = \case
 | 
			
		||||
  From addr -> "From: " <> addr
 | 
			
		||||
  To addrs -> "To: " <> T.intercalate ", " (F.toList addrs)
 | 
			
		||||
		Reference in New Issue
	
	Block a user