Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
9 changes: 8 additions & 1 deletion extra/Lamdera/Wire3/Decoder.hs
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,14 @@ decoderForType ifaces cname tipe =
let extendedRecord = TRecord resolved Nothing & resolveTvar tvars_
in decoderForType ifaces cname extendedRecord
Nothing -> normalDecoder
otherTypes -> normalDecoder
_ ->
-- Resolve extensible records through TAlias chains,
-- e.g. Color = ColorValue { red, green, blue, alpha }
case resolveTvar tvars_ tipe of
TAlias _ _ _ (Filled (TRecord fieldMap Nothing)) ->
let fields = fieldMap & fieldsToList & List.sortOn (\(name, field) -> name)
in decodeRecord ifaces cname fields
_ -> normalDecoder
Filled tipe ->
case tipe of
TRecord fieldMap extensibleName ->
Expand Down
9 changes: 8 additions & 1 deletion extra/Lamdera/Wire3/Encoder.hs
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,14 @@ inlineIfRecordOrCall depth ifaces cname tipe tvars aType =
in deepEncoderForType depth ifaces cname extendedRecord
Nothing -> normalEncoder

otherTypes -> normalEncoder
_ ->
-- Resolve extensible records through TAlias chains,
-- e.g. Color = ColorValue { red, green, blue, alpha }
case resolveTvar tvars tipe of
TAlias _ _ _ (Filled (TRecord fieldMap Nothing)) ->
let extendedRecord = TRecord fieldMap Nothing
Comment thread
dillonkearns marked this conversation as resolved.
Outdated
in deepEncoderForType depth ifaces cname extendedRecord
_ -> normalEncoder
Filled _ -> normalEncoder

{-| Called for encoding tvar type values, i.e.
Expand Down
1 change: 1 addition & 0 deletions test/Test/Wire.hs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ wire = do
, "src/Test/Wire_Tvar_Recursive_Reference.elm"
, "src/Test/Wire_Unsupported.elm"
, "src/Test/Wire_Unconstructable.elm"
, "src/Test/Wire_Union_ForeignRecordAlias.elm"
]

let
Expand Down
35 changes: 35 additions & 0 deletions test/scenario-alltypes/src/Test/External.elm
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ type alias SubSubRecordAlias threadedTvar =
}


type alias ExternalExtensibleBase compatible =
{ compatible | base : String }


type alias ExternalRecordViaExtensible =
ExternalExtensibleBase { red : Int, green : Int }


expected_w3_encode_ExternalRecordBasic : ExternalRecordBasic -> Lamdera.Wire3.Encoder
expected_w3_encode_ExternalRecordBasic =
\w3_rec_var0 -> Lamdera.Wire3.encodeSequenceWithoutLength [ Lamdera.Wire3.encodeInt w3_rec_var0.int ]
Expand Down Expand Up @@ -113,3 +121,30 @@ expected_w3_decode_ExternalCustomThreaded w3_x_c_threadedTvar w3_x_c_threadedTva
_ ->
Lamdera.Wire3.failDecode
)


expected_w3_encode_ExternalExtensibleBase : ({ compatible | base : String.String } -> Lamdera.Wire3.Encoder) -> ExternalExtensibleBase compatible -> Lamdera.Wire3.Encoder
expected_w3_encode_ExternalExtensibleBase w3_x_c_compatible =
w3_x_c_compatible


expected_w3_decode_ExternalExtensibleBase w3_x_c_compatible =
w3_x_c_compatible


expected_w3_encode_ExternalRecordViaExtensible : ExternalRecordViaExtensible -> Lamdera.Wire3.Encoder
expected_w3_encode_ExternalRecordViaExtensible =
\w3_rec_var0 ->
Lamdera.Wire3.encodeSequenceWithoutLength
[ Lamdera.Wire3.encodeString w3_rec_var0.base
, Lamdera.Wire3.encodeInt w3_rec_var0.green
, Lamdera.Wire3.encodeInt w3_rec_var0.red
]


