packages feed

ascii 1.0.1.4 → 1.0.1.6

raw patch · 5 files changed

+461/−383 lines, 5 filesdep +asciidep ~basedep ~textPVP ok

version bump matches the API change (PVP)

Dependencies added: ascii

Dependency ranges changed: base, text

API changes (from Hackage documentation)

Files

− ASCII.hs
@@ -1,379 +0,0 @@-{- |--The __American Standard Code for Information Interchange__ (ASCII) comprises a set of 128 characters, each represented by 7 bits. 33 of these characters are /'Control' codes/; a few of these are still in use, but most are obsolete relics of the early days of computing. The other 95 are /'Printable' characters/ such as letters and numbers, mostly corresponding to the keys on an American English keyboard.--Nowadays instead of ASCII we typically work with text using an encoding such as UTF-8 that can represent the entire Unicode character set, which includes over a hundred thousand characters and is not limited to the symbols of any particular writing system or culture. However, ASCII is still relevant to network protocols; for example, we can see it in the specification of [HTTP message headers](https://tools.ietf.org/html/rfc7230#section-1.2).--There is a convenient relationship between ASCII and Unicode: the ASCII characters are the first 128 characters of the much larger Unicode character set. The [C0 Controls and Basic Latin](https://www.unicode.org/charts/PDF/U0000.pdf) section of the Unicode standard contains a list of all the ASCII characters. You may also find this list replicated in the "ASCII.Char" module; each ASCII character corresponds to a constructor of the 'ASCII.Char' type.--We do not elaborate on the semantics of the control characters here, because this information is both obsolete and restricted by copyright law. It is described by a document entitled /"Coded Character Sets - 7-Bit American National Standard Code for Information Interchange (7-Bit ASCII)"/, published by American National Standards Institute (ANSI) and available for purchase [on their website](https://webstore.ansi.org/Standards/INCITS/INCITS1986R2012).---}--module ASCII-  (-    {- * @Char@ -} {- $char -} Char,--    {- * Character classifications -}-    {- ** Print/control groups -} {- $groups -} Group (..), charGroup,  inGroup,-    {- ** Upper/lower case     -} {- $case   -} Case (..),  letterCase, isCase, toCaseChar, toCaseString,--    {- * Monomorphic conversions -} {- $monomorphicConversions -}-    {- ** @Int@        -} {- $intConversions           -} charToInt,               intToCharMaybe,               intToCharUnsafe,-    {- ** @Word8@      -} {- $word8Conversions         -} charToWord8,             word8ToCharMaybe,             word8ToCharUnsafe,-    {- ** @Char@       -} {- $unicodeCharConversions   -} charToUnicode,           unicodeToCharMaybe,           unicodeToCharUnsafe,-    {- ** @String@     -} {- $unicodeStringConversions -} charListToUnicodeString, unicodeStringToCharListMaybe, unicodeStringToCharListUnsafe,-    {- ** @Text@       -} {- $textConversions          -} charListToText,          textToCharListMaybe,          textToCharListUnsafe,-    {- ** @ByteString@ -} {- $byteStringConversions    -} charListToByteString,    byteStringToCharListMaybe,    byteStringToCharListUnsafe,--    {- * Monomorphic conversions between ASCII supersets -} {- $monoSupersetConversions -}-    {- ** @ByteString@ / @String@ -} byteStringToUnicodeStringMaybe, unicodeStringToByteStringMaybe,-    {- ** @[Word8]@      / @String@ -} byteListToUnicodeStringMaybe,   unicodeStringToByteListMaybe,--    {- * Refinement type -} {- $refinement -} {- ** @ASCII@ -} ASCII,--    {- * Polymorphic conversions -}-    {- ** Validate -} validateChar, validateString,-    {- ** Lift -} {- $lift -} lift,-    {- ** Convert -} {- $supersetConversions -} convertCharMaybe, convertCharOrFail, convertStringMaybe, convertStringOrFail,--    {- * Classes -} {- ** @CharSuperset@ -} CharSuperset, {- ** @StringSuperset@ -} StringSuperset, {- ** @Lift@ -} Lift, {- ** @CharIso@ -} CharIso, {- ** @StringIso@ -} StringIso,--    {- * Quasi-quoters -} {- ** @char@ -} char, {- ** @string@ -} string-  )-  where--import ASCII.Case          ( Case (..) )-import ASCII.Char          ( Char )-import ASCII.Group         ( Group (..) )-import ASCII.Isomorphism   ( CharIso, StringIso )-import ASCII.Lift          ( Lift )-import ASCII.QuasiQuoters  ( char, string )-import ASCII.Refinement    ( ASCII, validateChar, validateString )-import ASCII.Superset      ( CharSuperset, StringSuperset )--import Control.Monad       ( (>=>) )-import Control.Monad.Fail  ( MonadFail )-import Data.Bool           ( Bool (..) )-import Data.Function       ( (.) )-import Data.Int            ( Int )-import Data.Maybe          ( Maybe, maybe )-import Data.Word           ( Word8 )--import qualified  ASCII.Case-import qualified  ASCII.Group-import qualified  ASCII.Isomorphism-import qualified  ASCII.Lift-import qualified  ASCII.Superset--import qualified  Data.ByteString  as  BS-import qualified  Data.Char        as  Unicode-import qualified  Data.String      as  Unicode-import qualified  Data.Text        as  Text--{- $setup-->>> import ASCII.Char (Char (..))->>> import Data.List (map)->>> import Data.Text (Text)->>> import Data.Word (Word8)---}--{- $char--See also: "ASCII.Char"---}--{- $groups--ASCII characters are broadly categorized into two groups: /control codes/ and /printable characters/.--See also: "ASCII.Group"---}---{- | Determine which group a particular character belongs to.-->>> map charGroup [CapitalLetterA,EndOfTransmission]-[Printable,Control]---}--charGroup :: CharIso char => char -> Group-charGroup = ASCII.Group.charGroup . ASCII.Isomorphism.toChar--{- | Test whether a character belongs to a particular ASCII group.-->>> inGroup Printable EndOfTransmission-False-->>> inGroup Control EndOfTransmission-True-->>> map (inGroup Printable) ( [-1, 5, 65, 97, 127, 130] :: [Int] )-[False,False,True,True,False,False]---}--inGroup :: CharSuperset char => Group -> char -> Bool-inGroup g = maybe False (ASCII.Group.inGroup g) . ASCII.Superset.toCharMaybe--{- $case--/Case/ is a property of letters. /A-Z/ are /upper case/ letters, and /a-z/ are /lower case/ letters. No other ASCII characters have case.--See also: "ASCII.Case"---}--{- | Determines whether a character is an ASCII letter, and if so, whether it is upper or lower case.-->>> map letterCase [SmallLetterA, CapitalLetterA, ExclamationMark]-[Just LowerCase,Just UpperCase,Nothing]-->>> map letterCase ( [string|Hey!|] :: [ASCII Word8] )-[Just UpperCase,Just LowerCase,Just LowerCase,Nothing]---}--letterCase :: CharSuperset char => char -> Maybe Case-letterCase = ASCII.Superset.toCharMaybe >=> ASCII.Case.letterCase--{- | Determines whether a character is an ASCII letter of a particular case.-->>> map (isCase UpperCase) [SmallLetterA, CapitalLetterA, ExclamationMark]-[False,True,False]-->>> map (isCase UpperCase) ( [string|Hey!|] :: [ASCII Word8] )-[True,False,False,False]-->>> map (isCase UpperCase) ( [-1, 65, 97, 150] :: [Int] )-[False,True,False,False]---}--isCase :: CharSuperset char => Case -> char -> Bool-isCase c = maybe False (ASCII.Case.isCase c) . ASCII.Superset.toCharMaybe--{- | Maps a letter character to its upper/lower case equivalent.-->>> toCaseChar UpperCase SmallLetterA-CapitalLetterA-->>> ([char|a|] :: ASCII Word8, toCaseChar UpperCase [char|a|] :: ASCII Word8)-(asciiUnsafe 97,asciiUnsafe 65)---}--toCaseChar :: CharIso char => Case -> char -> char-toCaseChar c = ASCII.Isomorphism.asChar (ASCII.Case.toCase c)--{- | Maps each of the characters in a string to its upper/lower case equivalent.-->>> toCaseString UpperCase [CapitalLetterH,SmallLetterE,SmallLetterY,ExclamationMark]-[CapitalLetterH,CapitalLetterE,CapitalLetterY,ExclamationMark]-->>> toCaseString UpperCase [string|Hey!|] :: ASCII Text-asciiUnsafe "HEY!"---}--toCaseString :: StringIso string => Case -> string -> string-toCaseString c = ASCII.Isomorphism.mapChars (ASCII.Case.toCase c)--{- $monomorphicConversions--These are a few simple monomorphic functions to convert between ASCII and types representing some other character set.--This is not intended to be an exhaustive list of all possible conversions. For more options, see "ASCII.Superset".---}--{- $intConversions--These functions convert between the ASCII 'Char' type and 'Int'.---}--{- |-->>> map charToInt [Null, CapitalLetterA, SmallLetterA, Delete]-[0,65,97,127]---}--charToInt :: Char -> Int-charToInt = ASCII.Superset.fromChar--intToCharMaybe :: Int -> Maybe Char-intToCharMaybe = ASCII.Superset.toCharMaybe--intToCharUnsafe :: Int -> Char-intToCharUnsafe = ASCII.Superset.toCharUnsafe--{- $word8Conversions--These functions convert between the ASCII 'Char' type and 'Word8'.---}--{- |-->>> map charToWord8 [Null, CapitalLetterA, SmallLetterA, Delete]-[0,65,97,127]---}--charToWord8 :: Char -> Word8-charToWord8 = ASCII.Superset.fromChar--word8ToCharMaybe :: Word8 -> Maybe Char-word8ToCharMaybe = ASCII.Superset.toCharMaybe--word8ToCharUnsafe :: Word8 -> Char-word8ToCharUnsafe = ASCII.Superset.toCharUnsafe--{- $unicodeCharConversions--These functions convert between the ASCII 'Char' type and the Unicode 'Unicode.Char' type.---}--charToUnicode :: Char -> Unicode.Char-charToUnicode = ASCII.Superset.fromChar--unicodeToCharMaybe :: Unicode.Char -> Maybe Char-unicodeToCharMaybe = ASCII.Superset.toCharMaybe--unicodeToCharUnsafe :: Unicode.Char -> Char-unicodeToCharUnsafe = ASCII.Superset.toCharUnsafe--{- $unicodeStringConversions--These functions convert between @['Char']@ (a list of ASCII characters) and 'Unicode.String' (a list of Unicode characters).---}--charListToUnicodeString :: [Char] -> Unicode.String-charListToUnicodeString = ASCII.Superset.fromCharList--unicodeStringToCharListMaybe :: Unicode.String -> Maybe [Char]-unicodeStringToCharListMaybe = ASCII.Superset.toCharListMaybe--unicodeStringToCharListUnsafe :: Unicode.String -> [Char]-unicodeStringToCharListUnsafe = ASCII.Superset.toCharListUnsafe--{- $textConversions--These functions convert between @['Char']@ and 'Text.Text'.---}--{- |-->>> charListToText [CapitalLetterH,SmallLetterI,ExclamationMark]-"Hi!"---}--charListToText :: [Char] -> Text.Text-charListToText = ASCII.Superset.fromCharList--textToCharListMaybe :: Text.Text -> Maybe [Char]-textToCharListMaybe = ASCII.Superset.toCharListMaybe--textToCharListUnsafe :: Text.Text -> [Char]-textToCharListUnsafe = ASCII.Superset.toCharListUnsafe--{- $byteStringConversions--These functions convert between @['Char']@ and 'BS.ByteString'.---}--charListToByteString :: [Char] -> BS.ByteString-charListToByteString = ASCII.Superset.fromCharList--byteStringToCharListMaybe :: BS.ByteString -> Maybe [Char]-byteStringToCharListMaybe = ASCII.Superset.toCharListMaybe--byteStringToCharListUnsafe :: BS.ByteString -> [Char]-byteStringToCharListUnsafe = ASCII.Superset.toCharListUnsafe--{- $refinement--See also: "ASCII.Refinement"---}--{- $lift--See also: "ASCII.Lift"---}--{- | Converts from ASCII to any larger type.--For example, @(lift \@ASCII.Char \@Word8)@ is the same function as 'charToWord8'.-->>> lift CapitalLetterA :: Word8-65--And @(lift \@[ASCII.Char] \@Text)@ is equivalent to 'charListToText'.-->>> lift [CapitalLetterH,SmallLetterI,ExclamationMark] :: Text-"Hi!"--Due to the highly polymorphic nature of the 'lift' function, often it must used with an explicit type signature or type application to avoid any type ambiguity.---}--lift :: Lift ascii superset => ascii -> superset-lift = ASCII.Lift.lift--{- $supersetConversions--These functions all convert from one ASCII-superset type to another, failing if any of the characters in the input is outside the ASCII character set.---}--convertCharMaybe :: (CharSuperset char1, CharSuperset char2) => char1 -> Maybe char2-convertCharMaybe = ASCII.Superset.convertCharMaybe--convertCharOrFail :: (CharSuperset char1, CharSuperset char2, MonadFail context) => char1 -> context char2-convertCharOrFail = ASCII.Superset.convertCharOrFail--convertStringMaybe :: (StringSuperset string1, StringSuperset string2) => string1 -> Maybe string2-convertStringMaybe = ASCII.Superset.convertStringMaybe--convertStringOrFail :: (StringSuperset string1, StringSuperset string2, MonadFail context) => string1 -> context string2-convertStringOrFail = ASCII.Superset.convertStringOrFail--{- $monoSupersetConversions--These functions are all specializations of 'convertStringMaybe'. They convert a string from one ASCII-superset type to another.-->>> ASCII.byteListToUnicodeStringMaybe [0x48, 0x54, 0x54, 0x50]-Just "HTTP"--If any of the characters in the input is outside the ASCII character set, the result is 'Nothing'.-->>> ASCII.byteListToUnicodeStringMaybe [0x48, 0x54, 0x54, 0x80]-Nothing---}--byteStringToUnicodeStringMaybe :: BS.ByteString -> Maybe Unicode.String-byteStringToUnicodeStringMaybe = convertStringMaybe--unicodeStringToByteStringMaybe :: Unicode.String -> Maybe BS.ByteString-unicodeStringToByteStringMaybe = convertStringMaybe--byteListToUnicodeStringMaybe :: [Word8] -> Maybe Unicode.String-byteListToUnicodeStringMaybe = convertStringMaybe--unicodeStringToByteListMaybe :: Unicode.String -> Maybe [Word8]-unicodeStringToByteListMaybe = convertStringMaybe
ascii.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.0  name: ascii-version: 1.0.1.4+version: 1.0.1.6 synopsis: The ASCII character set and encoding category: Data, Text @@ -18,8 +18,6 @@  build-type: Simple -tested-with: GHC == 9.0.1, GHC == 8.10.1, GHC == 8.8.1, GHC == 8.6.5, GHC == 8.4.3- extra-source-files: changelog.txt  source-repository head@@ -30,10 +28,11 @@     default-language: Haskell2010     default-extensions: NoImplicitPrelude     ghc-options: -Wall+    hs-source-dirs: library      build-depends: base       >= 4.11 && < 4.16     build-depends: bytestring ^>= 0.10 || ^>= 0.11-    build-depends: text       ^>= 1.2+    build-depends: text       ^>= 1.2.3      exposed-modules: ASCII @@ -66,3 +65,14 @@     reexported-modules: Data.Ascii.Blaze     reexported-modules: Data.Ascii.ByteString     reexported-modules: Data.Ascii.Word8++test-suite test+    type: exitcode-stdio-1.0+    default-language: Haskell2010+    default-extensions: NoImplicitPrelude+    default-extensions: OverloadedStrings+    default-extensions: QuasiQuotes+    ghc-options: -Wall+    hs-source-dirs: test+    main-is: test.hs+    build-depends: ascii, base, text
changelog.txt view
@@ -17,3 +17,8 @@ 1.0.1.2 - 2021-02-09 - Support bytestring-0.11  1.0.1.4 - 2021-02-10 - Support GHC 9.0++1.0.1.6 - 2021-09-26++    - Add a test suite+    - Raise 'text' lower bound to 1.2.3
+ library/ASCII.hs view
@@ -0,0 +1,370 @@+{- |++The __American Standard Code for Information Interchange__ (ASCII) comprises a set of 128 characters, each represented by 7 bits. 33 of these characters are /'Control' codes/; a few of these are still in use, but most are obsolete relics of the early days of computing. The other 95 are /'Printable' characters/ such as letters and numbers, mostly corresponding to the keys on an American English keyboard.++Nowadays instead of ASCII we typically work with text using an encoding such as UTF-8 that can represent the entire Unicode character set, which includes over a hundred thousand characters and is not limited to the symbols of any particular writing system or culture. However, ASCII is still relevant to network protocols; for example, we can see it in the specification of [HTTP message headers](https://tools.ietf.org/html/rfc7230#section-1.2).++There is a convenient relationship between ASCII and Unicode: the ASCII characters are the first 128 characters of the much larger Unicode character set. The [C0 Controls and Basic Latin](https://www.unicode.org/charts/PDF/U0000.pdf) section of the Unicode standard contains a list of all the ASCII characters. You may also find this list replicated in the "ASCII.Char" module; each ASCII character corresponds to a constructor of the 'ASCII.Char' type.++We do not elaborate on the semantics of the control characters here, because this information is both obsolete and restricted by copyright law. It is described by a document entitled /"Coded Character Sets - 7-Bit American National Standard Code for Information Interchange (7-Bit ASCII)"/, published by American National Standards Institute (ANSI) and available for purchase [on their website](https://webstore.ansi.org/Standards/INCITS/INCITS1986R2012).++-}++module ASCII+  (+    {- * @Char@ -} {- $char -} Char,++    {- * Character classifications -}+    {- ** Print/control groups -} {- $groups -} Group (..), charGroup,  inGroup,+    {- ** Upper/lower case     -} {- $case   -} Case (..),  letterCase, isCase, toCaseChar, toCaseString,++    {- * Monomorphic conversions -} {- $monomorphicConversions -}+    {- ** @Int@        -} {- $intConversions           -} charToInt,               intToCharMaybe,               intToCharUnsafe,+    {- ** @Word8@      -} {- $word8Conversions         -} charToWord8,             word8ToCharMaybe,             word8ToCharUnsafe,+    {- ** @Char@       -} {- $unicodeCharConversions   -} charToUnicode,           unicodeToCharMaybe,           unicodeToCharUnsafe,+    {- ** @String@     -} {- $unicodeStringConversions -} charListToUnicodeString, unicodeStringToCharListMaybe, unicodeStringToCharListUnsafe,+    {- ** @Text@       -} {- $textConversions          -} charListToText,          textToCharListMaybe,          textToCharListUnsafe,+    {- ** @ByteString@ -} {- $byteStringConversions    -} charListToByteString,    byteStringToCharListMaybe,    byteStringToCharListUnsafe,++    {- * Monomorphic conversions between ASCII supersets -} {- $monoSupersetConversions -}+    {- ** @ByteString@ / @String@ -} byteStringToUnicodeStringMaybe, unicodeStringToByteStringMaybe,+    {- ** @[Word8]@      / @String@ -} byteListToUnicodeStringMaybe,   unicodeStringToByteListMaybe,++    {- * Refinement type -} {- $refinement -} {- ** @ASCII@ -} ASCII,++    {- * Polymorphic conversions -}+    {- ** Validate -} validateChar, validateString,+    {- ** Lift -} {- $lift -} lift,+    {- ** Convert -} {- $supersetConversions -} convertCharMaybe, convertCharOrFail, convertStringMaybe, convertStringOrFail,++    {- * Classes -} {- ** @CharSuperset@ -} CharSuperset, {- ** @StringSuperset@ -} StringSuperset, {- ** @Lift@ -} Lift, {- ** @CharIso@ -} CharIso, {- ** @StringIso@ -} StringIso,++    {- * Quasi-quoters -} {- ** @char@ -} char, {- ** @string@ -} string+  )+  where++import ASCII.Case          ( Case (..) )+import ASCII.Char          ( Char )+import ASCII.Group         ( Group (..) )+import ASCII.Isomorphism   ( CharIso, StringIso )+import ASCII.Lift          ( Lift )+import ASCII.QuasiQuoters  ( char, string )+import ASCII.Refinement    ( ASCII, validateChar, validateString )+import ASCII.Superset      ( CharSuperset, StringSuperset )++import Control.Monad       ( (>=>) )+import Control.Monad.Fail  ( MonadFail )+import Data.Bool           ( Bool (..) )+import Data.Function       ( (.) )+import Data.Int            ( Int )+import Data.Maybe          ( Maybe, maybe )+import Data.Word           ( Word8 )++import qualified  ASCII.Case+import qualified  ASCII.Group+import qualified  ASCII.Isomorphism+import qualified  ASCII.Lift+import qualified  ASCII.Superset++import qualified  Data.ByteString  as  BS+import qualified  Data.Char        as  Unicode+import qualified  Data.String      as  Unicode+import qualified  Data.Text        as  Text++{- $char++See also: "ASCII.Char"++-}++{- $groups++ASCII characters are broadly categorized into two groups: /control codes/ and /printable characters/.++See also: "ASCII.Group"++-}+++{- | Determine which group a particular character belongs to.++>>> map charGroup [CapitalLetterA,EndOfTransmission]+[Printable,Control]++-}++charGroup :: CharIso char => char -> Group+charGroup = ASCII.Group.charGroup . ASCII.Isomorphism.toChar++{- | Test whether a character belongs to a particular ASCII group.++>>> inGroup Printable EndOfTransmission+False++>>> inGroup Control EndOfTransmission+True++>>> map (inGroup Printable) ( [-1, 5, 65, 97, 127, 130] :: [Int] )+[False,False,True,True,False,False]++-}++inGroup :: CharSuperset char => Group -> char -> Bool+inGroup g = maybe False (ASCII.Group.inGroup g) . ASCII.Superset.toCharMaybe++{- $case++/Case/ is a property of letters. /A-Z/ are /upper case/ letters, and /a-z/ are /lower case/ letters. No other ASCII characters have case.++See also: "ASCII.Case"++-}++{- | Determines whether a character is an ASCII letter, and if so, whether it is upper or lower case.++>>> map letterCase [SmallLetterA, CapitalLetterA, ExclamationMark]+[Just LowerCase,Just UpperCase,Nothing]++>>> map letterCase ( [string|Hey!|] :: [ASCII Word8] )+[Just UpperCase,Just LowerCase,Just LowerCase,Nothing]++-}++letterCase :: CharSuperset char => char -> Maybe Case+letterCase = ASCII.Superset.toCharMaybe >=> ASCII.Case.letterCase++{- | Determines whether a character is an ASCII letter of a particular case.++>>> map (isCase UpperCase) [SmallLetterA, CapitalLetterA, ExclamationMark]+[False,True,False]++>>> map (isCase UpperCase) ( [string|Hey!|] :: [ASCII Word8] )+[True,False,False,False]++>>> map (isCase UpperCase) ( [-1, 65, 97, 150] :: [Int] )+[False,True,False,False]++-}++isCase :: CharSuperset char => Case -> char -> Bool+isCase c = maybe False (ASCII.Case.isCase c) . ASCII.Superset.toCharMaybe++{- | Maps a letter character to its upper/lower case equivalent.++>>> toCaseChar UpperCase SmallLetterA+CapitalLetterA++>>> ([char|a|] :: ASCII Word8, toCaseChar UpperCase [char|a|] :: ASCII Word8)+(asciiUnsafe 97,asciiUnsafe 65)++-}++toCaseChar :: CharIso char => Case -> char -> char+toCaseChar c = ASCII.Isomorphism.asChar (ASCII.Case.toCase c)++{- | Maps each of the characters in a string to its upper/lower case equivalent.++>>> toCaseString UpperCase [CapitalLetterH,SmallLetterE,SmallLetterY,ExclamationMark]+[CapitalLetterH,CapitalLetterE,CapitalLetterY,ExclamationMark]++>>> toCaseString UpperCase [string|Hey!|] :: ASCII Text+asciiUnsafe "HEY!"++-}++toCaseString :: StringIso string => Case -> string -> string+toCaseString c = ASCII.Isomorphism.mapChars (ASCII.Case.toCase c)++{- $monomorphicConversions++These are a few simple monomorphic functions to convert between ASCII and types representing some other character set.++This is not intended to be an exhaustive list of all possible conversions. For more options, see "ASCII.Superset".++-}++{- $intConversions++These functions convert between the ASCII 'Char' type and 'Int'.++-}++{- |++>>> map charToInt [Null, CapitalLetterA, SmallLetterA, Delete]+[0,65,97,127]++-}++charToInt :: Char -> Int+charToInt = ASCII.Superset.fromChar++intToCharMaybe :: Int -> Maybe Char+intToCharMaybe = ASCII.Superset.toCharMaybe++intToCharUnsafe :: Int -> Char+intToCharUnsafe = ASCII.Superset.toCharUnsafe++{- $word8Conversions++These functions convert between the ASCII 'Char' type and 'Word8'.++-}++{- |++>>> map charToWord8 [Null, CapitalLetterA, SmallLetterA, Delete]+[0,65,97,127]++-}++charToWord8 :: Char -> Word8+charToWord8 = ASCII.Superset.fromChar++word8ToCharMaybe :: Word8 -> Maybe Char+word8ToCharMaybe = ASCII.Superset.toCharMaybe++word8ToCharUnsafe :: Word8 -> Char+word8ToCharUnsafe = ASCII.Superset.toCharUnsafe++{- $unicodeCharConversions++These functions convert between the ASCII 'Char' type and the Unicode 'Unicode.Char' type.++-}++charToUnicode :: Char -> Unicode.Char+charToUnicode = ASCII.Superset.fromChar++unicodeToCharMaybe :: Unicode.Char -> Maybe Char+unicodeToCharMaybe = ASCII.Superset.toCharMaybe++unicodeToCharUnsafe :: Unicode.Char -> Char+unicodeToCharUnsafe = ASCII.Superset.toCharUnsafe++{- $unicodeStringConversions++These functions convert between @['Char']@ (a list of ASCII characters) and 'Unicode.String' (a list of Unicode characters).++-}++charListToUnicodeString :: [Char] -> Unicode.String+charListToUnicodeString = ASCII.Superset.fromCharList++unicodeStringToCharListMaybe :: Unicode.String -> Maybe [Char]+unicodeStringToCharListMaybe = ASCII.Superset.toCharListMaybe++unicodeStringToCharListUnsafe :: Unicode.String -> [Char]+unicodeStringToCharListUnsafe = ASCII.Superset.toCharListUnsafe++{- $textConversions++These functions convert between @['Char']@ and 'Text.Text'.++-}++{- |++>>> charListToText [CapitalLetterH,SmallLetterI,ExclamationMark]+"Hi!"++-}++charListToText :: [Char] -> Text.Text+charListToText = ASCII.Superset.fromCharList++textToCharListMaybe :: Text.Text -> Maybe [Char]+textToCharListMaybe = ASCII.Superset.toCharListMaybe++textToCharListUnsafe :: Text.Text -> [Char]+textToCharListUnsafe = ASCII.Superset.toCharListUnsafe++{- $byteStringConversions++These functions convert between @['Char']@ and 'BS.ByteString'.++-}++charListToByteString :: [Char] -> BS.ByteString+charListToByteString = ASCII.Superset.fromCharList++byteStringToCharListMaybe :: BS.ByteString -> Maybe [Char]+byteStringToCharListMaybe = ASCII.Superset.toCharListMaybe++byteStringToCharListUnsafe :: BS.ByteString -> [Char]+byteStringToCharListUnsafe = ASCII.Superset.toCharListUnsafe++{- $refinement++See also: "ASCII.Refinement"++-}++{- $lift++See also: "ASCII.Lift"++-}++{- | Converts from ASCII to any larger type.++For example, @(lift \@ASCII.Char \@Word8)@ is the same function as 'charToWord8'.++>>> lift CapitalLetterA :: Word8+65++And @(lift \@[ASCII.Char] \@Text)@ is equivalent to 'charListToText'.++>>> lift [CapitalLetterH,SmallLetterI,ExclamationMark] :: Text+"Hi!"++Due to the highly polymorphic nature of the 'lift' function, often it must used with an explicit type signature or type application to avoid any type ambiguity.++-}++lift :: Lift ascii superset => ascii -> superset+lift = ASCII.Lift.lift++{- $supersetConversions++These functions all convert from one ASCII-superset type to another, failing if any of the characters in the input is outside the ASCII character set.++-}++convertCharMaybe :: (CharSuperset char1, CharSuperset char2) => char1 -> Maybe char2+convertCharMaybe = ASCII.Superset.convertCharMaybe++convertCharOrFail :: (CharSuperset char1, CharSuperset char2, MonadFail context) => char1 -> context char2+convertCharOrFail = ASCII.Superset.convertCharOrFail++convertStringMaybe :: (StringSuperset string1, StringSuperset string2) => string1 -> Maybe string2+convertStringMaybe = ASCII.Superset.convertStringMaybe++convertStringOrFail :: (StringSuperset string1, StringSuperset string2, MonadFail context) => string1 -> context string2+convertStringOrFail = ASCII.Superset.convertStringOrFail++{- $monoSupersetConversions++These functions are all specializations of 'convertStringMaybe'. They convert a string from one ASCII-superset type to another.++>>> ASCII.byteListToUnicodeStringMaybe [0x48, 0x54, 0x54, 0x50]+Just "HTTP"++If any of the characters in the input is outside the ASCII character set, the result is 'Nothing'.++>>> ASCII.byteListToUnicodeStringMaybe [0x48, 0x54, 0x54, 0x80]+Nothing++-}++byteStringToUnicodeStringMaybe :: BS.ByteString -> Maybe Unicode.String+byteStringToUnicodeStringMaybe = convertStringMaybe++unicodeStringToByteStringMaybe :: Unicode.String -> Maybe BS.ByteString+unicodeStringToByteStringMaybe = convertStringMaybe++byteListToUnicodeStringMaybe :: [Word8] -> Maybe Unicode.String+byteListToUnicodeStringMaybe = convertStringMaybe++unicodeStringToByteListMaybe :: Unicode.String -> Maybe [Word8]+unicodeStringToByteListMaybe = convertStringMaybe
+ test/test.hs view
@@ -0,0 +1,72 @@+module Main where++import ASCII++import ASCII.Char (Char (..))+import ASCII.Refinement (asciiUnsafe)++import Control.Applicative (Applicative (..))+import Control.Monad (Monad (..))+import Data.Bool (Bool (..))+import Data.Eq (Eq ((==)))+import Data.Function ((.), ($))+import Data.Functor (Functor (..))+import Data.Int (Int)+import Data.List (intercalate, map, null)+import Data.Maybe (Maybe (..))+import Data.Semigroup ((<>))+import Data.Text (Text)+import Data.Word (Word8)+import Numeric.Natural (Natural)+import System.Exit (die)+import System.IO (IO, putStrLn)+import Text.Show (show)++main :: IO ()+main = dieIfFailures $ do+    test 1 $ map charGroup [CapitalLetterA, EndOfTransmission] == [Printable, Control]+    test 2 $ inGroup Printable EndOfTransmission == False+    test 3 $ inGroup Control EndOfTransmission == True+    test 4 $ map (inGroup Printable) ([-1, 5, 65, 97, 127, 130] :: [Int]) == [False, False, True, True, False, False]+    test 5 $ map letterCase [SmallLetterA, CapitalLetterA, ExclamationMark] == [Just LowerCase, Just UpperCase, Nothing]+    test 6 $ map letterCase ([string|Hey!|] :: [ASCII Word8]) == [Just UpperCase, Just LowerCase, Just LowerCase, Nothing]+    test 7 $ map (isCase UpperCase) [SmallLetterA, CapitalLetterA, ExclamationMark] == [False, True, False]+    test 8 $ map (isCase UpperCase) ([string|Hey!|] :: [ASCII Word8]) == [True, False, False, False]+    test 9 $ map (isCase UpperCase) ([-1, 65, 97, 150] :: [Int]) == [False, True, False, False]+    test 10 $ toCaseChar UpperCase SmallLetterA == CapitalLetterA+    test 11 $ ([char|a|] :: ASCII Word8, toCaseChar UpperCase [char|a|] :: ASCII Word8) == (asciiUnsafe 97, asciiUnsafe 65)+    test 12 $ toCaseString UpperCase [CapitalLetterH,SmallLetterE,SmallLetterY,ExclamationMark] == [CapitalLetterH, CapitalLetterE, CapitalLetterY, ExclamationMark]+    test 13 $ (toCaseString UpperCase [string|Hey!|] :: ASCII Text) == asciiUnsafe "HEY!"+    test 14 $ map charToInt [Null, CapitalLetterA, SmallLetterA, Delete] == [0, 65, 97, 127]+    test 15 $ map charToWord8 [Null, CapitalLetterA, SmallLetterA, Delete] == [0, 65, 97, 127]+    test 16 $ charListToText [CapitalLetterH, SmallLetterI, ExclamationMark] == "Hi!"+    test 17 $ (lift CapitalLetterA :: Word8) == 65+    test 18 $ (lift [CapitalLetterH,SmallLetterI,ExclamationMark] :: Text) == "Hi!"+    test 19 $ ASCII.byteListToUnicodeStringMaybe [0x48, 0x54, 0x54, 0x50] == Just "HTTP"+    test 20 $ ASCII.byteListToUnicodeStringMaybe [0x48, 0x54, 0x54, 0x80] == Nothing++dieIfFailures :: Failures a -> IO a+dieIfFailures (Failures fs x) =+    if null fs+        then do putStrLn "💯"; return x+        else die $ intercalate " " (map (("🔥" <> ) . show) fs)++type TestNumber = Natural++test :: TestNumber -> Bool -> Failures ()+test n t = Failures (if t then [] else [n]) ()++data Failures a = Failures [TestNumber] a++instance Functor Failures+  where+    fmap f (Failures a x) = Failures a (f x)++instance Applicative Failures+  where+    pure x = Failures [] x+    Failures a f <*> Failures b x = Failures (a <> b) (f x)++instance Monad Failures+  where+    Failures a x >>= f = let Failures b y = f x in Failures (a <> b) y