-
Notifications
You must be signed in to change notification settings - Fork 12
Introduce Template Haskell companion library. #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
d89287f
Move main `bech32` library into a subdirectory.
jonathanknowles 4af0faa
Remove unnecessary `-O2` flag from `bech32.cabal`.
jonathanknowles 5c618aa
Split a paragraph within the README to increase readability.
jonathanknowles 5448963
Make `HumanReadablePartError` an instance of `Exception`.
jonathanknowles d741a81
Reverse the order of the `bech32` change log.
jonathanknowles 5d1a2c5
Add `bech32-th` library with accompanying test suite.
jonathanknowles 2630a26
Add cabal package checking to the travis script.
jonathanknowles 1f78b8e
Use more resilient method of checking package integrity.
jonathanknowles f156577
Prepare for 1.0.2 release of both `bech32` and `bech32-th`.
jonathanknowles File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# ChangeLog for `bech32-th` | ||
|
||
## 1.0.2 -- 2020-02-19 | ||
|
||
+ Initial release adapted from https://github.com/input-output-hk/cardano-wallet |
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
name: bech32-th | ||
version: 1.0.2 | ||
synopsis: Template Haskell extensions to the Bech32 library. | ||
description: Template Haskell extensions to the Bech32 library, including | ||
quasi-quoters for compile-time checking of Bech32 string | ||
literals. | ||
author: IOHK Engineering Team | ||
maintainer: [email protected], [email protected], [email protected] | ||
copyright: 2020 IOHK | ||
license: Apache-2.0 | ||
license-file: LICENSE | ||
homepage: https://github.com/input-output-hk/bech32 | ||
bug-reports: https://github.com/input-output-hk/bech32/issues | ||
category: Web | ||
build-type: Simple | ||
extra-source-files: ChangeLog.md | ||
cabal-version: >=1.10 | ||
|
||
source-repository head | ||
type: git | ||
location: https://github.com/input-output-hk/bech32.git | ||
|
||
flag werror | ||
description: Enable `-Werror` | ||
default: False | ||
manual: True | ||
|
||
library | ||
default-language: | ||
Haskell2010 | ||
default-extensions: | ||
NoImplicitPrelude | ||
OverloadedStrings | ||
ghc-options: | ||
-Wall | ||
-Wcompat | ||
-fwarn-redundant-constraints | ||
if (flag(werror)) | ||
ghc-options: | ||
-Werror | ||
build-depends: | ||
base | ||
, bech32 >= 1.0.2 | ||
, template-haskell | ||
, text | ||
hs-source-dirs: | ||
src | ||
exposed-modules: | ||
Codec.Binary.Bech32.TH | ||
|
||
test-suite bech32-th-test | ||
default-language: | ||
Haskell2010 | ||
default-extensions: | ||
NoImplicitPrelude | ||
OverloadedStrings | ||
type: | ||
exitcode-stdio-1.0 | ||
hs-source-dirs: | ||
test | ||
ghc-options: | ||
-threaded -rtsopts -with-rtsopts=-N | ||
-Wall | ||
if (flag(werror)) | ||
ghc-options: | ||
-Werror | ||
build-depends: | ||
base < 4.14 | ||
, bech32 | ||
, bech32-th | ||
, hspec | ||
, template-haskell | ||
build-tools: | ||
hspec-discover | ||
main-is: | ||
Main.hs | ||
other-modules: | ||
Codec.Binary.Bech32.THSpec |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
{-# LANGUAGE TemplateHaskell #-} | ||
|
||
-- | | ||
-- Copyright: © 2020 IOHK | ||
-- License: Apache-2.0 | ||
-- | ||
-- This module contains Template-Haskell-specific extensions to the | ||
-- [Bech32 library](https://github.com/input-output-hk/bech32). | ||
|
||
module Codec.Binary.Bech32.TH | ||
( | ||
-- ** Quasi-Quotation Support | ||
humanReadablePart | ||
) where | ||
|
||
import Prelude | ||
|
||
import Codec.Binary.Bech32 | ||
( HumanReadablePart, humanReadablePartFromText, humanReadablePartToText ) | ||
import Control.Exception | ||
( throw ) | ||
import Data.Text | ||
( Text ) | ||
import Language.Haskell.TH.Quote | ||
( QuasiQuoter (..) ) | ||
import Language.Haskell.TH.Syntax | ||
( Exp, Q ) | ||
|
||
import qualified Data.Text as T | ||
|
||
-- | A quasiquoter for Bech32 human-readable prefixes. | ||
-- | ||
-- This quasiquoter makes it possible to construct values of type | ||
-- 'HumanReadablePart' at compile time, using string literals. | ||
-- | ||
-- Failure to parse a string literal will result in a __compile-time error__. | ||
-- | ||
-- See 'Codec.Binary.Bech32.HumanReadablePartError' for the set of possible | ||
-- errors that can be raised. | ||
-- | ||
-- Example: | ||
-- | ||
-- >>> :set -XQuasiQuotes | ||
-- >>> import Codec.Binary.Bech32 | ||
-- >>> import Codec.Binary.Bech32.TH | ||
-- >>> let addrPrefix = [humanReadablePart|addr|] | ||
-- >>> addrPrefix | ||
-- HumanReadablePart "addr" | ||
-- >>> :t addrPrefix | ||
-- addrPrefix :: HumanReadablePart | ||
-- | ||
humanReadablePart :: QuasiQuoter | ||
humanReadablePart = QuasiQuoter | ||
{ quoteExp = quoteHumanReadablePart | ||
, quotePat = notHandled "patterns" | ||
, quoteType = notHandled "types" | ||
, quoteDec = notHandled "declarations" | ||
} | ||
where | ||
notHandled things = | ||
error $ things <> | ||
" are not handled by the Bech32 humanReadablePart quasiquoter." | ||
|
||
quoteHumanReadablePart :: String -> Q Exp | ||
quoteHumanReadablePart = quote | ||
. T.unpack | ||
. humanReadablePartToText | ||
. unsafeHumanReadablePart | ||
. T.pack | ||
where | ||
quote t = [| unsafeHumanReadablePart t |] | ||
|
||
unsafeHumanReadablePart :: Text -> HumanReadablePart | ||
unsafeHumanReadablePart = either throw id . humanReadablePartFromText |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
module Codec.Binary.Bech32.THSpec | ||
( spec | ||
) where | ||
|
||
import Prelude | ||
|
||
import Codec.Binary.Bech32 | ||
( CharPosition (..) | ||
, HumanReadablePartError (..) | ||
, humanReadableCharMaxBound | ||
, humanReadableCharMinBound | ||
, humanReadablePartMaxLength | ||
, humanReadablePartMinLength | ||
) | ||
import Codec.Binary.Bech32.TH | ||
( humanReadablePart ) | ||
import Control.Monad | ||
( forM_ ) | ||
import Language.Haskell.TH.Quote | ||
( QuasiQuoter (quoteExp) ) | ||
import Language.Haskell.TH.Syntax | ||
( Exp (..), runQ ) | ||
import Test.Hspec | ||
( Spec, describe, it, shouldSatisfy, shouldThrow ) | ||
|
||
spec :: Spec | ||
spec = | ||
describe "Quasi-Quotations" $ | ||
|
||
describe "Human-Readable Prefixes" $ do | ||
let mkHumanReadablePartExp = runQ . quoteExp humanReadablePart | ||
|
||
describe "Parsing valid human-readable prefixes should succeed." $ | ||
forM_ validHumanReadableParts $ \hrp -> | ||
it (show hrp) $ | ||
mkHumanReadablePartExp hrp >>= | ||
(`shouldSatisfy` isAppE) | ||
|
||
describe "Parsing invalid human-readable prefixes should fail." $ | ||
forM_ invalidHumanReadableParts $ \(hrp, expectedError) -> | ||
it (show hrp) $ | ||
mkHumanReadablePartExp hrp | ||
`shouldThrow` (== expectedError) | ||
|
||
-- | Matches only function application expressions. | ||
-- | ||
isAppE :: Exp -> Bool | ||
isAppE AppE {} = True | ||
isAppE _ = False | ||
|
||
-- | A selection of valid human-readable prefixes, that when parsed with the | ||
-- 'humanReadablePart' quasiquoter should not result in an exception. | ||
-- | ||
-- Note that this is not by any means intended to be an exhaustive list. | ||
-- The underlying parsing logic, provided by `humanReadablePartFromText`, | ||
-- is already tested in the `bech32` package. | ||
-- | ||
validHumanReadableParts :: [String] | ||
validHumanReadableParts = | ||
[ replicate humanReadablePartMinLength humanReadableCharMinBound | ||
, replicate humanReadablePartMaxLength humanReadableCharMaxBound | ||
, "addr" | ||
] | ||
|
||
-- | A selection of invalid human-readable prefixes, along with the errors that | ||
-- we expect to see if we attempt to parse them with the 'humanReadablePart' | ||
-- quasi-quoter. | ||
-- | ||
-- Note that this is not by any means intended to be an exhaustive list. | ||
-- The underlying parsing logic, provided by `humanReadablePartFromText`, | ||
-- is already tested in the `bech32` package. | ||
-- | ||
invalidHumanReadableParts :: [(String, HumanReadablePartError)] | ||
invalidHumanReadableParts = | ||
[ ( replicate (pred minLen) minChar | ||
, HumanReadablePartTooShort | ||
) | ||
, ( replicate (succ maxLen) maxChar | ||
, HumanReadablePartTooLong | ||
) | ||
, ( replicate (succ minLen) (pred minChar) | ||
, HumanReadablePartContainsInvalidChars (CharPosition <$> [0 .. minLen]) | ||
) | ||
, ( replicate (succ minLen) (succ maxChar) | ||
, HumanReadablePartContainsInvalidChars (CharPosition <$> [0 .. minLen]) | ||
) | ||
] | ||
where | ||
minChar = humanReadableCharMinBound | ||
maxChar = humanReadableCharMaxBound | ||
minLen = humanReadablePartMinLength | ||
maxLen = humanReadablePartMaxLength |
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