forked from loafle/openapi-generator-original
Scala cask api effects (#19936)
* Scala-cask improvements:
* fixe for grouped methods which have routes containing dashes.
Previously our OperationGroup work-around would potentially
Create methods like ‘foo-bar’, which isn’t a valid function name
* Fix to not import some.package.Array[Byte] when binary format is specified
* Fix for grouped operations which contain duplicate query parameters
* Fix for binary response fields. This can come up with the following example
"responses" : {
"200" : {
"content" : {
"application/json" : {
"schema" : {
"format" : "binary",
"type" : "string"
}
}
},
"description" : "data"
},
* Fix for enum model classes
Extracted complex logic for ‘asData’ and ‘asModel’ transformations for properties
* Introduced a generic effect F[_] for services
This was done to support composable services
(Service A calls Service B) by using monadic
Effect types (ones which can flatMap)
* Fixed unique union types for responses, asModel and asData fixes for non-model types
* scala-cask: regenerated samples
* Fix for reserved-word properties in the API
* Fix for null imports and reserved-word enum types
* Fixes for api methods with backticked params
* Fix for duplicate (by name) grouped params
* small syntax fix
* logging response type
* Regenerated samples
* String.format fix
This commit is contained in:
@@ -14,10 +14,10 @@
|
||||
* https://openapi-generator.tech
|
||||
*/
|
||||
|
||||
|
||||
// this file was generated from app.mustache
|
||||
package cask.groupId.server
|
||||
|
||||
import scala.util.Try
|
||||
import _root_.sample.cask.model.*
|
||||
import _root_.sample.cask.api.*
|
||||
|
||||
@@ -30,20 +30,23 @@ import _root_.sample.cask.api.*
|
||||
* If you wanted fine-grained control over the routes and services, you could
|
||||
* extend the cask.MainRoutes and mix in this trait by using this:
|
||||
*
|
||||
* \{\{\{
|
||||
* ```
|
||||
* override def allRoutes = appRoutes
|
||||
* \}\}\}
|
||||
* ```
|
||||
*
|
||||
* More typically, however, you would extend the 'BaseApp' class
|
||||
*/
|
||||
trait AppRoutes {
|
||||
def appPetService : PetService = PetService()
|
||||
def appPetService : PetService[Try] = PetService()
|
||||
def routeForPet : PetRoutes = PetRoutes(appPetService)
|
||||
def appStoreService : StoreService = StoreService()
|
||||
|
||||
def appStoreService : StoreService[Try] = StoreService()
|
||||
def routeForStore : StoreRoutes = StoreRoutes(appStoreService)
|
||||
def appUserService : UserService = UserService()
|
||||
|
||||
def appUserService : UserService[Try] = UserService()
|
||||
def routeForUser : UserRoutes = UserRoutes(appUserService)
|
||||
|
||||
|
||||
def appRoutes = Seq(
|
||||
routeForPet ,
|
||||
routeForStore ,
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
// this file was generated from app.mustache
|
||||
package cask.groupId.server
|
||||
|
||||
import scala.util.Try
|
||||
import _root_.sample.cask.model.*
|
||||
import _root_.sample.cask.api.*
|
||||
|
||||
@@ -26,11 +27,11 @@ import _root_.sample.cask.api.*
|
||||
* passing in the custom business logic services
|
||||
*/
|
||||
class BaseApp(
|
||||
override val appPetService : PetService = PetService(),
|
||||
override val appPetService : PetService[Try] = PetService(),
|
||||
|
||||
override val appStoreService : StoreService = StoreService(),
|
||||
override val appStoreService : StoreService[Try] = StoreService(),
|
||||
|
||||
override val appUserService : UserService = UserService(),
|
||||
override val appUserService : UserService[Try] = UserService(),
|
||||
override val port : Int = sys.env.get("PORT").map(_.toInt).getOrElse(8080)) extends cask.MainRoutes with AppRoutes {
|
||||
|
||||
/** routes for the UI
|
||||
|
||||
@@ -22,12 +22,13 @@ import sample.cask.model.*
|
||||
|
||||
import upickle.default.{ReadWriter => RW, macroRW}
|
||||
import upickle.default.*
|
||||
import scala.util.Try
|
||||
|
||||
import sample.cask.model.ApiResponse
|
||||
import java.io.File
|
||||
import sample.cask.model.Pet
|
||||
|
||||
class PetRoutes(service : PetService) extends cask.Routes {
|
||||
class PetRoutes(service : PetService[Try]) extends cask.Routes {
|
||||
|
||||
// route group for routeWorkAroundForPOSTPet
|
||||
@cask.post("/pet", true)
|
||||
@@ -63,7 +64,8 @@ class PetRoutes(service : PetService) extends cask.Routes {
|
||||
petJson <- Parsed.fromTry(request.bodyAsJson)
|
||||
petData <- Parsed.eval(PetData.fromJson(petJson)) /* not array or map */
|
||||
pet <- Parsed.fromTry(petData.validated(failFast))
|
||||
result <- Parsed.eval(service.addPet(pet))
|
||||
resultTry <- Parsed.eval(service.addPet(pet))
|
||||
result <- Parsed.fromTry(resultTry)
|
||||
} yield result
|
||||
|
||||
(result : @unchecked) match {
|
||||
@@ -84,7 +86,8 @@ class PetRoutes(service : PetService) extends cask.Routes {
|
||||
val result = for {
|
||||
petId <- Parsed(petId)
|
||||
apiKey <- request.headerSingleValueOptional("apiKey")
|
||||
result <- Parsed.eval(service.deletePet(petId, apiKey))
|
||||
resultTry <- Parsed.eval(service.deletePet(petId, apiKey))
|
||||
result <- Parsed.fromTry(resultTry)
|
||||
} yield result
|
||||
|
||||
(result : @unchecked) match {
|
||||
@@ -102,7 +105,8 @@ class PetRoutes(service : PetService) extends cask.Routes {
|
||||
def failFast = request.queryParams.keySet.contains("failFast")
|
||||
|
||||
val result = for {
|
||||
result <- Parsed.eval(service.findPetsByStatus(status))
|
||||
resultTry <- Parsed.eval(service.findPetsByStatus(status))
|
||||
result <- Parsed.fromTry(resultTry)
|
||||
} yield result
|
||||
|
||||
(result : @unchecked) match {
|
||||
@@ -121,7 +125,8 @@ class PetRoutes(service : PetService) extends cask.Routes {
|
||||
def failFast = request.queryParams.keySet.contains("failFast")
|
||||
|
||||
val result = for {
|
||||
result <- Parsed.eval(service.findPetsByTags(tags))
|
||||
resultTry <- Parsed.eval(service.findPetsByTags(tags))
|
||||
result <- Parsed.fromTry(resultTry)
|
||||
} yield result
|
||||
|
||||
(result : @unchecked) match {
|
||||
@@ -141,7 +146,8 @@ class PetRoutes(service : PetService) extends cask.Routes {
|
||||
|
||||
val result = for {
|
||||
petId <- Parsed(petId)
|
||||
result <- Parsed.eval(service.getPetById(petId))
|
||||
resultTry <- Parsed.eval(service.getPetById(petId))
|
||||
result <- Parsed.fromTry(resultTry)
|
||||
} yield result
|
||||
|
||||
(result : @unchecked) match {
|
||||
@@ -163,7 +169,8 @@ class PetRoutes(service : PetService) extends cask.Routes {
|
||||
petJson <- Parsed.fromTry(request.bodyAsJson)
|
||||
petData <- Parsed.eval(PetData.fromJson(petJson)) /* not array or map */
|
||||
pet <- Parsed.fromTry(petData.validated(failFast))
|
||||
result <- Parsed.eval(service.updatePet(pet))
|
||||
resultTry <- Parsed.eval(service.updatePet(pet))
|
||||
result <- Parsed.fromTry(resultTry)
|
||||
} yield result
|
||||
|
||||
(result : @unchecked) match {
|
||||
@@ -185,7 +192,8 @@ class PetRoutes(service : PetService) extends cask.Routes {
|
||||
petId <- Parsed(petId)
|
||||
name <- request.formSingleValueOptional("name")
|
||||
status <- request.formSingleValueOptional("status")
|
||||
result <- Parsed.eval(service.updatePetWithForm(petId, name, status))
|
||||
resultTry <- Parsed.eval(service.updatePetWithForm(petId, name, status))
|
||||
result <- Parsed.fromTry(resultTry)
|
||||
} yield result
|
||||
|
||||
(result : @unchecked) match {
|
||||
@@ -206,7 +214,8 @@ class PetRoutes(service : PetService) extends cask.Routes {
|
||||
petId <- Parsed(petId)
|
||||
additionalMetadata <- request.formSingleValueOptional("additionalMetadata")
|
||||
file <- request.formValueAsFileOptional("file")
|
||||
result <- Parsed.eval(service.uploadFile(petId, additionalMetadata, file))
|
||||
resultTry <- Parsed.eval(service.uploadFile(petId, additionalMetadata, file))
|
||||
result <- Parsed.fromTry(resultTry)
|
||||
} yield result
|
||||
|
||||
(result : @unchecked) match {
|
||||
|
||||
@@ -22,10 +22,11 @@ import sample.cask.model.*
|
||||
|
||||
import upickle.default.{ReadWriter => RW, macroRW}
|
||||
import upickle.default.*
|
||||
import scala.util.Try
|
||||
|
||||
import sample.cask.model.Order
|
||||
|
||||
class StoreRoutes(service : StoreService) extends cask.Routes {
|
||||
class StoreRoutes(service : StoreService[Try]) extends cask.Routes {
|
||||
|
||||
|
||||
/** Delete purchase order by ID
|
||||
@@ -38,7 +39,8 @@ class StoreRoutes(service : StoreService) extends cask.Routes {
|
||||
|
||||
val result = for {
|
||||
orderId <- Parsed(orderId)
|
||||
result <- Parsed.eval(service.deleteOrder(orderId))
|
||||
resultTry <- Parsed.eval(service.deleteOrder(orderId))
|
||||
result <- Parsed.fromTry(resultTry)
|
||||
} yield result
|
||||
|
||||
(result : @unchecked) match {
|
||||
@@ -56,7 +58,8 @@ class StoreRoutes(service : StoreService) extends cask.Routes {
|
||||
def failFast = request.queryParams.keySet.contains("failFast")
|
||||
|
||||
val result = for {
|
||||
result <- Parsed.eval(service.getInventory())
|
||||
resultTry <- Parsed.eval(service.getInventory())
|
||||
result <- Parsed.fromTry(resultTry)
|
||||
} yield result
|
||||
|
||||
(result : @unchecked) match {
|
||||
@@ -75,7 +78,8 @@ class StoreRoutes(service : StoreService) extends cask.Routes {
|
||||
|
||||
val result = for {
|
||||
orderId <- Parsed(orderId)
|
||||
result <- Parsed.eval(service.getOrderById(orderId))
|
||||
resultTry <- Parsed.eval(service.getOrderById(orderId))
|
||||
result <- Parsed.fromTry(resultTry)
|
||||
} yield result
|
||||
|
||||
(result : @unchecked) match {
|
||||
@@ -96,7 +100,8 @@ class StoreRoutes(service : StoreService) extends cask.Routes {
|
||||
orderJson <- Parsed.fromTry(request.bodyAsJson)
|
||||
orderData <- Parsed.eval(OrderData.fromJson(orderJson)) /* not array or map */
|
||||
order <- Parsed.fromTry(orderData.validated(failFast))
|
||||
result <- Parsed.eval(service.placeOrder(order))
|
||||
resultTry <- Parsed.eval(service.placeOrder(order))
|
||||
result <- Parsed.fromTry(resultTry)
|
||||
} yield result
|
||||
|
||||
(result : @unchecked) match {
|
||||
|
||||
@@ -22,11 +22,12 @@ import sample.cask.model.*
|
||||
|
||||
import upickle.default.{ReadWriter => RW, macroRW}
|
||||
import upickle.default.*
|
||||
import scala.util.Try
|
||||
|
||||
import java.time.OffsetDateTime
|
||||
import sample.cask.model.User
|
||||
|
||||
class UserRoutes(service : UserService) extends cask.Routes {
|
||||
class UserRoutes(service : UserService[Try]) extends cask.Routes {
|
||||
|
||||
// route group for routeWorkAroundForGETUser
|
||||
@cask.get("/user", true)
|
||||
@@ -52,7 +53,8 @@ class UserRoutes(service : UserService) extends cask.Routes {
|
||||
userJson <- Parsed.fromTry(request.bodyAsJson)
|
||||
userData <- Parsed.eval(UserData.fromJson(userJson)) /* not array or map */
|
||||
user <- Parsed.fromTry(userData.validated(failFast))
|
||||
result <- Parsed.eval(service.createUser(user))
|
||||
resultTry <- Parsed.eval(service.createUser(user))
|
||||
result <- Parsed.fromTry(resultTry)
|
||||
} yield result
|
||||
|
||||
(result : @unchecked) match {
|
||||
@@ -71,7 +73,8 @@ class UserRoutes(service : UserService) extends cask.Routes {
|
||||
|
||||
val result = for {
|
||||
user <- Parsed.fromTry(UserData.manyFromJsonStringValidated(request.bodyAsString)).mapError(e => s"Error parsing json as an array of User from >${request.bodyAsString}< : ${e}") /* array */
|
||||
result <- Parsed.eval(service.createUsersWithArrayInput(user))
|
||||
resultTry <- Parsed.eval(service.createUsersWithArrayInput(user))
|
||||
result <- Parsed.fromTry(resultTry)
|
||||
} yield result
|
||||
|
||||
(result : @unchecked) match {
|
||||
@@ -90,7 +93,8 @@ class UserRoutes(service : UserService) extends cask.Routes {
|
||||
|
||||
val result = for {
|
||||
user <- Parsed.fromTry(UserData.manyFromJsonStringValidated(request.bodyAsString)).mapError(e => s"Error parsing json as an array of User from >${request.bodyAsString}< : ${e}") /* array */
|
||||
result <- Parsed.eval(service.createUsersWithListInput(user))
|
||||
resultTry <- Parsed.eval(service.createUsersWithListInput(user))
|
||||
result <- Parsed.fromTry(resultTry)
|
||||
} yield result
|
||||
|
||||
(result : @unchecked) match {
|
||||
@@ -109,7 +113,8 @@ class UserRoutes(service : UserService) extends cask.Routes {
|
||||
|
||||
val result = for {
|
||||
username <- Parsed(username)
|
||||
result <- Parsed.eval(service.deleteUser(username))
|
||||
resultTry <- Parsed.eval(service.deleteUser(username))
|
||||
result <- Parsed.fromTry(resultTry)
|
||||
} yield result
|
||||
|
||||
(result : @unchecked) match {
|
||||
@@ -127,7 +132,8 @@ class UserRoutes(service : UserService) extends cask.Routes {
|
||||
|
||||
val result = for {
|
||||
username <- Parsed(username)
|
||||
result <- Parsed.eval(service.getUserByName(username))
|
||||
resultTry <- Parsed.eval(service.getUserByName(username))
|
||||
result <- Parsed.fromTry(resultTry)
|
||||
} yield result
|
||||
|
||||
(result : @unchecked) match {
|
||||
@@ -145,7 +151,8 @@ class UserRoutes(service : UserService) extends cask.Routes {
|
||||
def failFast = request.queryParams.keySet.contains("failFast")
|
||||
|
||||
val result = for {
|
||||
result <- Parsed.eval(service.loginUser(username, password))
|
||||
resultTry <- Parsed.eval(service.loginUser(username, password))
|
||||
result <- Parsed.fromTry(resultTry)
|
||||
} yield result
|
||||
|
||||
(result : @unchecked) match {
|
||||
@@ -164,7 +171,8 @@ class UserRoutes(service : UserService) extends cask.Routes {
|
||||
def failFast = request.queryParams.keySet.contains("failFast")
|
||||
|
||||
val result = for {
|
||||
result <- Parsed.eval(service.logoutUser())
|
||||
resultTry <- Parsed.eval(service.logoutUser())
|
||||
result <- Parsed.fromTry(resultTry)
|
||||
} yield result
|
||||
|
||||
(result : @unchecked) match {
|
||||
@@ -186,7 +194,8 @@ class UserRoutes(service : UserService) extends cask.Routes {
|
||||
userJson <- Parsed.fromTry(request.bodyAsJson)
|
||||
userData <- Parsed.eval(UserData.fromJson(userJson)) /* not array or map */
|
||||
user <- Parsed.fromTry(userData.validated(failFast))
|
||||
result <- Parsed.eval(service.updateUser(username, user))
|
||||
resultTry <- Parsed.eval(service.updateUser(username, user))
|
||||
result <- Parsed.fromTry(resultTry)
|
||||
} yield result
|
||||
|
||||
(result : @unchecked) match {
|
||||
|
||||
@@ -25,6 +25,16 @@ import scala.reflect.ClassTag
|
||||
import scala.util.*
|
||||
import upickle.default.*
|
||||
|
||||
|
||||
extension (f: java.io.File) {
|
||||
def bytes: Array[Byte] = java.nio.file.Files.readAllBytes(f.toPath)
|
||||
def toBase64: String = java.util.Base64.getEncoder.encodeToString(bytes)
|
||||
}
|
||||
|
||||
given Writer[java.io.File] = new Writer[java.io.File] {
|
||||
def write0[V](out: upickle.core.Visitor[?, V], v: java.io.File) = out.visitString(v.toBase64, -1)
|
||||
}
|
||||
|
||||
// needed for BigDecimal params
|
||||
given cask.endpoints.QueryParamReader.SimpleParam[BigDecimal](BigDecimal.apply)
|
||||
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
/**
|
||||
* OpenAPI Petstore
|
||||
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*
|
||||
* Contact: team@openapitools.org
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||
*
|
||||
* https://openapi-generator.tech
|
||||
*/
|
||||
/** OpenAPI Petstore This is a sample server Petstore server. For this sample, you can use the api
|
||||
* key `special-key` to test the authorization filters.
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*
|
||||
* Contact: team@openapitools.org
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||
*
|
||||
* https://openapi-generator.tech
|
||||
*/
|
||||
|
||||
// this model was generated using modelTest.mustache
|
||||
package sample.cask.model
|
||||
@@ -20,16 +19,16 @@ import scala.util.*
|
||||
|
||||
class ApiResponseTest extends AnyWordSpec with Matchers {
|
||||
|
||||
"ApiResponse.fromJson" should {
|
||||
"""not parse invalid json""" in {
|
||||
val Failure(err) = Try(ApiResponseData.fromJsonString("invalid jason"))
|
||||
err.getMessage should startWith ("Error parsing json 'invalid jason'")
|
||||
}
|
||||
"""parse """ ignore {
|
||||
val Failure(err : ValidationErrors) = ApiResponseData.fromJsonString("""""").validated()
|
||||
|
||||
sys.error("TODO")
|
||||
}
|
||||
"ApiResponse.fromJson" should {
|
||||
"""not parse invalid json""" in {
|
||||
val Failure(err) = Try(ApiResponseData.fromJsonString("invalid jason"))
|
||||
err.getMessage should startWith("Error parsing json 'invalid jason'")
|
||||
}
|
||||
"""parse """ ignore {
|
||||
val Failure(err: ValidationErrors) = ApiResponseData.fromJsonString("""""").validated()
|
||||
|
||||
sys.error("TODO")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
/**
|
||||
* OpenAPI Petstore
|
||||
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*
|
||||
* Contact: team@openapitools.org
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||
*
|
||||
* https://openapi-generator.tech
|
||||
*/
|
||||
/** OpenAPI Petstore This is a sample server Petstore server. For this sample, you can use the api
|
||||
* key `special-key` to test the authorization filters.
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*
|
||||
* Contact: team@openapitools.org
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||
*
|
||||
* https://openapi-generator.tech
|
||||
*/
|
||||
|
||||
// this model was generated using modelTest.mustache
|
||||
package sample.cask.model
|
||||
@@ -20,16 +19,16 @@ import scala.util.*
|
||||
|
||||
class CategoryTest extends AnyWordSpec with Matchers {
|
||||
|
||||
"Category.fromJson" should {
|
||||
"""not parse invalid json""" in {
|
||||
val Failure(err) = Try(CategoryData.fromJsonString("invalid jason"))
|
||||
err.getMessage should startWith ("Error parsing json 'invalid jason'")
|
||||
}
|
||||
"""parse """ ignore {
|
||||
val Failure(err : ValidationErrors) = CategoryData.fromJsonString("""""").validated()
|
||||
|
||||
sys.error("TODO")
|
||||
}
|
||||
"Category.fromJson" should {
|
||||
"""not parse invalid json""" in {
|
||||
val Failure(err) = Try(CategoryData.fromJsonString("invalid jason"))
|
||||
err.getMessage should startWith("Error parsing json 'invalid jason'")
|
||||
}
|
||||
"""parse """ ignore {
|
||||
val Failure(err: ValidationErrors) = CategoryData.fromJsonString("""""").validated()
|
||||
|
||||
sys.error("TODO")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
/**
|
||||
* OpenAPI Petstore
|
||||
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*
|
||||
* Contact: team@openapitools.org
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||
*
|
||||
* https://openapi-generator.tech
|
||||
*/
|
||||
/** OpenAPI Petstore This is a sample server Petstore server. For this sample, you can use the api
|
||||
* key `special-key` to test the authorization filters.
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*
|
||||
* Contact: team@openapitools.org
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||
*
|
||||
* https://openapi-generator.tech
|
||||
*/
|
||||
|
||||
// this model was generated using modelTest.mustache
|
||||
package sample.cask.model
|
||||
@@ -21,16 +20,16 @@ import scala.util.*
|
||||
|
||||
class OrderTest extends AnyWordSpec with Matchers {
|
||||
|
||||
"Order.fromJson" should {
|
||||
"""not parse invalid json""" in {
|
||||
val Failure(err) = Try(OrderData.fromJsonString("invalid jason"))
|
||||
err.getMessage should startWith ("Error parsing json 'invalid jason'")
|
||||
}
|
||||
"""parse """ ignore {
|
||||
val Failure(err : ValidationErrors) = OrderData.fromJsonString("""""").validated()
|
||||
|
||||
sys.error("TODO")
|
||||
}
|
||||
"Order.fromJson" should {
|
||||
"""not parse invalid json""" in {
|
||||
val Failure(err) = Try(OrderData.fromJsonString("invalid jason"))
|
||||
err.getMessage should startWith("Error parsing json 'invalid jason'")
|
||||
}
|
||||
"""parse """ ignore {
|
||||
val Failure(err: ValidationErrors) = OrderData.fromJsonString("""""").validated()
|
||||
|
||||
sys.error("TODO")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
/**
|
||||
* OpenAPI Petstore
|
||||
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*
|
||||
* Contact: team@openapitools.org
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||
*
|
||||
* https://openapi-generator.tech
|
||||
*/
|
||||
/** OpenAPI Petstore This is a sample server Petstore server. For this sample, you can use the api
|
||||
* key `special-key` to test the authorization filters.
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*
|
||||
* Contact: team@openapitools.org
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||
*
|
||||
* https://openapi-generator.tech
|
||||
*/
|
||||
|
||||
// this model was generated using modelTest.mustache
|
||||
package sample.cask.model
|
||||
import sample.cask.model.Category
|
||||
import sample.cask.model.Tag
|
||||
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
import org.scalatest.wordspec.AnyWordSpec
|
||||
@@ -22,16 +19,16 @@ import scala.util.*
|
||||
|
||||
class PetTest extends AnyWordSpec with Matchers {
|
||||
|
||||
"Pet.fromJson" should {
|
||||
"""not parse invalid json""" in {
|
||||
val Failure(err) = Try(PetData.fromJsonString("invalid jason"))
|
||||
err.getMessage should startWith ("Error parsing json 'invalid jason'")
|
||||
}
|
||||
"""parse """ ignore {
|
||||
val Failure(err : ValidationErrors) = PetData.fromJsonString("""""").validated()
|
||||
|
||||
sys.error("TODO")
|
||||
}
|
||||
"Pet.fromJson" should {
|
||||
"""not parse invalid json""" in {
|
||||
val Failure(err) = Try(PetData.fromJsonString("invalid jason"))
|
||||
err.getMessage should startWith("Error parsing json 'invalid jason'")
|
||||
}
|
||||
"""parse """ ignore {
|
||||
val Failure(err: ValidationErrors) = PetData.fromJsonString("""""").validated()
|
||||
|
||||
sys.error("TODO")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
/**
|
||||
* OpenAPI Petstore
|
||||
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*
|
||||
* Contact: team@openapitools.org
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||
*
|
||||
* https://openapi-generator.tech
|
||||
*/
|
||||
/** OpenAPI Petstore This is a sample server Petstore server. For this sample, you can use the api
|
||||
* key `special-key` to test the authorization filters.
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*
|
||||
* Contact: team@openapitools.org
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||
*
|
||||
* https://openapi-generator.tech
|
||||
*/
|
||||
|
||||
// this model was generated using modelTest.mustache
|
||||
package sample.cask.model
|
||||
@@ -20,16 +19,16 @@ import scala.util.*
|
||||
|
||||
class TagTest extends AnyWordSpec with Matchers {
|
||||
|
||||
"Tag.fromJson" should {
|
||||
"""not parse invalid json""" in {
|
||||
val Failure(err) = Try(TagData.fromJsonString("invalid jason"))
|
||||
err.getMessage should startWith ("Error parsing json 'invalid jason'")
|
||||
}
|
||||
"""parse """ ignore {
|
||||
val Failure(err : ValidationErrors) = TagData.fromJsonString("""""").validated()
|
||||
|
||||
sys.error("TODO")
|
||||
}
|
||||
"Tag.fromJson" should {
|
||||
"""not parse invalid json""" in {
|
||||
val Failure(err) = Try(TagData.fromJsonString("invalid jason"))
|
||||
err.getMessage should startWith("Error parsing json 'invalid jason'")
|
||||
}
|
||||
"""parse """ ignore {
|
||||
val Failure(err: ValidationErrors) = TagData.fromJsonString("""""").validated()
|
||||
|
||||
sys.error("TODO")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
/**
|
||||
* OpenAPI Petstore
|
||||
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*
|
||||
* Contact: team@openapitools.org
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||
*
|
||||
* https://openapi-generator.tech
|
||||
*/
|
||||
/** OpenAPI Petstore This is a sample server Petstore server. For this sample, you can use the api
|
||||
* key `special-key` to test the authorization filters.
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*
|
||||
* Contact: team@openapitools.org
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator.
|
||||
*
|
||||
* https://openapi-generator.tech
|
||||
*/
|
||||
|
||||
// this model was generated using modelTest.mustache
|
||||
package sample.cask.model
|
||||
@@ -20,16 +19,16 @@ import scala.util.*
|
||||
|
||||
class UserTest extends AnyWordSpec with Matchers {
|
||||
|
||||
"User.fromJson" should {
|
||||
"""not parse invalid json""" in {
|
||||
val Failure(err) = Try(UserData.fromJsonString("invalid jason"))
|
||||
err.getMessage should startWith ("Error parsing json 'invalid jason'")
|
||||
}
|
||||
"""parse """ ignore {
|
||||
val Failure(err : ValidationErrors) = UserData.fromJsonString("""""").validated()
|
||||
|
||||
sys.error("TODO")
|
||||
}
|
||||
"User.fromJson" should {
|
||||
"""not parse invalid json""" in {
|
||||
val Failure(err) = Try(UserData.fromJsonString("invalid jason"))
|
||||
err.getMessage should startWith("Error parsing json 'invalid jason'")
|
||||
}
|
||||
"""parse """ ignore {
|
||||
val Failure(err: ValidationErrors) = UserData.fromJsonString("""""").validated()
|
||||
|
||||
sys.error("TODO")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,64 +21,260 @@ package sample.cask.api
|
||||
import _root_.sample.cask.model.ApiResponse
|
||||
import _root_.java.io.File
|
||||
import _root_.sample.cask.model.Pet
|
||||
|
||||
import scala.util.Failure
|
||||
import scala.util.Try
|
||||
import _root_.sample.cask.model.*
|
||||
|
||||
/**
|
||||
* The PetService companion object.
|
||||
*
|
||||
* Use the PetService() companion object to create an instance which returns a 'not implemented' error
|
||||
* for each operation.
|
||||
*
|
||||
*/
|
||||
object PetService {
|
||||
def apply() : PetService = new PetService {
|
||||
override def addPet(pet : Pet) : Pet = ???
|
||||
override def deletePet(petId : Long, apiKey : Option[String]) : Unit = ???
|
||||
override def findPetsByStatus(status : Seq[String]) : List[Pet] = ???
|
||||
override def findPetsByTags(tags : Seq[String]) : List[Pet] = ???
|
||||
override def getPetById(petId : Long) : Pet = ???
|
||||
override def updatePet(pet : Pet) : Pet = ???
|
||||
override def updatePetWithForm(petId : Long, name : Option[String], status : Option[String]) : Unit = ???
|
||||
override def uploadFile(petId : Long, additionalMetadata : Option[String], file : Option[File]) : ApiResponse = ???
|
||||
|
||||
/**
|
||||
* The 'Handler' is an implementation of PetService convenient for delegating or overriding individual functions
|
||||
*/
|
||||
case class Handler[F[_]](
|
||||
addPetHandler : (pet : Pet) => F[Pet],
|
||||
deletePetHandler : (petId : Long, apiKey : Option[String]) => F[Unit],
|
||||
findPetsByStatusHandler : (status : Seq[String]) => F[List[Pet]],
|
||||
findPetsByTagsHandler : (tags : Seq[String]) => F[List[Pet]],
|
||||
getPetByIdHandler : (petId : Long) => F[Pet],
|
||||
updatePetHandler : (pet : Pet) => F[Pet],
|
||||
updatePetWithFormHandler : (petId : Long, name : Option[String], status : Option[String]) => F[Unit],
|
||||
uploadFileHandler : (petId : Long, additionalMetadata : Option[String], file : Option[File]) => F[ApiResponse]
|
||||
) extends PetService[F] {
|
||||
|
||||
override def addPet(pet : Pet) : F[Pet] = {
|
||||
addPetHandler(pet)
|
||||
}
|
||||
|
||||
override def deletePet(petId : Long, apiKey : Option[String]) : F[Unit] = {
|
||||
deletePetHandler(petId, apiKey)
|
||||
}
|
||||
|
||||
override def findPetsByStatus(status : Seq[String]) : F[List[Pet]] = {
|
||||
findPetsByStatusHandler(status)
|
||||
}
|
||||
|
||||
override def findPetsByTags(tags : Seq[String]) : F[List[Pet]] = {
|
||||
findPetsByTagsHandler(tags)
|
||||
}
|
||||
|
||||
override def getPetById(petId : Long) : F[Pet] = {
|
||||
getPetByIdHandler(petId)
|
||||
}
|
||||
|
||||
override def updatePet(pet : Pet) : F[Pet] = {
|
||||
updatePetHandler(pet)
|
||||
}
|
||||
|
||||
override def updatePetWithForm(petId : Long, name : Option[String], status : Option[String]) : F[Unit] = {
|
||||
updatePetWithFormHandler(petId, name, status)
|
||||
}
|
||||
|
||||
override def uploadFile(petId : Long, additionalMetadata : Option[String], file : Option[File]) : F[ApiResponse] = {
|
||||
uploadFileHandler(petId, additionalMetadata, file)
|
||||
}
|
||||
}
|
||||
|
||||
def apply() : PetService[Try] = PetService.Handler[Try](
|
||||
(_) => notImplemented("addPet"),
|
||||
(_, _) => notImplemented("deletePet"),
|
||||
(_) => notImplemented("findPetsByStatus"),
|
||||
(_) => notImplemented("findPetsByTags"),
|
||||
(_) => notImplemented("getPetById"),
|
||||
(_) => notImplemented("updatePet"),
|
||||
(_, _, _) => notImplemented("updatePetWithForm"),
|
||||
(_, _, _) => notImplemented("uploadFile")
|
||||
)
|
||||
|
||||
private def notImplemented(name : String) = Failure(new Exception(s"TODO: $name not implemented"))
|
||||
}
|
||||
|
||||
/**
|
||||
* The Pet business-logic
|
||||
*
|
||||
*
|
||||
* The 'asHandler' will return an implementation which allows for easily overriding individual operations.
|
||||
*
|
||||
* equally there are "on<Function>" helper methods for easily overriding individual functions
|
||||
*
|
||||
* @tparam F the effect type (Future, Try, IO, ID, etc) of the operations
|
||||
*/
|
||||
trait PetService {
|
||||
trait PetService[F[_]] {
|
||||
/** Add a new pet to the store
|
||||
*
|
||||
* @return Pet
|
||||
*/
|
||||
def addPet(pet : Pet) : Pet
|
||||
def addPet(pet : Pet) : F[Pet]
|
||||
|
||||
/**
|
||||
* override addPet with the given handler
|
||||
* @return a new implementation of PetService[F] with addPet overridden using the given handler
|
||||
*/
|
||||
final def onAddPet(handler : (pet : Pet) => F[Pet]) : PetService[F] = {
|
||||
asHandler.copy(addPetHandler = handler)
|
||||
}
|
||||
/** Deletes a pet
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
def deletePet(petId : Long, apiKey : Option[String]) : Unit
|
||||
def deletePet(petId : Long, apiKey : Option[String]) : F[Unit]
|
||||
|
||||
/**
|
||||
* override deletePet with the given handler
|
||||
* @return a new implementation of PetService[F] with deletePet overridden using the given handler
|
||||
*/
|
||||
final def onDeletePet(handler : (petId : Long, apiKey : Option[String]) => F[Unit]) : PetService[F] = {
|
||||
asHandler.copy(deletePetHandler = handler)
|
||||
}
|
||||
/** Finds Pets by status
|
||||
*
|
||||
* @return List[Pet]
|
||||
*/
|
||||
def findPetsByStatus(status : Seq[String]) : List[Pet]
|
||||
def findPetsByStatus(status : Seq[String]) : F[List[Pet]]
|
||||
|
||||
/**
|
||||
* override findPetsByStatus with the given handler
|
||||
* @return a new implementation of PetService[F] with findPetsByStatus overridden using the given handler
|
||||
*/
|
||||
final def onFindPetsByStatus(handler : (status : Seq[String]) => F[List[Pet]]) : PetService[F] = {
|
||||
asHandler.copy(findPetsByStatusHandler = handler)
|
||||
}
|
||||
/** Finds Pets by tags
|
||||
*
|
||||
* @return List[Pet]
|
||||
*/
|
||||
def findPetsByTags(tags : Seq[String]) : List[Pet]
|
||||
def findPetsByTags(tags : Seq[String]) : F[List[Pet]]
|
||||
|
||||
/**
|
||||
* override findPetsByTags with the given handler
|
||||
* @return a new implementation of PetService[F] with findPetsByTags overridden using the given handler
|
||||
*/
|
||||
final def onFindPetsByTags(handler : (tags : Seq[String]) => F[List[Pet]]) : PetService[F] = {
|
||||
asHandler.copy(findPetsByTagsHandler = handler)
|
||||
}
|
||||
/** Find pet by ID
|
||||
*
|
||||
* @return Pet
|
||||
*/
|
||||
def getPetById(petId : Long) : Pet
|
||||
def getPetById(petId : Long) : F[Pet]
|
||||
|
||||
/**
|
||||
* override getPetById with the given handler
|
||||
* @return a new implementation of PetService[F] with getPetById overridden using the given handler
|
||||
*/
|
||||
final def onGetPetById(handler : (petId : Long) => F[Pet]) : PetService[F] = {
|
||||
asHandler.copy(getPetByIdHandler = handler)
|
||||
}
|
||||
/** Update an existing pet
|
||||
*
|
||||
* @return Pet
|
||||
*/
|
||||
def updatePet(pet : Pet) : Pet
|
||||
def updatePet(pet : Pet) : F[Pet]
|
||||
|
||||
/**
|
||||
* override updatePet with the given handler
|
||||
* @return a new implementation of PetService[F] with updatePet overridden using the given handler
|
||||
*/
|
||||
final def onUpdatePet(handler : (pet : Pet) => F[Pet]) : PetService[F] = {
|
||||
asHandler.copy(updatePetHandler = handler)
|
||||
}
|
||||
/** Updates a pet in the store with form data
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
def updatePetWithForm(petId : Long, name : Option[String], status : Option[String]) : Unit
|
||||
def updatePetWithForm(petId : Long, name : Option[String], status : Option[String]) : F[Unit]
|
||||
|
||||
/**
|
||||
* override updatePetWithForm with the given handler
|
||||
* @return a new implementation of PetService[F] with updatePetWithForm overridden using the given handler
|
||||
*/
|
||||
final def onUpdatePetWithForm(handler : (petId : Long, name : Option[String], status : Option[String]) => F[Unit]) : PetService[F] = {
|
||||
asHandler.copy(updatePetWithFormHandler = handler)
|
||||
}
|
||||
/** uploads an image
|
||||
*
|
||||
* @return ApiResponse
|
||||
*/
|
||||
def uploadFile(petId : Long, additionalMetadata : Option[String], file : Option[File]) : ApiResponse
|
||||
def uploadFile(petId : Long, additionalMetadata : Option[String], file : Option[File]) : F[ApiResponse]
|
||||
|
||||
/**
|
||||
* override uploadFile with the given handler
|
||||
* @return a new implementation of PetService[F] with uploadFile overridden using the given handler
|
||||
*/
|
||||
final def onUploadFile(handler : (petId : Long, additionalMetadata : Option[String], file : Option[File]) => F[ApiResponse]) : PetService[F] = {
|
||||
asHandler.copy(uploadFileHandler = handler)
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a Handler implementation of this service
|
||||
*/
|
||||
final def asHandler : PetService.Handler[F] = this match {
|
||||
case h : PetService.Handler[F] => h
|
||||
case _ =>
|
||||
PetService.Handler[F](
|
||||
(pet) => addPet(pet),
|
||||
(petId, apiKey) => deletePet(petId, apiKey),
|
||||
(status) => findPetsByStatus(status),
|
||||
(tags) => findPetsByTags(tags),
|
||||
(petId) => getPetById(petId),
|
||||
(pet) => updatePet(pet),
|
||||
(petId, name, status) => updatePetWithForm(petId, name, status),
|
||||
(petId, additionalMetadata, file) => uploadFile(petId, additionalMetadata, file)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will change the effect type of this service.
|
||||
*
|
||||
* It's not unlike a typical map operation from A => B, except we're not mapping
|
||||
* a type from A to B, but rather from F[A] => G[A] using the 'changeEffect' function.
|
||||
*
|
||||
* For, this could turn an asynchronous service (one which returns Future[_] types) into
|
||||
* a synchronous one (one which returns Try[_] types) by awaiting on the Future.
|
||||
*
|
||||
* It could change an IO type (like cats effect or ZIO) into an ID[A] which is just:
|
||||
* ```
|
||||
* type ID[A] => A
|
||||
* ```
|
||||
*
|
||||
* @tparam G the new "polymorphic" effect type
|
||||
* @param changeEffect the "natural transformation" which can change one effect type into another
|
||||
* @return a new PetService service implementation with effect type [G]
|
||||
*/
|
||||
final def mapEffect[G[_]](changeEffect : [A] => F[A] => G[A]) : PetService[G] = {
|
||||
val self = this
|
||||
|
||||
new PetService[G] {
|
||||
override def addPet(pet : Pet) : G[Pet] = changeEffect {
|
||||
self.addPet(pet)
|
||||
}
|
||||
override def deletePet(petId : Long, apiKey : Option[String]) : G[Unit] = changeEffect {
|
||||
self.deletePet(petId, apiKey)
|
||||
}
|
||||
override def findPetsByStatus(status : Seq[String]) : G[List[Pet]] = changeEffect {
|
||||
self.findPetsByStatus(status)
|
||||
}
|
||||
override def findPetsByTags(tags : Seq[String]) : G[List[Pet]] = changeEffect {
|
||||
self.findPetsByTags(tags)
|
||||
}
|
||||
override def getPetById(petId : Long) : G[Pet] = changeEffect {
|
||||
self.getPetById(petId)
|
||||
}
|
||||
override def updatePet(pet : Pet) : G[Pet] = changeEffect {
|
||||
self.updatePet(pet)
|
||||
}
|
||||
override def updatePetWithForm(petId : Long, name : Option[String], status : Option[String]) : G[Unit] = changeEffect {
|
||||
self.updatePetWithForm(petId, name, status)
|
||||
}
|
||||
override def uploadFile(petId : Long, additionalMetadata : Option[String], file : Option[File]) : G[ApiResponse] = changeEffect {
|
||||
self.uploadFile(petId, additionalMetadata, file)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,40 +19,168 @@
|
||||
package sample.cask.api
|
||||
|
||||
import _root_.sample.cask.model.Order
|
||||
|
||||
import scala.util.Failure
|
||||
import scala.util.Try
|
||||
import _root_.sample.cask.model.*
|
||||
|
||||
/**
|
||||
* The StoreService companion object.
|
||||
*
|
||||
* Use the StoreService() companion object to create an instance which returns a 'not implemented' error
|
||||
* for each operation.
|
||||
*
|
||||
*/
|
||||
object StoreService {
|
||||
def apply() : StoreService = new StoreService {
|
||||
override def deleteOrder(orderId : String) : Unit = ???
|
||||
override def getInventory() : Map[String, Int] = ???
|
||||
override def getOrderById(orderId : Long) : Order = ???
|
||||
override def placeOrder(order : Order) : Order = ???
|
||||
|
||||
/**
|
||||
* The 'Handler' is an implementation of StoreService convenient for delegating or overriding individual functions
|
||||
*/
|
||||
case class Handler[F[_]](
|
||||
deleteOrderHandler : (orderId : String) => F[Unit],
|
||||
getInventoryHandler : () => F[Map[String, Int]],
|
||||
getOrderByIdHandler : (orderId : Long) => F[Order],
|
||||
placeOrderHandler : (order : Order) => F[Order]
|
||||
) extends StoreService[F] {
|
||||
|
||||
override def deleteOrder(orderId : String) : F[Unit] = {
|
||||
deleteOrderHandler(orderId)
|
||||
}
|
||||
|
||||
override def getInventory() : F[Map[String, Int]] = {
|
||||
getInventoryHandler()
|
||||
}
|
||||
|
||||
override def getOrderById(orderId : Long) : F[Order] = {
|
||||
getOrderByIdHandler(orderId)
|
||||
}
|
||||
|
||||
override def placeOrder(order : Order) : F[Order] = {
|
||||
placeOrderHandler(order)
|
||||
}
|
||||
}
|
||||
|
||||
def apply() : StoreService[Try] = StoreService.Handler[Try](
|
||||
(_) => notImplemented("deleteOrder"),
|
||||
() => notImplemented("getInventory"),
|
||||
(_) => notImplemented("getOrderById"),
|
||||
(_) => notImplemented("placeOrder")
|
||||
)
|
||||
|
||||
private def notImplemented(name : String) = Failure(new Exception(s"TODO: $name not implemented"))
|
||||
}
|
||||
|
||||
/**
|
||||
* The Store business-logic
|
||||
*
|
||||
*
|
||||
* The 'asHandler' will return an implementation which allows for easily overriding individual operations.
|
||||
*
|
||||
* equally there are "on<Function>" helper methods for easily overriding individual functions
|
||||
*
|
||||
* @tparam F the effect type (Future, Try, IO, ID, etc) of the operations
|
||||
*/
|
||||
trait StoreService {
|
||||
trait StoreService[F[_]] {
|
||||
/** Delete purchase order by ID
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
def deleteOrder(orderId : String) : Unit
|
||||
def deleteOrder(orderId : String) : F[Unit]
|
||||
|
||||
/**
|
||||
* override deleteOrder with the given handler
|
||||
* @return a new implementation of StoreService[F] with deleteOrder overridden using the given handler
|
||||
*/
|
||||
final def onDeleteOrder(handler : (orderId : String) => F[Unit]) : StoreService[F] = {
|
||||
asHandler.copy(deleteOrderHandler = handler)
|
||||
}
|
||||
/** Returns pet inventories by status
|
||||
*
|
||||
* @return Map[String, Int]
|
||||
*/
|
||||
def getInventory() : Map[String, Int]
|
||||
def getInventory() : F[Map[String, Int]]
|
||||
|
||||
/**
|
||||
* override getInventory with the given handler
|
||||
* @return a new implementation of StoreService[F] with getInventory overridden using the given handler
|
||||
*/
|
||||
final def onGetInventory(handler : () => F[Map[String, Int]]) : StoreService[F] = {
|
||||
asHandler.copy(getInventoryHandler = handler)
|
||||
}
|
||||
/** Find purchase order by ID
|
||||
*
|
||||
* @return Order
|
||||
*/
|
||||
def getOrderById(orderId : Long) : Order
|
||||
def getOrderById(orderId : Long) : F[Order]
|
||||
|
||||
/**
|
||||
* override getOrderById with the given handler
|
||||
* @return a new implementation of StoreService[F] with getOrderById overridden using the given handler
|
||||
*/
|
||||
final def onGetOrderById(handler : (orderId : Long) => F[Order]) : StoreService[F] = {
|
||||
asHandler.copy(getOrderByIdHandler = handler)
|
||||
}
|
||||
/** Place an order for a pet
|
||||
*
|
||||
* @return Order
|
||||
*/
|
||||
def placeOrder(order : Order) : Order
|
||||
def placeOrder(order : Order) : F[Order]
|
||||
|
||||
/**
|
||||
* override placeOrder with the given handler
|
||||
* @return a new implementation of StoreService[F] with placeOrder overridden using the given handler
|
||||
*/
|
||||
final def onPlaceOrder(handler : (order : Order) => F[Order]) : StoreService[F] = {
|
||||
asHandler.copy(placeOrderHandler = handler)
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a Handler implementation of this service
|
||||
*/
|
||||
final def asHandler : StoreService.Handler[F] = this match {
|
||||
case h : StoreService.Handler[F] => h
|
||||
case _ =>
|
||||
StoreService.Handler[F](
|
||||
(orderId) => deleteOrder(orderId),
|
||||
() => getInventory(),
|
||||
(orderId) => getOrderById(orderId),
|
||||
(order) => placeOrder(order)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will change the effect type of this service.
|
||||
*
|
||||
* It's not unlike a typical map operation from A => B, except we're not mapping
|
||||
* a type from A to B, but rather from F[A] => G[A] using the 'changeEffect' function.
|
||||
*
|
||||
* For, this could turn an asynchronous service (one which returns Future[_] types) into
|
||||
* a synchronous one (one which returns Try[_] types) by awaiting on the Future.
|
||||
*
|
||||
* It could change an IO type (like cats effect or ZIO) into an ID[A] which is just:
|
||||
* ```
|
||||
* type ID[A] => A
|
||||
* ```
|
||||
*
|
||||
* @tparam G the new "polymorphic" effect type
|
||||
* @param changeEffect the "natural transformation" which can change one effect type into another
|
||||
* @return a new StoreService service implementation with effect type [G]
|
||||
*/
|
||||
final def mapEffect[G[_]](changeEffect : [A] => F[A] => G[A]) : StoreService[G] = {
|
||||
val self = this
|
||||
|
||||
new StoreService[G] {
|
||||
override def deleteOrder(orderId : String) : G[Unit] = changeEffect {
|
||||
self.deleteOrder(orderId)
|
||||
}
|
||||
override def getInventory() : G[Map[String, Int]] = changeEffect {
|
||||
self.getInventory()
|
||||
}
|
||||
override def getOrderById(orderId : Long) : G[Order] = changeEffect {
|
||||
self.getOrderById(orderId)
|
||||
}
|
||||
override def placeOrder(order : Order) : G[Order] = changeEffect {
|
||||
self.placeOrder(order)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,64 +20,260 @@ package sample.cask.api
|
||||
|
||||
import _root_.java.time.OffsetDateTime
|
||||
import _root_.sample.cask.model.User
|
||||
|
||||
import scala.util.Failure
|
||||
import scala.util.Try
|
||||
import _root_.sample.cask.model.*
|
||||
|
||||
/**
|
||||
* The UserService companion object.
|
||||
*
|
||||
* Use the UserService() companion object to create an instance which returns a 'not implemented' error
|
||||
* for each operation.
|
||||
*
|
||||
*/
|
||||
object UserService {
|
||||
def apply() : UserService = new UserService {
|
||||
override def createUser(user : User) : Unit = ???
|
||||
override def createUsersWithArrayInput(user : Seq[User]) : Unit = ???
|
||||
override def createUsersWithListInput(user : Seq[User]) : Unit = ???
|
||||
override def deleteUser(username : String) : Unit = ???
|
||||
override def getUserByName(username : String) : User = ???
|
||||
override def loginUser(username : String, password : String) : String = ???
|
||||
override def logoutUser() : Unit = ???
|
||||
override def updateUser(username : String, user : User) : Unit = ???
|
||||
|
||||
/**
|
||||
* The 'Handler' is an implementation of UserService convenient for delegating or overriding individual functions
|
||||
*/
|
||||
case class Handler[F[_]](
|
||||
createUserHandler : (user : User) => F[Unit],
|
||||
createUsersWithArrayInputHandler : (user : Seq[User]) => F[Unit],
|
||||
createUsersWithListInputHandler : (user : Seq[User]) => F[Unit],
|
||||
deleteUserHandler : (username : String) => F[Unit],
|
||||
getUserByNameHandler : (username : String) => F[User],
|
||||
loginUserHandler : (username : String, password : String) => F[String],
|
||||
logoutUserHandler : () => F[Unit],
|
||||
updateUserHandler : (username : String, user : User) => F[Unit]
|
||||
) extends UserService[F] {
|
||||
|
||||
override def createUser(user : User) : F[Unit] = {
|
||||
createUserHandler(user)
|
||||
}
|
||||
|
||||
override def createUsersWithArrayInput(user : Seq[User]) : F[Unit] = {
|
||||
createUsersWithArrayInputHandler(user)
|
||||
}
|
||||
|
||||
override def createUsersWithListInput(user : Seq[User]) : F[Unit] = {
|
||||
createUsersWithListInputHandler(user)
|
||||
}
|
||||
|
||||
override def deleteUser(username : String) : F[Unit] = {
|
||||
deleteUserHandler(username)
|
||||
}
|
||||
|
||||
override def getUserByName(username : String) : F[User] = {
|
||||
getUserByNameHandler(username)
|
||||
}
|
||||
|
||||
override def loginUser(username : String, password : String) : F[String] = {
|
||||
loginUserHandler(username, password)
|
||||
}
|
||||
|
||||
override def logoutUser() : F[Unit] = {
|
||||
logoutUserHandler()
|
||||
}
|
||||
|
||||
override def updateUser(username : String, user : User) : F[Unit] = {
|
||||
updateUserHandler(username, user)
|
||||
}
|
||||
}
|
||||
|
||||
def apply() : UserService[Try] = UserService.Handler[Try](
|
||||
(_) => notImplemented("createUser"),
|
||||
(_) => notImplemented("createUsersWithArrayInput"),
|
||||
(_) => notImplemented("createUsersWithListInput"),
|
||||
(_) => notImplemented("deleteUser"),
|
||||
(_) => notImplemented("getUserByName"),
|
||||
(_, _) => notImplemented("loginUser"),
|
||||
() => notImplemented("logoutUser"),
|
||||
(_, _) => notImplemented("updateUser")
|
||||
)
|
||||
|
||||
private def notImplemented(name : String) = Failure(new Exception(s"TODO: $name not implemented"))
|
||||
}
|
||||
|
||||
/**
|
||||
* The User business-logic
|
||||
*
|
||||
*
|
||||
* The 'asHandler' will return an implementation which allows for easily overriding individual operations.
|
||||
*
|
||||
* equally there are "on<Function>" helper methods for easily overriding individual functions
|
||||
*
|
||||
* @tparam F the effect type (Future, Try, IO, ID, etc) of the operations
|
||||
*/
|
||||
trait UserService {
|
||||
trait UserService[F[_]] {
|
||||
/** Create user
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
def createUser(user : User) : Unit
|
||||
def createUser(user : User) : F[Unit]
|
||||
|
||||
/**
|
||||
* override createUser with the given handler
|
||||
* @return a new implementation of UserService[F] with createUser overridden using the given handler
|
||||
*/
|
||||
final def onCreateUser(handler : (user : User) => F[Unit]) : UserService[F] = {
|
||||
asHandler.copy(createUserHandler = handler)
|
||||
}
|
||||
/** Creates list of users with given input array
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
def createUsersWithArrayInput(user : Seq[User]) : Unit
|
||||
def createUsersWithArrayInput(user : Seq[User]) : F[Unit]
|
||||
|
||||
/**
|
||||
* override createUsersWithArrayInput with the given handler
|
||||
* @return a new implementation of UserService[F] with createUsersWithArrayInput overridden using the given handler
|
||||
*/
|
||||
final def onCreateUsersWithArrayInput(handler : (user : Seq[User]) => F[Unit]) : UserService[F] = {
|
||||
asHandler.copy(createUsersWithArrayInputHandler = handler)
|
||||
}
|
||||
/** Creates list of users with given input array
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
def createUsersWithListInput(user : Seq[User]) : Unit
|
||||
def createUsersWithListInput(user : Seq[User]) : F[Unit]
|
||||
|
||||
/**
|
||||
* override createUsersWithListInput with the given handler
|
||||
* @return a new implementation of UserService[F] with createUsersWithListInput overridden using the given handler
|
||||
*/
|
||||
final def onCreateUsersWithListInput(handler : (user : Seq[User]) => F[Unit]) : UserService[F] = {
|
||||
asHandler.copy(createUsersWithListInputHandler = handler)
|
||||
}
|
||||
/** Delete user
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
def deleteUser(username : String) : Unit
|
||||
def deleteUser(username : String) : F[Unit]
|
||||
|
||||
/**
|
||||
* override deleteUser with the given handler
|
||||
* @return a new implementation of UserService[F] with deleteUser overridden using the given handler
|
||||
*/
|
||||
final def onDeleteUser(handler : (username : String) => F[Unit]) : UserService[F] = {
|
||||
asHandler.copy(deleteUserHandler = handler)
|
||||
}
|
||||
/** Get user by user name
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
def getUserByName(username : String) : User
|
||||
def getUserByName(username : String) : F[User]
|
||||
|
||||
/**
|
||||
* override getUserByName with the given handler
|
||||
* @return a new implementation of UserService[F] with getUserByName overridden using the given handler
|
||||
*/
|
||||
final def onGetUserByName(handler : (username : String) => F[User]) : UserService[F] = {
|
||||
asHandler.copy(getUserByNameHandler = handler)
|
||||
}
|
||||
/** Logs user into the system
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
def loginUser(username : String, password : String) : String
|
||||
def loginUser(username : String, password : String) : F[String]
|
||||
|
||||
/**
|
||||
* override loginUser with the given handler
|
||||
* @return a new implementation of UserService[F] with loginUser overridden using the given handler
|
||||
*/
|
||||
final def onLoginUser(handler : (username : String, password : String) => F[String]) : UserService[F] = {
|
||||
asHandler.copy(loginUserHandler = handler)
|
||||
}
|
||||
/** Logs out current logged in user session
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
def logoutUser() : Unit
|
||||
def logoutUser() : F[Unit]
|
||||
|
||||
/**
|
||||
* override logoutUser with the given handler
|
||||
* @return a new implementation of UserService[F] with logoutUser overridden using the given handler
|
||||
*/
|
||||
final def onLogoutUser(handler : () => F[Unit]) : UserService[F] = {
|
||||
asHandler.copy(logoutUserHandler = handler)
|
||||
}
|
||||
/** Updated user
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
def updateUser(username : String, user : User) : Unit
|
||||
def updateUser(username : String, user : User) : F[Unit]
|
||||
|
||||
/**
|
||||
* override updateUser with the given handler
|
||||
* @return a new implementation of UserService[F] with updateUser overridden using the given handler
|
||||
*/
|
||||
final def onUpdateUser(handler : (username : String, user : User) => F[Unit]) : UserService[F] = {
|
||||
asHandler.copy(updateUserHandler = handler)
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a Handler implementation of this service
|
||||
*/
|
||||
final def asHandler : UserService.Handler[F] = this match {
|
||||
case h : UserService.Handler[F] => h
|
||||
case _ =>
|
||||
UserService.Handler[F](
|
||||
(user) => createUser(user),
|
||||
(user) => createUsersWithArrayInput(user),
|
||||
(user) => createUsersWithListInput(user),
|
||||
(username) => deleteUser(username),
|
||||
(username) => getUserByName(username),
|
||||
(username, password) => loginUser(username, password),
|
||||
() => logoutUser(),
|
||||
(username, user) => updateUser(username, user)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will change the effect type of this service.
|
||||
*
|
||||
* It's not unlike a typical map operation from A => B, except we're not mapping
|
||||
* a type from A to B, but rather from F[A] => G[A] using the 'changeEffect' function.
|
||||
*
|
||||
* For, this could turn an asynchronous service (one which returns Future[_] types) into
|
||||
* a synchronous one (one which returns Try[_] types) by awaiting on the Future.
|
||||
*
|
||||
* It could change an IO type (like cats effect or ZIO) into an ID[A] which is just:
|
||||
* ```
|
||||
* type ID[A] => A
|
||||
* ```
|
||||
*
|
||||
* @tparam G the new "polymorphic" effect type
|
||||
* @param changeEffect the "natural transformation" which can change one effect type into another
|
||||
* @return a new UserService service implementation with effect type [G]
|
||||
*/
|
||||
final def mapEffect[G[_]](changeEffect : [A] => F[A] => G[A]) : UserService[G] = {
|
||||
val self = this
|
||||
|
||||
new UserService[G] {
|
||||
override def createUser(user : User) : G[Unit] = changeEffect {
|
||||
self.createUser(user)
|
||||
}
|
||||
override def createUsersWithArrayInput(user : Seq[User]) : G[Unit] = changeEffect {
|
||||
self.createUsersWithArrayInput(user)
|
||||
}
|
||||
override def createUsersWithListInput(user : Seq[User]) : G[Unit] = changeEffect {
|
||||
self.createUsersWithListInput(user)
|
||||
}
|
||||
override def deleteUser(username : String) : G[Unit] = changeEffect {
|
||||
self.deleteUser(username)
|
||||
}
|
||||
override def getUserByName(username : String) : G[User] = changeEffect {
|
||||
self.getUserByName(username)
|
||||
}
|
||||
override def loginUser(username : String, password : String) : G[String] = changeEffect {
|
||||
self.loginUser(username, password)
|
||||
}
|
||||
override def logoutUser() : G[Unit] = changeEffect {
|
||||
self.logoutUser()
|
||||
}
|
||||
override def updateUser(username : String, user : User) : G[Unit] = changeEffect {
|
||||
self.updateUser(username, user)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,41 +13,44 @@
|
||||
|
||||
// this model was generated using model.mustache
|
||||
package sample.cask.model
|
||||
|
||||
import scala.util.control.NonFatal
|
||||
|
||||
// see https://com-lihaoyi.github.io/upickle/
|
||||
import upickle.default.{ReadWriter => RW, macroRW}
|
||||
import upickle.default.*
|
||||
|
||||
|
||||
|
||||
case class ApiResponse(
|
||||
code: Option[Int] = None ,
|
||||
`type`: Option[String] = None ,
|
||||
message: Option[String] = None
|
||||
code: Option[Int] = None ,
|
||||
`type`: Option[String] = None ,
|
||||
message: Option[String] = None
|
||||
|
||||
|
||||
) {
|
||||
|
||||
def asJsonString: String = asData.asJsonString
|
||||
def asJson: ujson.Value = asData.asJson
|
||||
def asJsonString: String = asData.asJsonString
|
||||
def asJson: ujson.Value = asData.asJson
|
||||
|
||||
def asData : ApiResponseData = {
|
||||
ApiResponseData(
|
||||
code = code.getOrElse(0),
|
||||
`type` = `type`.getOrElse(""),
|
||||
message = message.getOrElse("")
|
||||
|
||||
)
|
||||
}
|
||||
def asData : ApiResponseData = {
|
||||
ApiResponseData(
|
||||
code = code.getOrElse(0) /* 1 */,
|
||||
`type` = `type`.getOrElse("") /* 1 */,
|
||||
message = message.getOrElse("") /* 1 */
|
||||
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object ApiResponse {
|
||||
given RW[ApiResponse] = summon[RW[ujson.Value]].bimap[ApiResponse](_.asJson, json => read[ApiResponseData](json).asModel)
|
||||
given RW[ApiResponse] = summon[RW[ujson.Value]].bimap[ApiResponse](_.asJson, json => read[ApiResponseData](json).asModel)
|
||||
|
||||
enum Fields(val fieldName : String) extends Field(fieldName) {
|
||||
case code extends Fields("code")
|
||||
case `type` extends Fields("`type`")
|
||||
case message extends Fields("message")
|
||||
}
|
||||
enum Fields(val fieldName : String) extends Field(fieldName) {
|
||||
case code extends Fields("code")
|
||||
case `type` extends Fields("`type`")
|
||||
case message extends Fields("message")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@ import scala.util.*
|
||||
import upickle.default.{ReadWriter => RW, macroRW}
|
||||
import upickle.default.*
|
||||
|
||||
/** ApiResponseData a data transfer object, primarily for simple json serialisation.
|
||||
|
||||
/** ApiResponseData a data transfer object, primarily for simple json serialisation.
|
||||
* It has no validation - there may be nulls, values out of range, etc
|
||||
*/
|
||||
case class ApiResponseData(
|
||||
@@ -61,6 +62,9 @@ case class ApiResponseData(
|
||||
errors.toSeq
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the validated model within a Try (if successful)
|
||||
*/
|
||||
def validated(failFast : Boolean = false) : scala.util.Try[ApiResponse] = {
|
||||
validationErrors(Vector(), failFast) match {
|
||||
case Seq() => Success(asModel)
|
||||
@@ -71,18 +75,9 @@ case class ApiResponseData(
|
||||
/** use 'validated' to check validation */
|
||||
def asModel : ApiResponse = {
|
||||
ApiResponse(
|
||||
code = Option(
|
||||
code
|
||||
)
|
||||
,
|
||||
`type` = Option(
|
||||
`type`
|
||||
)
|
||||
,
|
||||
message = Option(
|
||||
message
|
||||
)
|
||||
|
||||
code = Option(code) /* 1 */,
|
||||
`type` = Option(`type`) /* 1 */,
|
||||
message = Option(message) /* 1 */
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
@@ -13,38 +13,41 @@
|
||||
|
||||
// this model was generated using model.mustache
|
||||
package sample.cask.model
|
||||
|
||||
import scala.util.control.NonFatal
|
||||
|
||||
// see https://com-lihaoyi.github.io/upickle/
|
||||
import upickle.default.{ReadWriter => RW, macroRW}
|
||||
import upickle.default.*
|
||||
|
||||
|
||||
|
||||
case class Category(
|
||||
id: Option[Long] = None ,
|
||||
name: Option[String] = None
|
||||
id: Option[Long] = None ,
|
||||
name: Option[String] = None
|
||||
|
||||
|
||||
) {
|
||||
|
||||
def asJsonString: String = asData.asJsonString
|
||||
def asJson: ujson.Value = asData.asJson
|
||||
def asJsonString: String = asData.asJsonString
|
||||
def asJson: ujson.Value = asData.asJson
|
||||
|
||||
def asData : CategoryData = {
|
||||
CategoryData(
|
||||
id = id.getOrElse(0),
|
||||
name = name.getOrElse("")
|
||||
|
||||
)
|
||||
}
|
||||
def asData : CategoryData = {
|
||||
CategoryData(
|
||||
id = id.getOrElse(0) /* 1 */,
|
||||
name = name.getOrElse("") /* 1 */
|
||||
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object Category {
|
||||
given RW[Category] = summon[RW[ujson.Value]].bimap[Category](_.asJson, json => read[CategoryData](json).asModel)
|
||||
given RW[Category] = summon[RW[ujson.Value]].bimap[Category](_.asJson, json => read[CategoryData](json).asModel)
|
||||
|
||||
enum Fields(val fieldName : String) extends Field(fieldName) {
|
||||
case id extends Fields("id")
|
||||
case name extends Fields("name")
|
||||
}
|
||||
enum Fields(val fieldName : String) extends Field(fieldName) {
|
||||
case id extends Fields("id")
|
||||
case name extends Fields("name")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@ import scala.util.*
|
||||
import upickle.default.{ReadWriter => RW, macroRW}
|
||||
import upickle.default.*
|
||||
|
||||
/** CategoryData a data transfer object, primarily for simple json serialisation.
|
||||
|
||||
/** CategoryData a data transfer object, primarily for simple json serialisation.
|
||||
* It has no validation - there may be nulls, values out of range, etc
|
||||
*/
|
||||
case class CategoryData(
|
||||
@@ -60,6 +61,9 @@ case class CategoryData(
|
||||
errors.toSeq
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the validated model within a Try (if successful)
|
||||
*/
|
||||
def validated(failFast : Boolean = false) : scala.util.Try[Category] = {
|
||||
validationErrors(Vector(), failFast) match {
|
||||
case Seq() => Success(asModel)
|
||||
@@ -70,14 +74,8 @@ case class CategoryData(
|
||||
/** use 'validated' to check validation */
|
||||
def asModel : Category = {
|
||||
Category(
|
||||
id = Option(
|
||||
id
|
||||
)
|
||||
,
|
||||
name = Option(
|
||||
name
|
||||
)
|
||||
|
||||
id = Option(id) /* 1 */,
|
||||
name = Option(name) /* 1 */
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
@@ -14,51 +14,54 @@
|
||||
// this model was generated using model.mustache
|
||||
package sample.cask.model
|
||||
import java.time.OffsetDateTime
|
||||
|
||||
import scala.util.control.NonFatal
|
||||
|
||||
// see https://com-lihaoyi.github.io/upickle/
|
||||
import upickle.default.{ReadWriter => RW, macroRW}
|
||||
import upickle.default.*
|
||||
|
||||
|
||||
|
||||
case class Order(
|
||||
id: Option[Long] = None ,
|
||||
petId: Option[Long] = None ,
|
||||
quantity: Option[Int] = None ,
|
||||
shipDate: Option[OffsetDateTime] = None ,
|
||||
/* Order Status */
|
||||
status: Option[Order.StatusEnum] = None ,
|
||||
complete: Option[Boolean] = None
|
||||
id: Option[Long] = None ,
|
||||
petId: Option[Long] = None ,
|
||||
quantity: Option[Int] = None ,
|
||||
shipDate: Option[OffsetDateTime] = None ,
|
||||
/* Order Status */
|
||||
status: Option[Order.StatusEnum] = None ,
|
||||
complete: Option[Boolean] = None
|
||||
|
||||
|
||||
) {
|
||||
|
||||
def asJsonString: String = asData.asJsonString
|
||||
def asJson: ujson.Value = asData.asJson
|
||||
def asJsonString: String = asData.asJsonString
|
||||
def asJson: ujson.Value = asData.asJson
|
||||
|
||||
def asData : OrderData = {
|
||||
OrderData(
|
||||
id = id.getOrElse(0),
|
||||
petId = petId.getOrElse(0),
|
||||
quantity = quantity.getOrElse(0),
|
||||
shipDate = shipDate.getOrElse(null),
|
||||
status = status.getOrElse(null),
|
||||
complete = complete.getOrElse(false)
|
||||
|
||||
)
|
||||
}
|
||||
def asData : OrderData = {
|
||||
OrderData(
|
||||
id = id.getOrElse(0) /* 1 */,
|
||||
petId = petId.getOrElse(0) /* 1 */,
|
||||
quantity = quantity.getOrElse(0) /* 1 */,
|
||||
shipDate = shipDate.getOrElse(null) /* 1 */,
|
||||
status = status.getOrElse(null) /* 1 */,
|
||||
complete = complete.getOrElse(false) /* 1 */
|
||||
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object Order {
|
||||
given RW[Order] = summon[RW[ujson.Value]].bimap[Order](_.asJson, json => read[OrderData](json).asModel)
|
||||
given RW[Order] = summon[RW[ujson.Value]].bimap[Order](_.asJson, json => read[OrderData](json).asModel)
|
||||
|
||||
enum Fields(val fieldName : String) extends Field(fieldName) {
|
||||
case id extends Fields("id")
|
||||
case petId extends Fields("petId")
|
||||
case quantity extends Fields("quantity")
|
||||
case shipDate extends Fields("shipDate")
|
||||
case status extends Fields("status")
|
||||
case complete extends Fields("complete")
|
||||
}
|
||||
enum Fields(val fieldName : String) extends Field(fieldName) {
|
||||
case id extends Fields("id")
|
||||
case petId extends Fields("petId")
|
||||
case quantity extends Fields("quantity")
|
||||
case shipDate extends Fields("shipDate")
|
||||
case status extends Fields("status")
|
||||
case complete extends Fields("complete")
|
||||
}
|
||||
|
||||
// baseName=status
|
||||
// nameInCamelCase = status
|
||||
|
||||
@@ -21,7 +21,8 @@ import scala.util.*
|
||||
import upickle.default.{ReadWriter => RW, macroRW}
|
||||
import upickle.default.*
|
||||
|
||||
/** OrderData a data transfer object, primarily for simple json serialisation.
|
||||
|
||||
/** OrderData a data transfer object, primarily for simple json serialisation.
|
||||
* It has no validation - there may be nulls, values out of range, etc
|
||||
*/
|
||||
case class OrderData(
|
||||
@@ -84,6 +85,9 @@ case class OrderData(
|
||||
errors.toSeq
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the validated model within a Try (if successful)
|
||||
*/
|
||||
def validated(failFast : Boolean = false) : scala.util.Try[Order] = {
|
||||
validationErrors(Vector(), failFast) match {
|
||||
case Seq() => Success(asModel)
|
||||
@@ -94,30 +98,12 @@ case class OrderData(
|
||||
/** use 'validated' to check validation */
|
||||
def asModel : Order = {
|
||||
Order(
|
||||
id = Option(
|
||||
id
|
||||
)
|
||||
,
|
||||
petId = Option(
|
||||
petId
|
||||
)
|
||||
,
|
||||
quantity = Option(
|
||||
quantity
|
||||
)
|
||||
,
|
||||
shipDate = Option(
|
||||
shipDate
|
||||
)
|
||||
,
|
||||
status = Option(
|
||||
status
|
||||
)
|
||||
,
|
||||
complete = Option(
|
||||
complete
|
||||
)
|
||||
|
||||
id = Option(id) /* 1 */,
|
||||
petId = Option(petId) /* 1 */,
|
||||
quantity = Option(quantity) /* 1 */,
|
||||
shipDate = Option(shipDate) /* 1 */,
|
||||
status = Option(status) /* 1 */,
|
||||
complete = Option(complete) /* 1 */
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
@@ -13,53 +13,54 @@
|
||||
|
||||
// this model was generated using model.mustache
|
||||
package sample.cask.model
|
||||
import sample.cask.model.Category
|
||||
import sample.cask.model.Tag
|
||||
|
||||
import scala.util.control.NonFatal
|
||||
|
||||
// see https://com-lihaoyi.github.io/upickle/
|
||||
import upickle.default.{ReadWriter => RW, macroRW}
|
||||
import upickle.default.*
|
||||
|
||||
|
||||
|
||||
case class Pet(
|
||||
id: Option[Long] = None ,
|
||||
category: Option[Category] = None ,
|
||||
name: String,
|
||||
photoUrls: Seq[String],
|
||||
tags: Seq[Tag] = Nil ,
|
||||
/* pet status in the store */
|
||||
status: Option[Pet.StatusEnum] = None
|
||||
id: Option[Long] = None ,
|
||||
category: Option[Category] = None ,
|
||||
name: String,
|
||||
photoUrls: Seq[String],
|
||||
tags: Seq[Tag] = Nil ,
|
||||
/* pet status in the store */
|
||||
status: Option[Pet.StatusEnum] = None
|
||||
|
||||
|
||||
) {
|
||||
|
||||
def asJsonString: String = asData.asJsonString
|
||||
def asJson: ujson.Value = asData.asJson
|
||||
def asJsonString: String = asData.asJsonString
|
||||
def asJson: ujson.Value = asData.asJson
|
||||
|
||||
def asData : PetData = {
|
||||
PetData(
|
||||
id = id.getOrElse(0),
|
||||
category = category.map(_.asData).getOrElse(null),
|
||||
name = name,
|
||||
photoUrls = photoUrls,
|
||||
tags = tags.map(_.asData),
|
||||
status = status.getOrElse(null)
|
||||
|
||||
)
|
||||
}
|
||||
def asData : PetData = {
|
||||
PetData(
|
||||
id = id.getOrElse(0) /* 1 */,
|
||||
category = category.map(_.asData).getOrElse(null) /* 4 */,
|
||||
name = name /* 2 */,
|
||||
photoUrls = photoUrls /* 2 */,
|
||||
tags = tags.map(_.asData) /* 6 */,
|
||||
status = status.getOrElse(null) /* 1 */
|
||||
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object Pet {
|
||||
given RW[Pet] = summon[RW[ujson.Value]].bimap[Pet](_.asJson, json => read[PetData](json).asModel)
|
||||
given RW[Pet] = summon[RW[ujson.Value]].bimap[Pet](_.asJson, json => read[PetData](json).asModel)
|
||||
|
||||
enum Fields(val fieldName : String) extends Field(fieldName) {
|
||||
case id extends Fields("id")
|
||||
case category extends Fields("category")
|
||||
case name extends Fields("name")
|
||||
case photoUrls extends Fields("photoUrls")
|
||||
case tags extends Fields("tags")
|
||||
case status extends Fields("status")
|
||||
}
|
||||
enum Fields(val fieldName : String) extends Field(fieldName) {
|
||||
case id extends Fields("id")
|
||||
case category extends Fields("category")
|
||||
case name extends Fields("name")
|
||||
case photoUrls extends Fields("photoUrls")
|
||||
case tags extends Fields("tags")
|
||||
case status extends Fields("status")
|
||||
}
|
||||
|
||||
// baseName=status
|
||||
// nameInCamelCase = status
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
|
||||
// this model was generated using modelData.mustache
|
||||
package sample.cask.model
|
||||
import sample.cask.model.Category
|
||||
import sample.cask.model.Tag
|
||||
import scala.util.control.NonFatal
|
||||
import scala.util.*
|
||||
|
||||
@@ -22,7 +20,8 @@ import scala.util.*
|
||||
import upickle.default.{ReadWriter => RW, macroRW}
|
||||
import upickle.default.*
|
||||
|
||||
/** PetData a data transfer object, primarily for simple json serialisation.
|
||||
|
||||
/** PetData a data transfer object, primarily for simple json serialisation.
|
||||
* It has no validation - there may be nulls, values out of range, etc
|
||||
*/
|
||||
case class PetData(
|
||||
@@ -101,6 +100,9 @@ case class PetData(
|
||||
errors.toSeq
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the validated model within a Try (if successful)
|
||||
*/
|
||||
def validated(failFast : Boolean = false) : scala.util.Try[Pet] = {
|
||||
validationErrors(Vector(), failFast) match {
|
||||
case Seq() => Success(asModel)
|
||||
@@ -111,30 +113,12 @@ case class PetData(
|
||||
/** use 'validated' to check validation */
|
||||
def asModel : Pet = {
|
||||
Pet(
|
||||
id = Option(
|
||||
id
|
||||
)
|
||||
,
|
||||
category = Option(
|
||||
category
|
||||
)
|
||||
.map(_.asModel),
|
||||
name =
|
||||
name
|
||||
|
||||
,
|
||||
photoUrls =
|
||||
photoUrls
|
||||
|
||||
,
|
||||
tags =
|
||||
tags
|
||||
|
||||
.map(_.asModel),
|
||||
status = Option(
|
||||
status
|
||||
)
|
||||
|
||||
id = Option(id) /* 1 */,
|
||||
category = Option(category).map(_.asModel) /* 4 */,
|
||||
name = name /* 2 */,
|
||||
photoUrls = photoUrls /* 2 */,
|
||||
tags = tags.map(_.asModel) /* 5 */,
|
||||
status = Option(status) /* 1 */
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
@@ -13,38 +13,41 @@
|
||||
|
||||
// this model was generated using model.mustache
|
||||
package sample.cask.model
|
||||
|
||||
import scala.util.control.NonFatal
|
||||
|
||||
// see https://com-lihaoyi.github.io/upickle/
|
||||
import upickle.default.{ReadWriter => RW, macroRW}
|
||||
import upickle.default.*
|
||||
|
||||
|
||||
|
||||
case class Tag(
|
||||
id: Option[Long] = None ,
|
||||
name: Option[String] = None
|
||||
id: Option[Long] = None ,
|
||||
name: Option[String] = None
|
||||
|
||||
|
||||
) {
|
||||
|
||||
def asJsonString: String = asData.asJsonString
|
||||
def asJson: ujson.Value = asData.asJson
|
||||
def asJsonString: String = asData.asJsonString
|
||||
def asJson: ujson.Value = asData.asJson
|
||||
|
||||
def asData : TagData = {
|
||||
TagData(
|
||||
id = id.getOrElse(0),
|
||||
name = name.getOrElse("")
|
||||
|
||||
)
|
||||
}
|
||||
def asData : TagData = {
|
||||
TagData(
|
||||
id = id.getOrElse(0) /* 1 */,
|
||||
name = name.getOrElse("") /* 1 */
|
||||
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object Tag {
|
||||
given RW[Tag] = summon[RW[ujson.Value]].bimap[Tag](_.asJson, json => read[TagData](json).asModel)
|
||||
given RW[Tag] = summon[RW[ujson.Value]].bimap[Tag](_.asJson, json => read[TagData](json).asModel)
|
||||
|
||||
enum Fields(val fieldName : String) extends Field(fieldName) {
|
||||
case id extends Fields("id")
|
||||
case name extends Fields("name")
|
||||
}
|
||||
enum Fields(val fieldName : String) extends Field(fieldName) {
|
||||
case id extends Fields("id")
|
||||
case name extends Fields("name")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@ import scala.util.*
|
||||
import upickle.default.{ReadWriter => RW, macroRW}
|
||||
import upickle.default.*
|
||||
|
||||
/** TagData a data transfer object, primarily for simple json serialisation.
|
||||
|
||||
/** TagData a data transfer object, primarily for simple json serialisation.
|
||||
* It has no validation - there may be nulls, values out of range, etc
|
||||
*/
|
||||
case class TagData(
|
||||
@@ -54,6 +55,9 @@ case class TagData(
|
||||
errors.toSeq
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the validated model within a Try (if successful)
|
||||
*/
|
||||
def validated(failFast : Boolean = false) : scala.util.Try[Tag] = {
|
||||
validationErrors(Vector(), failFast) match {
|
||||
case Seq() => Success(asModel)
|
||||
@@ -64,14 +68,8 @@ case class TagData(
|
||||
/** use 'validated' to check validation */
|
||||
def asModel : Tag = {
|
||||
Tag(
|
||||
id = Option(
|
||||
id
|
||||
)
|
||||
,
|
||||
name = Option(
|
||||
name
|
||||
)
|
||||
|
||||
id = Option(id) /* 1 */,
|
||||
name = Option(name) /* 1 */
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
@@ -13,57 +13,60 @@
|
||||
|
||||
// this model was generated using model.mustache
|
||||
package sample.cask.model
|
||||
|
||||
import scala.util.control.NonFatal
|
||||
|
||||
// see https://com-lihaoyi.github.io/upickle/
|
||||
import upickle.default.{ReadWriter => RW, macroRW}
|
||||
import upickle.default.*
|
||||
|
||||
|
||||
|
||||
case class User(
|
||||
id: Option[Long] = None ,
|
||||
username: Option[String] = None ,
|
||||
firstName: Option[String] = None ,
|
||||
lastName: Option[String] = None ,
|
||||
email: Option[String] = None ,
|
||||
password: Option[String] = None ,
|
||||
phone: Option[String] = None ,
|
||||
/* User Status */
|
||||
userStatus: Option[Int] = None
|
||||
id: Option[Long] = None ,
|
||||
username: Option[String] = None ,
|
||||
firstName: Option[String] = None ,
|
||||
lastName: Option[String] = None ,
|
||||
email: Option[String] = None ,
|
||||
password: Option[String] = None ,
|
||||
phone: Option[String] = None ,
|
||||
/* User Status */
|
||||
userStatus: Option[Int] = None
|
||||
|
||||
|
||||
) {
|
||||
|
||||
def asJsonString: String = asData.asJsonString
|
||||
def asJson: ujson.Value = asData.asJson
|
||||
def asJsonString: String = asData.asJsonString
|
||||
def asJson: ujson.Value = asData.asJson
|
||||
|
||||
def asData : UserData = {
|
||||
UserData(
|
||||
id = id.getOrElse(0),
|
||||
username = username.getOrElse(""),
|
||||
firstName = firstName.getOrElse(""),
|
||||
lastName = lastName.getOrElse(""),
|
||||
email = email.getOrElse(""),
|
||||
password = password.getOrElse(""),
|
||||
phone = phone.getOrElse(""),
|
||||
userStatus = userStatus.getOrElse(0)
|
||||
|
||||
)
|
||||
}
|
||||
def asData : UserData = {
|
||||
UserData(
|
||||
id = id.getOrElse(0) /* 1 */,
|
||||
username = username.getOrElse("") /* 1 */,
|
||||
firstName = firstName.getOrElse("") /* 1 */,
|
||||
lastName = lastName.getOrElse("") /* 1 */,
|
||||
email = email.getOrElse("") /* 1 */,
|
||||
password = password.getOrElse("") /* 1 */,
|
||||
phone = phone.getOrElse("") /* 1 */,
|
||||
userStatus = userStatus.getOrElse(0) /* 1 */
|
||||
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object User {
|
||||
given RW[User] = summon[RW[ujson.Value]].bimap[User](_.asJson, json => read[UserData](json).asModel)
|
||||
given RW[User] = summon[RW[ujson.Value]].bimap[User](_.asJson, json => read[UserData](json).asModel)
|
||||
|
||||
enum Fields(val fieldName : String) extends Field(fieldName) {
|
||||
case id extends Fields("id")
|
||||
case username extends Fields("username")
|
||||
case firstName extends Fields("firstName")
|
||||
case lastName extends Fields("lastName")
|
||||
case email extends Fields("email")
|
||||
case password extends Fields("password")
|
||||
case phone extends Fields("phone")
|
||||
case userStatus extends Fields("userStatus")
|
||||
}
|
||||
enum Fields(val fieldName : String) extends Field(fieldName) {
|
||||
case id extends Fields("id")
|
||||
case username extends Fields("username")
|
||||
case firstName extends Fields("firstName")
|
||||
case lastName extends Fields("lastName")
|
||||
case email extends Fields("email")
|
||||
case password extends Fields("password")
|
||||
case phone extends Fields("phone")
|
||||
case userStatus extends Fields("userStatus")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@ import scala.util.*
|
||||
import upickle.default.{ReadWriter => RW, macroRW}
|
||||
import upickle.default.*
|
||||
|
||||
/** UserData a data transfer object, primarily for simple json serialisation.
|
||||
|
||||
/** UserData a data transfer object, primarily for simple json serialisation.
|
||||
* It has no validation - there may be nulls, values out of range, etc
|
||||
*/
|
||||
case class UserData(
|
||||
@@ -97,6 +98,9 @@ case class UserData(
|
||||
errors.toSeq
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the validated model within a Try (if successful)
|
||||
*/
|
||||
def validated(failFast : Boolean = false) : scala.util.Try[User] = {
|
||||
validationErrors(Vector(), failFast) match {
|
||||
case Seq() => Success(asModel)
|
||||
@@ -107,38 +111,14 @@ case class UserData(
|
||||
/** use 'validated' to check validation */
|
||||
def asModel : User = {
|
||||
User(
|
||||
id = Option(
|
||||
id
|
||||
)
|
||||
,
|
||||
username = Option(
|
||||
username
|
||||
)
|
||||
,
|
||||
firstName = Option(
|
||||
firstName
|
||||
)
|
||||
,
|
||||
lastName = Option(
|
||||
lastName
|
||||
)
|
||||
,
|
||||
email = Option(
|
||||
email
|
||||
)
|
||||
,
|
||||
password = Option(
|
||||
password
|
||||
)
|
||||
,
|
||||
phone = Option(
|
||||
phone
|
||||
)
|
||||
,
|
||||
userStatus = Option(
|
||||
userStatus
|
||||
)
|
||||
|
||||
id = Option(id) /* 1 */,
|
||||
username = Option(username) /* 1 */,
|
||||
firstName = Option(firstName) /* 1 */,
|
||||
lastName = Option(lastName) /* 1 */,
|
||||
email = Option(email) /* 1 */,
|
||||
password = Option(password) /* 1 */,
|
||||
phone = Option(phone) /* 1 */,
|
||||
userStatus = Option(userStatus) /* 1 */
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user