text-display 0.0.1.0 → 0.0.2.0
raw patch · 5 files changed
+69/−41 lines, 5 filesdep +quickcheck-textdep ~bytestringPVP ok
version bump matches the API change (PVP)
Dependencies added: quickcheck-text
Dependency ranges changed: bytestring
API changes (from Hackage documentation)
Files
- CHANGELOG.md +11/−2
- README.md +5/−2
- src/Data/Text/Display.hs +28/−22
- test/Main.hs +21/−12
- text-display.cabal +4/−3
CHANGELOG.md view
@@ -1,8 +1,17 @@ # CHANGELOG -## [Unreleased]+## [v0.0.2.0] – 13/03/2022 -## [v0.0.1.0] – 20/10/2021+This is an experimental release.++* Typo corrections, documentation improvements+* Fix the String instance (https://github.com/haskell-text/text-display/pull/17)+* Bump dependencies++## [v0.0.1.0] – 2/11/2021++This is an experimental release.+ * Initial release [Unreleased]: https://github.com/kleidukos/text-display/compare/v0.0.1.0...HEAD
README.md view
@@ -4,12 +4,15 @@ </p> <p align="center">-<a href="https://github.com/Kleidukos/text-display/actions"></a>+<a href="https://github.com/Kleidukos/text-display/actions"> <img src="https://img.shields.io/github/workflow/status/Kleidukos/text-display/CI?style=flat-square" alt="CI badge" /> </a> <a href="https://haskell.org"> <img src="https://img.shields.io/badge/Made%20in-Haskell-%235e5086?logo=haskell&style=flat-square" alt="made with Haskell"/> </a>+<a href="https://hackage.haskell.org/package/text-display">+ <img src="https://img.shields.io/hackage/v/text-display?style=flat-square" alt="Hackage" />+</a> </p> <p align="center">@@ -24,7 +27,7 @@ The `text-display` library offers a way for developers to print a textual representation of datatypes that does not have to abide by the rules of the [Show typeclass][Show]. -If you wish to learn more about how things are done and why, please read the [DESIGN.md](./DESIGN.md) file.+If you wish to learn more about how things are done and why, please read the [DESIGN.md](https://github.com/haskell-text/text-display/blob/main/DESIGN.md) file. ## Examples
src/Data/Text/Display.hs view
@@ -11,7 +11,7 @@ {-# LANGUAGE UndecidableInstances #-} {-|- Module : Data.Text.Entity+ Module : Data.Text.Display Copyright : © Hécate Moonlight, 2021 License : MIT Maintainer : hecate@glitchbra.in@@ -41,12 +41,12 @@ import Data.Text (Text) import Data.Text.Lazy.Builder (Builder) import Data.Word-import GHC.Show (showLitString) import GHC.TypeLits import qualified Data.ByteString.Lazy as BL import qualified Data.Text.Lazy.Builder as TB import qualified Data.Text.Lazy.Builder.Int as TB import qualified Data.Text.Lazy.Builder.RealFloat as TB+import qualified Data.Text as T import qualified Data.Text.Lazy as TL import Data.Proxy @@ -67,13 +67,12 @@ -- -- === Example --+ -- > import qualified Data.Text.Lazy.Builder as TB+ -- > -- > instance Display Char where- -- > displayBuilder '\'' = "'\\''"- -- > displayBuilder c = "'" <> TB.singleton c <> "\'"- -- > -- 'displayList' is overloaded, so that when the @Display [a]@ instance calls 'displayList',- -- > -- we end up with a nice string enclosed between double quotes.- -- > displayList cs = TB.fromString $ "\"" <> showLitString cs "\""- --+ -- > displayBuilder c = TB.fromText $ T.singleton c+ -- > displayList cs = TB.fromText $ T.pack cs+ -- > -- > instance Display a => Display [a] where -- > -- In this instance, 'displayBuilder' is defined in terms of 'displayList', which for most types -- > -- is defined as the default written in the class declaration.@@ -151,7 +150,7 @@ -- | 🚫 You should not try to display functions! -- -- 💡 Write a 'newtype' wrapper that represents your domain more accurately.--- If you are not consciously trying to use `display` on a function,+-- If you are not consciously trying to use 'display' on a function, -- make sure that you are not missing an argument somewhere. -- -- @since 0.0.1.0@@ -170,7 +169,7 @@ -- | 🚫 You should not try to display strict ByteStrings! -- -- 💡 Always provide an explicit encoding.--- Use 'Data.Text.Encoding.decudeUtf8'' or 'Data.Text.Encoding.decudeUtf8With' to convert from UTF-8+-- Use 'Data.Text.Encoding.decodeUtf8'' or 'Data.Text.Encoding.decodeUtf8With' to convert from UTF-8 -- -- @since 0.0.1.0 instance CannotDisplayByteStrings => Display ByteString where@@ -179,7 +178,7 @@ -- | 🚫 You should not try to display lazy ByteStrings! -- -- 💡 Always provide an explicit encoding.--- Use 'Data.Text.Encoding.decudeUtf8'' or 'Data.Text.Encoding.decudeUtf8With' to convert from UTF-8+-- Use 'Data.Text.Encoding.decodeUtf8'' or 'Data.Text.Encoding.decodeUtf8With' to convert from UTF-8 -- -- @since 0.0.1.0 instance CannotDisplayByteStrings => Display BL.ByteString where@@ -189,7 +188,7 @@ CannotDisplayByteStrings = TypeError ( 'Text "🚫 You should not try to display ByteStrings!" ':$$: 'Text "💡 Always provide an explicit encoding" ':$$:- 'Text "Use 'Data.Text.Encoding.decudeUtf8'' or 'Data.Text.Encoding.decudeUtf8With' to convert from UTF-8"+ 'Text "Use 'Data.Text.Encoding.decodeUtf8'' or 'Data.Text.Encoding.decodeUtf8With' to convert from UTF-8" ) -- | A utility function that surrounds the given 'Builder' with parentheses when the Bool parameter is True.@@ -274,12 +273,19 @@ deriving via (ShowInstance Bool) instance Display Bool -- | @since 0.0.1.0+-- 'displayList' is overloaded, so that when the @Display [a]@ instance calls 'displayList',+-- we end up with a nice string instead of a list of chars between brackets.+--+-- >>> display [1, 2, 3]+-- "[1,2,3]"+--+-- >>> display ['h', 'e', 'l', 'l', 'o']+-- "hello" instance Display Char where- displayBuilder '\'' = "'\\''"- displayBuilder c = "'" <> TB.singleton c <> "\'"- -- 'displayList' is overloaded, so that when the @Display [a]@ instance calls 'displayList',- -- we end up with a nice string enclosed between double quotes.- displayList cs = TB.fromString $ "\"" <> showLitString cs "\""+ -- This instance's implementation is used in the haddocks of the typeclass.+ -- If you change it, reflect the change in the documentation.+ displayBuilder c = TB.fromText $ T.singleton c+ displayList cs = TB.fromText $ T.pack cs -- | Lazy 'TL.Text' --@@ -381,9 +387,9 @@ -- -- === A “Lawless Typeclass” ----- The `Display` typeclass does not contain any law. This is a controversial choice for some people,+-- The 'Display' typeclass does not contain any law. This is a controversial choice for some people, -- but the truth is that there are not any laws to ask of the consumer that are not already enforced--- by the type system and the internals of the `Data.Text.Internal.Text` type.+-- by the type system and the internals of the 'Data.Text.Internal.Text' type. -- -- === "🚫 You should not try to display functions!" --@@ -394,13 +400,13 @@ -- > If you are not consciously trying to use `display` on a function, -- > make sure that you are not missing an argument somewhere. ----- The `display` library does not allow the definition and usage of `Display` on+-- The 'display' library does not allow the definition and usage of 'Display' on -- bare function types (@(a -> b)@). -- Experience and time have shown that due to partial application being baked in the language, -- many users encounter a partial application-related error message when a simple missing -- argument to a function is the root cause. ----- There may be legitimate uses of a `Display` instance on a function type.+-- There may be legitimate uses of a 'Display' instance on a function type. -- But these usages are extremely dependent on their domain of application. -- That is why it is best to wrap them in a newtype that can better -- express and enforce the domain.@@ -410,5 +416,5 @@ -- An arbitrary ByteStrings cannot be safely converted to text without prior knowledge of its encoding. -- -- As such, in order to avoid dangerously blind conversions, it is recommended to use a specialised--- function such as `Data.Text.Encoding.decudeUtf8'` or `Data.Text.Encoding.decudeUtf8With` if you wish to turn a UTF8-encoded ByteString+-- function such as 'Data.Text.Encoding.decodeUtf8'' or 'Data.Text.Encoding.decodeUtf8With' if you wish to turn a UTF8-encoded ByteString -- to Text.
test/Main.hs view
@@ -8,8 +8,9 @@ import Data.ByteString import Data.List.NonEmpty-import Data.Text (Text) import Test.Hspec+import Test.Hspec.QuickCheck+import Data.Text.Arbitrary import Test.ShouldNotTypecheck (shouldNotTypecheck) import qualified Data.List.NonEmpty as NE import qualified Data.Text as T@@ -34,7 +35,7 @@ spec :: Spec spec = do- describe "Display Tests" $ do+ describe "Display Tests:" $ do it "Display instance for Text stays the same" $ display ("3" :: Text) `shouldBe` ("3" :: Text) it "Deriving via its own Show instance works" $@@ -59,20 +60,24 @@ T.unpack (display nestedMaybe) `shouldBe` show nestedMaybe it "Nothing instance is equivalent to Show" $ do T.unpack (display (Nothing @Bool)) `shouldBe` show (Nothing @Bool)- it "String instance is equivalent to Show" $ do- let string = "Bonjour \"tout le monde\" !" :: String- T.unpack (display string) `shouldBe` show string- it "Char 'c' instance is equivalent to Show" $ do- T.unpack (display 'c') `shouldBe` show 'c'- it "Char '\'' instance is equivalent to Show" $ do- T.unpack (display '\'') `shouldBe` show '\''+ it "Char '\'' instance is equivalent to Text" $ do+ display '\'' `shouldBe` T.singleton '\'' it "2-Tuple instance is equivalent to Show" $ do let tuple = (1 :: Int, True) T.unpack (display tuple) `shouldBe` show tuple it "3-Tuple instance is equivalent to Show" $ do let tuple = (1 :: Int, True, "hahahha" :: String)- T.unpack (display tuple) `shouldBe` show tuple+ display tuple `shouldBe` "(" <> display (1 :: Int) <> "," <> display True <> "," <> display @String "hahahha" <> ")" + describe "Display props:" $ do+ prop "Text instance stays the same" $ do+ \string -> display (string :: Text) `shouldBe` string+ prop "String instance is equivalent to Text" $ do+ \string -> display (string :: String) `shouldBe` T.pack string+ prop "Chars are packed" $+ \c -> display (c :: Char) `shouldBe` T.singleton c++ describe "Forbidden instances" $ do it "Should not compile for a function instance" $ shouldNotTypecheck (display id) `shouldThrow` anyErrorCall it "Should not compile for ByteStrings" $@@ -80,7 +85,11 @@ in shouldNotTypecheck (display bs) `shouldThrow` anyErrorCall describe "displayParen tests" $ do- it "surrounds with parens when True" $+ it "Surrounds with parens when True" $ displayParen True "foo" `shouldBe` "(foo)"- it "doesn't surround with parens when False" $+ it "Doesn't surround with parens when False" $ displayParen False "foo" `shouldBe` "foo"+ it "Surrounds deeply-nested Maybes with a prec of 10" $+ displayPrec 10 (Just (Just (Just (3 :: Int)))) `shouldBe` "Just (Just (Just 3))"+ it "Surrounds deeply-nested Maybes with a prec of 11" $+ displayPrec 11 (Just (Just (Just (3 :: Int)))) `shouldBe` "(Just (Just (Just 3)))"
text-display.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: text-display-version: 0.0.1.0+version: 0.0.2.0 category: Text synopsis: A typeclass for user-facing output description:@@ -41,8 +41,8 @@ hs-source-dirs: src exposed-modules: Data.Text.Display build-depends:- , base >= 4.12 && <= 5- , bytestring ^>=0.11+ , base >=4.12 && <= 5+ , bytestring ^>=0.10 || ^>=0.11 , text ^>=1.2 test-suite text-display-test@@ -59,3 +59,4 @@ , hspec , text , should-not-typecheck+ , quickcheck-text