packages feed

elm-street 0.2.0.0 → 0.2.1.0

raw patch · 8 files changed

+239/−138 lines, 8 filesdep ~basedep ~textPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: base, text

API changes (from Hackage documentation)

- Elm.Aeson: ElmStreet :: a -> ElmStreet a
- Elm.Aeson: [unElmStreet] :: ElmStreet a -> a
- Elm.Aeson: elmStreetJsonOptions :: forall a. Typeable a => Options
- Elm.Aeson: elmStreetParseJson :: forall a. (Typeable a, Generic a, GFromJSON Zero (Rep a)) => Value -> Parser a
- Elm.Aeson: elmStreetToJson :: forall a. (Typeable a, Generic a, GToJSON Zero (Rep a)) => a -> Value
- Elm.Aeson: instance (Data.Typeable.Internal.Typeable a, GHC.Generics.Generic a, Data.Aeson.Types.Class.GToJSON Data.Aeson.Types.Generic.Zero (GHC.Generics.Rep a)) => Data.Aeson.Types.ToJSON.ToJSON (Elm.Aeson.ElmStreet a)
- Elm.Aeson: instance (Data.Typeable.Internal.Typeable a, GHC.Generics.Generic a, Data.Aeson.Types.FromJSON.GFromJSON Data.Aeson.Types.Generic.Zero (GHC.Generics.Rep a)) => Data.Aeson.Types.FromJSON.FromJSON (Elm.Aeson.ElmStreet a)
- Elm.Aeson: instance (Elm.Generic.HasNoTypeVars a, Elm.Generic.HasLessThanEightUnnamedFields a, Elm.Generic.HasNoNamedSum a, GHC.Generics.Generic a, Elm.Generic.GenericElmDefinition (GHC.Generics.Rep a)) => Elm.Generic.Elm (Elm.Aeson.ElmStreet a)
- Elm.Aeson: newtype ElmStreet a
- Elm.Ast: DefPrim :: !ElmPrim -> ElmDefinition
- Elm.Ast: DefRecord :: !ElmRecord -> ElmDefinition
- Elm.Ast: DefType :: !ElmType -> ElmDefinition
- Elm.Ast: ElmBool :: ElmPrim
- Elm.Ast: ElmChar :: ElmPrim
- Elm.Ast: ElmConstructor :: !Text -> ![TypeRef] -> ElmConstructor
- Elm.Ast: ElmFloat :: ElmPrim
- Elm.Ast: ElmInt :: ElmPrim
- Elm.Ast: ElmList :: !TypeRef -> ElmPrim
- Elm.Ast: ElmMaybe :: !TypeRef -> ElmPrim
- Elm.Ast: ElmNever :: ElmPrim
- Elm.Ast: ElmNonEmptyPair :: !TypeRef -> ElmPrim
- Elm.Ast: ElmPair :: !TypeRef -> !TypeRef -> ElmPrim
- Elm.Ast: ElmRecord :: !Text -> !NonEmpty ElmRecordField -> !Bool -> ElmRecord
- Elm.Ast: ElmRecordField :: !TypeRef -> !Text -> ElmRecordField
- Elm.Ast: ElmResult :: !TypeRef -> !TypeRef -> ElmPrim
- Elm.Ast: ElmString :: ElmPrim
- Elm.Ast: ElmTime :: ElmPrim
- Elm.Ast: ElmTriple :: !TypeRef -> !TypeRef -> !TypeRef -> ElmPrim
- Elm.Ast: ElmType :: !Text -> ![Text] -> !Bool -> !NonEmpty ElmConstructor -> ElmType
- Elm.Ast: ElmUnit :: ElmPrim
- Elm.Ast: ElmValue :: ElmPrim
- Elm.Ast: RefCustom :: !TypeName -> TypeRef
- Elm.Ast: RefPrim :: !ElmPrim -> TypeRef
- Elm.Ast: TypeName :: Text -> TypeName
- Elm.Ast: [elmConstructorFields] :: ElmConstructor -> ![TypeRef]
- Elm.Ast: [elmConstructorName] :: ElmConstructor -> !Text
- Elm.Ast: [elmRecordFieldName] :: ElmRecordField -> !Text
- Elm.Ast: [elmRecordFieldType] :: ElmRecordField -> !TypeRef
- Elm.Ast: [elmRecordFields] :: ElmRecord -> !NonEmpty ElmRecordField
- Elm.Ast: [elmRecordIsNewtype] :: ElmRecord -> !Bool
- Elm.Ast: [elmRecordName] :: ElmRecord -> !Text
- Elm.Ast: [elmTypeConstructors] :: ElmType -> !NonEmpty ElmConstructor
- Elm.Ast: [elmTypeIsNewtype] :: ElmType -> !Bool
- Elm.Ast: [elmTypeName] :: ElmType -> !Text
- Elm.Ast: [elmTypeVars] :: ElmType -> ![Text]
- Elm.Ast: [unTypeName] :: TypeName -> Text
- Elm.Ast: data ElmConstructor
- Elm.Ast: data ElmDefinition
- Elm.Ast: data ElmPrim
- Elm.Ast: data ElmRecord
- Elm.Ast: data ElmRecordField
- Elm.Ast: data ElmType
- Elm.Ast: data TypeRef
- Elm.Ast: definitionToRef :: ElmDefinition -> TypeRef
- Elm.Ast: getConstructorNames :: ElmType -> [Text]
- Elm.Ast: instance GHC.Show.Show Elm.Ast.ElmConstructor
- Elm.Ast: instance GHC.Show.Show Elm.Ast.ElmDefinition
- Elm.Ast: instance GHC.Show.Show Elm.Ast.ElmPrim
- Elm.Ast: instance GHC.Show.Show Elm.Ast.ElmRecord
- Elm.Ast: instance GHC.Show.Show Elm.Ast.ElmRecordField
- Elm.Ast: instance GHC.Show.Show Elm.Ast.ElmType
- Elm.Ast: instance GHC.Show.Show Elm.Ast.TypeName
- Elm.Ast: instance GHC.Show.Show Elm.Ast.TypeRef
- Elm.Ast: isEnum :: ElmType -> Bool
- Elm.Ast: newtype TypeName
- Elm.Generate: Settings :: !FilePath -> ![FilePath] -> !FilePath -> !FilePath -> !FilePath -> Settings
- Elm.Generate: [settingsDecoderFile] :: Settings -> !FilePath
- Elm.Generate: [settingsDirectory] :: Settings -> !FilePath
- Elm.Generate: [settingsEncoderFile] :: Settings -> !FilePath
- Elm.Generate: [settingsModule] :: Settings -> ![FilePath]
- Elm.Generate: [settingsTypesFile] :: Settings -> !FilePath
- Elm.Generate: class RenderElm (types :: [Type])
- Elm.Generate: data Settings
- Elm.Generate: defaultSettings :: FilePath -> [FilePath] -> Settings
- Elm.Generate: generateElm :: forall (ts :: [Type]). RenderElm ts => Settings -> IO ()
- Elm.Generate: instance (Elm.Generic.Elm t, Elm.Generate.RenderElm ts) => Elm.Generate.RenderElm (t : ts)
- Elm.Generate: instance Elm.Generate.RenderElm '[]
- Elm.Generate: renderDecoder :: RenderElm types => [Text]
- Elm.Generate: renderEncoder :: RenderElm types => [Text]
- Elm.Generate: renderType :: RenderElm types => [Text]
- Elm.Generic: GenericConstructor :: !Text -> ![(TypeRef, Maybe Text)] -> GenericConstructor
- Elm.Generic: [genericConstructorFields] :: GenericConstructor -> ![(TypeRef, Maybe Text)]
- Elm.Generic: [genericConstructorName] :: GenericConstructor -> !Text
- Elm.Generic: class Elm a
- Elm.Generic: class GenericElmConstructors (f :: k -> Type)
- Elm.Generic: class GenericElmDefinition (f :: k -> Type)
- Elm.Generic: class GenericElmFields (f :: k -> Type)
- Elm.Generic: data GenericConstructor
- Elm.Generic: elmNewtype :: forall a. Elm a => Text -> Text -> ElmDefinition
- Elm.Generic: elmRef :: forall a. Elm a => TypeRef
- Elm.Generic: genericToElmConstructors :: GenericElmConstructors f => TypeName -> f a -> NonEmpty GenericConstructor
- Elm.Generic: genericToElmDefinition :: GenericElmDefinition f => f a -> ElmDefinition
- Elm.Generic: genericToElmFields :: GenericElmFields f => TypeName -> f a -> [(TypeRef, Maybe Text)]
- Elm.Generic: instance (Elm.Generic.Elm a, Elm.Generic.Elm b) => Elm.Generic.Elm (Data.Either.Either a b)
- Elm.Generic: instance (Elm.Generic.Elm a, Elm.Generic.Elm b) => Elm.Generic.Elm (a, b)
- Elm.Generic: instance (Elm.Generic.Elm a, Elm.Generic.Elm b, Elm.Generic.Elm c) => Elm.Generic.Elm (a, b, c)
- Elm.Generic: instance (GHC.Generics.Selector s, Elm.Generic.Elm a) => Elm.Generic.GenericElmFields (GHC.Generics.S1 s (GHC.Generics.Rec0 a))
- Elm.Generic: instance Elm.Generic.Elm ()
- Elm.Generic: instance Elm.Generic.Elm Data.Aeson.Types.Internal.Value
- Elm.Generic: instance Elm.Generic.Elm Data.Text.Internal.Lazy.Text
- Elm.Generic: instance Elm.Generic.Elm Data.Text.Internal.Text
- Elm.Generic: instance Elm.Generic.Elm Data.Time.Clock.Internal.UTCTime.UTCTime
- Elm.Generic: instance Elm.Generic.Elm Data.Void.Void
- Elm.Generic: instance Elm.Generic.Elm GHC.Base.String
- Elm.Generic: instance Elm.Generic.Elm GHC.Int.Int16
- Elm.Generic: instance Elm.Generic.Elm GHC.Int.Int32
- Elm.Generic: instance Elm.Generic.Elm GHC.Int.Int8
- Elm.Generic: instance Elm.Generic.Elm GHC.Types.Bool
- Elm.Generic: instance Elm.Generic.Elm GHC.Types.Char
- Elm.Generic: instance Elm.Generic.Elm GHC.Types.Double
- Elm.Generic: instance Elm.Generic.Elm GHC.Types.Float
- Elm.Generic: instance Elm.Generic.Elm GHC.Types.Int
- Elm.Generic: instance Elm.Generic.Elm GHC.Types.Word
- Elm.Generic: instance Elm.Generic.Elm GHC.Word.Word16
- Elm.Generic: instance Elm.Generic.Elm GHC.Word.Word32
- Elm.Generic: instance Elm.Generic.Elm GHC.Word.Word8
- Elm.Generic: instance Elm.Generic.Elm a => Elm.Generic.Elm (GHC.Base.NonEmpty a)
- Elm.Generic: instance Elm.Generic.Elm a => Elm.Generic.Elm (GHC.Maybe.Maybe a)
- Elm.Generic: instance Elm.Generic.Elm a => Elm.Generic.Elm [a]
- Elm.Generic: instance Elm.Generic.GenericElmFields GHC.Generics.U1
- Elm.Generic: instance forall k (c :: GHC.Generics.Meta) (f :: k -> *). (GHC.Generics.Constructor c, Elm.Generic.GenericElmFields f) => Elm.Generic.GenericElmConstructors (GHC.Generics.C1 c f)
- Elm.Generic: instance forall k (d :: GHC.Generics.Meta) (f :: k -> *). (GHC.Generics.Datatype d, Elm.Generic.GenericElmConstructors f) => Elm.Generic.GenericElmDefinition (GHC.Generics.D1 d f)
- Elm.Generic: instance forall k (f :: k -> *) (g :: k -> *). (Elm.Generic.GenericElmConstructors f, Elm.Generic.GenericElmConstructors g) => Elm.Generic.GenericElmConstructors (f GHC.Generics.:+: g)
- Elm.Generic: instance forall k (f :: k -> *) (g :: k -> *). (Elm.Generic.GenericElmFields f, Elm.Generic.GenericElmFields g) => Elm.Generic.GenericElmFields (f GHC.Generics.:*: g)
- Elm.Generic: stripTypeNamePrefix :: TypeName -> Text -> Text
- Elm.Generic: toElmConstructor :: GenericConstructor -> Either (NonEmpty ElmRecordField) ElmConstructor
- Elm.Generic: toElmDefinition :: (Elm a, HasNoTypeVars a, HasLessThanEightUnnamedFields a, HasNoNamedSum a, Generic a, GenericElmDefinition (Rep a)) => Proxy a -> ElmDefinition
- Elm.Generic: type family CheckConst (f :: k -> Type) :: Bool
- Elm.Print.Common: arrow :: Doc ann
- Elm.Print.Common: mkQualified :: Text -> Doc ann
- Elm.Print.Common: qualifiedTypeWithVarsDoc :: Text -> [Text] -> Doc ann
- Elm.Print.Common: showDoc :: Doc ann -> Text
- Elm.Print.Common: typeWithVarsDoc :: Bool -> Text -> [Text] -> Doc ann
- Elm.Print.Common: wrapParens :: Doc ann -> Doc ann
- Elm.Print.Decoder: decodeChar :: Text
- Elm.Print.Decoder: decodeEither :: Text
- Elm.Print.Decoder: decodeEnum :: Text
- Elm.Print.Decoder: decodeNonEmpty :: Text
- Elm.Print.Decoder: decodePair :: Text
- Elm.Print.Decoder: decodeTriple :: Text
- Elm.Print.Decoder: prettyShowDecoder :: ElmDefinition -> Text
- Elm.Print.Encoder: encodeEither :: Text
- Elm.Print.Encoder: encodeMaybe :: Text
- Elm.Print.Encoder: encodeNonEmpty :: Text
- Elm.Print.Encoder: encodePair :: Text
- Elm.Print.Encoder: encodeTriple :: Text
- Elm.Print.Encoder: prettyShowEncoder :: ElmDefinition -> Text
- Elm.Print.Types: elmRecordDoc :: ElmRecord -> Doc ann
- Elm.Print.Types: elmTypeDoc :: ElmType -> Doc ann
- Elm.Print.Types: prettyShowDefinition :: ElmDefinition -> Text
+ Types: Age :: Int -> Age
+ Types: Approved :: RequestStatus
+ Types: Blocked :: Guest
+ Types: CustomCodeGen :: String -> Int -> CustomCodeGen
+ Types: Id :: Text -> Id a
+ Types: Newtype :: Int -> Newtype
+ Types: NewtypeList :: [Int] -> NewtypeList
+ Types: OneConstructor :: OneConstructor
+ Types: OneType :: !Prims -> !MyUnit -> !MyResult -> !Id OneType -> !Age -> !Newtype -> !NewtypeList -> !OneConstructor -> !RequestStatus -> !User -> ![Guest] -> !UserRequest -> !NonEmpty MyUnit -> OneType
+ Types: Prims :: !() -> !Bool -> !Char -> !Int -> !Double -> !Text -> !String -> !UTCTime -> !Value -> !Maybe Word -> !Either Int Text -> !(Char, Bool) -> !(Char, Bool, [Int]) -> ![Int] -> !NonEmpty Int -> Prims
+ Types: Regular :: Text -> Int -> Guest
+ Types: Rejected :: RequestStatus
+ Types: Reviewing :: RequestStatus
+ Types: Special :: Maybe [Int] -> Guest
+ Types: User :: !Id User -> !Text -> !Age -> !RequestStatus -> User
+ Types: UserRequest :: ![Id User] -> !Word32 -> !Maybe (Either User Guest) -> UserRequest
+ Types: Visitor :: Text -> Guest
+ Types: [customCodeGenInt] :: CustomCodeGen -> Int
+ Types: [customCodeGenString] :: CustomCodeGen -> String
+ Types: [oneTypeAge] :: OneType -> !Age
+ Types: [oneTypeGuests] :: OneType -> ![Guest]
+ Types: [oneTypeId] :: OneType -> !Id OneType
+ Types: [oneTypeMyResult] :: OneType -> !MyResult
+ Types: [oneTypeMyUnit] :: OneType -> !MyUnit
+ Types: [oneTypeNewtypeList] :: OneType -> !NewtypeList
+ Types: [oneTypeNewtype] :: OneType -> !Newtype
+ Types: [oneTypeNonEmpty] :: OneType -> !NonEmpty MyUnit
+ Types: [oneTypeOneConstructor] :: OneType -> !OneConstructor
+ Types: [oneTypePrims] :: OneType -> !Prims
+ Types: [oneTypeRequestStatus] :: OneType -> !RequestStatus
+ Types: [oneTypeUserRequest] :: OneType -> !UserRequest
+ Types: [oneTypeUser] :: OneType -> !User
+ Types: [primsBool] :: Prims -> !Bool
+ Types: [primsChar] :: Prims -> !Char
+ Types: [primsFloat] :: Prims -> !Double
+ Types: [primsInt] :: Prims -> !Int
+ Types: [primsList] :: Prims -> ![Int]
+ Types: [primsMaybe] :: Prims -> !Maybe Word
+ Types: [primsNonEmpty] :: Prims -> !NonEmpty Int
+ Types: [primsPair] :: Prims -> !(Char, Bool)
+ Types: [primsResult] :: Prims -> !Either Int Text
+ Types: [primsString] :: Prims -> !String
+ Types: [primsText] :: Prims -> !Text
+ Types: [primsTime] :: Prims -> !UTCTime
+ Types: [primsTriple] :: Prims -> !(Char, Bool, [Int])
+ Types: [primsUnit] :: Prims -> !()
+ Types: [primsValue] :: Prims -> !Value
+ Types: [unAge] :: Age -> Int
+ Types: [unId] :: Id a -> Text
+ Types: [userAge] :: User -> !Age
+ Types: [userId] :: User -> !Id User
+ Types: [userName] :: User -> !Text
+ Types: [userRequestExample] :: UserRequest -> !Maybe (Either User Guest)
+ Types: [userRequestIds] :: UserRequest -> ![Id User]
+ Types: [userRequestLimit] :: UserRequest -> !Word32
+ Types: [userStatus] :: User -> !RequestStatus
+ Types: data CustomCodeGen
+ Types: data Guest
+ Types: data OneConstructor
+ Types: data OneType
+ Types: data Prims
+ Types: data RequestStatus
+ Types: data User
+ Types: data UserRequest
+ Types: defaultCustomCodeGen :: CustomCodeGen
+ Types: defaultOneType :: OneType
+ Types: instance (GHC.Generics.Generic a, Data.Aeson.Types.Class.GToJSON Data.Aeson.Types.Generic.Zero (GHC.Generics.Rep a)) => Data.Aeson.Types.ToJSON.ToJSON (Types.CustomElm a)
+ Types: instance (GHC.Generics.Generic a, Data.Aeson.Types.FromJSON.GFromJSON Data.Aeson.Types.Generic.Zero (GHC.Generics.Rep a)) => Data.Aeson.Types.FromJSON.FromJSON (Types.CustomElm a)
+ Types: instance Data.Aeson.Types.FromJSON.FromJSON (Types.Id a)
+ Types: instance Data.Aeson.Types.FromJSON.FromJSON Types.Age
+ Types: instance Data.Aeson.Types.FromJSON.FromJSON Types.CustomCodeGen
+ Types: instance Data.Aeson.Types.FromJSON.FromJSON Types.Guest
+ Types: instance Data.Aeson.Types.FromJSON.FromJSON Types.MyResult
+ Types: instance Data.Aeson.Types.FromJSON.FromJSON Types.MyUnit
+ Types: instance Data.Aeson.Types.FromJSON.FromJSON Types.Newtype
+ Types: instance Data.Aeson.Types.FromJSON.FromJSON Types.NewtypeList
+ Types: instance Data.Aeson.Types.FromJSON.FromJSON Types.OneConstructor
+ Types: instance Data.Aeson.Types.FromJSON.FromJSON Types.OneType
+ Types: instance Data.Aeson.Types.FromJSON.FromJSON Types.Prims
+ Types: instance Data.Aeson.Types.FromJSON.FromJSON Types.RequestStatus
+ Types: instance Data.Aeson.Types.FromJSON.FromJSON Types.User
+ Types: instance Data.Aeson.Types.FromJSON.FromJSON Types.UserRequest
+ Types: instance Data.Aeson.Types.ToJSON.ToJSON (Types.Id a)
+ Types: instance Data.Aeson.Types.ToJSON.ToJSON Types.Age
+ Types: instance Data.Aeson.Types.ToJSON.ToJSON Types.CustomCodeGen
+ Types: instance Data.Aeson.Types.ToJSON.ToJSON Types.Guest
+ Types: instance Data.Aeson.Types.ToJSON.ToJSON Types.MyResult
+ Types: instance Data.Aeson.Types.ToJSON.ToJSON Types.MyUnit
+ Types: instance Data.Aeson.Types.ToJSON.ToJSON Types.Newtype
+ Types: instance Data.Aeson.Types.ToJSON.ToJSON Types.NewtypeList
+ Types: instance Data.Aeson.Types.ToJSON.ToJSON Types.OneConstructor
+ Types: instance Data.Aeson.Types.ToJSON.ToJSON Types.OneType
+ Types: instance Data.Aeson.Types.ToJSON.ToJSON Types.Prims
+ Types: instance Data.Aeson.Types.ToJSON.ToJSON Types.RequestStatus
+ Types: instance Data.Aeson.Types.ToJSON.ToJSON Types.User
+ Types: instance Data.Aeson.Types.ToJSON.ToJSON Types.UserRequest
+ Types: instance Elm.Generic.Elm (Types.Id a)
+ Types: instance Elm.Generic.Elm Types.Age
+ Types: instance Elm.Generic.Elm Types.CustomCodeGen
+ Types: instance Elm.Generic.Elm Types.Guest
+ Types: instance Elm.Generic.Elm Types.MyResult
+ Types: instance Elm.Generic.Elm Types.MyUnit
+ Types: instance Elm.Generic.Elm Types.Newtype
+ Types: instance Elm.Generic.Elm Types.NewtypeList
+ Types: instance Elm.Generic.Elm Types.OneConstructor
+ Types: instance Elm.Generic.Elm Types.OneType
+ Types: instance Elm.Generic.Elm Types.Prims
+ Types: instance Elm.Generic.Elm Types.RequestStatus
+ Types: instance Elm.Generic.Elm Types.User
+ Types: instance Elm.Generic.Elm Types.UserRequest
+ Types: instance Elm.Generic.ElmStreetGenericConstraints a => Elm.Generic.Elm (Types.CustomElm a)
+ Types: instance GHC.Classes.Eq (Types.Id a)
+ Types: instance GHC.Classes.Eq Types.Age
+ Types: instance GHC.Classes.Eq Types.CustomCodeGen
+ Types: instance GHC.Classes.Eq Types.Guest
+ Types: instance GHC.Classes.Eq Types.MyResult
+ Types: instance GHC.Classes.Eq Types.MyUnit
+ Types: instance GHC.Classes.Eq Types.Newtype
+ Types: instance GHC.Classes.Eq Types.NewtypeList
+ Types: instance GHC.Classes.Eq Types.OneConstructor
+ Types: instance GHC.Classes.Eq Types.OneType
+ Types: instance GHC.Classes.Eq Types.Prims
+ Types: instance GHC.Classes.Eq Types.RequestStatus
+ Types: instance GHC.Classes.Eq Types.User
+ Types: instance GHC.Classes.Eq Types.UserRequest
+ Types: instance GHC.Classes.Ord Types.MyUnit
+ Types: instance GHC.Generics.Generic Types.Age
+ Types: instance GHC.Generics.Generic Types.CustomCodeGen
+ Types: instance GHC.Generics.Generic Types.Guest
+ Types: instance GHC.Generics.Generic Types.MyResult
+ Types: instance GHC.Generics.Generic Types.MyUnit
+ Types: instance GHC.Generics.Generic Types.Newtype
+ Types: instance GHC.Generics.Generic Types.NewtypeList
+ Types: instance GHC.Generics.Generic Types.OneConstructor
+ Types: instance GHC.Generics.Generic Types.OneType
+ Types: instance GHC.Generics.Generic Types.Prims
+ Types: instance GHC.Generics.Generic Types.RequestStatus
+ Types: instance GHC.Generics.Generic Types.User
+ Types: instance GHC.Generics.Generic Types.UserRequest
+ Types: instance GHC.Show.Show (Types.Id a)
+ Types: instance GHC.Show.Show Types.Age
+ Types: instance GHC.Show.Show Types.CustomCodeGen
+ Types: instance GHC.Show.Show Types.Guest
+ Types: instance GHC.Show.Show Types.MyResult
+ Types: instance GHC.Show.Show Types.MyUnit
+ Types: instance GHC.Show.Show Types.Newtype
+ Types: instance GHC.Show.Show Types.NewtypeList
+ Types: instance GHC.Show.Show Types.OneConstructor
+ Types: instance GHC.Show.Show Types.OneType
+ Types: instance GHC.Show.Show Types.Prims
+ Types: instance GHC.Show.Show Types.RequestStatus
+ Types: instance GHC.Show.Show Types.User
+ Types: instance GHC.Show.Show Types.UserRequest
+ Types: newtype Age
+ Types: newtype Id a
+ Types: newtype Newtype
+ Types: newtype NewtypeList
+ Types: type Types = '[Prims, MyUnit, MyResult, Id (), Age, Newtype, NewtypeList, OneConstructor, RequestStatus, User, Guest, UserRequest, OneType, CustomCodeGen]

