Skip to content

Instantly share code, notes, and snippets.

@angoglez
Created June 29, 2020 16:28
Show Gist options
  • Save angoglez/524bc8249934aeddd0130a4eb9c0e56e to your computer and use it in GitHub Desktop.
Save angoglez/524bc8249934aeddd0130a4eb9c0e56e to your computer and use it in GitHub Desktop.
Unexpected behavior? - OpenAPIParser
name := "test-srcgen"
version := "0.1"
scalaVersion := "2.13.2"
scalacOptions += "-Ymacro-annotations"
libraryDependencies += "org.typelevel" %% "cats-effect" % "2.1.3"
libraryDependencies += "org.typelevel" %% "cats-core" % "2.1.1"
libraryDependencies += "io.higherkindness" %% "skeuomorph" % "0.0.23"
import cats.effect._
import java.io.{File, PrintWriter}
import cats.implicits._
import higherkindness.droste.data.Mu
import higherkindness.skeuomorph.openapi.ParseOpenApi.YamlSource
import higherkindness.skeuomorph.openapi.schema.OpenApi
import higherkindness.skeuomorph.openapi.{JsonSchemaF, ParseOpenApi}
object TestOpenAPIParser extends IOApp {
val msg =
""" {
| "openapi": "3.0.0",
| "info": {
| "version": "1.0.0",
| "title": "AnotherPetstore",
| "license": {
| "name": "MIT"
| }
| },
| "servers": [
| {
| "url": "http://petstore.swagger.io/v1"
| }
| ],
| "paths": {
| "/pets": {
| "get": {
| "summary": "List all pets",
| "operationId": "getPets",
| "parameters": [
| {
| "name": "limit",
| "in": "query",
| "description": "How many items to return at one time",
| "required": false,
| "schema": {
| "type": "integer",
| "format": "int32"
| }
| },
| {
| "name": "name",
| "in": "query",
| "description": "Items that contains in name the provided string",
| "required": false,
| "schema": {
| "type": "string"
| }
| }
| ],
| "responses": {
| "200": {
| "description": "A paged array of pets",
| "content": {
| "application/json": {
| "schema": {
| "$ref": "#/components/schemas/Pets"
| }
| }
| }
| }
| }
| },
| "post": {
| "summary": "Create a pet",
| "operationId": "createPet",
| "requestBody": {
| "required": true,
| "content": {
| "application/json": {
| "schema": {
| "$ref": "#/components/schemas/NewPet"
| }
| }
| }
| },
| "responses": {
| "201": {
| "description": "Null response"
| },
| "400": {
| "description": "Duplicated response",
| "content": {
| "application/json": {
| "schema": {
| "type": "string"
| }
| }
| }
| },
| "default": {
| "description": "unexpected error",
| "content": {
| "application/json": {
| "schema": {
| "$ref": "#/components/schemas/PetError"
| }
| }
| }
| }
| }
| }
| },
| "/pets/{petId}": {
| "put": {
| "summary": "Update a pet",
| "parameters": [
| {
| "name": "petId",
| "in": "path",
| "required": true,
| "description": "The id of the pet to update",
| "schema": {
| "type": "integer"
| }
| }
| ],
| "operationId": "updatePet",
| "requestBody": {
| "required": true,
| "content": {
| "application/json": {
| "schema": {
| "$ref": "#/components/schemas/UpdatePet"
| }
| }
| }
| },
| "responses": {
| "200": {
| "description": "Null response"
| }
| }
| },
| "delete": {
| "summary": "Delete a pet",
| "operationId": "deletePet",
| "parameters": [
| {
| "name": "petId",
| "in": "path",
| "required": true,
| "description": "The id of the pet to delete",
| "schema": {
| "type": "integer"
| }
| }
| ],
| "responses": {
| "200": {
| "description": "Null response"
| }
| }
| },
| "get": {
| "summary": "Info for a specific pet",
| "operationId": "getPet",
| "parameters": [
| {
| "name": "petId",
| "in": "path",
| "required": true,
| "description": "The id of the pet to retrieve",
| "schema": {
| "type": "integer"
| }
| }
| ],
| "responses": {
| "200": {
| "description": "Expected response to a valid request",
| "content": {
| "application/json": {
| "schema": {
| "$ref": "#/components/schemas/Pet"
| }
| }
| }
| },
| "404": {
| "description": "Not found response",
| "content": {
| "application/json": {
| "schema": {
| "type": "string"
| }
| }
| }
| },
| "default": {
| "description": "unexpected error",
| "content": {
| "application/json": {
| "schema": {
| "$ref": "#/components/schemas/PetError"
| }
| }
| }
| }
| }
| }
| }
| },
| "components": {
| "schemas": {
| "Pet": {
| "required": [
| "id",
| "name"
| ],
| "properties": {
| "id": {
| "type": "integer",
| "format": "int64"
| },
| "name": {
| "type": "string"
| },
| "tag": {
| "type": "string"
| }
| }
| },
| "NewPet": {
| "required": [
| "name"
| ],
| "properties": {
| "name": {
| "type": "string"
| },
| "tag": {
| "type": "string"
| }
| }
| },
| "UpdatePet": {
| "required": [
| "tag"
| ],
| "properties": {
| "tag": {
| "type": "string"
| }
| }
| },
| "Pets": {
| "type": "array",
| "items": {
| "$ref": "#/components/schemas/Pet"
| }
| },
| "PetError": {
| "required": [
| "code",
| "message"
| ],
| "properties": {
| "code": {
| "type": "integer",
| "format": "int32"
| },
| "message": {
| "type": "string"
| }
| }
| },
| "Owner": {
| "required": [
| "person"
| ],
| "properties": {
| "address": {
| "type": "string"
| },
| "person": {
| "type": "object",
| "required": [
| "name",
| "surname"
| ],
| "properties": {
| "name": {
| "type": "string"
| },
| "surname": {
| "type": "string"
| },
| "age": {
| "type": "integer"
| }
| }
| }
| }
| }
| }
| }
| } """.stripMargin
case class FilePrintWriter(file: File, pw: PrintWriter)
private def writeTempFile[F[_]: Sync](
msg: String,
prefix: String,
suffix: String
): F[FilePrintWriter] =
Resource
.make(Sync[F].delay {
val file = File.createTempFile(prefix, suffix)
file.deleteOnExit()
FilePrintWriter(file, new PrintWriter(file))
}) { fpw: FilePrintWriter =>
Sync[F].delay(fpw.pw.close())
}
.use((fpw: FilePrintWriter) => Sync[F].delay(fpw.pw.write(msg)).as(fpw))
private def parserOpenAPIYaml[F[_]: Sync](
raw: String): F[OpenApi[Mu[JsonSchemaF]]] =
for {
tmpFile <- writeTempFile(raw, "OpenAPITempFile", ".yaml")
p <- ParseOpenApi
.parseYamlOpenApi[F, Mu[JsonSchemaF]]
.parse(YamlSource(tmpFile.file))
} yield p
def run(args: List[String]): IO[ExitCode] = {
val smt = parserOpenAPIYaml[IO](msg).unsafeRunSync().info
IO.delay(println(smt)).as(ExitCode.Success)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment