Skip to content

Commit

Permalink
Add discriminator property to generated typeables. Fix tofu-tf#113
Browse files Browse the repository at this point in the history
  • Loading branch information
danslapman committed Sep 17, 2020
1 parent ac65c9e commit 6cd4f47
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package ru.tinkoff.tschema.finagle

import scala.language.reflectiveCalls

import com.twitter.finagle.http.Response
import monix.eval.Task
import org.scalatest.flatspec.AnyFlatSpec
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import cats.instances.list._
import cats.syntax.option._
import derevo.Derivation
import magnolia.{CaseClass, Magnolia, SealedTrait, TypeName}
import ru.tinkoff.tschema.swagger._
import ru.tinkoff.tschema.swagger.SwaggerTypeable.{Config, seq}
import ru.tinkoff.tschema.swagger.{SwaggerTypeable, _}

object Swagger extends Derivation[SwaggerTypeable] {
type Typeclass[T] = SwaggerTypeable[T]
Expand All @@ -33,22 +33,42 @@ object Swagger extends Derivation[SwaggerTypeable] {
desc: DescribeTypeable[T] = DescribeTypeable.empty[T]
): Typeclass[T] =
new Typeclass[T] {
private val dtr = cfg.discriminator.map(cfg.propMod)

private def addDiscriminatorProperty(props: Vector[SwaggerProperty]): Vector[SwaggerProperty] =
dtr.fold(props) { dName =>
if (props.exists(_.name == dName))
props
else props :+ SwaggerProperty(dName, None, Eval.now(SwaggerPrimitive.string))
}

private def discriminatorRequired(required: Vector[String]): Vector[String] =
dtr.fold(required) { dName =>
if (required.contains(dName)) required else required :+ dName
}

lazy val typ: SwaggerType =
SwaggerRef(
name = calcTypeName(caseClass.typeName, cfg),
descr = desc.whole,
typ = Eval.now(
SwaggerObject(
properties = caseClass.parameters.map { param =>
SwaggerProperty(
name = cfg.propMod(param.label),
description = desc.element(param.label),
typ = Eval.later(param.typeclass.typ)
properties = addDiscriminatorProperty(
caseClass.parameters.map { param =>
SwaggerProperty(
name = cfg.propMod(param.label),
description = desc.element(param.label),
typ = Eval.later(param.typeclass.typ)
)
}.toVector
),
required = Eval.later(
discriminatorRequired(
caseClass.parameters.toVector.collect {
case prop if !prop.typeclass.optional && prop.default.isEmpty => cfg.propMod(prop.label)
}
)
}.toVector,
required = Eval.later(caseClass.parameters.toVector.collect {
case prop if !prop.typeclass.optional && prop.default.isEmpty => cfg.propMod(prop.label)
})
)
)
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,11 +274,30 @@ object GenericSwaggerTypeable {
implicit def genericProductTypeable[T, L <: HList](implicit
lgen: LabelledGeneric.Aux[T, L],
list: HListProps[L],
descr: DescribeTypeable[T] = DescribeTypeable.empty[T]
descr: DescribeTypeable[T] = DescribeTypeable.empty[T],
cfg: Config = SwaggerTypeable.defaultConfig
): GenericSwaggerTypeable[T] = {
def required = Eval.later(list.props.collect { case (name, tt) if !tt.value._2 => name }.toVector)

def props = list.props.map { case (name, tt) => SwaggerProperty(name, descr.element(name), tt.map(_._1)) }.toVector
val dtr = cfg.discriminator.map(cfg.propMod)

def addDiscriminatorProperty(props: Vector[SwaggerProperty]): Vector[SwaggerProperty] =
dtr.fold(props) { dName =>
if (props.exists(_.name == dName))
props
else props :+ SwaggerProperty(dName, None, Eval.now(SwaggerPrimitive.string))
}

def discriminatorRequired(required: Vector[String]): Vector[String] =
dtr.fold(required) { dName =>
if (required.contains(dName)) required else required :+ dName
}

def required = Eval.later(discriminatorRequired(list.props.collect {
case (name, tt) if !tt.value._2 => cfg.propMod(name)
}.toVector))

def props = addDiscriminatorProperty(list.props.map {
case (name, tt) => SwaggerProperty(name, descr.element(name), tt.map(_._1))
}.toVector)

make[T](SwaggerObject(props, required), descr.whole)
}
Expand Down

0 comments on commit 6cd4f47

Please sign in to comment.