text-builder 0.6.7 → 0.6.7.1
raw patch · 6 files changed
+157/−125 lines, 6 filesdep −QuickCheckdep −quickcheck-instancesdep ~text-builder-dev
Dependencies removed: QuickCheck, quickcheck-instances
Dependency ranges changed: text-builder-dev
Files
- benchmark-char/Main.hs +11/−10
- benchmark-text/Main.hs +19/−15
- library/Text/Builder.hs +12/−14
- library/Text/Builder/Prelude.hs +1/−3
- test/Main.hs +33/−33
- text-builder.cabal +81/−50
benchmark-char/Main.hs view
@@ -7,20 +7,21 @@ import qualified Text.Builder as A import Prelude +main :: IO () main =- defaultMain $- [ subjectBenchmark "builderSubject" builderSubject,- subjectBenchmark "lazyTextBuilderSubject" lazyTextBuilderSubject,- subjectBenchmark "plainTextPackingSubject" plainTextPackingSubject- ]+ defaultMain+ $ [ subjectBenchmark "builderSubject" builderSubject,+ subjectBenchmark "lazyTextBuilderSubject" lazyTextBuilderSubject,+ subjectBenchmark "plainTextPackingSubject" plainTextPackingSubject+ ] subjectBenchmark :: String -> Subject -> Benchmark subjectBenchmark title subject =- bgroup title $- [ benchmark "Small input" smallInput subject,- benchmark "Medium input" mediumInput subject,- benchmark "Large input" largeInput subject- ]+ bgroup title+ $ [ benchmark "Small input" smallInput subject,+ benchmark "Medium input" mediumInput subject,+ benchmark "Large input" largeInput subject+ ] benchmark :: String -> [Int] -> Subject -> Benchmark benchmark title input subject =
benchmark-text/Main.hs view
@@ -1,24 +1,24 @@ module Main where import Criterion.Main-import qualified Data.Text as D import qualified Data.Text.Lazy as C import qualified Data.Text.Lazy.Builder as B import qualified Text.Builder as A import Prelude +main :: IO () main =- defaultMain $- [ subjectBenchmark "builderSubject" builderSubject,- subjectBenchmark "lazyTextBuilderSubject" lazyTextBuilderSubject- ]+ defaultMain+ $ [ subjectBenchmark "builderSubject" builderSubject,+ subjectBenchmark "lazyTextBuilderSubject" lazyTextBuilderSubject+ ] subjectBenchmark :: String -> Subject -> Benchmark subjectBenchmark title subject =- bgroup title $- [ benchmark "Small input" smallSample subject,- benchmark "Large input" largeSample subject- ]+ bgroup title+ $ [ benchmark "Small input" smallSample subject,+ benchmark "Large input" largeSample subject+ ] benchmark :: String -> Sample -> Subject -> Benchmark benchmark title sample subject =@@ -41,13 +41,17 @@ {-# NOINLINE smallSample #-} smallSample :: Sample smallSample (Subject text (<>) mempty run) =- run $- text "abcd" <> (text "ABCD" <> text "Фываолдж") <> text "漢"+ run+ $ text "abcd"+ <> (text "ABCD" <> text "Фываолдж")+ <> text "漢" {-# NOINLINE largeSample #-} largeSample :: Sample largeSample (Subject text (<>) mempty run) =- run $- foldl' (<>) mempty $- replicate 100000 $- text "abcd" <> (text "ABCD" <> text "Фываолдж") <> text "漢"+ run+ $ foldl' (<>) mempty+ $ replicate 100000+ $ text "abcd"+ <> (text "ABCD" <> text "Фываолдж")+ <> text "漢"
library/Text/Builder.hs view
@@ -68,8 +68,6 @@ ) where -import Data.ByteString (ByteString)-import Data.Text (Text) import qualified Data.Text.Lazy as TextLazy import Text.Builder.Prelude hiding (intercalate, length, null) import qualified TextBuilderDev as Dev@@ -177,32 +175,32 @@ -- | Decimal representation of an integral value {-# INLINEABLE decimal #-}-decimal :: Integral a => a -> Builder+decimal :: (Integral a) => a -> Builder decimal = coerce . Dev.decimal -- | Decimal representation of an unsigned integral value {-# INLINEABLE unsignedDecimal #-}-unsignedDecimal :: Integral a => a -> Builder+unsignedDecimal :: (Integral a) => a -> Builder unsignedDecimal = coerce . Dev.unsignedDecimal -- | Decimal representation of an integral value with thousands separated by the specified character {-# INLINEABLE thousandSeparatedDecimal #-}-thousandSeparatedDecimal :: Integral a => Char -> a -> Builder+thousandSeparatedDecimal :: (Integral a) => Char -> a -> Builder thousandSeparatedDecimal = fmap coerce . Dev.thousandSeparatedDecimal -- | Decimal representation of an unsigned integral value with thousands separated by the specified character {-# INLINEABLE thousandSeparatedUnsignedDecimal #-}-thousandSeparatedUnsignedDecimal :: Integral a => Char -> a -> Builder+thousandSeparatedUnsignedDecimal :: (Integral a) => Char -> a -> Builder thousandSeparatedUnsignedDecimal = fmap coerce . Dev.thousandSeparatedUnsignedDecimal -- | Data size in decimal notation over amount of bytes. {-# INLINEABLE dataSizeInBytesInDecimal #-}-dataSizeInBytesInDecimal :: Integral a => Char -> a -> Builder+dataSizeInBytesInDecimal :: (Integral a) => Char -> a -> Builder dataSizeInBytesInDecimal = fmap coerce . Dev.dataSizeInBytesInDecimal -- | Unsigned binary number {-# INLINE unsignedBinary #-}-unsignedBinary :: Integral a => a -> Builder+unsignedBinary :: (Integral a) => a -> Builder unsignedBinary = coerce . Dev.unsignedBinary -- | Unsigned binary number@@ -212,27 +210,27 @@ -- | Hexadecimal representation of an integral value {-# INLINE hexadecimal #-}-hexadecimal :: Integral a => a -> Builder+hexadecimal :: (Integral a) => a -> Builder hexadecimal = coerce . Dev.hexadecimal -- | Unsigned hexadecimal representation of an integral value {-# INLINE unsignedHexadecimal #-}-unsignedHexadecimal :: Integral a => a -> Builder+unsignedHexadecimal :: (Integral a) => a -> Builder unsignedHexadecimal = coerce . Dev.unsignedHexadecimal -- | Decimal digit {-# INLINE decimalDigit #-}-decimalDigit :: Integral a => a -> Builder+decimalDigit :: (Integral a) => a -> Builder decimalDigit = coerce . Dev.decimalDigit -- | Hexadecimal digit {-# INLINE hexadecimalDigit #-}-hexadecimalDigit :: Integral a => a -> Builder+hexadecimalDigit :: (Integral a) => a -> Builder hexadecimalDigit = coerce . Dev.hexadecimalDigit -- | Intercalate builders {-# INLINE intercalate #-}-intercalate :: Foldable foldable => Builder -> foldable Builder -> Builder+intercalate :: (Foldable foldable) => Builder -> foldable Builder -> Builder intercalate a b = coerce (Dev.intercalate (coerce a) (foldr ((:) . coerce) [] b)) -- | Pad a builder from the left side to the specified length with the specified character@@ -249,7 +247,7 @@ -- Time interval in seconds. -- Directly applicable to 'DiffTime' and 'NominalDiffTime'. {-# INLINEABLE intervalInSeconds #-}-intervalInSeconds :: RealFrac seconds => seconds -> Builder+intervalInSeconds :: (RealFrac seconds) => seconds -> Builder intervalInSeconds = coerce . Dev.intervalInSeconds -- | Double with a fixed number of decimal places.
library/Text/Builder/Prelude.hs view
@@ -25,7 +25,7 @@ import Data.Fixed as Exports import Data.Foldable as Exports import Data.Function as Exports hiding (id, (.))-import Data.Functor as Exports+import Data.Functor as Exports hiding (unzip) import Data.Functor.Identity as Exports import Data.IORef as Exports import Data.Int as Exports@@ -64,8 +64,6 @@ import System.Mem as Exports import System.Mem.StableName as Exports import System.Timeout as Exports-import Text.ParserCombinators.ReadP as Exports (ReadP, ReadS, readP_to_S, readS_to_P)-import Text.ParserCombinators.ReadPrec as Exports (ReadPrec, readP_to_Prec, readPrec_to_P, readPrec_to_S, readS_to_Prec) import Text.Printf as Exports (hPrintf, printf) import Text.Read as Exports (Read (..), readEither, readMaybe) import Unsafe.Coerce as Exports
test/Main.hs view
@@ -3,49 +3,49 @@ import qualified Data.ByteString as ByteString import qualified Data.Text as A import qualified Data.Text.Encoding as Text-import Test.QuickCheck.Instances import Test.Tasty import Test.Tasty.HUnit import Test.Tasty.QuickCheck import qualified Text.Builder as B import Prelude hiding (choose) +main :: IO () main =- defaultMain $- testGroup "All tests" $- [ testProperty "ASCII ByteString" $- let gen = listOf $ do- list <- listOf (choose (0, 127))- return (ByteString.pack list)- in forAll gen $ \chunks ->- mconcat chunks- === Text.encodeUtf8 (B.run (foldMap B.asciiByteString chunks)),- testProperty "Intercalation has the same effect as in Text" $- \separator texts ->+ defaultMain+ $ testGroup "All tests"+ $ [ testProperty "ASCII ByteString"+ $ let gen = listOf $ do+ list <- listOf (choose (0, 127))+ return (ByteString.pack list)+ in forAll gen $ \chunks ->+ mconcat chunks+ === Text.encodeUtf8 (B.run (foldMap B.asciiByteString chunks)),+ testProperty "Intercalation has the same effect as in Text"+ $ \separator texts -> A.intercalate separator texts === B.run (B.intercalate (B.text separator) (fmap B.text texts)),- testProperty "Packing a list of chars is isomorphic to appending a list of builders" $- \chars ->+ testProperty "Packing a list of chars is isomorphic to appending a list of builders"+ $ \chars -> A.pack chars === B.run (foldMap B.char chars),- testProperty "Concatting a list of texts is isomorphic to fold-mapping with builders" $- \texts ->+ testProperty "Concatting a list of texts is isomorphic to fold-mapping with builders"+ $ \texts -> mconcat texts === B.run (foldMap B.text texts),- testProperty "Concatting a list of texts is isomorphic to concatting a list of builders" $- \texts ->+ testProperty "Concatting a list of texts is isomorphic to concatting a list of builders"+ $ \texts -> mconcat texts === B.run (mconcat (map B.text texts)),- testProperty "Concatting a list of trimmed texts is isomorphic to concatting a list of builders" $- \texts ->+ testProperty "Concatting a list of trimmed texts is isomorphic to concatting a list of builders"+ $ \texts -> let trimmedTexts = fmap (A.drop 3) texts in mconcat trimmedTexts === B.run (mconcat (map B.text trimmedTexts)), testProperty "Decimal" $ \(x :: Integer) -> (fromString . show) x === (B.run (B.decimal x)), testProperty "Hexadecimal vs std show" $ \(x :: Integer) ->- x >= 0- ==> (fromString . showHex x) "" === (B.run . B.hexadecimal) x,+ x >= 0 ==>+ (fromString . showHex x) "" === (B.run . B.hexadecimal) x, testCase "Separated thousands" $ do assertEqual "" "0" (B.run (B.thousandSeparatedUnsignedDecimal ',' 0)) assertEqual "" "123" (B.run (B.thousandSeparatedUnsignedDecimal ',' 123))@@ -64,17 +64,17 @@ assertEqual "" "12" (B.run (B.padFromRight 2 '0' "12")) assertEqual "" "123" (B.run (B.padFromRight 2 '0' "123")) assertEqual "" "1 " (B.run (B.padFromRight 3 ' ' "1")),- testCase "Hexadecimal" $- assertEqual "" "1f23" (B.run (B.hexadecimal 0x01f23)),- testCase "Negative Hexadecimal" $- assertEqual "" "-1f23" (B.run (B.hexadecimal (-0x01f23))),- testGroup "Time interval" $- [ testCase "59s" $ assertEqual "" "00:00:00:59" $ B.run $ B.intervalInSeconds 59,- testCase "minute" $ assertEqual "" "00:00:01:00" $ B.run $ B.intervalInSeconds 60,- testCase "90s" $ assertEqual "" "00:00:01:30" $ B.run $ B.intervalInSeconds 90,- testCase "hour" $ assertEqual "" "00:01:00:00" $ B.run $ B.intervalInSeconds 3600,- testCase "day" $ assertEqual "" "01:00:00:00" $ B.run $ B.intervalInSeconds 86400- ],+ testCase "Hexadecimal"+ $ assertEqual "" "1f23" (B.run (B.hexadecimal 0x01f23)),+ testCase "Negative Hexadecimal"+ $ assertEqual "" "-1f23" (B.run (B.hexadecimal (-0x01f23))),+ testGroup "Time interval"+ $ [ testCase "59s" $ assertEqual "" "00:00:00:59" $ B.run $ B.intervalInSeconds 59,+ testCase "minute" $ assertEqual "" "00:00:01:00" $ B.run $ B.intervalInSeconds 60,+ testCase "90s" $ assertEqual "" "00:00:01:30" $ B.run $ B.intervalInSeconds 90,+ testCase "hour" $ assertEqual "" "00:01:00:00" $ B.run $ B.intervalInSeconds 3600,+ testCase "day" $ assertEqual "" "01:00:00:00" $ B.run $ B.intervalInSeconds 86400+ ], testCase "dataSizeInBytesInDecimal" $ do assertEqual "" "999B" (B.run (B.dataSizeInBytesInDecimal ',' 999)) assertEqual "" "1kB" (B.run (B.dataSizeInBytesInDecimal ',' 1000))
text-builder.cabal view
@@ -1,70 +1,101 @@ cabal-version: 3.0--name: text-builder-version: 0.6.7-category: Text-synopsis: An efficient strict text builder-homepage: https://github.com/nikita-volkov/text-builder-bug-reports: https://github.com/nikita-volkov/text-builder/issues-author: Nikita Volkov <nikita.y.volkov@mail.ru>-maintainer: Nikita Volkov <nikita.y.volkov@mail.ru>-copyright: (c) 2017, Nikita Volkov-license: MIT-license-file: LICENSE+name: text-builder+version: 0.6.7.1+category: Text, Builders+synopsis: Efficient strict text builder+description: Text formatting library and efficient builder library.+homepage: https://github.com/nikita-volkov/text-builder+bug-reports: https://github.com/nikita-volkov/text-builder/issues+author: Nikita Volkov <nikita.y.volkov@mail.ru>+maintainer: Nikita Volkov <nikita.y.volkov@mail.ru>+copyright: (c) 2017, Nikita Volkov+license: MIT+license-file: LICENSE source-repository head- type: git+ type: git location: git://github.com/nikita-volkov/text-builder.git -common language-settings- default-extensions: BangPatterns, ConstraintKinds, DataKinds, DefaultSignatures, DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric, DeriveTraversable, EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies, GADTs, GeneralizedNewtypeDeriving, LambdaCase, LiberalTypeSynonyms, MagicHash, MultiParamTypeClasses, MultiWayIf, NoImplicitPrelude, NoMonomorphismRestriction, OverloadedStrings, PatternGuards, ParallelListComp, QuasiQuotes, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TemplateHaskell, TupleSections, TypeFamilies, TypeOperators, UnboxedTuples- default-language: Haskell2010+common base+ default-language: Haskell2010+ default-extensions:+ NoImplicitPrelude+ NoMonomorphismRestriction+ BangPatterns+ ConstraintKinds+ DataKinds+ DefaultSignatures+ DeriveDataTypeable+ DeriveFoldable+ DeriveFunctor+ DeriveGeneric+ DeriveTraversable+ EmptyDataDecls+ FlexibleContexts+ FlexibleInstances+ FunctionalDependencies+ GADTs+ GeneralizedNewtypeDeriving+ LambdaCase+ LiberalTypeSynonyms+ MagicHash+ MultiParamTypeClasses+ MultiWayIf+ OverloadedStrings+ ParallelListComp+ PatternGuards+ QuasiQuotes+ RankNTypes+ RecordWildCards+ ScopedTypeVariables+ StandaloneDeriving+ TemplateHaskell+ TupleSections+ TypeFamilies+ TypeOperators+ UnboxedTuples library- import: language-settings- hs-source-dirs: library- exposed-modules:- Text.Builder- other-modules:- Text.Builder.Prelude+ import: base+ hs-source-dirs: library+ exposed-modules: Text.Builder+ other-modules: Text.Builder.Prelude build-depends:- base >=4.11 && <5,- bytestring >=0.10 && <0.12,- text >=1.2 && <3,- text-builder-dev >=0.3.1 && <0.4,+ , base >=4.11 && <5+ , bytestring >=0.10 && <0.12+ , text >=1.2 && <3+ , text-builder-dev >=0.3.4.1 && <0.4 test-suite test- import: language-settings- type: exitcode-stdio-1.0+ import: base+ type: exitcode-stdio-1.0 hs-source-dirs: test- main-is: Main.hs+ main-is: Main.hs build-depends:- QuickCheck >=2.13 && <3,- quickcheck-instances >=0.3.22 && <0.4,- rerebase <2,- tasty >=1.2.3 && <2,- tasty-hunit >=0.10.0.2 && <0.11,- tasty-quickcheck >=0.10.1 && <0.11,- text-builder,+ , rerebase <2+ , tasty >=1.2.3 && <2+ , tasty-hunit >=0.10.0.2 && <0.11+ , tasty-quickcheck >=0.10.1 && <0.11+ , text-builder benchmark benchmark-text- import: language-settings- type: exitcode-stdio-1.0+ import: base+ type: exitcode-stdio-1.0 hs-source-dirs: benchmark-text- ghc-options: -O2 -threaded "-with-rtsopts=-N" -funbox-strict-fields- main-is: Main.hs+ ghc-options: -O2 -threaded -with-rtsopts=-N -funbox-strict-fields+ main-is: Main.hs build-depends:- criterion >=1.5.6.1 && <2,- rerebase ==1.*,- text-builder,+ , criterion >=1.5.6.1 && <2+ , rerebase >=1 && <2+ , text-builder benchmark benchmark-char- import: language-settings- type: exitcode-stdio-1.0+ import: base+ type: exitcode-stdio-1.0 hs-source-dirs: benchmark-char- ghc-options: -O2 -threaded "-with-rtsopts=-N" -funbox-strict-fields- main-is: Main.hs+ ghc-options: -O2 -threaded -with-rtsopts=-N -funbox-strict-fields+ main-is: Main.hs build-depends:- criterion >=1.5.6.1 && <2,- rerebase ==1.*,- text-builder,+ , criterion >=1.5.6.1 && <2+ , rerebase >=1 && <2+ , text-builder