    {-# 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 :: Builder -> Builder
    fromBuilder = Builder -> Builder
    forall a. a -> a
    id
      {-# INLINE fromBuilder #-}

    instance FromBuilder TL.Text where
      fromBuilder :: Builder -> Text
    fromBuilder = Builder -> Text
    TL.toLazyText
      {-# INLINE fromBuilder #-}

    instance FromBuilder T.Text where
      fromBuilder :: Builder -> Text
    fromBuilder = Text -> Text
    TL.toStrict (Text -> Text) -> (Builder -> Text) -> Builder -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Builder -> Text
    TL.toLazyText
      {-# INLINE fromBuilder #-}

    instance FromBuilder [Char] where
      fromBuilder :: Builder -> [Char]
    fromBuilder = Text -> [Char]
    TL.unpack (Text -> [Char]) -> (Builder -> Text) -> Builder -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Builder -> Text
    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 :: forall t o a. FromBuilder t => (t -> o) -> Format o a -> a
    formatted t -> o
    k Format o a
    f = Format o a -> (Builder -> o) -> a
    forall r a. Format r a -> (Builder -> r) -> a
    runFormat Format o a
    f (t -> o
    k (t -> o) -> (Builder -> t) -> Builder -> o
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Builder -> t
    forall a. FromBuilder a => Builder -> a
    fromBuilder)