packages feed

ascii 1.4.1.0 → 1.4.1.1

raw patch · 4 files changed

+309/−393 lines, 4 filesdep +hspecdep −hedgehogPVP ok

version bump matches the API change (PVP)

Dependencies added: hspec

Dependencies removed: hedgehog

API changes (from Hackage documentation)

Files

ascii.cabal view
@@ -1,7 +1,7 @@ cabal-version: 3.0  name: ascii-version: 1.4.1.0+version: 1.4.1.1 synopsis: The ASCII character set and encoding category: Data, Text @@ -28,7 +28,7 @@     ghc-options: -Wall     default-extensions: NoImplicitPrelude     build-depends:-        ascii-caseless == 0.0.0.*+      , ascii-caseless == 0.0.0.*       , ascii-char == 1.0.1.*       , ascii-group == 1.0.0.*       , ascii-case == 1.0.1.*@@ -46,7 +46,7 @@     default-extensions: RankNTypes ScopedTypeVariables TypeApplications     exposed-modules: ASCII     reexported-modules:-        ASCII.Case+      , ASCII.Case       , ASCII.Caseless       , ASCII.CaseRefinement       , ASCII.Char@@ -69,7 +69,7 @@     type: exitcode-stdio-1.0     hs-source-dirs: test     main-is: Main.hs-    default-extensions: OverloadedStrings QuasiQuotes TemplateHaskell+    default-extensions: OverloadedStrings QuasiQuotes     build-depends:-        ascii-      , hedgehog ^>= 1.0.5 || ^>= 1.1 || ^>= 1.2+      , ascii+      , hspec ^>= 2.8.5 || ^>= 2.9 || ^>= 2.10
changelog.md view
@@ -1,3 +1,7 @@+### 1.4.1.1 (2023-01-05)++Change test suite from `hedgehog` to `hspec`+ ### 1.4.1.0 (2023-01-05)  Raise `ascii-char` version to `1.0.1`. This adds `Word8` conversions to the
library/ASCII.hs view
@@ -35,16 +35,16 @@      {- * Character classifications -}     {- ** Print/control groups -} {- $groups -}-    Group (..), charGroup,  inGroup,+    Group (..), charGroup, inGroup,     {- ** Upper/lower case -} {- $case -}     Case (..), letterCase, isCase, toCaseChar, toCaseString,     disregardCase, refineCharToCase, refineStringToCase,-    {- ** Letters  -} isLetter,-    {- ** Letters and numbers  -} isAlphaNum,+    {- ** Letters -} isLetter,+    {- ** Letters and numbers -} isAlphaNum,     {- ** Decimal digits -} {- $digit -} isDigit, Digit,     {- ** Hexadecimal digits -} {- $hexchar -} isHexDigit, HexChar,     {- ** Octal digits -} isOctDigit,-    {- ** Spaces and symbols   -} isSpace, isPunctuation, isSymbol, isVisible,+    {- ** Spaces and symbols -} isSpace, isPunctuation, isSymbol, isVisible,      {- * Monomorphic character conversions -} {- $monomorphicConversions -}     {- ** @ASCII.Char@ ↔ @Int@ -} {- $intConversions -}@@ -158,145 +158,127 @@  {- $char -See also: "ASCII.Char"---}+See also: "ASCII.Char" -}  {- $caselessChar -See also: "ASCII.Caseless"+See also: "ASCII.Caseless" -} --}+{-| A character in the full range of Unicode --- | A character in the full range of Unicode------ ASCII 'Char' is a subset of this type. Convert using 'charToUnicode' and 'unicodeToCharMaybe'.+ASCII 'Char' is a subset of this type. Convert using 'charToUnicode' and+'unicodeToCharMaybe'. -} type UnicodeChar = Unicode.Char  {- $groups -ASCII characters are broadly categorized into two groups: /control codes/ and /printable characters/.--See also: "ASCII.Group"---}-+ASCII characters are broadly categorized into two groups: /control codes/ and+/printable characters/. -{- | Determine which group a particular character belongs to.+See also: "ASCII.Group" -} ->>> map charGroup [CapitalLetterA,EndOfTransmission]-[Printable,Control]+{-| Determine which group a particular character belongs to --}+@+charGroup CapitalLetterA == Printable +charGroup EndOfTransmission == 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+{-| Test whether a character belongs to a particular ASCII group ->>> map (inGroup Printable) ( [-1, 5, 65, 97, 127, 130] :: [Int] )-[False,False,True,True,False,False]+@+not (inGroup Printable EndOfTransmission) --}+inGroup Control EndOfTransmission +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.+/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. ->>> map letterCase [SmallLetterA, CapitalLetterA, ExclamationMark]-[Just LowerCase,Just UpperCase,Nothing]+See also: "ASCII.Case" -} ->>> map letterCase ( [string|Hey!|] :: [ASCII Word8] )-[Just UpperCase,Just LowerCase,Just LowerCase,Nothing]+{-| 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]+{-| Determines whether a character is an ASCII letter of a particular case ->>> map (isCase UpperCase) ( [-1, 65, 97, 150] :: [Int] )-[False,True,False,False]+@+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)+{-| Maps a letter character to its upper/lower case equivalent --}+@+toCaseChar UpperCase SmallLetterA == CapitalLetterA +(                     [char|a|] :: ASCII Word8) == asciiUnsafe 97+(toCaseChar UpperCase [char|a|] :: ASCII Word8) == asciiUnsafe 65+@ -} toCaseChar :: CharSuperset char => Case -> char -> char toCaseChar = ASCII.Superset.toCaseChar -{- | 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!"+{-| 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 :: StringSuperset string => Case -> string -> string toCaseString = ASCII.Superset.toCaseString  {-| Convert from ASCII character to caseless ASCII character, discarding the-case if the character is a letter -}+    case if the character is a letter -} disregardCase :: Char -> CaselessChar disregardCase = ASCII.Caseless.disregardCase  {- $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".+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]+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 @@ -308,17 +290,13 @@  {- $word8Conversions -These functions convert between the ASCII 'Char' type and 'Word8'.---}--{- |-->>> map charToWord8 [Null, CapitalLetterA, SmallLetterA, Delete]-[0,65,97,127]+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 @@ -330,9 +308,8 @@  {- $unicodeCharConversions -These functions convert between the ASCII 'Char' type and the 'UnicodeChar' type.---}+These functions convert between the ASCII 'Char' type and the 'UnicodeChar'+type. -}  charToUnicode :: Char -> UnicodeChar charToUnicode = ASCII.Superset.fromChar@@ -345,11 +322,11 @@  {- $digitWord8Conversions -These functions convert between the ASCII 'Digit' type and ASCII digits in their byte encoding.--These conversions do /not/ correspond to the numeric interpretations of 'Digit' and 'Word8'. For example, 'digitToWord8' 'ASCII.Decimal.Digit0' is 48, not 0.+These functions convert between the ASCII 'Digit' type and ASCII digits in their+byte encoding. --}+These conversions do /not/ correspond to the numeric interpretations of 'Digit'+and 'Word8'. For example, 'digitToWord8' 'ASCII.Decimal.Digit0' is 48, not 0. -}  digitToWord8 :: Digit -> Word8 digitToWord8 = ASCII.Decimal.fromDigit@@ -362,9 +339,8 @@  {- $digitCharConversions -These functions convert between the ASCII 'Digit' type and the ASCII 'Char' type.---}+These functions convert between the ASCII 'Digit' type and the ASCII 'Char'+type. -}  digitToChar :: Digit -> Char digitToChar = ASCII.Decimal.fromDigit@@ -377,9 +353,8 @@  {- $digitUnicodeConversions -These functions convert between the ASCII 'Digit' type and the 'UnicodeChar' type.---}+These functions convert between the ASCII 'Digit' type and the 'UnicodeChar'+type. -}  digitToUnicode :: Digit -> UnicodeChar digitToUnicode = ASCII.Decimal.fromDigit@@ -393,11 +368,12 @@  {- $hexCharWord8Conversions -These functions convert between the ASCII 'HexChar' type and ASCII characters in their byte encoding.--These conversions do /not/ correspond to the numeric interpretations of 'HexChar' and 'Word8'. For example, 'hexCharToWord8' 'ASCII.Hexadecimal.CapitalLetterA' is 65, not 10.+These functions convert between the ASCII 'HexChar' type and ASCII characters in+their byte encoding. --}+These conversions do /not/ correspond to the numeric interpretations of+'HexChar' and 'Word8'. For example, 'hexCharToWord8'+'ASCII.Hexadecimal.CapitalLetterA' is 65, not 10. -}  hexCharToWord8 :: HexChar -> Word8 hexCharToWord8 = ASCII.Hexadecimal.fromHexChar@@ -410,9 +386,8 @@  {- $hexCharCharConversions -These functions convert between the ASCII 'HexChar' type and the ASCII 'Char' type.---}+These functions convert between the ASCII 'HexChar' type and the ASCII 'Char'+type. -}  hexCharToChar :: HexChar -> Char hexCharToChar = ASCII.Hexadecimal.fromHexChar@@ -425,9 +400,8 @@  {- $hexCharUnicodeConversions -These functions convert between the ASCII 'HexChar' type and the 'UnicodeChar' type.---}+These functions convert between the ASCII 'HexChar' type and the 'UnicodeChar'+type. -}  hexCharToUnicode :: HexChar -> UnicodeChar hexCharToUnicode = ASCII.Hexadecimal.fromHexChar@@ -440,9 +414,8 @@  {- $unicodeStringConversions -These functions convert between @['Char']@ (a list of ASCII characters) and 'Unicode.String' (a list of Unicode characters).---}+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@@ -455,17 +428,13 @@  {- $textConversions -These functions convert between @['Char']@ and 'Text.Text'.---}--{- |-->>> charListToText [CapitalLetterH,SmallLetterI,ExclamationMark]-"Hi!"+These functions convert between @['Char']@ and 'Text.Text'. -} --}+{-| +@+charListToText [CapitalLetterH, SmallLetterI, ExclamationMark] == "Hi!"+@ -} charListToText :: [Char] -> Text.Text charListToText = ASCII.Superset.fromCharList @@ -477,9 +446,7 @@  {- $byteStringConversions -These functions convert between @['Char']@ and 'BS.ByteString'.---}+These functions convert between @['Char']@ and 'BS.ByteString'. -}  charListToByteString :: [Char] -> BS.ByteString charListToByteString = ASCII.Superset.fromCharList@@ -492,40 +459,36 @@  {- $refinement -See also: "ASCII.Refinement", "ASCII.CaseRefinement"---}+See also: "ASCII.Refinement", "ASCII.CaseRefinement" -}  {- $lift -See also: "ASCII.Lift"---}+See also: "ASCII.Lift" -} -{- | Converts from ASCII to any larger type.+{-| Converts from ASCII to any larger type  For example, @(lift \@ASCII.Char \@Word8)@ is the same function as 'charToWord8'. ->>> lift CapitalLetterA :: Word8-65+@+(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 [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.---}+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@@ -541,18 +504,19 @@  {- $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'.+These functions are all specializations of 'convertStringMaybe'.+They convert a string from one ASCII-superset type to another. ->>> ASCII.byteListToUnicodeStringMaybe [0x48, 0x54, 0x54, 0x80]-Nothing+@+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 @@ -565,59 +529,48 @@ unicodeStringToByteListMaybe :: Unicode.String -> Maybe [Word8] unicodeStringToByteListMaybe = convertStringMaybe -{- | Returns True for ASCII letters:+{-| Returns True for ASCII letters:  - 'ASCII.Char.SmallLetterA' to 'ASCII.Char.SmallLetterZ'-- 'ASCII.Char.CapitalLetterA' to 'ASCII.Char.CapitalLetterZ'---}-+- 'ASCII.Char.CapitalLetterA' to 'ASCII.Char.CapitalLetterZ' -} isLetter :: CharSuperset char => char -> Bool isLetter x = any ASCII.Predicates.isLetter (convertCharMaybe x) -{- | Returns True for the characters from 'ASCII.Char.Digit0' to 'ASCII.Char.Digit9'. -}-+{-| Returns True for the characters from 'ASCII.Char.Digit0' to+'ASCII.Char.Digit9'. -} isDigit :: CharSuperset char => char -> Bool isDigit x = any ASCII.Predicates.isDigit (convertCharMaybe x) --{- | Returns True for the characters from 'ASCII.Char.Digit0' to 'ASCII.Char.Digit7'. -}-+{-| Returns True for the characters from 'ASCII.Char.Digit0' to+'ASCII.Char.Digit7'. -} isOctDigit :: CharSuperset char => char -> Bool isOctDigit x = any ASCII.Predicates.isOctDigit (convertCharMaybe x) --{- | Returns True for characters in any of the following ranges:+{-| Returns True for characters in any of the following ranges:  - 'ASCII.Char.Digit0' to 'ASCII.Char.Digit9' - 'ASCII.Char.CapitalLetterA' to 'ASCII.Char.CapitalLetterF'-- 'ASCII.Char.SmallLetterA' to 'ASCII.Char.SmallLetterF'---}-+- 'ASCII.Char.SmallLetterA' to 'ASCII.Char.SmallLetterF' -} isHexDigit :: CharSuperset char => char -> Bool isHexDigit x = any ASCII.Predicates.isHexDigit (convertCharMaybe x) -{- | Returns True for the following characters:+{-| Returns True for the following characters:  - 'ASCII.Char.Space' - 'ASCII.Char.HorizontalTab' - 'ASCII.Char.LineFeed' - 'ASCII.Char.VerticalTab' - 'ASCII.Char.FormFeed'-- 'ASCII.Char.CarriageReturn'---}-+- 'ASCII.Char.CarriageReturn' -} isSpace :: CharSuperset char => char -> Bool isSpace x = any ASCII.Predicates.isSpace (convertCharMaybe x) -{- | Returns True if the character is either an ASCII letter ('isLetter') or an ASCII digit ('isDigit'). -}-+{-| Returns True if the character is either an ASCII letter ('isLetter') or an+ASCII digit ('isDigit'). -} isAlphaNum :: CharSuperset char => char -> Bool isAlphaNum x = any ASCII.Predicates.isAlphaNum (convertCharMaybe x) -{- | Returns True for the following characters:+{-| Returns True for the following characters:  - 'ASCII.Char.ExclamationMark' - 'ASCII.Char.QuotationMark'@@ -641,14 +594,11 @@ - 'ASCII.Char.RightSquareBracket' - 'ASCII.Char.Underscore' - 'ASCII.Char.LeftCurlyBracket'-- 'ASCII.Char.RightCurlyBracket'---}-+- 'ASCII.Char.RightCurlyBracket' -} isPunctuation :: CharSuperset char => char -> Bool isPunctuation x = any ASCII.Predicates.isPunctuation (convertCharMaybe x) -{- | Returns True for the following characters:+{-| Returns True for the following characters:  - 'ASCII.Char.DollarSign' - 'ASCII.Char.PlusSign'@@ -658,61 +608,46 @@ - 'ASCII.Char.Caret' - 'ASCII.Char.GraveAccent' - 'ASCII.Char.VerticalLine'-- 'ASCII.Char.Tilde'---}-+- 'ASCII.Char.Tilde' -} isSymbol :: CharSuperset char => char -> Bool isSymbol x = any ASCII.Predicates.isSymbol (convertCharMaybe x) -{- | Returns True for visible characters.--This includes all print characters except 'ASCII.Char.Space'.---}+{- |Returns True for visible characters +This includes all print characters except 'ASCII.Char.Space'. -} isVisible :: CharSuperset char => char -> Bool isVisible x = any ASCII.Predicates.isVisible (convertCharMaybe x)  {- $numbers -See also: "ASCII.Decimal" and "ASCII.Hexadecimal"---}--{- |--Gives the ASCII string representation of an integer in decimal (base 10)-notation, using digits 'ASCII.Char.Digit0' through 'ASCII.Char.Digit9',-leading with 'ASCII.Char.HyphenMinus' for negative numbers.--For example, @'showIntegralDecimal' (-512 :: 'Prelude.Integer')@ = @"-512"@.+See also: "ASCII.Decimal" and "ASCII.Hexadecimal" -} --}+{-| Gives the ASCII string representation of an integer in decimal (base 10)+    notation, using digits 'ASCII.Char.Digit0' through 'ASCII.Char.Digit9',+    leading with 'ASCII.Char.HyphenMinus' for negative numbers +For example, @'showIntegralDecimal' (-512 :: 'Prelude.Integer')@ = @"-512"@. -} showIntegralDecimal :: (Integral n, StringSuperset string) => n -> string showIntegralDecimal = ASCII.Decimal.showIntegral -{- |+{-| Gives the ASCII string representation of an integer in hexadecimal (base 16)+    notation -Gives the ASCII string representation of an integer in hexadecimal (base 16)-notation, using digits 'ASCII.Char.Digit0' through 'ASCII.Char.Digit9', for-digits 0 though 9. The representation of digits 10 to 15 is determined by the-value of 'Case' parameter: 'UpperCase' means 'ASCII.Char.CapitalLetterA' to+The characters 'ASCII.Char.Digit0' through 'ASCII.Char.Digit9' represent digits+0 though 9. The representation of digits 10 to 15 is determined by the value of+'Case' parameter: 'UpperCase' means 'ASCII.Char.CapitalLetterA' to 'ASCII.Char.CapitalLetterF', and 'LowerCase' means 'ASCII.Char.SmallLetterA' to 'ASCII.Char.SmallLetterF'. For negative numbers, the resulting string begins with 'ASCII.Char.HyphenMinus'. -For example, @'showIntegralHexadecimal' 'UpperCase' ('Prelude.negate' (256 + 12) :: 'Prelude.Integer')@ = @"-10C"@.---}--showIntegralHexadecimal :: (Integral n, StringSuperset string) => Case -> n -> string+@+'showIntegralHexadecimal' 'UpperCase' ('Prelude.negate' (256 + 12) :: 'Prelude.Integer') == "-10C"+@ -}+showIntegralHexadecimal :: (Integral n, StringSuperset string) =>+    Case -> n -> string showIntegralHexadecimal = ASCII.Hexadecimal.showIntegral -{- |--Roughly the inverse of 'showIntegralDecimal'+{-| Roughly the inverse of 'showIntegralDecimal'  * Leading zeroes are accepted, as in @"0074"@ and @"-0074"@ @@ -720,16 +655,13 @@  * If the input is empty * If the input contains any other extraneous characters-* If the resulting number would be outside the range supported by the 'Integral' (determined by its 'Bits' instance)---}--readIntegralDecimal :: (StringSuperset string, Integral number, Bits number) => string -> Maybe number+* If the resulting number would be outside the range supported by the 'Integral'+  (determined by its 'Bits' instance) -}+readIntegralDecimal :: (StringSuperset string, Integral number, Bits number) =>+    string -> Maybe number readIntegralDecimal = ASCII.Decimal.readIntegral -{- |--Roughly the inverse of 'showIntegralHexadecimal'+{-| Roughly the inverse of 'showIntegralHexadecimal'  * Upper and lower case letters are treated equally * Leading zeroes are accepted, as in @"006a"@ and @"-006a"@@@ -738,60 +670,48 @@  * If the input is empty * If the input contains any other extraneous characters-* If the resulting number would be outside the range supported by the 'Integral' (determined by its 'Bits' instance)---}--readIntegralHexadecimal :: (StringSuperset string, Integral number, Bits number) => string -> Maybe number+* If the resulting number would be outside the range supported by the 'Integral'+  (determined by its 'Bits' instance) -}+readIntegralHexadecimal :: (StringSuperset string, Integral number, Bits number) =>+    string -> Maybe number readIntegralHexadecimal = ASCII.Hexadecimal.readIntegral -{- |--Gives the ASCII string representation of an natural number in decimal (base 10)-notation, using digits 'ASCII.Char.Digit0' through 'ASCII.Char.Digit9'.--For example, @'showNaturalDecimal' 512@ = @"512"@.---}+{-| Gives the ASCII string representation of an natural number in decimal+    (base 10) notation, using digits 'ASCII.Char.Digit0' through 'ASCII.Char.Digit9' +@+'showNaturalDecimal' 512 == @"512"+@ -} showNaturalDecimal :: DigitStringSuperset string => Natural -> string showNaturalDecimal = ASCII.Decimal.showNatural -{- |+{-| Gives the ASCII string representation of an integer in hexadecimal (base 16)+    notation -Gives the ASCII string representation of an integer in hexadecimal (base 16)-notation, using digits 'ASCII.Char.Digit0' through 'ASCII.Char.Digit9', for-digits 0 though 9. The representation of digits 10 to 15 is determined by the-value of 'Case' parameter: 'UpperCase' means 'ASCII.Char.CapitalLetterA' to+Characters 'ASCII.Char.Digit0' through 'ASCII.Char.Digit9' represent digits 0+though 9. The representation of digits 10 to 15 is determined by the value of+'Case' parameter: 'UpperCase' means 'ASCII.Char.CapitalLetterA' to 'ASCII.Char.CapitalLetterF', and 'LowerCase' means 'ASCII.Char.SmallLetterA' to 'ASCII.Char.SmallLetterF'. -For example, @'showNaturalHexadecimal' 'UpperCase' (256 + 12)@ = @"10C"@.---}-+@+'showNaturalHexadecimal' 'UpperCase' (256 + 12) == "10C"+@ -} showNaturalHexadecimal :: HexStringSuperset string => Case -> Natural -> string showNaturalHexadecimal = ASCII.Hexadecimal.showNatural -{- |--Roughly the inverse of 'showNaturalDecimal'+{-| Roughly the inverse of 'showNaturalDecimal'  * Leading zeroes are accepted, as in @"0074"@  Conditions where the result is 'Data.Maybe.Nothing':  * If the input is empty-* If the input contains any other extraneous characters---}-+* If the input contains any other extraneous characters -} readNaturalDecimal :: DigitStringSuperset string => string -> Maybe Natural readNaturalDecimal = ASCII.Decimal.readNatural -{- |--Roughly the inverse of 'showNaturalHexadecimal'+{-| Roughly the inverse of 'showNaturalHexadecimal'  * Upper and lower case letters are treated equally * Leading zeroes are accepted, as in @"006a"@@@ -799,82 +719,49 @@ Conditions where the result is 'Data.Maybe.Nothing':  * If the input is empty-* If the input contains any other extraneous characters---}-+* If the input contains any other extraneous characters -} readNaturalHexadecimal :: HexStringSuperset string => string -> Maybe Natural readNaturalHexadecimal = ASCII.Hexadecimal.readNatural  {- $digit -See also: "ASCII.Decimal"---}+See also: "ASCII.Decimal" -}  {- $hexchar -See also: "ASCII.Hexadecimal"---}--{- |--Specialization of 'showNaturalDecimal'--See also: 'showIntegralDecimal'+See also: "ASCII.Hexadecimal" -} --}+{-| Specialization of 'showNaturalDecimal' +See also: 'showIntegralDecimal' -} showNaturalDigits :: Natural -> [Digit] showNaturalDigits = showNaturalDecimal -{- |--Specialization of 'readNaturalDecimal'--See also: 'readIntegralDecimal'---}+{-| Specialization of 'readNaturalDecimal' +See also: 'readIntegralDecimal' -} readNaturalDigits :: [Digit] -> Maybe Natural readNaturalDigits = readNaturalDecimal -{- |--Specialization of 'showNaturalHexadecimal'--See also: 'showIntegralHexadecimal'+{-| Specialization of 'showNaturalHexadecimal' --}+See also: 'showIntegralHexadecimal' -}  showNaturalHexChars :: Case -> Natural -> [HexChar] showNaturalHexChars = showNaturalHexadecimal -{- |--Specialization of 'readNaturalHexadecimal'--See also: 'readIntegralHexadecimal'---}+{-| Specialization of 'readNaturalHexadecimal' +See also: 'readIntegralHexadecimal' -} readNaturalHexChars :: [HexChar] -> Maybe Natural readNaturalHexChars = readNaturalHexadecimal -{- |--A string containing a single digit character 0-9---}+{-| A string containing a single digit character 0-9 -} digitString :: DigitStringSuperset string => Digit -> string digitString x = ASCII.Decimal.fromDigitList [x] -{- |--A string containing a single hexadecimal digit character 0-9, A-F, or a-f.---}+{-| A string containing a single hexadecimal digit character+    0-9, A-F, or a-f -} hexCharString :: HexStringSuperset string => HexChar -> string hexCharString x = ASCII.Hexadecimal.fromHexCharList [x] 
test/Main.hs view
@@ -5,8 +5,7 @@ import ASCII.Char (Char (..)) import ASCII.Refinement (asciiUnsafe) -import Control.Monad (Monad (..), when)-import Data.Bool (Bool (..), not)+import Data.Bool (Bool (..)) import Data.Function (($)) import Data.Int (Int) import Data.List (map)@@ -14,108 +13,134 @@ import Data.Text (Text) import Data.Word (Word8) import Prelude (enumFromTo, maxBound, minBound)-import System.Exit (exitFailure) import System.IO (IO) -import Hedgehog (Property, assert, checkParallel, discover, property, withTests,-                 (===))+import Test.Hspec (describe, hspec, it, shouldBe)  main :: IO ()-main = checkParallel $$(discover) >>= \ok -> when (not ok) exitFailure+main = hspec $ do -prop_letter_printable :: Property-prop_letter_printable = withTests 1 $ property $-    charGroup CapitalLetterA === Printable+    describe "charGroup" $ do+        let c ~> g = charGroup c `shouldBe` g -prop_eot_control :: Property-prop_eot_control = withTests 1 $ property $-    charGroup EndOfTransmission === Control+        it "A is printable"                 $ CapitalLetterA    ~> Printable+        it "end-of-transmission is control" $ EndOfTransmission ~> Control -prop_eot_not_printable :: Property-prop_eot_not_printable = withTests 1 $ property $-    assert $ not $ inGroup Printable EndOfTransmission+    describe "inGroup" $ do -prop_is_eot_control :: Property-prop_is_eot_control = withTests 1 $ property $-    assert $ inGroup Control EndOfTransmission+        describe "tests Char" $ do+            it "end-of-transmission is not printable" $+                inGroup Printable EndOfTransmission `shouldBe` False+            it "end-of-transmission is control" $+                inGroup Control   EndOfTransmission `shouldBe` True -prop_inGroup_printable :: Property-prop_inGroup_printable = withTests 1 $ property $-    map (inGroup Printable) ([-1, 5, 65, 97, 127, 130] :: [Int]) === [False, False, True, True, False, False]+        describe "tests Int" $ do+            let i ~> b = inGroup Printable (i :: Int) `shouldBe` b -prop_cases :: Property-prop_cases = withTests 1 $ property $-    map letterCase [SmallLetterA, CapitalLetterA, ExclamationMark] === [Just LowerCase, Just UpperCase, Nothing]+            it "-1 is not printable (isn't anything)"  $ (-1) ~> False+            it "5 is not printable"                    $ 5    ~> False+            it "65 is printable"                       $ 65   ~> True+            it "97 is printable"                       $ 97   ~> True+            it "127 is not printable"                  $ 127  ~> False+            it "128 is not printable (isn't anything)" $ 128  ~> False -prop_cases_string_qq :: Property-prop_cases_string_qq = withTests 1 $ property $-    map letterCase ([string|Hey!|] :: [ASCII Word8]) === [Just UpperCase, Just LowerCase, Just LowerCase, Nothing]+    describe "letterCase" $ do+        let ch ~> ca = letterCase ch `shouldBe` ca -prop_is_upper_char :: Property-prop_is_upper_char = withTests 1 $ property $-    map (isCase UpperCase) [SmallLetterA, CapitalLetterA, ExclamationMark] === [False, True, False]+        describe "works with Char" $ do+            it "a is lower"    $ SmallLetterA    ~> Just LowerCase+            it "A is upper"    $ CapitalLetterA  ~> Just UpperCase+            it "! has no case" $ ExclamationMark ~> Nothing -prop_is_upper_string_qq :: Property-prop_is_upper_string_qq = withTests 1 $ property $-    map (isCase UpperCase) ([string|Hey!|] :: [ASCII Word8]) === [True, False, False, False]+        it "works with ASCII Word8" $ do+            map letterCase ([string|Hey!|] :: [ASCII Word8]) `shouldBe`+                [Just UpperCase, Just LowerCase, Just LowerCase, Nothing] -prop_is_upper_int :: Property-prop_is_upper_int = withTests 1 $ property $-    map (isCase UpperCase) ([-1, 65, 97, 150] :: [Int]) === [False, True, False, False]+    describe "isCase" $ do -prop_to_upper_letter :: Property-prop_to_upper_letter = withTests 1 $ property $-    toCaseChar UpperCase SmallLetterA === CapitalLetterA+        describe "works with Char" $ do+            let c ~> b = isCase UpperCase c `shouldBe` b -prop_to_upper_char_qq :: Property-prop_to_upper_char_qq = withTests 1 $ property $-    ([char|a|] :: ASCII Word8, toCaseChar UpperCase [char|a|] :: ASCII Word8) === (asciiUnsafe 97, asciiUnsafe 65)+            it "a is not upper" $ SmallLetterA    ~> False+            it "A is upper"     $ CapitalLetterA  ~> True+            it "! is not upper" $ ExclamationMark ~> False -prop_to_upper_various :: Property-prop_to_upper_various = withTests 1 $ property $-    toCaseString UpperCase [CapitalLetterH,SmallLetterE,SmallLetterY,ExclamationMark] === [CapitalLetterH, CapitalLetterE, CapitalLetterY, ExclamationMark]+        it "works with ASCII Word8" $ do+            map (isCase UpperCase) ([string|Hey!|] :: [ASCII Word8])+                `shouldBe` [True, False, False, False] -prop_to_upper_string_qq :: Property-prop_to_upper_string_qq = withTests 1 $ property $-    (toCaseString UpperCase [string|Hey!|] :: ASCII Text) === asciiUnsafe "HEY!"+        describe "works with Int" $ do+            let i ~> b = isCase UpperCase (i :: Int) `shouldBe` b -prop_to_int :: Property-prop_to_int = withTests 1 $ property $-    map charToInt [Null, CapitalLetterA, SmallLetterA, Delete] === [0, 65, 97, 127]+            it "-1 is not upper (isn't anything)"  $ (-1) ~> False+            it "65 is upper"                       $ 65   ~> True+            it "97 is not upper"                   $ 97   ~> False+            it "128 is not upper (isn't anything)" $ 128  ~> False -prop_to_word8 :: Property-prop_to_word8 = withTests 1 $ property $-    map charToWord8 [Null, CapitalLetterA, SmallLetterA, Delete] === [0, 65, 97, 127]+    describe "toCaseChar" $ do -prop_to_text :: Property-prop_to_text = withTests 1 $ property $-    charListToText [CapitalLetterH, SmallLetterI, ExclamationMark] === "Hi!"+        describe "works with Char" $ do+            it "a to upper is A" $ toCaseChar UpperCase SmallLetterA+                `shouldBe` CapitalLetterA -prop_lift_to_word8 :: Property-prop_lift_to_word8 = withTests 1 $ property $-    (lift CapitalLetterA :: Word8) === 65+        describe "works with ASCII Word8" $ do+            it "a to upper is 65" $ toCaseChar UpperCase ([char|a|] :: ASCII Word8)+                `shouldBe` (asciiUnsafe 65 :: ASCII Word8) -prop_lift_to_text :: Property-prop_lift_to_text = withTests 1 $ property $-    (lift [CapitalLetterH,SmallLetterI,ExclamationMark] :: Text) === "Hi!"+    describe "toCaseString" $ do+        it "converts each Char to a case" $ do+            let check a b = toCaseString UpperCase a `shouldBe` b+            check [ CapitalLetterH, SmallLetterE,   SmallLetterY,   ExclamationMark ]+                  [ CapitalLetterH, CapitalLetterE, CapitalLetterY, ExclamationMark ] -prop_bytes_to_string :: Property-prop_bytes_to_string = withTests 1 $ property $-    ASCII.byteListToUnicodeStringMaybe [0x48, 0x54, 0x54, 0x50] === Just "HTTP"+        it "works with ASCII Text" $+            (toCaseString UpperCase [string|Hey!|] :: ASCII Text)+                `shouldBe` asciiUnsafe "HEY!" -prop_bytes_to_string_fail :: Property-prop_bytes_to_string_fail = withTests 1 $ property $-    ASCII.byteListToUnicodeStringMaybe [0x48, 0x54, 0x54, 0x80] === Nothing+    describe "charToInt" $ do+        let c ~> i = charToInt c `shouldBe` i -prop_digitStrings :: Property-prop_digitStrings = withTests 1 $ property $-    map digitString (enumFromTo minBound maxBound) ===-    (["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] :: [Text])+        it "Null is 0"     $ Null           ~> 0+        it "A is 65"       $ CapitalLetterA ~> 65+        it "a is 97"       $ SmallLetterA   ~> 97+        it "Delete is 127" $ Delete         ~> 127 -prop_hexCharStrings :: Property-prop_hexCharStrings = withTests 1 $ property $-    map hexCharString (enumFromTo minBound maxBound) ===-    ( [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"-      , "A", "B", "C", "D", "E", "F"-      , "a", "b", "c", "d", "e", "f"-      ] :: [Text] )+    describe "charToWord8" $ do+        let c ~> i = charToWord8 c `shouldBe` i++        it "Null is 0"     $ Null           ~> 0+        it "A is 65"       $ CapitalLetterA ~> 65+        it "a is 97"       $ SmallLetterA   ~> 97+        it "Delete is 127" $ Delete         ~> 127++    describe "charListToText" $ do+        it "packs a list of Char into Text" $+            charListToText [CapitalLetterH, SmallLetterI, ExclamationMark]+                `shouldBe` "Hi!"++    describe "lift" $ do+        it "converts Char to Word8" $ (lift CapitalLetterA :: Word8) `shouldBe` 65+        it "converts [Char] to Text" $+            (lift [CapitalLetterH, SmallLetterI, ExclamationMark] :: Text)+                `shouldBe` "Hi!"++    describe "byteListToUnicodeStringMaybe" $ do+        it "converts [Word8] to String" $+            ASCII.byteListToUnicodeStringMaybe [0x48, 0x54, 0x54, 0x50]+                `shouldBe` Just "HTTP"+        it "can fail" $ ASCII.byteListToUnicodeStringMaybe [0x48, 0x54, 0x54, 0x80]+            `shouldBe` Nothing++    describe "digitString" $ do+        it "converts Digit to a single character of Text" $ do+            let f = digitString :: Digit -> Text+            map f (enumFromTo minBound maxBound) `shouldBe`+                ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]++    describe "hexCharString" $ do+        it "converts HexChar to a single character of Text" $ do+            let f = hexCharString :: HexChar -> Text+            map f (enumFromTo minBound maxBound) `shouldBe`+                [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"+                , "A", "B", "C", "D", "E", "F"+                , "a", "b", "c", "d", "e", "f" ]