Skip to content

Commit

Permalink
Flip codec and codecType so codec is defined in terms of codecType in…
Browse files Browse the repository at this point in the history
…stead of the other way around.
  • Loading branch information
mrdziuban committed Oct 23, 2024
1 parent f3c754d commit 7ee5c0f
Showing 1 changed file with 18 additions and 33 deletions.
51 changes: 18 additions & 33 deletions src/main/scala/scalats/TsGenerator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ final class TsGenerator(

case class WrapCodec(custom: Generated => (Generated => Generated => Generated => Generated) => Generated) {
final def apply(codec: Generated): Generated =
custom(codec)(codec => codecType => valueType => codec |+| codecType |+| valueType)
custom(codec)(codecType => codec => valueType => codecType |+| codec |+| valueType)
}

object WrapCodec {
Expand Down Expand Up @@ -135,13 +135,13 @@ final class TsGenerator(

/**
* Produces TypeScript function parameters, typically used in conjunction with `typeArgsMixed`
* e.g. `(A1: A1, A2: A2, ...) => `
* e.g. `(A1: A1, A2: A2, ...)[: RetType] => `
*/
private def typeArgsFnParams(state: State, typeArgs: List[TsModel]): Generated =
private def typeArgsFnParams(state: State, typeArgs: List[TsModel], retType: Option[Generated]): Generated =
if (typeArgs.isEmpty) Generated.empty
else "(" |+| typeArgs.intercalateMap(imports.lift(", "))(
generate(state, _).foldMap(_._2).pipe(x => x |+| ": " |+| x)
) |+| ") => "
) |+| ")" |+| retType.fold(Generated.empty)(t => ": " |+| t) |+| " => "

/**
* The `io-ts` value corresponding to a Scala `Map`
Expand Down Expand Up @@ -348,12 +348,12 @@ final class TsGenerator(
lazy val minimalTaggedFields = List(tagField(name))

lazy val minimalTaggedCodec: Generated =
// Tagged codec type
"export type " |+| cap(taggedCodecName) |+| " = " |+| generateFieldsType(minimalTaggedFields) |+| ";\n" |+|
// Codec with only `_tag` value
"export const " |+| taggedCodecName |+| ": " |+| generateFieldsType(minimalTaggedFields) |+| " = " |+|
"export const " |+| taggedCodecName |+| ": " |+| cap(taggedCodecName) |+| " = " |+|
generateFieldsCodec(state, minimalTaggedFields) |+|
";\n" |+|
// Tagged codec type
"export type " |+| cap(taggedCodecName) |+| " = typeof " |+| taggedCodecName |+| ";\n" |+|
// Tagged value type
"export type " |+| taggedValueType |+| " = " |+| imports.iotsTypeOf(cap(taggedCodecName)) |+| ";\n" |+|
// Full codec type
Expand All @@ -367,11 +367,11 @@ final class TsGenerator(
",\n" |+|
" (x: " |+| valueType |+| "): " |+| taggedValueType |+| " => ({ ...x, _tag: `" |+| name |+| "`}),\n" |+|
")"
))(codec => codecType => _ /* we create our own value type */ =>
))(codecType => codec => _ /* we create our own value type */ =>
// Full value type
"export type " |+| valueType |+| " = " |+| taggedValueType |+| " & typeof " |+| constName |+| ";\n" |+|
codec |+|
codecType
codecType |+|
codec
)

val codec =
Expand Down Expand Up @@ -453,7 +453,7 @@ final class TsGenerator(
Monoid[List[(Option[TypeName], Generated)]].combine(memberCodecs.flatten, List((Some(typeName),
"export const all" |+| valueType |+| "C = " |+|
typeArgsMixed(state.copy(top = false), typeArgs) |+|
typeArgsFnParams(state.copy(top = false), typeArgs) |+|
typeArgsFnParams(state.copy(top = false), typeArgs, None) |+|
allMemberCodecsArr |+| " as const;\n" |+|
"export const " |+| allNamesConstName |+| " = [" |+| memberNames.intercalateMap(", ")(s => s"`$s`") |+| "] as const;\n" |+|
"export type " |+| valueType |+| "Name = (typeof " |+| allNamesConstName |+| ")[number];\n\n" |+|
Expand Down Expand Up @@ -664,39 +664,26 @@ final class TsGenerator(
})
val codecType = cap(codecName)
val valueType = codecType.replaceAll("C(U?)$", "$1")
val className = codecName ++ "C"
val hasTypeArgs = model match {
case _: TsModel.Interface | _: TsModel.Object | _: TsModel.Union => model.typeArgs.nonEmpty
case _ => false
}

if (hasTypeArgs) {
val updState = State(false, WrapCodec.id)
val tpArgsPlain = model.typeArgs.intercalateMap(imports.lift(","))(generate(updState, _).foldMap(_._2))
val tpArgsPlain = model.typeArgs.intercalateMap(imports.lift(","))(genNotTop(updState, _))
val tpArgsIots = typeArgsMixed(updState, model.typeArgs)
val fnArgs = typeArgsFnParams(updState, model.typeArgs)
val fnArgs = typeArgsFnParams(updState, model.typeArgs, Some(codecType |+| "<" |+| tpArgsPlain |+| ">"))
generate(State(true, WrapCodec(codec => f =>
f(
"export class " |+| className |+|
tpArgsIots |+|
"{ codec: " |+| fnArgs |+| generateType(model) |+| " = " |+|
fnArgs |+|
codec |+|
"}\n" |+|
"export const " |+| codecName |+| " = " |+|
tpArgsIots |+|
fnArgs |+|
"new " |+| className |+| "<" |+| tpArgsPlain |+| ">().codec(" |+| tpArgsPlain |+| ");\n"
"export type " |+| codecType |+| tpArgsIots |+| " = " |+| generateType(model) |+| ";\n"
)(
"export type " |+| codecType |+| tpArgsIots |+|
" = ReturnType<" |+| className |+| "<" |+| tpArgsPlain |+| ">[\"codec\"]>;\n"
"export const " |+| codecName |+| " = " |+| tpArgsIots |+| fnArgs |+| codec |+| ";\n"
)(
"export type " |+| valueType |+| "<" |+| tpArgsPlain |+| "> = " |+|
imports.iotsTypeOf(
codecType |+| "<" |+|
model.typeArgs.intercalateMap(imports.lift(","))(
t => imports.iotsTypeType(generate(updState, t).foldMap(_._2))
) |+|
model.typeArgs.intercalateMap(imports.lift(", "))(t => imports.iotsTypeType(genNotTop(updState, t))) |+|
">"
) |+|
";"
Expand All @@ -705,11 +692,9 @@ final class TsGenerator(
} else
generate(State(true, WrapCodec(codec => f =>
f(
"export const " |+| codecName |+| ": " |+| generateType(model) |+| " = " |+|
codec |+|
";\n"
"export type " |+| codecType |+| " = " |+| generateType(model) |+| ";\n"
)(
"export type " |+| codecType |+| " = typeof " |+| codecName |+| ";\n"
"export const " |+| codecName |+| ": " |+| codecType |+| " = " |+| codec |+| ";\n"
)(
"export type " |+| valueType |+| " = " |+| imports.iotsTypeOf(codecType) |+| ";\n"
)
Expand Down

0 comments on commit 7ee5c0f

Please sign in to comment.