{-# LANGUAGE FlexibleInstances #-} module Formatting.FromBuilder ( FromBuilder(..) , formatted ) where import qualified Data.Text as T import qualified Data.Text.Lazy as TL import Data.Text.Lazy.Builder (Builder) import qualified Data.Text.Lazy.Builder as TL import Formatting.Internal (Format (..)) -- $setup -- >>> import qualified Data.Text.Lazy as TL (Text) -- >>> import qualified Data.Text.Lazy.IO as TL -- >>> import qualified Data.Text as T (Text) -- >>> import qualified Data.Text.IO as T -- >>> import Formatting ((%)) -- >>> import Formatting.Formatters (int) -- >>> :set -XOverloadedStrings -- >>> :set -XTypeApplications -- | Anything that can be created from a 'Builder'. -- This class makes it easier to add formatting to other API's. -- See 'formatted' for some examples of this class in action. class FromBuilder a where fromBuilder :: Builder -> a instance FromBuilder Builder where fromBuilder = id {-# INLINE fromBuilder #-} instance FromBuilder TL.Text where fromBuilder = TL.toLazyText {-# INLINE fromBuilder #-} instance FromBuilder T.Text where fromBuilder = TL.toStrict . TL.toLazyText {-# INLINE fromBuilder #-} instance FromBuilder [Char] where fromBuilder = TL.unpack . TL.toLazyText {-# INLINE fromBuilder #-} -- | Makes it easy to add formatting to any api that is expecting a builder, -- a strict or lazy text, or a string. -- It is essentially (flip runFormat), but with a more generous type due to -- the typeclass. -- -- For example: -- >>> formatted TL.putStr ("x is: " % int % "\n") 7 -- x is: 7 -- >>> formatted T.putStr ("x is: " % int % "\n") 7 -- x is: 7 -- >>> formatted (id @TL.Text) ("x is: " % int % "\n") 7 -- "x is: 7\n" -- >>> formatted (id @T.Text) ("x is: " % int % "\n") 7 -- "x is: 7\n" formatted :: FromBuilder t => (t -> o) -> Format o a -> a formatted k f = runFormat f (k . fromBuilder)