packages feed

debug-print (empty) → 0.0.0.0

raw patch · 11 files changed

+412/−0 lines, 11 filesdep +aesondep +basedep +containers

Dependencies added: aeson, base, containers, debug-print, hspec, markdown-unlit, text, vector

Files

+ CHANGELOG.md view
@@ -0,0 +1,5 @@+## [_Unreleased_](https://github.com/freckle/debug-print/compare/v0.0.0.0...main)++## [v0.0.0.0](https://github.com/freckle/debug-print/tree/v0.0.0.0)++First tagged release.
+ LICENSE view
@@ -0,0 +1,21 @@+The MIT License (MIT)++Copyright (c) 2025 Renaissance Learning Inc++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+SOFTWARE.
+ README.lhs view
@@ -0,0 +1,48 @@+# debug-print++Offers `ToDebugPrintValue`, a structured alternative to `Show`+for printing values for testing and debugging purposes.++<!--+```haskell+module Main (main) where++import Prelude++import Data.Text (Text)+import GHC.Generics (Generic)+import Text.Markdown.Unlit ()+import Test.Hspec+```+-->++```haskell+import DebugPrint+import DebugPrint.Aeson+import Data.Aeson qualified as Aeson+```++```haskell+data Report = Report+  { milliseconds :: Int+  , errors :: [Text]+  }+  deriving stock Generic+  deriving anyclass (ToDebugPrintRecord, ToDebugPrintValue)++report :: Report+report = Report{ milliseconds = 5_824+               , errors = ["Warning! Problems."] }+```++```haskell+main :: IO ()+main = hspec $ do+  it "" $ do+    Aeson.encode (debugPrintValueToAeson report) `shouldBe`+      "{\"errors\":[\"Warning! Problems.\"],\"milliseconds\":5824}"+```++---++[LICENSE](./LICENSE) | [CHANGELOG](./CHANGELOG.md)
+ README.md view
@@ -0,0 +1,48 @@+# debug-print++Offers `ToDebugPrintValue`, a structured alternative to `Show`+for printing values for testing and debugging purposes.++<!--+```haskell+module Main (main) where++import Prelude++import Data.Text (Text)+import GHC.Generics (Generic)+import Text.Markdown.Unlit ()+import Test.Hspec+```+-->++```haskell+import DebugPrint+import DebugPrint.Aeson+import Data.Aeson qualified as Aeson+```++```haskell+data Report = Report+  { milliseconds :: Int+  , errors :: [Text]+  }+  deriving stock Generic+  deriving anyclass (ToDebugPrintRecord, ToDebugPrintValue)++report :: Report+report = Report{ milliseconds = 5_824+               , errors = ["Warning! Problems."] }+```++```haskell+main :: IO ()+main = hspec $ do+  it "" $ do+    Aeson.encode (debugPrintValueToAeson report) `shouldBe`+      "{\"errors\":[\"Warning! Problems.\"],\"milliseconds\":5824}"+```++---++[LICENSE](./LICENSE) | [CHANGELOG](./CHANGELOG.md)
+ debug-print.cabal view
@@ -0,0 +1,79 @@+cabal-version:   1.18+name:            debug-print+version:         0.0.0.0+license:         MIT+license-file:    LICENSE+maintainer:      Freckle Education+homepage:        https://github.com/freckle/debug-print#readme+bug-reports:     https://github.com/freckle/debug-print/issues+synopsis:        A structured alternative to Show+category:        Debug+build-type:      Simple+extra-doc-files:+    README.md+    CHANGELOG.md++source-repository head+    type:     git+    location: https://github.com/freckle/debug-print++library+    exposed-modules:+        DebugPrint+        DebugPrint.Aeson+        DebugPrint.Class+        DebugPrint.Show+        DebugPrint.Tagged+        DebugPrint.Types++    hs-source-dirs:     library+    other-modules:      Paths_debug_print+    default-language:   GHC2021+    default-extensions:+        DefaultSignatures DeriveAnyClass DerivingVia NoFieldSelectors+        NoImplicitPrelude NoMonomorphismRestriction OverloadedStrings+        StrictData++    ghc-options:+        -Weverything -Wno-all-missed-specialisations+        -Wno-missing-import-lists -Wno-missing-kind-signatures+        -Wno-missing-safe-haskell-mode -Wno-safe -Wno-unsafe++    build-depends:+        aeson >=2.2.3.0,+        base >=4.19.2.0 && <5,+        containers >=0.6.8,+        text >=2.1.1,+        vector >=0.13.2.0++    if impl(ghc >=9.8)+        ghc-options:+            -Wno-missing-role-annotations -Wno-missing-poly-kind-signatures++test-suite readme+    type:               exitcode-stdio-1.0+    main-is:            README.lhs+    other-modules:      Paths_debug_print+    default-language:   GHC2021+    default-extensions:+        DefaultSignatures DeriveAnyClass DerivingVia NoFieldSelectors+        NoImplicitPrelude NoMonomorphismRestriction OverloadedStrings+        StrictData++    ghc-options:+        -Weverything -Wno-all-missed-specialisations+        -Wno-missing-import-lists -Wno-missing-kind-signatures+        -Wno-missing-safe-haskell-mode -Wno-safe -Wno-unsafe -pgmL+        markdown-unlit++    build-depends:+        aeson >=2.2.3.0,+        base >=4.19.2.0 && <5,+        debug-print,+        hspec >=2.11.11,+        markdown-unlit >=0.6.0,+        text >=2.1.1++    if impl(ghc >=9.8)+        ghc-options:+            -Wno-missing-role-annotations -Wno-missing-poly-kind-signatures
+ library/DebugPrint.hs view
@@ -0,0 +1,9 @@+module DebugPrint+  ( DebugPrintValue (..)+  , DebugPrintRecord (..)+  , ToDebugPrintValue (..)+  , ToDebugPrintRecord (..)+  ) where++import DebugPrint.Class+import DebugPrint.Types
+ library/DebugPrint/Aeson.hs view
@@ -0,0 +1,29 @@+module DebugPrint.Aeson+  ( debugPrintRecordToAeson+  , debugPrintValueToAeson+  ) where++import Prelude++import Data.Aeson qualified as Aeson+import Data.Aeson.Key qualified as Key+import Data.Aeson.KeyMap qualified as KeyMap+import Data.Bifunctor (bimap)+import Data.Map.Strict qualified as Map+import DebugPrint.Class+import DebugPrint.Types++debugPrintRecordToAeson :: ToDebugPrintRecord a => a -> Aeson.Object+debugPrintRecordToAeson a =+  let DebugPrintRecord m = toDebugPrintRecord a+  in  KeyMap.fromList+        $ bimap Key.fromText debugPrintValueToAeson+          <$> Map.toList m++debugPrintValueToAeson :: ToDebugPrintValue a => a -> Aeson.Value+debugPrintValueToAeson a = case toDebugPrintValue a of+  DebugPrintValueInt x -> Aeson.Number $ fromIntegral x+  DebugPrintValueText x -> Aeson.String x+  DebugPrintValueBool x -> Aeson.Bool x+  DebugPrintValueVector x -> Aeson.Array $ fmap debugPrintValueToAeson x+  DebugPrintValueRecord x -> Aeson.Object $ debugPrintRecordToAeson x
+ library/DebugPrint/Class.hs view
@@ -0,0 +1,109 @@+-- | Generic-derivable classes for converting to 'DebugPrintRecord' and 'Value'+--+-- These classes are designed to be used only for pretty-printing in tests+-- and logging. They should generally be used anywhere you would derive 'Show'.+module DebugPrint.Class+  ( ToDebugPrintValue (..)+  , ToDebugPrintRecord (..)+  , ToDebugPrintValueRep+  , ToDebugPrintRecordRep+  ) where++import Prelude++import Data.Foldable (toList)+import Data.Kind (Type)+import Data.List.NonEmpty (NonEmpty)+import Data.Map.Strict qualified as Map+import Data.Sequence (Seq)+import Data.Text qualified as T+import Data.Text.Lazy qualified as TL+import Data.Vector (Vector)+import Data.Vector qualified as V+import DebugPrint.Types+import GHC.Generics+import Numeric.Natural (Natural)++class ToDebugPrintValue a where+  toDebugPrintValue :: a -> DebugPrintValue+  default toDebugPrintValue+    :: (Generic a, ToDebugPrintRecordRep (Rep a)) => a -> DebugPrintValue+  toDebugPrintValue = DebugPrintValueRecord . gToRecord . from++instance ToDebugPrintValue DebugPrintValue where+  toDebugPrintValue = id++instance ToDebugPrintValue Int where+  toDebugPrintValue = DebugPrintValueInt++instance ToDebugPrintValue Char where+  toDebugPrintValue = DebugPrintValueText . T.singleton++instance ToDebugPrintValue Natural where+  toDebugPrintValue = DebugPrintValueInt . fromIntegral++instance ToDebugPrintValue T.Text where+  toDebugPrintValue = DebugPrintValueText++instance ToDebugPrintValue TL.Text where+  toDebugPrintValue = DebugPrintValueText . TL.toStrict++instance ToDebugPrintValue Bool where+  toDebugPrintValue = DebugPrintValueBool++instance ToDebugPrintValue a => ToDebugPrintValue (Maybe a) where+  toDebugPrintValue = toDebugPrintValue . toList++instance ToDebugPrintValue a => ToDebugPrintValue [a] where+  toDebugPrintValue = toDebugPrintValue . V.fromList++instance ToDebugPrintValue a => ToDebugPrintValue (NonEmpty a) where+  toDebugPrintValue = toDebugPrintValue . toList++instance ToDebugPrintValue a => ToDebugPrintValue (Seq a) where+  toDebugPrintValue = toDebugPrintValue . toList++instance ToDebugPrintValue a => ToDebugPrintValue (Vector a) where+  toDebugPrintValue = DebugPrintValueVector . fmap toDebugPrintValue++---++class ToDebugPrintRecord a where+  toDebugPrintRecord :: a -> DebugPrintRecord+  default toDebugPrintRecord+    :: (Generic a, ToDebugPrintRecordRep (Rep a)) => a -> DebugPrintRecord+  toDebugPrintRecord = gToRecord . from++instance ToDebugPrintRecord DebugPrintRecord where+  toDebugPrintRecord = id++---++class ToDebugPrintValueRep (f :: Type -> Type) where+  gToValue :: f a -> DebugPrintValue++instance ToDebugPrintValue a => ToDebugPrintValueRep (K1 i a) where+  gToValue (K1 x) = toDebugPrintValue x++---++class ToDebugPrintRecordRep (f :: Type -> Type) where+  gToRecord :: f a -> DebugPrintRecord++instance ToDebugPrintRecordRep U1 where+  gToRecord _ = DebugPrintRecord mempty++instance+  (ToDebugPrintRecordRep f, ToDebugPrintRecordRep g)+  => ToDebugPrintRecordRep (f :*: g)+  where+  gToRecord (x :*: y) = gToRecord x <> gToRecord y++instance ToDebugPrintRecordRep f => ToDebugPrintRecordRep (D1 i f) where+  gToRecord (M1 x) = gToRecord x++instance ToDebugPrintRecordRep f => ToDebugPrintRecordRep (C1 i f) where+  gToRecord (M1 x) = gToRecord x++instance (Selector s, ToDebugPrintValueRep f) => ToDebugPrintRecordRep (S1 s f) where+  gToRecord s1@(M1 x) = DebugPrintRecord $ Map.singleton (T.pack (selName s1)) (gToValue x)
+ library/DebugPrint/Show.hs view
@@ -0,0 +1,16 @@+module DebugPrint.Show+  ( DebugShow (..)+  ) where++import Prelude++import Data.Text qualified as T+import DebugPrint.Class++-- | For use with deriving-via, provides a simple 'ToDebugPrintValue'+--   instance based on 'Show' which renders as text+newtype DebugShow a = DebugShow a++instance Show a => ToDebugPrintValue (DebugShow a) where+  toDebugPrintValue (DebugShow x) =+    toDebugPrintValue $ T.pack $ show x
+ library/DebugPrint/Tagged.hs view
@@ -0,0 +1,19 @@+module DebugPrint.Tagged+  ( tag+  , Tagged (..)+  ) where++import Prelude++import Data.Text qualified as T+import DebugPrint.Class+import DebugPrint.Types+import GHC.Generics (Generic)++-- | Useful for debug-printing discriminated unions+data Tagged = Tagged {tag :: T.Text, value :: DebugPrintValue}+  deriving stock (Generic)+  deriving anyclass (ToDebugPrintRecord, ToDebugPrintValue)++tag :: ToDebugPrintValue a => T.Text -> a -> DebugPrintValue+tag t = toDebugPrintValue . Tagged t . toDebugPrintValue
+ library/DebugPrint/Types.hs view
@@ -0,0 +1,29 @@+-- | A general structure to which data values may be converted+--+-- This is often useful for testing and logging to get an output that is+-- more structured and better pretty-printed than what 'show' can offer.+module DebugPrint.Types+  ( DebugPrintRecord (..)+  , DebugPrintValue (..)+  ) where++import Prelude++import Data.Map (Map)+import Data.String (IsString (..))+import Data.Text (Text)+import Data.Text qualified as T+import Data.Vector (Vector)++newtype DebugPrintRecord = DebugPrintRecord (Map Text DebugPrintValue)+  deriving newtype (Monoid, Semigroup)++data DebugPrintValue+  = DebugPrintValueInt Int+  | DebugPrintValueText Text+  | DebugPrintValueBool Bool+  | DebugPrintValueVector (Vector DebugPrintValue)+  | DebugPrintValueRecord DebugPrintRecord++instance IsString DebugPrintValue where+  fromString = DebugPrintValueText . T.pack