guardrail-dev / guardrail

Principled code generation from OpenAPI specifications
https://guardrail.dev
MIT License
524 stars 132 forks source link

[Circe refined] - validation information gets lost when referencing primitive types #1596

Open stanislav-chetvertkov opened 2 years ago

stanislav-chetvertkov commented 2 years ago

When referencing primitive types with added validation properties the information on validation gets lost

definitions:
  Validated:
    type: object
    properties:
      v1:
        $ref: '#/definitions/Pattern'

  Pattern:
    type: string
    pattern: "[0-9]+"

generates

case class Validated(v1: Option[String] = None)

a possible solution is to treat primitive objects with validation as classes during the protocol generation phase

case class Validated(v1: Option[Pattern] = None)

case class Pattern(value: String Refined _root_.eu.timepit.refined.string.MatchesRegex[Pattern.`".*[0-9]+.*"`.T]) extends AnyVal
object Pattern {
  val `".*[0-9]+.*"` = _root_.shapeless.Witness(".*[0-9]+.*")
  // decode and encode as a primitive
}
blast-hardcheese commented 2 years ago

This seems like a reasonable strategy.

Tracing through ProtocolGenerator's fromSwagger, it looks like it should be possible to conditionally enable this by just make extractProperties(model) return value: String Refined ... to bypass this rejection

The other half is whether $ref's will also need special casing, I would hope that it just works.