diff --git a/.github/workflows/hlint.yaml b/.github/workflows/hlint.yaml index 2508ee3..aa85604 100644 --- a/.github/workflows/hlint.yaml +++ b/.github/workflows/hlint.yaml @@ -6,3 +6,5 @@ jobs: steps: - uses: actions/checkout@v2 - uses: tfausak/hlint-action@v1 + with: + config: config/hlint.yaml diff --git a/.gitignore b/.gitignore index 064ab2b..cdd1392 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,5 @@ -/.cabal-sandbox/ -/.ghc.environment* /.stack-work/ /cabal.project.freeze /cabal.project.local* -/cabal.sandbox.config /dist-newstyle/ -/dist/ /stack.yaml.lock diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..c089f68 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "taylorfausak.purple-yolk" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json index e7cfef6..8b1060f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,13 +1,6 @@ { "purple-yolk.brittany.command": "brittany --config-file config/brittany.yaml --write-mode inplace", - "purple-yolk.ghci.command": "cabal repl --ghc-options -Wwarn --repl-options -ddump-json", - "purple-yolk.hlint.command": "hlint --json --no-exit-code", - "purple-yolk.hlint.onSave": true, - "editor.rulers": [ - 79 - ], - "editor.tabSize": 2, - "files.trimTrailingWhitespace": true, - "files.insertFinalNewline": true, - "files.trimFinalNewlines": true + "purple-yolk.ghci.command": "cabal repl --repl-options -ddump-json", + "purple-yolk.hlint.command": "hlint --hint config/hlint.yaml --json --no-exit-code", + "purple-yolk.hlint.onSave": true } diff --git a/LICENSE.markdown b/LICENSE.markdown new file mode 100644 index 0000000..6b302e2 --- /dev/null +++ b/LICENSE.markdown @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Taylor Fausak + +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. diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index f32ab92..0000000 --- a/LICENSE.txt +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2021 Taylor Fausak - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. diff --git a/config/brittany.yaml b/config/brittany.yaml index b85e4ad..5cd9d88 100644 --- a/config/brittany.yaml +++ b/config/brittany.yaml @@ -1,4 +1,4 @@ conf_layout: - lconfig_columnAlignMode: - tag: ColumnAlignModeDisabled + lconfig_cols: 79 + lconfig_columnAlignMode: { tag: ColumnAlignModeDisabled } lconfig_indentPolicy: IndentPolicyLeft diff --git a/config/hlint.yaml b/config/hlint.yaml new file mode 100644 index 0000000..abe5f23 --- /dev/null +++ b/config/hlint.yaml @@ -0,0 +1,4 @@ +- group: { name: dollar, enabled: true } +- group: { name: generalise, enabled: true } +- ignore: { name: Use lambda-case } +- ignore: { name: Use tuple-section } diff --git a/src/ghc-8.10/Witch/Lift.hs b/source/ghc-8.10/Witch/Lift.hs similarity index 100% rename from src/ghc-8.10/Witch/Lift.hs rename to source/ghc-8.10/Witch/Lift.hs diff --git a/src/ghc-8.8/Witch/Lift.hs b/source/ghc-8.8/Witch/Lift.hs similarity index 100% rename from src/ghc-8.8/Witch/Lift.hs rename to source/ghc-8.8/Witch/Lift.hs diff --git a/src/ghc-9.0/Witch/Lift.hs b/source/ghc-9.0/Witch/Lift.hs similarity index 100% rename from src/ghc-9.0/Witch/Lift.hs rename to source/ghc-9.0/Witch/Lift.hs diff --git a/src/lib/Witch.hs b/source/library/Witch.hs similarity index 100% rename from src/lib/Witch.hs rename to source/library/Witch.hs diff --git a/src/lib/Witch/From.hs b/source/library/Witch/From.hs similarity index 100% rename from src/lib/Witch/From.hs rename to source/library/Witch/From.hs diff --git a/src/lib/Witch/Instances.hs b/source/library/Witch/Instances.hs similarity index 99% rename from src/lib/Witch/Instances.hs rename to source/library/Witch/Instances.hs index 9fe74f9..dd00f8b 100644 --- a/src/lib/Witch/Instances.hs +++ b/source/library/Witch/Instances.hs @@ -634,8 +634,9 @@ instance TryFrom.TryFrom Word.Word64 Float where -- | Uses 'fromIntegral' when the input is less than or equal to -- 9,007,199,254,740,991. instance TryFrom.TryFrom Word.Word64 Double where - tryFrom = Utility.eitherTryFrom $ \s -> - if s <= maxDouble then Right $ fromIntegral s else Left Exception.Overflow + tryFrom = Utility.eitherTryFrom $ \s -> if s <= maxDouble + then Right $ fromIntegral s + else Left Exception.Overflow -- Word @@ -750,8 +751,9 @@ instance TryFrom.TryFrom Natural.Natural Float where -- | Uses 'fromIntegral' when the input is less than or equal to -- 9,007,199,254,740,991. instance TryFrom.TryFrom Natural.Natural Double where - tryFrom = Utility.eitherTryFrom $ \s -> - if s <= maxDouble then Right $ fromIntegral s else Left Exception.Overflow + tryFrom = Utility.eitherTryFrom $ \s -> if s <= maxDouble + then Right $ fromIntegral s + else Left Exception.Overflow -- Float diff --git a/src/lib/Witch/TryFrom.hs b/source/library/Witch/TryFrom.hs similarity index 100% rename from src/lib/Witch/TryFrom.hs rename to source/library/Witch/TryFrom.hs diff --git a/src/lib/Witch/TryFromException.hs b/source/library/Witch/TryFromException.hs similarity index 100% rename from src/lib/Witch/TryFromException.hs rename to source/library/Witch/TryFromException.hs diff --git a/src/lib/Witch/Utility.hs b/source/library/Witch/Utility.hs similarity index 100% rename from src/lib/Witch/Utility.hs rename to source/library/Witch/Utility.hs diff --git a/src/test/Main.hs b/source/test-suite/Main.hs similarity index 95% rename from src/test/Main.hs rename to source/test-suite/Main.hs index 5c23f9c..e3aab70 100644 --- a/src/test/Main.hs +++ b/source/test-suite/Main.hs @@ -35,7 +35,8 @@ main :: IO () main = runTestTTAndExit $ "Witch" - ~: [ "From" ~: ["from" ~: [Witch.from (1 :: Int.Int8) ~?= (1 :: Int.Int16)]] + ~: [ "From" + ~: ["from" ~: [Witch.from (1 :: Int.Int8) ~?= (1 :: Int.Int16)]] , "TryFrom" ~: [ "tryFrom" ~: let f = hush . Witch.tryFrom @Int.Int16 @Int.Int8 @@ -170,16 +171,20 @@ main = in [f 0 ~?= Just 0, f 127 ~?= Just 127, f (-1) ~?= Nothing] , "TryFrom Int16 Word32" ~: let f = hush . Witch.tryFrom @Int.Int16 @Word.Word32 - in [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f (-1) ~?= Nothing] + in + [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f (-1) ~?= Nothing] , "TryFrom Int16 Word64" ~: let f = hush . Witch.tryFrom @Int.Int16 @Word.Word64 - in [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f (-1) ~?= Nothing] + in + [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f (-1) ~?= Nothing] , "TryFrom Int16 Word" ~: let f = hush . Witch.tryFrom @Int.Int16 @Word - in [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f (-1) ~?= Nothing] + in + [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f (-1) ~?= Nothing] , "TryFrom Int16 Natural" ~: let f = hush . Witch.tryFrom @Int.Int16 @Natural.Natural - in [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f (-1) ~?= Nothing] + in + [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f (-1) ~?= Nothing] , "From Int16 Float" ~: let f = Witch.from @Int.Int16 @Float in [f 0 ~?= 0, f 32767 ~?= 32767, f (-32768) ~?= (-32768)] @@ -323,7 +328,8 @@ main = , let x = maxBound :: Int in if toInteger x >= 9223372036854775807 - then f 9223372036854775807 ~?= Just 9223372036854775807 + then f 9223372036854775807 + ~?= Just 9223372036854775807 else f (fromIntegral x) ~?= Just x , let x = minBound :: Int in @@ -376,7 +382,8 @@ main = , let x = maxBound :: Word in if toInteger x >= 9223372036854775807 - then f 9223372036854775807 ~?= Just 9223372036854775807 + then f 9223372036854775807 + ~?= Just 9223372036854775807 else f (fromIntegral x) ~?= Just x , f (-1) ~?= Nothing ] @@ -535,7 +542,8 @@ main = , let x = minBound :: Int in if toInteger x <= (-9007199254740991) - then f (-9007199254740991) ~?= Just (-9007199254740991) + then f (-9007199254740991) + ~?= Just (-9007199254740991) else f x ~?= Just (fromIntegral x) , let x = minBound :: Int in @@ -586,9 +594,11 @@ main = in [ f 0 ~?= Just 0 , let x = maxBound :: Int in f (fromIntegral x) ~?= Just x - , let x = toInteger (maxBound :: Int) + 1 in f x ~?= Nothing + , let x = toInteger (maxBound :: Int) + 1 + in f x ~?= Nothing , let x = minBound :: Int in f (fromIntegral x) ~?= Just x - , let x = toInteger (minBound :: Int) - 1 in f x ~?= Nothing + , let x = toInteger (minBound :: Int) - 1 + in f x ~?= Nothing ] , "TryFrom Integer Word8" ~: let f = hush . Witch.tryFrom @Integer @Word.Word8 @@ -720,7 +730,10 @@ main = , "TryFrom Word16 Int16" ~: let f = hush . Witch.tryFrom @Word.Word16 @Int.Int16 in - [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f 32768 ~?= Nothing] + [ f 0 ~?= Just 0 + , f 32767 ~?= Just 32767 + , f 32768 ~?= Nothing + ] , "From Word16 Int32" ~: let f = Witch.from @Word.Word16 @Int.Int32 in [f 0 ~?= 0, f 65535 ~?= 65535] @@ -747,7 +760,10 @@ main = , "TryFrom Word32 Word16" ~: let f = hush . Witch.tryFrom @Word.Word32 @Word.Word16 in - [f 0 ~?= Just 0, f 65535 ~?= Just 65535, f 65536 ~?= Nothing] + [ f 0 ~?= Just 0 + , f 65535 ~?= Just 65535 + , f 65536 ~?= Nothing + ] , "From Word32 Word64" ~: let f = Witch.from @Word.Word32 @Word.Word64 in [f 0 ~?= 0, f 4294967295 ~?= 4294967295] @@ -763,7 +779,10 @@ main = , "TryFrom Word32 Int16" ~: let f = hush . Witch.tryFrom @Word.Word32 @Int.Int16 in - [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f 32768 ~?= Nothing] + [ f 0 ~?= Just 0 + , f 32767 ~?= Just 32767 + , f 32768 ~?= Nothing + ] , "TryFrom Word32 Int32" ~: let f = hush . Witch.tryFrom @Word.Word32 @Int.Int32 in @@ -805,7 +824,10 @@ main = , "TryFrom Word64 Word16" ~: let f = hush . Witch.tryFrom @Word.Word64 @Word.Word16 in - [f 0 ~?= Just 0, f 65535 ~?= Just 65535, f 65536 ~?= Nothing] + [ f 0 ~?= Just 0 + , f 65535 ~?= Just 65535 + , f 65536 ~?= Nothing + ] , "TryFrom Word64 Word32" ~: let f = hush . Witch.tryFrom @Word.Word64 @Word.Word32 in @@ -826,14 +848,18 @@ main = ] , "From Word64 Natural" ~: let f = Witch.from @Word.Word64 @Natural.Natural - in [f 0 ~?= 0, f 18446744073709551615 ~?= 18446744073709551615] + in + [f 0 ~?= 0, f 18446744073709551615 ~?= 18446744073709551615] , "TryFrom Word64 Int8" ~: let f = hush . Witch.tryFrom @Word.Word64 @Int.Int8 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f 128 ~?= Nothing] , "TryFrom Word64 Int16" ~: let f = hush . Witch.tryFrom @Word.Word64 @Int.Int16 in - [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f 32768 ~?= Nothing] + [ f 0 ~?= Just 0 + , f 32767 ~?= Just 32767 + , f 32768 ~?= Nothing + ] , "TryFrom Word64 Int32" ~: let f = hush . Witch.tryFrom @Word.Word64 @Int.Int32 in @@ -861,7 +887,8 @@ main = ] , "From Word64 Integer" ~: let f = Witch.from @Word.Word64 @Integer - in [f 0 ~?= 0, f 18446744073709551615 ~?= 18446744073709551615] + in + [f 0 ~?= 0, f 18446744073709551615 ~?= 18446744073709551615] , "TryFrom Word64 Float" ~: let f = hush . Witch.tryFrom @Word.Word64 @Float in @@ -884,7 +911,10 @@ main = , "TryFrom Word Word16" ~: let f = hush . Witch.tryFrom @Word @Word.Word16 in - [f 0 ~?= Just 0, f 65535 ~?= Just 65535, f 65536 ~?= Nothing] + [ f 0 ~?= Just 0 + , f 65535 ~?= Just 65535 + , f 65536 ~?= Nothing + ] , "TryFrom Word Word32" ~: let f = hush . Witch.tryFrom @Word @Word.Word32 in @@ -908,7 +938,10 @@ main = , "TryFrom Word Int16" ~: let f = hush . Witch.tryFrom @Word @Int.Int16 in - [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f 32768 ~?= Nothing] + [ f 0 ~?= Just 0 + , f 32767 ~?= Just 32767 + , f 32768 ~?= Nothing + ] , "TryFrom Word Int32" ~: let f = hush . Witch.tryFrom @Word @Int.Int32 in @@ -923,7 +956,8 @@ main = , let x = maxBound :: Word in if toInteger x >= 9223372036854775807 - then f 9223372036854775807 ~?= Just 9223372036854775807 + then f 9223372036854775807 + ~?= Just 9223372036854775807 else f x ~?= Just (fromIntegral x) , let x = maxBound :: Word in @@ -975,7 +1009,10 @@ main = , "TryFrom Natural Word16" ~: let f = hush . Witch.tryFrom @Natural.Natural @Word.Word16 in - [f 0 ~?= Just 0, f 65535 ~?= Just 65535, f 65536 ~?= Nothing] + [ f 0 ~?= Just 0 + , f 65535 ~?= Just 65535 + , f 65536 ~?= Nothing + ] , "TryFrom Natural Word32" ~: let f = hush . Witch.tryFrom @Natural.Natural @Word.Word32 in @@ -1005,7 +1042,8 @@ main = x = fromIntegral (maxBound :: Word) + 1 :: Natural.Natural in - hush (Witch.tryFrom @Natural.Natural @Word x) ~?= Nothing + hush (Witch.tryFrom @Natural.Natural @Word x) + ~?= Nothing ] , "TryFrom Natural Int8" ~: let f = hush . Witch.tryFrom @Natural.Natural @Int.Int8 @@ -1013,7 +1051,10 @@ main = , "TryFrom Natural Int16" ~: let f = hush . Witch.tryFrom @Natural.Natural @Int.Int16 in - [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f 32768 ~?= Nothing] + [ f 0 ~?= Just 0 + , f 32767 ~?= Just 32767 + , f 32768 ~?= Nothing + ] , "TryFrom Natural Int32" ~: let f = hush . Witch.tryFrom @Natural.Natural @Int.Int32 in @@ -1035,13 +1076,15 @@ main = , let x = maxBound :: Int in hush - (Witch.tryFrom @Natural.Natural @Int (fromIntegral x) + (Witch.tryFrom @Natural.Natural @Int + (fromIntegral x) ) ~?= Just x , let x = fromIntegral (maxBound :: Int) + 1 :: Natural.Natural - in hush (Witch.tryFrom @Natural.Natural @Int x) ~?= Nothing + in + hush (Witch.tryFrom @Natural.Natural @Int x) ~?= Nothing ] , "From Natural Integer" ~: let f = Witch.from @Natural.Natural @Integer @@ -1285,7 +1328,8 @@ main = , let x = minBound :: Int in if toInteger x <= (-9007199254740991) - then f (-9007199254740991) ~?= Just (-9007199254740991) + then f (-9007199254740991) + ~?= Just (-9007199254740991) else f (fromIntegral x) ~?= Just x , f (-9007199254740992) ~?= Nothing , f (0 / 0) ~?= Nothing @@ -1625,7 +1669,8 @@ main = ~?= ShortByteString.pack [0x0f, 0xf0] ] , "TryFrom ByteString Text" - ~: let f = hush . Witch.tryFrom @ByteString.ByteString @Text.Text + ~: let + f = hush . Witch.tryFrom @ByteString.ByteString @Text.Text in [ f (ByteString.pack []) ~?= Just (Text.pack "") , f (ByteString.pack [0x61]) ~?= Just (Text.pack "a") @@ -1678,10 +1723,12 @@ main = ~: let f = hush - . Witch.tryFrom @LazyByteString.ByteString @LazyText.Text + . Witch.tryFrom @LazyByteString.ByteString + @LazyText.Text in [ f (LazyByteString.pack []) ~?= Just (LazyText.pack "") - , f (LazyByteString.pack [0x61]) ~?= Just (LazyText.pack "a") + , f (LazyByteString.pack [0x61]) + ~?= Just (LazyText.pack "a") , f (LazyByteString.pack [0xff]) ~?= Nothing ] , "TryFrom LazyByteString Text" @@ -1891,9 +1938,12 @@ main = -- CalendarDiffTime , "From CalendarDiffDays CalendarDiffTime" ~: let - f = Witch.from @Time.CalendarDiffDays @Time.CalendarDiffTime + f = + Witch.from @Time.CalendarDiffDays @Time.CalendarDiffTime in - [f (Time.CalendarDiffDays 0 0) ~?= Time.CalendarDiffTime 0 0] + [ f (Time.CalendarDiffDays 0 0) + ~?= Time.CalendarDiffTime 0 0 + ] , "From NominalDiffTime CalendarDiffTime" ~: let f = Witch.from @Time.NominalDiffTime @Time.CalendarDiffTime diff --git a/witch.cabal b/witch.cabal index 6992265..a6aa532 100644 --- a/witch.cabal +++ b/witch.cabal @@ -1,15 +1,15 @@ cabal-version: 2.2 name: witch -version: 0.3.4.2 +version: 1.0.0.0 synopsis: Convert values from one type into another. description: Witch converts values from one type into another. build-type: Simple category: Data extra-source-files: CHANGELOG.markdown README.markdown -license-file: LICENSE.txt -license: ISC +license-file: LICENSE.markdown +license: MIT maintainer: Taylor Fausak source-repository head @@ -21,11 +21,12 @@ flag pedantic description: Enables @-Werror@, which turns warnings into errors. manual: True -common basics +common library build-depends: , base >= 4.10.0 && < 4.17 , bytestring >= 0.10.8 && < 0.12 , containers >= 0.5.10 && < 0.7 + , template-haskell >= 2.12.0 && < 2.19 , text >= 1.2.3 && < 1.3 , time >= 1.9.1 && < 1.13 default-language: Haskell2010 @@ -60,11 +61,18 @@ common basics ghc-options: -Werror -library - import: basics +common executable + import: library + + build-depends: witch + ghc-options: + -rtsopts + -threaded + -Wno-unused-packages + +library + import: library - build-depends: - , template-haskell >= 2.12.0 && < 2.19 exposed-modules: Witch Witch.From @@ -73,26 +81,20 @@ library Witch.TryFrom Witch.TryFromException Witch.Utility - hs-source-dirs: src/lib + hs-source-dirs: source/library if impl(ghc >= 9.0) - hs-source-dirs: src/ghc-9.0 + hs-source-dirs: source/ghc-9.0 + elif impl(ghc >= 8.10) + hs-source-dirs: source/ghc-8.10 else - if impl(ghc >= 8.10) - hs-source-dirs: src/ghc-8.10 - else - hs-source-dirs: src/ghc-8.8 + hs-source-dirs: source/ghc-8.8 test-suite test - import: basics + import: executable build-depends: , HUnit >= 1.6.2 && < 1.7 - , witch - ghc-options: - -rtsopts - -threaded - -Wno-all-missed-specialisations - hs-source-dirs: src/test + hs-source-dirs: source/test-suite main-is: Main.hs type: exitcode-stdio-1.0