Skip to content
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
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
8 changes: 7 additions & 1 deletion extra/Lamdera/Wire3/Encoder.hs
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,13 @@ 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 extendedRecord@(TRecord _ Nothing)) ->
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
)