45 lines
1.3 KiB
Plaintext
45 lines
1.3 KiB
Plaintext
|
module App.Validation.Email where
|
||
|
|
||
|
import Prelude
|
||
|
|
||
|
import Data.Either (Either(..))
|
||
|
import Data.Maybe (Maybe(..))
|
||
|
import Data.Validation.Semigroup (V, invalid, toEither)
|
||
|
|
||
|
import GenericParser.RFC5322 as RFC5322
|
||
|
import GenericParser.SomeParsers as SomeParsers
|
||
|
import GenericParser.Parser as G
|
||
|
|
||
|
data EmailParsingError
|
||
|
= CannotParse
|
||
|
| CannotEntirelyParse
|
||
|
| Size Int Int Int
|
||
|
|
||
|
data Error
|
||
|
= ParsingError (G.Error EmailParsingError)
|
||
|
|
||
|
min_email_size :: Int
|
||
|
min_email_size = 5
|
||
|
max_email_size :: Int
|
||
|
max_email_size = 100
|
||
|
|
||
|
parse :: forall e v. G.Parser e v -> String -> ((G.Error e) -> Error) -> V (Array Error) v
|
||
|
parse (G.Parser p) str c = case p { string: str, position: 0 } of
|
||
|
Left x -> invalid $ [c x]
|
||
|
Right x -> pure x.result
|
||
|
|
||
|
parse_full_email :: G.Parser EmailParsingError String
|
||
|
parse_full_email = do
|
||
|
email_address <- RFC5322.address G.<:> \_ -> CannotParse
|
||
|
_ <- SomeParsers.eof G.<:> \_ -> CannotEntirelyParse
|
||
|
pos <- G.current_position
|
||
|
if between min_email_size max_email_size pos
|
||
|
then pure email_address
|
||
|
else G.errorParser $ Just $ Size min_email_size max_email_size pos
|
||
|
|
||
|
parserEmail :: String -> V (Array Error) String
|
||
|
parserEmail str = parse parse_full_email str ParsingError
|
||
|
|
||
|
email :: String -> Either (Array Error) String
|
||
|
email s = toEither $ parserEmail s
|