Skip to content

Introduce purs-tidy formatter #38

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 2 commits into from
Nov 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ jobs:

- name: Set up a PureScript toolchain
uses: purescript-contrib/setup-purescript@main
with:
purs-tidy: "latest"

- name: Cache PureScript dependencies
uses: actions/cache@v2
Expand All @@ -32,3 +34,6 @@ jobs:

- name: Run tests
run: spago test --no-install

- name: Check formatting
run: purs-tidy check src test
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
!.gitignore
!.github
!.editorconfig
!.tidyrc.json

output
generated-docs
Expand Down
10 changes: 10 additions & 0 deletions .tidyrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"importSort": "source",
"importWrap": "source",
"indent": 2,
"operatorsFile": null,
"ribbon": 1,
"typeArrowPlacement": "first",
"unicode": "never",
"width": null
}
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ New features:
Bugfixes:

Other improvements:
- Added `purs-tidy` formatter (#38 by @thomashoneyman)

## [v7.0.1](https://github.com/purescript-contrib/purescript-argonaut-generic/releases/tag/v7.0.1) - 2021-05-06

Expand Down
151 changes: 78 additions & 73 deletions src/Data/Argonaut/Decode/Generic.purs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
module Data.Argonaut.Decode.Generic (
class DecodeRep,
class DecodeRepArgs,
class DecodeLiteral,
decodeRep,
decodeRepWith,
decodeRepArgs,
genericDecodeJson,
genericDecodeJsonWith,
decodeLiteralSum,
decodeLiteralSumWithTransform,
decodeLiteral
) where
module Data.Argonaut.Decode.Generic
( class DecodeRep
, class DecodeRepArgs
, class DecodeLiteral
, decodeRep
, decodeRepWith
, decodeRepArgs
, genericDecodeJson
, genericDecodeJsonWith
, decodeLiteralSum
, decodeLiteralSumWithTransform
, decodeLiteral
) where

import Prelude

Expand Down Expand Up @@ -40,90 +40,94 @@ instance decodeRepNoConstructors :: DecodeRep Rep.NoConstructors where
instance decodeRepSum :: (DecodeRep a, DecodeRep b) => DecodeRep (Rep.Sum a b) where
decodeRepWith e j = Rep.Inl <$> decodeRepWith e j <|> Rep.Inr <$> decodeRepWith e j

withTag ::
Encoding ->
Json ->
String ->
Either JsonDecodeError
{ tag :: String
, decodingErr :: JsonDecodeError -> JsonDecodeError
}
withTag
:: Encoding
-> Json
-> String
-> Either JsonDecodeError
{ tag :: String
, decodingErr :: JsonDecodeError -> JsonDecodeError
}
withTag e j name = do
let decodingErr = Named name
jObj <- note (decodingErr $ TypeMismatch "Object") (toObject j)
jTag <- note (decodingErr $ AtKey e.tagKey MissingValue) (FO.lookup e.tagKey jObj)
tag <- note (decodingErr $ AtKey e.tagKey $ TypeMismatch "String") (toString jTag)
when (tag /= name) $
Left $ decodingErr $ AtKey e.tagKey $ UnexpectedValue $ fromString tag
pure {tag, decodingErr}

withTagAndValues ::
Encoding ->
Json ->
String ->
Either JsonDecodeError
{ tag :: String
, values :: Json
, decodingErr :: JsonDecodeError -> JsonDecodeError
}
when (tag /= name)
$ Left
$ decodingErr
$ AtKey e.tagKey
$ UnexpectedValue
$ fromString tag
pure { tag, decodingErr }

withTagAndValues
:: Encoding
-> Json
-> String
-> Either JsonDecodeError
{ tag :: String
, values :: Json
, decodingErr :: JsonDecodeError -> JsonDecodeError
}
withTagAndValues e j name = do
{tag, decodingErr} <- withTag e j name
{ tag, decodingErr } <- withTag e j name
jObj <- note (decodingErr $ TypeMismatch "Object") (toObject j)
values <- note (decodingErr $ AtKey e.valuesKey MissingValue) (FO.lookup e.valuesKey jObj)
pure {tag, values, decodingErr}

construct ::
forall e t s .
DecodeRepArgs t =>
Encoding ->
Array Json ->
(JsonDecodeError -> e) ->
Either e (Rep.Constructor s t)
pure { tag, values, decodingErr }

construct
:: forall e t s
. DecodeRepArgs t
=> Encoding
-> Array Json
-> (JsonDecodeError -> e)
-> Either e (Rep.Constructor s t)
construct e valuesArray decodingErr = do
{init, rest} <- lmap decodingErr $ decodeRepArgs valuesArray
when (rest /= []) $
Left $ decodingErr $ AtKey e.valuesKey $ UnexpectedValue (fromArray rest)
{ init, rest } <- lmap decodingErr $ decodeRepArgs valuesArray
when (rest /= [])
$ Left
$ decodingErr
$ AtKey e.valuesKey
$ UnexpectedValue (fromArray rest)
pure $ Rep.Constructor init

instance decodeRepConstructorNoArgs :: IsSymbol name => DecodeRep (Rep.Constructor name Rep.NoArguments) where
decodeRepWith e j = do
let name = reflectSymbol (Proxy :: Proxy name)
{decodingErr} <- withTag e j name
{ decodingErr } <- withTag e j name
construct e [] decodingErr
else
instance decodeRepConstructorArg :: (IsSymbol name, DecodeJson a) => DecodeRep (Rep.Constructor name (Rep.Argument a)) where
else instance decodeRepConstructorArg :: (IsSymbol name, DecodeJson a) => DecodeRep (Rep.Constructor name (Rep.Argument a)) where
decodeRepWith e j = do
let name = reflectSymbol (Proxy :: Proxy name)
{values, decodingErr} <- withTagAndValues e j name
if e.unwrapSingleArguments
then construct e [values] decodingErr
else do
valuesArray <- note (decodingErr $ AtKey e.valuesKey $ TypeMismatch "Array") (toArray values)
construct e valuesArray decodingErr
else
instance decodeRepConstructor :: (IsSymbol name, DecodeRepArgs a) => DecodeRep (Rep.Constructor name a) where
{ values, decodingErr } <- withTagAndValues e j name
if e.unwrapSingleArguments then construct e [ values ] decodingErr
else do
valuesArray <- note (decodingErr $ AtKey e.valuesKey $ TypeMismatch "Array") (toArray values)
construct e valuesArray decodingErr
else instance decodeRepConstructor :: (IsSymbol name, DecodeRepArgs a) => DecodeRep (Rep.Constructor name a) where
decodeRepWith e j = do
let name = reflectSymbol (Proxy :: Proxy name)
{values, decodingErr} <- withTagAndValues e j name
{ values, decodingErr } <- withTagAndValues e j name
valuesArray <- note (decodingErr $ AtKey e.valuesKey $ TypeMismatch "Array") (toArray values)
construct e valuesArray decodingErr

class DecodeRepArgs r where
decodeRepArgs :: Array Json -> Either JsonDecodeError {init :: r, rest :: Array Json}
decodeRepArgs :: Array Json -> Either JsonDecodeError { init :: r, rest :: Array Json }

instance decodeRepArgsNoArguments :: DecodeRepArgs Rep.NoArguments where
decodeRepArgs js = Right {init: Rep.NoArguments, rest: js}
decodeRepArgs js = Right { init: Rep.NoArguments, rest: js }

instance decodeRepArgsProduct :: (DecodeRepArgs a, DecodeRepArgs b) => DecodeRepArgs (Rep.Product a b) where
decodeRepArgs js = do
{init: a, rest: js'} <- decodeRepArgs js
{init: b, rest: js''} <- decodeRepArgs js'
pure {init: Rep.Product a b, rest: js''}
{ init: a, rest: js' } <- decodeRepArgs js
{ init: b, rest: js'' } <- decodeRepArgs js'
pure { init: Rep.Product a b, rest: js'' }

instance decodeRepArgsArgument :: (DecodeJson a) => DecodeRepArgs (Rep.Argument a) where
decodeRepArgs js = do
{head, tail} <- note (TypeMismatch "NonEmptyArray") (uncons js)
{init: _, rest: tail} <<< Rep.Argument <$> decodeJson head
{ head, tail } <- note (TypeMismatch "NonEmptyArray") (uncons js)
{ init: _, rest: tail } <<< Rep.Argument <$> decodeJson head

-- | Decode `Json` representation of a value which has a `Generic` type.
genericDecodeJson :: forall a r. Rep.Generic a r => DecodeRep r => Json -> Either JsonDecodeError a
Expand Down Expand Up @@ -154,15 +158,16 @@ instance decodeLiteralConstructor :: (IsSymbol name) => DecodeLiteral (Rep.Const
let name = reflectSymbol (Proxy :: Proxy name)
let decodingErr = Named name
tag <- note (decodingErr $ TypeMismatch "String") (toString j)
when (tag /= tagNameTransform name) $
Left $ decodingErr $ UnexpectedValue (fromString tag)
when (tag /= tagNameTransform name)
$ Left
$ decodingErr
$ UnexpectedValue (fromString tag)
pure $ Rep.Constructor (Rep.NoArguments)


type FailMessage =
Text "`decodeLiteralSum` can only be used with sum types, where all of the constructors are nullary. This is because a string literal cannot be encoded into a product type."

instance decodeLiteralConstructorCannotTakeProduct
:: Fail FailMessage
=> DecodeLiteral (Rep.Product a b) where
decodeLiteral _ _ = unsafeCrashWith "unreachable DecodeLiteral was reached."
instance decodeLiteralConstructorCannotTakeProduct ::
Fail FailMessage =>
DecodeLiteral (Rep.Product a b) where
decodeLiteral _ _ = unsafeCrashWith "unreachable DecodeLiteral was reached."
49 changes: 25 additions & 24 deletions src/Data/Argonaut/Encode/Generic.purs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
module Data.Argonaut.Encode.Generic (
class EncodeRep,
class EncodeRepArgs,
class EncodeLiteral,
encodeRep,
encodeRepWith,
encodeRepArgs,
genericEncodeJson,
genericEncodeJsonWith,
encodeLiteralSum,
encodeLiteralSumWithTransform,
encodeLiteral
) where
module Data.Argonaut.Encode.Generic
( class EncodeRep
, class EncodeRepArgs
, class EncodeLiteral
, encodeRep
, encodeRepWith
, encodeRepArgs
, genericEncodeJson
, genericEncodeJsonWith
, encodeLiteralSum
, encodeLiteralSumWithTransform
, encodeLiteral
) where

import Prelude

Expand Down Expand Up @@ -44,13 +44,14 @@ instance encodeRepConstructor :: (IsSymbol name, EncodeRepArgs a) => EncodeRep (
$ FO.insert e.valuesKey values
$ FO.empty
where
values =
let vs = encodeRepArgs a in
if e.unwrapSingleArguments
then case vs of
[v] -> v
_ -> fromArray vs
else fromArray vs
values =
let
vs = encodeRepArgs a
in
if e.unwrapSingleArguments then case vs of
[ v ] -> v
_ -> fromArray vs
else fromArray vs

class EncodeRepArgs r where
encodeRepArgs :: r -> Array Json
Expand All @@ -62,7 +63,7 @@ instance encodeRepArgsProduct :: (EncodeRepArgs a, EncodeRepArgs b) => EncodeRep
encodeRepArgs (Rep.Product a b) = encodeRepArgs a <> encodeRepArgs b

instance encodeRepArgsArgument :: (EncodeJson a) => EncodeRepArgs (Rep.Argument a) where
encodeRepArgs (Rep.Argument a) = [encodeJson a]
encodeRepArgs (Rep.Argument a) = [ encodeJson a ]

-- | Encode any `Generic` data structure into `Json`.
genericEncodeJson :: forall a r. Rep.Generic a r => EncodeRep r => a -> Json
Expand Down Expand Up @@ -95,7 +96,7 @@ instance encodeLiteralConstructor :: (IsSymbol name) => EncodeLiteral (Rep.Const
type FailMessage =
Text """`encodeLiteralSum` can only be used with sum types, where all of the constructors are nullary. This is because a string literal cannot be encoded into a product type."""

instance encodeLiteralConstructorCannotBeProduct
:: Fail FailMessage
=> EncodeLiteral (Rep.Product a b) where
instance encodeLiteralConstructorCannotBeProduct ::
Fail FailMessage =>
EncodeLiteral (Rep.Product a b) where
encodeLiteral _ _ = unsafeCrashWith "unreachable encodeLiteral was reached."
8 changes: 4 additions & 4 deletions src/Data/Argonaut/Types/Generic.purs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module Data.Argonaut.Types.Generic (
Encoding(..),
defaultEncoding
) where
module Data.Argonaut.Types.Generic
( Encoding(..)
, defaultEncoding
) where

-- | Encoding settings:
-- | tagKey -- which key to use in the JSON object for sum-type constructors
Expand Down
Loading