Skip to content

Commit

Permalink
Merge pull request #1905 from blast-hardcheese/resolve-1904
Browse files Browse the repository at this point in the history
Resolve 1904
  • Loading branch information
blast-hardcheese authored Dec 25, 2023
2 parents 3482f33 + b3e0edd commit 9e64878
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 79 deletions.
6 changes: 4 additions & 2 deletions modules/core/src/main/scala/dev/guardrail/WriteTree.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ object WriteTree {
.zipWithIndex
.find { case ((a, b), _) => a != b }
.map(_._2)
.orElse(Some(Math.max(exists.length, data.length)))
.filterNot(Function.const(data.length == exists.length))
.orElse(
Some(Math.max(exists.length, data.length))
.filterNot(Function.const(data.length == exists.length))
)

diffIdx.fold[Writer[List[String], WriteTreeState]](Writer.value(FileIdentical)) { diffIdx =>
val existSample = new String(exists, UTF_8)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ abstract class LanguageTerms[L <: LA, F[_]] { self =>
server: Server[L]
): F[List[WriteTree]]

def wrapToObject(name: L#TermName, imports: List[L#Import], definitions: List[L#Definition]): F[Option[L#ObjectDefinition]]
def wrapToObject(name: L#TermName, imports: List[L#Import], definitions: List[L#Definition], statements: List[L#Statement]): F[Option[L#ObjectDefinition]]

def copy(
litString: String => F[L#Term] = self.litString _,
Expand Down Expand Up @@ -209,7 +209,7 @@ abstract class LanguageTerms[L <: LA, F[_]] { self =>
self.writeClient _,
writeServer: (Path, NonEmptyList[String], List[L#Import], List[L#TermName], Option[NonEmptyList[String]], Server[L]) => F[List[WriteTree]] =
self.writeServer _,
wrapToObject: (L#TermName, List[L#Import], List[L#Definition]) => F[Option[L#ObjectDefinition]] = self.wrapToObject _
wrapToObject: (L#TermName, List[L#Import], List[L#Definition], List[L#Statement]) => F[Option[L#ObjectDefinition]] = self.wrapToObject _
) = {
val newLitString = litString
val newLitFloat = litFloat
Expand Down Expand Up @@ -383,7 +383,8 @@ abstract class LanguageTerms[L <: LA, F[_]] { self =>
dtoComponents: Option[NonEmptyList[String]],
server: Server[L]
) = newWriteServer(pkgPath, pkgName, customImports, frameworkImplicitNames, dtoComponents, server)
def wrapToObject(name: L#TermName, imports: List[L#Import], definitions: List[L#Definition]) = newWrapToObject(name, imports, definitions)
def wrapToObject(name: L#TermName, imports: List[L#Import], definitions: List[L#Definition], statements: List[L#Statement]) =
newWrapToObject(name, imports, definitions, statements)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,8 @@ class JavaGenerator private extends LanguageTerms[JavaLanguage, Target] {
override def wrapToObject(
name: com.github.javaparser.ast.expr.Name,
imports: List[com.github.javaparser.ast.ImportDeclaration],
definitions: List[com.github.javaparser.ast.body.BodyDeclaration[_ <: com.github.javaparser.ast.body.BodyDeclaration[_]]]
definitions: List[com.github.javaparser.ast.body.BodyDeclaration[_ <: com.github.javaparser.ast.body.BodyDeclaration[_]]],
statements: List[com.github.javaparser.ast.Node]
): Target[Option[Nothing]] =
Target.pure(Option.empty[Nothing])
}
Original file line number Diff line number Diff line change
Expand Up @@ -764,14 +764,14 @@ class JacksonGenerator private (implicit Cl: CollectionsLibTerms[JavaLanguage, T
for {
widenClass <- widenClassDefinition(classDefinition.cls)
companionTerm <- pureTermName(classDefinition.name)
companionDefinition <- wrapToObject(companionTerm, classDefinition.staticDefns.extraImports, classDefinition.staticDefns.definitions)
companionDefinition <- wrapToObject(companionTerm, classDefinition.staticDefns.extraImports, classDefinition.staticDefns.definitions, Nil)
widenCompanion <- companionDefinition.traverse(widenObjectDefinition)
} yield List(widenClass) ++ widenCompanion.fold(classDefinition.staticDefns.definitions)(List(_))
case enumDefinition: EnumDefinition[JavaLanguage] =>
for {
widenClass <- widenClassDefinition(enumDefinition.cls)
companionTerm <- pureTermName(enumDefinition.name)
companionDefinition <- wrapToObject(companionTerm, enumDefinition.staticDefns.extraImports, enumDefinition.staticDefns.definitions)
companionDefinition <- wrapToObject(companionTerm, enumDefinition.staticDefns.extraImports, enumDefinition.staticDefns.definitions, Nil)
widenCompanion <- companionDefinition.traverse(widenObjectDefinition)
} yield List(widenClass) ++ widenCompanion.fold(enumDefinition.staticDefns.definitions)(List(_))
}
Expand Down
45 changes: 32 additions & 13 deletions modules/sample-akkaHttp/src/test/scala/core/issues/Issue195.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,45 @@ import io.circe._, io.circe.syntax._
import issues.issue195.server.akkaHttp.definitions._

class Issue195 extends AnyFunSpec with Matchers {
def emit[A](label: String, func: () => A, expected: Json)(implicit ev: A => Foo): Unit =
describe(label) {
it("should encode") {
Foo(func()).asJson shouldBe expected
}
describe("oneOf mapping") {
def emit[A](label: String, func: () => A, expected: Json)(implicit ev: A => Foo): Unit =
describe(label) {
it("should encode") {
Foo(func()).asJson shouldBe expected
}

it("should decode") {
expected.as[Foo] shouldBe Right(Foo(func()))
}
it("should decode") {
expected.as[Foo] shouldBe Right(Foo(func()))
}

it("should round-trip") {
Foo(func()).asJson.as[Foo] shouldBe Right(Foo(func()))
it("should round-trip") {
Foo(func()).asJson.as[Foo] shouldBe Right(Foo(func()))
}
}
}

describe("oneOf mapping") {
emit("TypeA", () => TypeA("foo"), Json.obj("type" -> Json.fromString("foo"), "beepBorp" -> Json.fromString("typea")))
emit("TypeB", () => TypeB("foo"), Json.obj("type" -> Json.fromString("foo"), "beepBorp" -> Json.fromString("TypeB")))
emit("TypeC", () => Foo.WrappedC(TypeC("foo")), Json.obj("C" -> Json.obj("type" -> Json.fromString("foo")), "beepBorp" -> Json.fromString("WrappedC")))
emit("typed", () => Foo.Nested2(Typed("foo")), Json.obj("D" -> Json.obj("type" -> Json.fromString("foo")), "beepBorp" -> Json.fromString("Nested2")))
emit("TypeE", () => Foo.Nested3(TypeE("foo")), Json.obj("E" -> Json.obj("type" -> Json.fromString("foo")), "beepBorp" -> Json.fromString("Nested3")))
}

describe("anonymous oneOf mapping") {
def emit[A](label: String, func: () => A, expected: Json)(implicit ev: A => X.Links): Unit =
describe(label) {
it("should encode") {
X(func()).asJson shouldBe expected
}

it("should decode") {
expected.as[X] shouldBe Right(X(func()))
}

it("should round-trip") {
X(func()).asJson.as[X] shouldBe Right(X(func()))
}
}

emit("first branch, Vector[String]", () => X.Links(Vector("1", "2")), Json.obj("links" -> Json.arr(Json.fromString("1"), Json.fromString("2"))))
emit("second branch, object", () => X.Links(Json.obj("a" -> Json.fromString("hey"))), Json.obj("links" -> Json.obj("a" -> Json.fromString("hey"))))
}
}
10 changes: 10 additions & 0 deletions modules/sample/src/main/resources/issues/issue195.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ components:
propertyName: beepBorp
mapping:
typea: '#/components/schemas/TypeA'
X:
type: object
required: [ links ]
properties:
links:
oneOf:
- type: array
items:
type: string
- type: object
paths:
/foobar:
get:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -510,12 +510,14 @@ class ScalaGenerator private extends LanguageTerms[ScalaLanguage, Target] {
override def wrapToObject(
name: scala.meta.Term.Name,
imports: List[scala.meta.Import],
definitions: List[scala.meta.Defn]
definitions: List[scala.meta.Defn],
statements: List[scala.meta.Stat]
): Target[Option[scala.meta.Defn.Object]] =
Target.pure(Some(q"""
object $name {
..$imports
..$definitions
..$statements
}
"""))
}
Loading

0 comments on commit 9e64878

Please sign in to comment.