addy-0.1.0.0: src/Addy/Internal/Char.hs
-- |
--
-- Copyright:
-- This file is part of the package addy. It is subject to the license
-- terms in the LICENSE file found in the top-level directory of this
-- distribution and at:
--
-- https://code.devalot.com/open/addy
--
-- No part of this package, including this file, may be copied,
-- modified, propagated, or distributed except according to the terms
-- contained in the LICENSE file.
--
-- License: BSD-2-Clause
--
-- Internal functions representing character classes in email
-- addresses.
--
-- Obsolete characters are only supported in
-- 'Addy.Internal.Parser.Lenient' mode and are filtered out after
-- parsing.
module Addy.Internal.Char
( utf8NonAscii,
obsNoWsCtl,
wsp,
vchar,
atext,
dtext,
ctext,
ctextObs,
qtext,
qtextObs,
quotedPair,
quotedPairObs,
)
where
import Data.Char
-- | Is a character in the @UTF8-non-ascii@ class from RFC 6532?
--
-- @since 0.1.0.0
utf8NonAscii :: Char -> Bool
utf8NonAscii c = ord c >= 0xc2 && isPrint c
-- | Obsolete control characters.
--
-- > obs-NO-WS-CTL = %d1-8 / ; US-ASCII control
-- > %d11 / ; characters that do not
-- > %d12 / ; include the carriage
-- > %d14-31 / ; return, line feed, and
-- > %d127 ; white space characters
--
-- @since 0.1.0.0
obsNoWsCtl :: Char -> Bool
obsNoWsCtl = ord >>> go
where
go n =
(n >= 1 && n <= 8)
|| n == 11
|| n == 12
|| (n >= 14 && n <= 31)
|| n == 127
-- | Whitepace.
--
-- @since 0.1.0.0
wsp :: Char -> Bool
wsp c = c == ' ' || c == '\t'
-- | RFC 5234: Visible character.
--
-- > VCHAR = %x21-7E
-- > ; visible (printing) characters
--
-- RFC 6532 §3.2
--
-- > VCHAR =/ UTF8-non-ascii
--
-- @since 0.1.0.0
vchar :: Char -> Bool
vchar c = vchar' (ord c) || utf8NonAscii c
where
vchar' n = n >= 0x21 && n <= 0x7e
-- | RFC 5322 §3.2.3
--
-- > atext = ALPHA / DIGIT / ; Printable US-ASCII
-- > "!" / "#" / ; characters not including
-- > "$" / "%" / ; specials. Used for atoms.
-- > "&" / "'" /
-- > "*" / "+" /
-- > "-" / "/" /
-- > "=" / "?" /
-- > "^" / "_" /
-- > "`" / "{" /
-- > "|" / "}" /
-- > "~"
--
-- RFC 6532 §3.2
--
-- > atext =/ UTF8-non-ascii
--
-- @since 0.1.0.0
atext :: Char -> Bool
atext c =
isAlphaNum c
|| utf8NonAscii c
|| c == '!'
|| c == '#'
|| c == '$'
|| c == '%'
|| c == '&'
|| c == '\''
|| c == '*'
|| c == '+'
|| c == '-'
|| c == '/'
|| c == '='
|| c == '?'
|| c == '^'
|| c == '_'
|| c == '`'
|| c == '{'
|| c == '|'
|| c == '}'
|| c == '~'
-- | RFC 5322 @dtext@.
--
-- > dtext = %d33-90 / ; Printable US-ASCII
-- > %d94-126 / ; characters not including
-- > obs-dtext ; "[", "]", or "\"
-- > obs-dtext = obs-NO-WS-CTL / quoted-pair
--
-- RFC 6532 §3.2
--
-- > dtext =/ UTF8-non-ascii
-- @since 0.1.0.0
dtext :: Char -> Bool
dtext c = asciidtext (ord c) || utf8NonAscii c
where
asciidtext n =
(n >= 33 && n <= 90)
|| (n >= 94 && n <= 126)
-- | RFC 5322 @ctext@.
--
-- > ctext = %d33-39 / ; Printable US-ASCII
-- > %d42-91 / ; characters not including
-- > %d93-126 / ; "(", ")", or "\"
-- > obs-ctext
-- >
-- > obs-ctext = obs-NO-WS-CTL
--
-- RFC 6532 §3.2
--
-- > ctext =/ UTF8-non-ascii
--
-- @since 0.1.0.0
ctext :: Char -> Bool
ctext c = asciictext (ord c) || utf8NonAscii c
where
asciictext n =
(n >= 33 && n <= 39)
|| (n >= 42 && n <= 91)
|| (n >= 93 && n <= 126)
-- | Obsolete @ctext@.
--
-- > obs-ctext = obs-NO-WS-CTL
--
-- @since 0.1.0.0
ctextObs :: Char -> Bool
ctextObs = obsNoWsCtl
-- | Characters that can appear in a quoted string.
--
-- RFC 5322 §3.2.4:
--
-- > qtext = %d33 / ; Printable US-ASCII
-- > %d35-91 / ; characters not including
-- > %d93-126 / ; "\" or the quote character
-- > obs-qtext
--
-- RFC 6532 §3.2:
--
-- > qtext =/ UTF8-non-ascii
-- @since 0.1.0.0
qtext :: Char -> Bool
qtext c = asciiqtext (ord c) || utf8NonAscii c
where
asciiqtext n =
n == 33
|| (n >= 35 && n <= 91)
|| (n >= 93 && n <= 126)
-- | Obsolete @qtext@.
--
-- > obs-qtext = obs-NO-WS-CTL
--
-- @since 0.1.0.0
qtextObs :: Char -> Bool
qtextObs = obsNoWsCtl
-- | Characters that can follow a backslash.
--
-- > quoted-pair = ("\" (VCHAR / WSP)) / obs-qp
--
-- @since 0.1.0.0
quotedPair :: Char -> Bool
quotedPair c = vchar c || wsp c
-- | Obsolete characters that can be escaped with a backslash.
--
-- > obs-qp = "\" (%d0 / obs-NO-WS-CTL / LF / CR)
--
-- @since 0.1.0.0
quotedPairObs :: Char -> Bool
quotedPairObs c =
obsNoWsCtl c
|| c == '\r'
|| c == '\n'
|| c == '\0'