com.twilio.guardrail.generators.helpers.DropwizardHelpers.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of guardrail_2.12 Show documentation
Show all versions of guardrail_2.12 Show documentation
Principled code generation for Scala services from OpenAPI specifications
The newest version!
package com.twilio.guardrail.generators.helpers
import cats.data.NonEmptyList
import cats.syntax.all._
import com.twilio.guardrail.core.Tracker
import com.twilio.guardrail.generators.LanguageParameters
import com.twilio.guardrail.languages.LA
import com.twilio.guardrail.protocol.terms._
import io.swagger.v3.oas.models.Operation
object DropwizardHelpers {
private val CONSUMES_PRIORITY = NonEmptyList.of(ApplicationJson, TextPlain, OctetStream)
private val PRODUCES_PRIORITY = NonEmptyList.of(ApplicationJson, TextPlain, OctetStream)
def getBestConsumes[L <: LA](operation: Tracker[Operation], contentTypes: List[ContentType], parameters: LanguageParameters[L]): Option[ContentType] =
if (parameters.formParams.nonEmpty) {
if (parameters.formParams.exists(_.isFile) || contentTypes.contains(MultipartFormData)) {
Some(MultipartFormData)
} else {
Some(UrlencodedFormData)
}
} else {
parameters.bodyParams.map({ bodyParam =>
CONSUMES_PRIORITY
.collectFirstSome(ct => contentTypes.find(_ == ct))
.orElse(contentTypes.collectFirst({ case tc: TextContent => tc }))
.orElse(contentTypes.collectFirst({ case bc: BinaryContent => bc }))
.getOrElse({
val fallback =
if (bodyParam.rawType.tpe.forall(_ == "object")) ApplicationJson
else TextPlain
println(s"WARNING: no supported body param type at ${operation.showHistory}; falling back to $fallback")
fallback
})
})
}
def getBestProduces[L <: LA](
operationId: String,
contentTypes: List[ContentType],
response: Response[L],
fallbackIsString: L#Type => Boolean
): Option[ContentType] =
response.value
.map(_._2)
.flatMap({ valueType =>
PRODUCES_PRIORITY
.collectFirstSome(ct => contentTypes.find(_ == ct))
.orElse(contentTypes.collectFirst({ case tc: TextContent => tc }))
.orElse(contentTypes.collectFirst({ case bc: BinaryContent => bc }))
.orElse({
val fallback = if (fallbackIsString(valueType)) TextPlain else ApplicationJson
println(
s"WARNING: no supported body param type for operation '$operationId', response code ${response.statusCode}; falling back to ${fallback.value}"
)
Option(fallback)
})
})
def removeEmpty(s: String): Option[String] = if (s.trim.isEmpty) None else Some(s.trim)
def splitPathComponents(s: String): List[String] = s.split("/").flatMap(removeEmpty).toList
def findPathPrefix(routePaths: List[String]): List[String] = {
def getHeads(sss: List[List[String]]): (List[Option[String]], List[List[String]]) =
(sss.map(_.headOption), sss.map(_.drop(1)))
def checkMatch(matching: List[String], headsToCheck: List[Option[String]], restOfHeads: List[List[String]]): List[String] =
headsToCheck match {
case Nil => matching
case x :: xs =>
x.fold(matching) { first =>
if (xs.forall(_.contains(first))) {
val (nextHeads, nextRest) = getHeads(restOfHeads)
checkMatch(matching :+ first, nextHeads, nextRest)
} else {
matching
}
}
}
val splitRoutePaths = routePaths.map(splitPathComponents)
val (initialHeads, initialRest) = getHeads(splitRoutePaths)
checkMatch(List.empty, initialHeads, initialRest)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy