Skip to content
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

Add support for miniBill/codec #13

Merged
merged 8 commits into from
May 13, 2024
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
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ This rule isn't limited to generating toString functions for custom types though
Required package: [MartinSStewart/elm-serialize]
Type features supported: **All\***

### `Codec.Codec e MyType`

Required package: [miniBill/elm-codec]
MartinSStewart marked this conversation as resolved.
Show resolved Hide resolved
Type features supported: **All\***

### `Csv.Decode.Decoder MyType`

Required package: [BrianHicks/elm-csv]
Expand Down Expand Up @@ -82,6 +87,7 @@ unless there is a `Decoder Color` available in the project or dependencies).
\*\* By Enum we mean a custom type where none of the constructors take any arguments. (i.e. `type Semaphore = Red | Yellow | Green`).

[MartinSStewart/elm-serialize]: https://package.elm-lang.org/packages/MartinSStewart/elm-serialize/latest/
[miniBill/elm-codec]: https://package.elm-lang.org/packages/miniBill/elm-codec/latest/
[BrianHicks/elm-csv]: https://package.elm-lang.org/packages/BrianHicks/elm-csv/latest/
[elm/core]: https://package.elm-lang.org/packages/elm/core/latest/
[elm-explorations/test]: https://package.elm-lang.org/packages/elm-explorations/test/latest/
Expand Down
127 changes: 127 additions & 0 deletions src/Internal/Builtin/MiniBillCodec.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
module Internal.Builtin.MiniBillCodec exposing (codeGen)

import CodeGenerator exposing (CodeGenerator)
import Elm.CodeGen as CG
import ResolvedType
import String.Extra
import TypePattern exposing (TypePattern(..))


val =
CG.fqVal [ "Codec" ]


fn1 name arg =
CG.apply [ CG.fqVal [ "Codec" ] name, arg ]


codeGen : CodeGenerator
codeGen =
CodeGenerator.define
{ id = "miniBill/elm-codec/Codec"
, dependency = "miniBill/elm-codec"
, typePattern = Typed [ "Codec" ] "Codec" [ Target ]
, makeName = \name -> String.Extra.decapitalize name ++ "Codec"
}
[ CodeGenerator.int (val "int")
, CodeGenerator.float (val "float")
, CodeGenerator.string (val "string")
, CodeGenerator.list (fn1 "list")
, CodeGenerator.use "Codec.nullable"
, CodeGenerator.dict
(\key value ->
CG.apply
[ val "map"
, CG.fqVal [ "Dict" ] "fromList"
, CG.fqVal [ "Dict" ] "toList"
, CG.apply [ val "list", CG.apply [ val "tuple", key, value ] ]
]
)
, CodeGenerator.unit (val "unit")
, CodeGenerator.tuple (\arg1 arg2 -> CG.apply [ val "tuple", arg1, arg2 ])
, CodeGenerator.triple (\arg1 arg2 arg3 -> CG.apply [ val "tuple", arg1, arg2, arg3 ])
, CodeGenerator.customType
(\ctors exprs ->
CG.pipe
(CG.apply
[ val "custom"
, CG.lambda (List.map (\( ctorRef, _ ) -> CG.varPattern (String.Extra.decapitalize ctorRef.name ++ "Encoder")) ctors ++ [ CG.varPattern "value" ])
(ctors
|> List.map
(\( ctorRef, arguments ) ->
( CG.fqNamedPattern ctorRef.modulePath ctorRef.name (thingsToPatterns arguments)
, CG.apply (CG.val (String.Extra.decapitalize ctorRef.name ++ "Encoder") :: thingsToValues arguments)
)
)
|> CG.caseExpr (CG.val "value")
)
]
)
(List.map Tuple.second exprs ++ [ val "buildCustom" ])
)
, CodeGenerator.combiner
(\t fn exprs ->
case t of
ResolvedType.Opaque reference args ->
CG.apply
([ val ("variant" ++ String.fromInt (List.length args))
, CG.string reference.name
, fn
]
++ exprs
)
|> Just

ResolvedType.AnonymousRecord _ fields ->
CG.pipe
(CG.apply [ val "object", fn ])
(List.map2
(\( field, _ ) expr ->
CG.apply
[ val "field"
, CG.string field
, CG.accessFun ("." ++ field)
, expr
]
)
fields
exprs
++ [ val "buildObject" ]
)
|> Just

ResolvedType.TypeAlias _ _ (ResolvedType.AnonymousRecord _ fields) ->
CG.pipe (CG.apply [ val "object", fn ])
(List.map2
(\( field, _ ) expr ->
CG.apply
[ val "field"
, CG.string field
, CG.accessFun ("." ++ field)
, expr
]
)
fields
exprs
++ [ val "buildObject" ]
)
|> Just

_ ->
Nothing
)
, CodeGenerator.lambdaBreaker
(\expr ->
fn1 "lazy" (CG.lambda [ CG.unitPattern ] expr)
)
]


thingsToPatterns : List a -> List CG.Pattern
thingsToPatterns =
List.indexedMap (\i _ -> CG.varPattern ("arg" ++ String.fromInt i))


thingsToValues : List a -> List CG.Expression
thingsToValues =
List.indexedMap (\i _ -> CG.val ("arg" ++ String.fromInt i))
8 changes: 6 additions & 2 deletions src/Internal/DependencyScanner.elm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Elm.Syntax.ModuleName exposing (ModuleName)
import Elm.Type as T exposing (Type)
import Internal.CodeGenerator exposing (ConfiguredCodeGenerator, ExistingFunctionProvider)
import List.Extra
import Maybe.Extra
import ResolvedType as RT exposing (ResolvedType)
import Review.Project.Dependency as Dependency exposing (Dependency)
import TypePattern as TP exposing (TypePattern)
Expand Down Expand Up @@ -105,8 +106,11 @@ heuristicRejectIfMultiplePatternsForSameType codeGens providers =
Dict.get provider.codeGenId codeGens
|> Maybe.andThen
(\codeGen ->
List.Extra.find (\ref -> ref.modulePath == provider.moduleName && ref.name == provider.functionName) codeGen.blessedImplementations
|> Maybe.map (always provider)
List.Extra.find
(\{ moduleName, functionName } ->
Maybe.Extra.isJust (List.Extra.find (\ref -> ref.modulePath == moduleName && ref.name == functionName) codeGen.blessedImplementations)
)
(provider :: rest)
)
)

Expand Down
2 changes: 2 additions & 0 deletions src/NoDebug/TodoItForMe.elm
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import Internal.Builtin.Fuzzer
import Internal.Builtin.JsonDecoder
import Internal.Builtin.JsonEncoder
import Internal.Builtin.ListAllVariants
import Internal.Builtin.MiniBillCodec
import Internal.Builtin.Random
import Internal.Builtin.ToString
import Internal.CodeGenTodo exposing (CodeGenTodo)
Expand Down Expand Up @@ -80,6 +81,7 @@ rule generators =
, Internal.Builtin.JsonEncoder.codeGen
, Internal.Builtin.JsonDecoder.codeGen
, Internal.Builtin.Codec.codeGen
, Internal.Builtin.MiniBillCodec.codeGen
, Internal.Builtin.Fuzzer.codeGen
, Internal.Builtin.ListAllVariants.codeGen
, Internal.Builtin.ToString.codeGen
Expand Down
Loading
Loading