fmt 0.1.0.0 → 0.2.0.0
raw patch · 4 files changed
+45/−30 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Fmt.Internal: class FormatType r
+ Fmt.Internal: format' :: FormatType r => Format -> [Builder] -> r
+ Fmt.Internal: instance (Data.Text.Buildable.Buildable a, Fmt.Internal.FormatType r) => Fmt.Internal.FormatType (a -> r)
+ Fmt.Internal: instance Fmt.Internal.FromBuilder r => Fmt.Internal.FormatType r
- Fmt: build :: p -> Builder
+ Fmt: build :: Buildable p => p -> Builder
- Fmt: format :: (FromBuilder b, Params ps) => Format -> ps -> b
+ Fmt: format :: FormatType r => Format -> r
- Fmt: formatLn :: (FromBuilder b, Params ps) => Format -> ps -> b
+ Fmt: formatLn :: FormatType r => Format -> r
Files
- CHANGELOG.md +4/−0
- fmt.cabal +1/−1
- lib/Fmt.hs +13/−21
- lib/Fmt/Internal.hs +27/−8
CHANGELOG.md view
@@ -1,3 +1,7 @@+# 0.2.0.0++* Changed `format` and `formatLn` to be polyvariadic.+ # 0.1.0.0 * Added `genericF` for formatting arbitrary data.
fmt.cabal view
@@ -1,5 +1,5 @@ name: fmt-version: 0.1.0.0+version: 0.2.0.0 synopsis: A new formatting library description: A new formatting library that tries to be simple to understand while still
lib/Fmt.hs view
@@ -158,7 +158,6 @@ -- 'Buildable' and text-format import Data.Text.Buildable import qualified Data.Text.Format as TF-import qualified Data.Text.Format.Params as TF -- Text 'Builder' import Data.Text.Lazy.Builder hiding (fromString) -- 'Foldable' and 'IsList' for list/map formatters@@ -449,31 +448,24 @@ {- | An old-style formatting function taken from @text-format@ (see "Data.Text.Format"). Unlike 'Data.Text.Format.format' from "Data.Text.Format", it can produce 'String' and strict 'Text' as well (and-print to console too).--To provide substitution arguments, use a tuple:+print to console too). Also it's polyvariadic: ->>> format "{} + {} = {}" (2, 2, 4)+>>> format "{} + {} = {}" 2 2 4 "2 + 2 = 4" You can use arbitrary formatters: ->>> format "0x{} + 0x{} = 0x{}" (hexF 130, hexF 270, hexF (130+270))-"2 + 2 = 4"--To provide just one argument, use a list instead of a tuple:-->>> format "Hello {}!" ["world"]-"Hello world!"+>>> format "0x{} + 0x{} = 0x{}" (hexF 130) (hexF 270) (hexF (130+270))+"0x82 + 0x10e = 0x190" -}-format :: (FromBuilder b, TF.Params ps) => TF.Format -> ps -> b-format f ps = fromBuilder (TF.build f ps)+format :: FormatType r => TF.Format -> r+format f = format' f [] {-# INLINE format #-} {- | Like 'format', but adds a newline. -}-formatLn :: (FromBuilder b, TF.Params ps) => TF.Format -> ps -> b-formatLn f ps = fromBuilder (TF.build f ps <> "\n")+formatLn :: FormatType r => TF.Format -> r+formatLn f = format' (f <> "\n") [] {-# INLINE formatLn #-} ----------------------------------------------------------------------------@@ -1189,11 +1181,11 @@ -- * And ":|" can be prefix when defined as "(:|) a b" gbuild c@(M1 x) = case conFixity c of Infix _ _- | [a, b] <- fields -> format "({} {} {})" (a, infixName, b)+ | [a, b] <- fields -> format "({} {} {})" a infixName b -- this case should never happen, but still | otherwise -> format "<{}: {}>"- ( prefixName- , mconcat (intersperse ", " fields) )+ prefixName+ (mconcat (intersperse ", " fields)) Prefix | isTuple -> tupleLikeF fields | conIsRecord c -> nameF (build prefixName) (blockMapF fieldsWithNames)@@ -1201,8 +1193,8 @@ -- I believe that there will be only one field in this case | null (conName c) -> mconcat (intersperse ", " fields) | otherwise -> format "<{}: {}>"- ( prefixName- , mconcat (intersperse ", " fields) )+ prefixName+ (mconcat (intersperse ", " fields)) where (prefixName, infixName) | ":" `isPrefixOf` conName c = ("(" ++ conName c ++ ")", conName c)
lib/Fmt/Internal.hs view
@@ -4,9 +4,16 @@ {-# LANGUAGE GADTs #-} {-# LANGUAGE CPP #-} --- for FormatAsHex+-- for FormatAsHex and FormatType #if __GLASGOW_HASKELL__ < 710 {-# LANGUAGE OverlappingInstances #-}+# define _OVERLAPPING_+# define _OVERLAPPABLE_+# define _OVERLAPS_+#else+# define _OVERLAPPING_ {-# OVERLAPPING #-}+# define _OVERLAPPABLE_ {-# OVERLAPPABLE #-}+# define _OVERLAPS_ {-# OVERLAPS #-} #endif {- | A module providing access to internals (in case you really need them). Can@@ -25,6 +32,9 @@ GetFields(..), Buildable'(..), + -- * Polyvariadic 'format'+ FormatType(..),+ -- * Helpers groupInt, atBase,@@ -109,13 +119,8 @@ instance FormatAsHex BSL.ByteString where hexF = fromLazyText . TL.decodeLatin1 . B16L.encode -#if __GLASGOW_HASKELL__ >= 710-instance {-# OVERLAPPABLE #-} Integral a => FormatAsHex a where- hexF = TF.hex-#else-instance Integral a => FormatAsHex a where+instance _OVERLAPPABLE_ Integral a => FormatAsHex a where hexF = TF.hex-#endif ---------------------------------------------------------------------------- -- Base64@@ -128,7 +133,7 @@ >>> base64F ("\0\50\63\80" :: BS.ByteString) "ADI/UA==" -}- base64F :: a -> Builder+ base64F :: a -> Builder {- | Convert a bytestring to base64url (a variant of base64 which omits @\/@ and thus can be used in URLs):@@ -186,6 +191,20 @@ -- tuples, lists, maps, etc., as well as combinations thereof. class Buildable' a where build' :: a -> Builder++----------------------------------------------------------------------------+-- Classes used for polyvariadic 'format'+----------------------------------------------------------------------------++-- | Something like 'Text.Printf.PrintfType' in "Text.Printf".+class FormatType r where+ format' :: TF.Format -> [Builder] -> r++instance (Buildable a, FormatType r) => FormatType (a -> r) where+ format' f xs = \x -> format' f (build x : xs)++instance _OVERLAPPABLE_ FromBuilder r => FormatType r where+ format' f xs = fromBuilder $ TF.build f (reverse xs) ---------------------------------------------------------------------------- -- Helpers