Files

CHANGELOG.md view
@@ -2,7 +2,11 @@  `elm-street` uses [PVP Versioning][1]. The changelog is available [on GitHub][2].-## Unreleased++## 0.2.1.0 - Aug 3, 2023++* Add GHC 9.4.5 and 9.6.2 to CI / tested-with+* Introduce CodeGenOptions to allow customizing record field names.  ## 0.2.0.0 - Mar 29, 2022 
README.md view
@@ -4,16 +4,13 @@  [![Hackage](https://img.shields.io/hackage/v/elm-street.svg)](https://hackage.haskell.org/package/elm-street) [![MPL-2.0 license](https://img.shields.io/badge/license-MPL--2.0-blue.svg)](LICENSE)-[![Stackage Lts](http://stackage.org/package/elm-street/badge/lts)](http://stackage.org/lts/package/elm-street)-[![Stackage Nightly](http://stackage.org/package/elm-street/badge/nightly)](http://stackage.org/nightly/package/elm-street)  Crossing the road between Haskell and Elm.  ## What is this library about? -`Elm-street` allows you to generate automatically derived from Haskell types-definitions of Elm data types, JSON encoders and decoders. This helps to avoid-writing and maintaining huge chunk of boilerplate code when developing full-stack+`elm-street` allows you to automatically generate definitions of Elm data types and compatible JSON encoders and decoders+ from Haskell types. This helps to avoid writing and maintaining huge chunk of boilerplate code when developing full-stack applications.  ## Getting started@@ -58,13 +55,13 @@    > **NOTE:** This requires extension `-XDataKinds`. 4. Use `generateElm` function to output definitions to specified directory under    specified module prefix.-   ```+   ```haskell    main :: IO ()    main = generateElm @Types $ defaultSettings "frontend/src" ["Core", "Generated"]    ```    > **NOTE:** This requires extension `-XTypeApplications`. -   The above command when called generates the following files:+   When executed, the above program generates the following files:       + `frontend/src/Core/Generated/Types.elm`: `Core.Generated.Types` module with the definitions of all types      + `frontend/src/Core/Generated/Encoder.elm`: `Core.Generated.Encoder` module with the JSON encoders for the types@@ -104,7 +101,7 @@        }    ``` 2. Data types with type variables are not supported (see [issue #45](https://github.com/Holmusk/elm-street/issues/45) for more details).-   Though, if type variables are phantom, you still can implement `Elm` instance which+   Though, if type variables are phantom, you can still implement `Elm` instance which    will generate valid Elm defintions. Here is how you can create `Elm` instance for    `newtype`s with phantom type variables:    ```haskell
elm-street.cabal view
@@ -1,6 +1,6 @@ cabal-version:       2.4 name:                elm-street-version:             0.2.0.0+version:             0.2.1.0 synopsis:            Crossing the road between Haskell and Elm description:     `Elm-street` allows you to generate automatically derived from Haskell types@@ -18,17 +18,18 @@ build-type:          Simple extra-doc-files:     README.md                      CHANGELOG.md-tested-with:         GHC == 8.8.4-                     GHC == 8.10.7+tested-with:         GHC == 8.10.7                      GHC == 9.0.2-                     GHC == 9.2.2+                     GHC == 9.2.8+                     GHC == 9.4.5+                     GHC == 9.6.2  source-repository head   type:                git   location:            https://github.com/Holmusk/elm-street.git  common common-options-  build-depends:       base >= 4.11.1.0 && < 4.17+  build-depends:       base >= 4.11.1.0 && < 4.19    ghc-options:         -Wall                        -Wincomplete-uni-patterns@@ -75,7 +76,7 @@                      , directory ^>= 1.3                      , filepath ^>= 1.4                      , prettyprinter >= 1.2.1 && < 1.8-                     , text >= 1.2 && <= 2.0+                     , text >= 1.2 && <= 2.1                      , time  library types
src/Elm/Aeson.hs view
@@ -1,5 +1,3 @@-{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}- {-# LANGUAGE AllowAmbiguousTypes  #-} {-# LANGUAGE FlexibleContexts     #-} {-# LANGUAGE UndecidableInstances #-}@@ -10,7 +8,9 @@  module Elm.Aeson        ( elmStreetParseJson+       , elmStreetParseJsonWith        , elmStreetToJson+       , elmStreetToJsonWith        , elmStreetJsonOptions         , ElmStreet (..)@@ -20,22 +20,20 @@                    defaultOptions, genericParseJSON, genericToJSON) import Data.Aeson.Types (Parser) import GHC.Generics (Generic, Rep)-import Type.Reflection (Typeable, typeRep)+import Type.Reflection (Typeable) -import Elm.Ast (TypeName (..))-import Elm.Generic (Elm (..), GenericElmDefinition (..), HasLessThanEightUnnamedFields,-                    HasNoNamedSum, HasNoTypeVars, stripTypeNamePrefix)+import Elm.Generic (Elm (..), CodeGenOptions (..), GenericElmDefinition (..), ElmStreetGenericConstraints, defaultCodeGenOptions)  import qualified Data.Text as T import qualified GHC.Generics as Generic (from)  -{- | Allows to create 'Data.Aeson.FromJSON' instance that strips the supported-by @elm-street@ data type name prefix from every field..+{- | Allows to create 'Data.Aeson.FromJSON' instance for data types supported by +@elm-street@. Strips data type name prefix from every field.  __Example:__ -With the following @JSON@+The following @JSON@  @ { \"name\": \"John\"@@ -43,16 +41,16 @@ } @ -it is decoded it the following way for each of the specified types:+is decoded in the following way for each of the specified types:  +-------------------------------+--------------------------+ | Haskell data type             | Parsed type              | +===============================+==========================+ | @                             | @                        | | data User = User              | User                     |-| \   { userName :: String      |    { userName = \"John\" |-| \   , userAge  :: Int         |    , userAge  = 42       |-| \   }                         |    }                     |+|    { userName :: String       |    { userName = \"John\" |+|    , userAge  :: Int          |    , userAge  = 42       |+|    }                          |    }                     | | @                             | @                        | +-------------------------------+--------------------------+ |                               |                          |@@ -73,13 +71,13 @@  >>> data User = User { userName :: String, userAge :: Int } deriving (Generic, Show) >>> instance FromJSON User where parseJSON = elmStreetParseJson->>> decode @User "{ \"name\": \"John\", \"age\": 42 }"+>>> decode @User "{\"age\":42,\"name\":\"John\",\"tag\":\"User\"}" Just (User {userName = "John", userAge = 42})   >>> data VeryLongType = VeryLongType { vltName :: String, vltAge :: Int } deriving (Generic, Show) >>> instance FromJSON VeryLongType where parseJSON = elmStreetParseJson->>> decode @VeryLongType "{ \"name\": \"John\", \"age\": 42 }"+>>> decode @VeryLongType "{\"age\":42,\"name\":\"John\",\"tag\":\"VeryLongType\"}" Just (VeryLongType {vltName = "John", vltAge = 42})  -}@@ -88,58 +86,60 @@        (Typeable a, Generic a, GFromJSON Zero (Rep a))     => Value     -> Parser a-elmStreetParseJson = genericParseJSON (elmStreetJsonOptions @a)+elmStreetParseJson = elmStreetParseJsonWith (defaultCodeGenOptions @a) -{- | Allows to create 'Data.Aeson.ToJSON' instance that strips the supported by-@elm-street@ data type name prefix from every field.+{- | Use custom 'CodeGenOptions' to customize the behavior of derived FromJSON instance.+-}+elmStreetParseJsonWith+    :: forall a .+       (Generic a, GFromJSON Zero (Rep a))+    => CodeGenOptions+    -> Value+    -> Parser a+elmStreetParseJsonWith options = genericParseJSON (elmStreetJsonOptions options) +{- | Allows to create 'Data.Aeson.ToJSON' instance for types supported by @elm-street@.+Strips type name prefix from every record field.+ >>> data User = User { userName :: String, userAge :: Int } deriving (Generic, Show) >>> instance ToJSON User where toJSON = elmStreetToJson >>> encode $ User { userName = "John", userAge = 42 }-"{\"age\":42,\"name\":\"John\"}"+"{\"age\":42,\"name\":\"John\",\"tag\":\"User\"}"  >>> data VeryLongType = VeryLongType { vltName :: String, vltAge :: Int } deriving (Generic, Show) >>> instance ToJSON VeryLongType where toJSON = elmStreetToJson >>> encode $ VeryLongType {vltName = "John", vltAge = 42}-"{\"age\":42,\"name\":\"John\"}"+"{\"age\":42,\"name\":\"John\",\"tag\":\"VeryLongType\"}"  >>> data User = User { name :: String, age :: Int } deriving (Generic, Show) >>> instance ToJSON User where toJSON = elmStreetToJson >>> encode $ User { name = "John", age = 42 }-"{\"age\":42,\"name\":\"John\"}"+"{\"age\":42,\"name\":\"John\",\"tag\":\"User\"}" -} elmStreetToJson     :: forall a .        (Typeable a, Generic a, GToJSON Zero (Rep a))     => a     -> Value-elmStreetToJson = genericToJSON (elmStreetJsonOptions @a)--{- | Options to strip type name from the field names.--+----------------+----------------+---------------------+-| Data type name | Field name     | Stripped field name |-+================+================+=====================+-| @User@         | @userName@     | @name@              |-+----------------+----------------+---------------------+-| @AaaBbbCcc@    | @abcFieldName@ | @fieldName@         |-+----------------+----------------+---------------------+-| @Foo@          | @field@        | @field@             |-+----------------+----------------+---------------------+-| @Field@        | @field@        | @field@             |-+----------------+----------------+---------------------++elmStreetToJson = elmStreetToJsonWith (defaultCodeGenOptions @a) +{- | Use custom 'CodeGenOptions' to customize the behavior of derived ToJSON instance. -}-elmStreetJsonOptions :: forall a . Typeable a => Options-elmStreetJsonOptions = defaultOptions-    { fieldLabelModifier = T.unpack . stripTypeNamePrefix typeName . T.pack+elmStreetToJsonWith+    :: forall a .+       (Generic a, GToJSON Zero (Rep a))+    => CodeGenOptions+    -> a+    -> Value+elmStreetToJsonWith options = genericToJSON (elmStreetJsonOptions options)++-- | Build @elm-street@ compatible 'Data.Aeson.Options' from 'CodeGenOptions'.+elmStreetJsonOptions :: CodeGenOptions -> Options+elmStreetJsonOptions options = defaultOptions+    { fieldLabelModifier = T.unpack . cgoFieldLabelModifier options . T.pack     , tagSingleConstructors = True     }-  where-    typeName :: TypeName-    typeName = TypeName $ T.pack $ show $ typeRep @a - {- | Newtype for reusing in @DerivingVia@.  In order to use it with your type @MyType@ add the following deriving to your type:@@ -152,13 +152,8 @@     { unElmStreet :: a     } -instance ( HasNoTypeVars a-         , HasLessThanEightUnnamedFields a-         , HasNoNamedSum a-         , Generic a-         , GenericElmDefinition (Rep a)-         ) => Elm (ElmStreet a) where-    toElmDefinition _ = genericToElmDefinition+instance (ElmStreetGenericConstraints a, Typeable a) => Elm (ElmStreet a) where+    toElmDefinition _ = genericToElmDefinition (defaultCodeGenOptions @a)         $ Generic.from (error "Proxy for generic elm was evaluated" :: a)  instance (Typeable a, Generic a, GToJSON Zero (Rep a)) => ToJSON (ElmStreet a) where
src/Elm/Generate.hs view
@@ -1,5 +1,3 @@-{-# OPTIONS_GHC -fno-warn-orphans #-}- {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE DataKinds           #-} {-# LANGUAGE GADTs               #-}
src/Elm/Generic.hs view
@@ -1,5 +1,3 @@-{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}- {-# LANGUAGE AllowAmbiguousTypes  #-} {-# LANGUAGE DataKinds            #-} {-# LANGUAGE DefaultSignatures    #-}@@ -28,6 +26,9 @@         , GenericConstructor (..)        , toElmConstructor+         -- * Customizing generated elm code and JSON instances+       , CodeGenOptions (..)+       , defaultCodeGenOptions           -- * Type families for compile-time checks        , HasNoTypeVars@@ -42,6 +43,7 @@        , NamedSumError        , CheckNamedSum        , CheckConst+       , ElmStreetGenericConstraints           -- * Internals        , stripTypeNamePrefix@@ -54,6 +56,7 @@ import Data.List.NonEmpty (NonEmpty (..)) import Data.Proxy (Proxy (..)) import Data.Text (Text)+import Type.Reflection (Typeable, typeRep) import Data.Time.Clock (UTCTime) import Data.Type.Bool (If, type (||)) import Data.Void (Void)@@ -77,15 +80,10 @@     toElmDefinition :: Proxy a -> ElmDefinition      default toElmDefinition-        :: ( HasNoTypeVars a-           , HasLessThanEightUnnamedFields a-           , HasNoNamedSum a-           , Generic a-           , GenericElmDefinition (Rep a)-           )+        :: (ElmStreetGenericConstraints a, Typeable a)         => Proxy a         -> ElmDefinition-    toElmDefinition _ = genericToElmDefinition+    toElmDefinition _ = genericToElmDefinition (defaultCodeGenOptions @a)         $ Generic.from (error "Proxy for generic elm was evaluated" :: a)  {- | Returns 'TypeRef' for the existing type. This function always returns the@@ -182,10 +180,10 @@ type and decides what to generate. -} class GenericElmDefinition (f :: k -> Type) where-    genericToElmDefinition :: f a -> ElmDefinition+    genericToElmDefinition :: CodeGenOptions -> f a -> ElmDefinition  instance (Datatype d, GenericElmConstructors f) => GenericElmDefinition (D1 d f) where-    genericToElmDefinition datatype = case genericToElmConstructors (TypeName typeName) (unM1 datatype) of+    genericToElmDefinition options datatype = case genericToElmConstructors options (unM1 datatype) of         c :| [] -> case toElmConstructor c of             Left fields -> DefRecord $ ElmRecord typeName fields elmIsNewtype             Right ctor  -> DefType $ ElmType typeName [] elmIsNewtype (ctor :| [])@@ -232,34 +230,34 @@ {- | Typeclass to collect all constructors of the Haskell data type generically. -} class GenericElmConstructors (f :: k -> Type) where     genericToElmConstructors-        :: TypeName  -- ^ Name of the data type; to be stripped+        :: CodeGenOptions          -> f a  -- ^ Generic value         -> NonEmpty GenericConstructor  -- ^ List of the data type constructors  -- | If it's a sum type then just combine constructors instance (GenericElmConstructors f, GenericElmConstructors g) => GenericElmConstructors (f :+: g) where-    genericToElmConstructors name _ =-        genericToElmConstructors name (error "'f :+:' is evaluated" :: f p)-     <> genericToElmConstructors name (error "':+: g' is evaluated" :: g p)+    genericToElmConstructors options _ =+        genericToElmConstructors options (error "'f :+:' is evaluated" :: f p)+     <> genericToElmConstructors options (error "':+: g' is evaluated" :: g p)  -- | Create singleton list for case of a one constructor. instance (Constructor c, GenericElmFields f) => GenericElmConstructors (C1 c f) where-    genericToElmConstructors name constructor = pure $ GenericConstructor+    genericToElmConstructors options constructor = pure $ GenericConstructor         (T.pack $ conName constructor)-        (genericToElmFields name $ unM1 constructor)+        (genericToElmFields options $ unM1 constructor)  -- | Collect all fields when inside constructor. class GenericElmFields (f :: k -> Type) where     genericToElmFields-        :: TypeName  -- ^ Name of the data type; to be stripped+        :: CodeGenOptions         -> f a  -- ^ Generic value         -> [(TypeRef, Maybe Text)]  -- | If multiple fields then just combine all results. instance (GenericElmFields f, GenericElmFields g) => GenericElmFields (f :*: g) where-    genericToElmFields name _ =-        genericToElmFields name (error "'f :*:' is evaluated" :: f p)-     <> genericToElmFields name (error "':*: g' is evaluated" :: g p)+    genericToElmFields options _ =+        genericToElmFields options (error "'f :*:' is evaluated" :: f p)+     <> genericToElmFields options (error "':*: g' is evaluated" :: g p)  -- | Constructor without fields. instance GenericElmFields U1 where@@ -267,9 +265,9 @@  -- | Single constructor field. instance (Selector s, Elm a) => GenericElmFields (S1 s (Rec0 a)) where-    genericToElmFields typeName selector = case selName selector of+    genericToElmFields options selector = case selName selector of         ""   -> [(elmRef @a, Nothing)]-        name -> [(elmRef @a, Just $ stripTypeNamePrefix typeName $ T.pack name)]+        name -> [(elmRef @a, Just $ cgoFieldLabelModifier options $ T.pack name)]  {- | Strips name of the type name from field name prefix. @@ -303,6 +301,83 @@     leaveIfEmpty :: Text -> Text     leaveIfEmpty rest = if T.null rest then fieldName else headToLower rest +{- | CodeGenOptions allow for customizing some aspects of generated Elm code as well as+ ToJSON and FromJSON instances derived generically.++They can be passed to 'elmStreetParseJsonWith', 'elmStreetToJsonWith' and 'genericToElmDefinition'+to influence the behavior of FromJSON \/ ToJSON and Elm instances respectively.++Note that for Generated Elm encoders \/ decoders to be compatible+with ToJSON \/ FromJSON instances for given type,+__the same CodeGenOptions must be used in Elm \/ ToJSON \/ FromJSON instance declarations__.++Example: Say you don't like the default behavior (stripping type name prefix from all record fields)+and you would like to keep all record field names unmodified instead.+You can achieve that by declaring custom options:++@+myCodeGenOptions :: CodeGenOptions+myCodeGenOptions = CodeGenOptions { cgoFieldLabelModifier = id }+@++And then pass these options when defining Elm \/ ToJSON \/ FromJSON instances.+It is recommended to use DerivingVia to reduce the amount of boilerplate needed.+First declare a newtype whose Elm \/ ToJSON \/ FromJSON instances use your custom CodeGenOptions:++@+newtype CustomElm a = CustomElm {unCustomElm :: a}++instance ElmStreetGenericConstraints a => Elm (CustomElm a) where+    toElmDefinition _ = genericToElmDefinition myCodeGenOptions $+        GHC.Generics.from (error "Proxy for generic elm was evaluated" :: a)++instance (Generic a, GToJSON Zero (Rep a)) => ToJSON (CustomElm a) where+    toJSON = elmStreetToJsonWith myCodeGenOptions . unCustomElm++instance (Generic a, GFromJSON Zero (Rep a)) => FromJSON (CustomElm a) where+    parseJSON = fmap CustomElm . elmStreetParseJsonWith myCodeGenOptions+@++Then derive Elm \/ ToJSON \/ FromJSON instance via that newtype:++@+data MyType = MyType+    { myTypeFieldOne :: String+    , myTypeFieldTwo :: Int+    } deriving stock (Show, Generic)+      deriving (Elm, ToJSON, FromJSON) via CustomElm MyType+@++We can check that type name prefix is no longer stripped from record field names:++>>> encode (MyType "Hello" 10)+"{\"myTypeFieldOne\":\"Hello\",\"myTypeFieldTwo\":10,\"tag\":\"MyType\"}"+-}+newtype CodeGenOptions = CodeGenOptions+    { cgoFieldLabelModifier :: Text -> Text -- ^ Function that modifies record field names (e.g. by dropping type name prefix)+    }++{- | Options to strip type name from the field names.+++----------------+----------------+---------------------++| Data type name | Field name     | Stripped field name |++================+================+=====================++| @User@         | @userName@     | @name@              |++----------------+----------------+---------------------++| @AaaBbbCcc@    | @abcFieldName@ | @fieldName@         |++----------------+----------------+---------------------++| @Foo@          | @field@        | @field@             |++----------------+----------------+---------------------++| @Field@        | @field@        | @field@             |++----------------+----------------+---------------------+++-}+defaultCodeGenOptions :: forall a. Typeable a => CodeGenOptions+defaultCodeGenOptions = CodeGenOptions (stripTypeNamePrefix typeName)+  where+    typeName :: TypeName+    typeName = TypeName $ T.pack $ show $ typeRep @a+ ---------------------------------------------------------------------------- -- ~Magic~ ----------------------------------------------------------------------------@@ -384,3 +459,13 @@     NamedSumError t =              'Text "'elm-street' doesn't support Sum types with records."         ':$$: 'Text "But '" ':<>: 'ShowType t ':<>: 'Text "' has records."++-- | Convenience grouping of constraints that type has to satisfy+-- in order to be eligible for automatic derivation of Elm instance via generics+type ElmStreetGenericConstraints a =+    ( HasNoTypeVars a+    , HasLessThanEightUnnamedFields a+    , HasNoNamedSum a+    , Generic a+    , GenericElmDefinition (Rep a)+    )
test/Test/Golden.hs view
@@ -1,20 +1,25 @@-module Test.Golden-       ( goldenSpec-       ) where--import Test.Hspec (Spec, describe, it, runIO, shouldBe)+module Test.Golden (goldenSpec) where -import Types (OneType, defaultOneType)+import Test.Hspec (Spec, describe, it, shouldBe, shouldReturn) -import Data.Aeson as A-import Data.ByteString.Lazy as LBS+import Types (CustomCodeGen, OneType, defaultCustomCodeGen, defaultOneType) +import qualified Data.Aeson as A+import qualified Data.ByteString.Lazy as LBS  goldenSpec :: Spec goldenSpec = describe "golden tests" $ do-    golden <- runIO $ LBS.readFile "test/golden/oneType.json"--    it "Golden JSON -> Haskell == default" $-        A.eitherDecode @OneType golden `shouldBe` Right defaultOneType-    it "default -> JSON -> Haskell == default" $-        (A.eitherDecode @OneType $ A.encode defaultOneType) `shouldBe` Right defaultOneType+    describe "Default CodeGenOptions" $ do+        it "Golden JSON -> Haskell == default" $+            A.eitherDecode @OneType <$> LBS.readFile "test/golden/oneType.json"+                `shouldReturn` Right defaultOneType+        it "default -> JSON -> Haskell == default" $+            A.eitherDecode @OneType (A.encode defaultOneType)+                `shouldBe` Right defaultOneType+    describe "Custom CodeGenOptions" $ do+        it "should decode type with custom CodeGenOptions" $+            A.eitherDecode @CustomCodeGen "{\"customFunTestInt\": 78,\"customFunTestString\": \"Hello\",\"tag\": \"CustomCodeGen\"}"+                `shouldBe` Right defaultCustomCodeGen+        it "should encode type with custom CodeGen" $+            A.eitherDecode @CustomCodeGen (A.encode defaultCustomCodeGen)+                `shouldBe` Right defaultCustomCodeGen
types/Types.hs view
@@ -1,7 +1,8 @@-{-# LANGUAGE DataKinds          #-}-{-# LANGUAGE DeriveAnyClass     #-}-{-# LANGUAGE DerivingVia        #-}-{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE DataKinds            #-}+{-# LANGUAGE DeriveAnyClass       #-}+{-# LANGUAGE DerivingVia          #-}+{-# LANGUAGE FlexibleContexts     #-}+{-# LANGUAGE UndecidableInstances #-}  {- | Haskell types used for testing `elm-street` generated Elm types. -}@@ -10,6 +11,7 @@        ( Types        , OneType (..)        , defaultOneType+       , defaultCustomCodeGen           -- * All test types        , Prims (..)@@ -22,17 +24,22 @@        , User (..)        , Guest (..)        , UserRequest (..)+       , CustomCodeGen (..)        ) where -import Data.Aeson (FromJSON (..), ToJSON (..), Value(..), object, (.=))+import Data.Aeson (FromJSON(..), ToJSON(..), Value(..), object, (.=), GFromJSON, GToJSON, Zero) import Data.List.NonEmpty (NonEmpty(..)) import Data.Text (Text) import Data.Time.Calendar (fromGregorian) import Data.Time.Clock (UTCTime (..)) import Data.Word (Word32)-import Elm (Elm (..), ElmStreet (..), elmNewtype, elmStreetParseJson, elmStreetToJson)-import GHC.Generics (Generic)+import Elm (Elm (..), ElmStreet (..), elmNewtype)+import Elm.Generic (CodeGenOptions (..), ElmStreetGenericConstraints, GenericElmDefinition(..))+import Elm.Aeson (elmStreetParseJsonWith, elmStreetToJsonWith)+import GHC.Generics (Generic, Rep) +import qualified GHC.Generics as Generic (from)+import qualified Data.Text as Text  data Prims = Prims     { primsUnit     :: !()@@ -79,20 +86,14 @@  data OneConstructor = OneConstructor     deriving stock (Generic, Eq, Show)-    deriving anyclass (Elm)--instance ToJSON   OneConstructor where toJSON = elmStreetToJson-instance FromJSON OneConstructor where parseJSON = elmStreetParseJson+    deriving (Elm, FromJSON, ToJSON) via ElmStreet OneConstructor  data RequestStatus     = Approved     | Rejected     | Reviewing     deriving (Generic, Eq, Show)-    deriving anyclass (Elm)--instance ToJSON   RequestStatus where toJSON = elmStreetToJson-instance FromJSON RequestStatus where parseJSON = elmStreetParseJson+    deriving (Elm, FromJSON, ToJSON) via ElmStreet RequestStatus  data User = User     { userId     :: !(Id User)@@ -100,10 +101,7 @@     , userAge    :: !Age     , userStatus :: !RequestStatus     } deriving (Generic, Eq, Show)-      deriving anyclass (Elm)--instance ToJSON   User where toJSON = elmStreetToJson-instance FromJSON User where parseJSON = elmStreetParseJson+      deriving (Elm, FromJSON, ToJSON) via ElmStreet User  data Guest     = Regular Text Int@@ -111,20 +109,14 @@     | Special (Maybe [Int])     | Blocked     deriving (Generic, Eq, Show)-    deriving anyclass (Elm)--instance ToJSON   Guest where toJSON = elmStreetToJson-instance FromJSON Guest where parseJSON = elmStreetParseJson+    deriving (Elm, FromJSON, ToJSON) via ElmStreet Guest  data UserRequest = UserRequest     { userRequestIds     :: ![Id User]     , userRequestLimit   :: !Word32     , userRequestExample :: !(Maybe (Either User Guest))     } deriving (Generic, Eq, Show)-      deriving anyclass (Elm)--instance ToJSON   UserRequest where toJSON = elmStreetToJson-instance FromJSON UserRequest where parseJSON = elmStreetParseJson+      deriving (Elm, FromJSON, ToJSON) via ElmStreet UserRequest  data MyUnit = MyUnit ()     deriving stock (Show, Eq, Ord, Generic)@@ -135,10 +127,7 @@     = Ok     | Err Text     deriving (Generic, Eq, Show)-    deriving anyclass (Elm)--instance ToJSON   MyResult where toJSON = elmStreetToJson-instance FromJSON MyResult where parseJSON = elmStreetParseJson+    deriving (Elm, FromJSON, ToJSON) via ElmStreet MyResult  -- | All test types together in one type to play with. data OneType = OneType@@ -156,11 +145,31 @@     , oneTypeUserRequest    :: !UserRequest     , oneTypeNonEmpty       :: !(NonEmpty MyUnit)     } deriving (Generic, Eq, Show)-      deriving anyclass (Elm)+      deriving (Elm, FromJSON, ToJSON) via ElmStreet OneType -instance ToJSON   OneType where toJSON = elmStreetToJson-instance FromJSON OneType where parseJSON = elmStreetParseJson+data CustomCodeGen = CustomCodeGen+    { customCodeGenString :: String+    , customCodeGenInt :: Int+    } deriving stock (Generic, Eq, Show)+      deriving (Elm, FromJSON, ToJSON) via CustomElm CustomCodeGen +-- Settings which do some custom modifications of record filed names+customCodeGenOptions :: CodeGenOptions+customCodeGenOptions = CodeGenOptions (Text.replace "CodeGen" "FunTest")++-- Newtype whose Elm/ToJSON/FromJSON instance use custom CodeGenOptions+newtype CustomElm a = CustomElm {unCustomElm :: a}++instance ElmStreetGenericConstraints a => Elm (CustomElm a) where+    toElmDefinition _ = genericToElmDefinition customCodeGenOptions+        $ Generic.from (error "Proxy for generic elm was evaluated" :: a)++instance (Generic a, GToJSON Zero (Rep a)) => ToJSON (CustomElm a) where+    toJSON = elmStreetToJsonWith customCodeGenOptions . unCustomElm++instance (Generic a, GFromJSON Zero (Rep a)) => FromJSON (CustomElm a) where+    parseJSON = fmap CustomElm . elmStreetParseJsonWith customCodeGenOptions+ -- | Type level list of all test types. type Types =    '[ Prims@@ -176,6 +185,7 @@     , Guest     , UserRequest     , OneType+    , CustomCodeGen     ]  @@ -233,3 +243,9 @@         , userRequestLimit   = 123         , userRequestExample = Just (Right Blocked)         }++defaultCustomCodeGen :: CustomCodeGen+defaultCustomCodeGen = CustomCodeGen+    { customCodeGenString = "Hello"+    , customCodeGenInt = 78+    }