expected_w3_decode_ExternalRecordViaExtensible =
Lamdera.Wire3.succeedDecode
(\base0 green0 red0 -> { base = base0, green = green0, red = red0 })
|> Lamdera.Wire3.andMapDecode Lamdera.Wire3.decodeString
|> Lamdera.Wire3.andMapDecode Lamdera.Wire3.decodeInt
|> Lamdera.Wire3.andMapDecode Lamdera.Wire3.decodeInt
85 changes: 85 additions & 0 deletions test/scenario-alltypes/src/Test/Wire_Union_ForeignRecordAlias.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
module Test.Wire_Union_ForeignRecordAlias exposing (..)

import Bytes.Decode
import Bytes.Encode
import Lamdera.Wire3
import Test.External exposing (ExternalRecordBasic, ExternalRecordViaExtensible)


{-| Regression test: extensible record aliases through alias chains.
See: <https://github.com/elm-explorations/test/pull/249#issuecomment-4076937757>
-}
type WrapsBasicRecord
= WrapsBasicRecord ExternalRecordBasic


type WrapsExtensibleRecord
= WrapsExtensibleRecord ExternalRecordViaExtensible


type WrapsInRecord
= WrapsInRecord { field : ExternalRecordViaExtensible }


expected_w3_encode_WrapsBasicRecord : WrapsBasicRecord -> Lamdera.Wire3.Encoder
expected_w3_encode_WrapsBasicRecord w3v =
case w3v of
WrapsBasicRecord v0 ->
Lamdera.Wire3.encodeSequenceWithoutLength [ Bytes.Encode.unsignedInt8 0, Test.External.w3_encode_ExternalRecordBasic v0 ]


expected_w3_decode_WrapsBasicRecord =
Bytes.Decode.unsignedInt8
|> Lamdera.Wire3.andThenDecode
(\w3v ->
case w3v of
0 ->
Lamdera.Wire3.succeedDecode WrapsBasicRecord |> Lamdera.Wire3.andMapDecode Test.External.w3_decode_ExternalRecordBasic

_ ->
Lamdera.Wire3.failDecode
)


expected_w3_encode_WrapsExtensibleRecord : WrapsExtensibleRecord -> Lamdera.Wire3.Encoder
expected_w3_encode_WrapsExtensibleRecord w3v =
case w3v of
WrapsExtensibleRecord v0 ->
Lamdera.Wire3.encodeSequenceWithoutLength [ Bytes.Encode.unsignedInt8 0, Test.External.w3_encode_ExternalRecordViaExtensible v0 ]


expected_w3_decode_WrapsExtensibleRecord =
Bytes.Decode.unsignedInt8
|> Lamdera.Wire3.andThenDecode
(\w3v ->
case w3v of
0 ->
Lamdera.Wire3.succeedDecode WrapsExtensibleRecord |> Lamdera.Wire3.andMapDecode Test.External.w3_decode_ExternalRecordViaExtensible

_ ->
Lamdera.Wire3.failDecode
)


expected_w3_encode_WrapsInRecord : WrapsInRecord -> Lamdera.Wire3.Encoder
expected_w3_encode_WrapsInRecord w3v =
case w3v of
WrapsInRecord v0 ->
Lamdera.Wire3.encodeSequenceWithoutLength [ Bytes.Encode.unsignedInt8 0, Test.External.w3_encode_ExternalRecordViaExtensible v0.field ]


expected_w3_decode_WrapsInRecord =
Bytes.Decode.unsignedInt8
|> Lamdera.Wire3.andThenDecode
(\w3v ->
case w3v of
0 ->
Lamdera.Wire3.succeedDecode WrapsInRecord
|> Lamdera.Wire3.andMapDecode
(Lamdera.Wire3.succeedDecode (\field0 -> { field = field0 })
|> Lamdera.Wire3.andMapDecode Test.External.w3_decode_ExternalRecordViaExtensible
)

_ ->
Lamdera.Wire3.failDecode
)