diff options
-rw-r--r-- | core/shared/src/main/scala/magnolia.scala | 47 | ||||
-rw-r--r-- | tests/src/main/scala/tests.scala | 12 |
2 files changed, 41 insertions, 18 deletions
diff --git a/core/shared/src/main/scala/magnolia.scala b/core/shared/src/main/scala/magnolia.scala index c4c13e6..e8350da 100644 --- a/core/shared/src/main/scala/magnolia.scala +++ b/core/shared/src/main/scala/magnolia.scala @@ -289,24 +289,35 @@ object Magnolia { val preAssignments = caseParams.map(_.typeclass) val defaults = if (!isValueClass) { - val caseClassCompanion = genericType.companion - - // If a companion object is defined with alternative apply methods - // it is needed get all the alternatives - val constructorMethods = - caseClassCompanion.decl(TermName("apply")).alternatives.map(_.asMethod) - - // The last apply method in the alternatives is the one that belongs - // to the case class, not the user defined companion object - val indexedConstructorParams = - constructorMethods.last.paramLists.head.map(_.asTerm).zipWithIndex - - indexedConstructorParams.map { - case (p, idx) => - if (p.isParamWithDefault) { - val method = TermName("apply$default$" + (idx + 1)) - q"$scalaPkg.Some(${genericType.typeSymbol.companion.asTerm}.$method)" - } else q"$scalaPkg.None" + + val constructorParams = genericType.decls.collect { + case a: MethodSymbol if a.isConstructor => a + }.head.paramLists.head.map(_.asTerm) + val noDefaults = constructorParams.forall(!_.isParamWithDefault) + + if (noDefaults) { + constructorParams.map(_ => q"$scalaPkg.None") + } else { + val caseClassCompanion = genericType.companion + + // If a companion object is defined with alternative apply methods + // it is needed get all the alternatives + val constructorMethods = + caseClassCompanion.decl(TermName("apply")).alternatives.map(_.asMethod) + + // The last apply method in the alternatives is the one that belongs + // to the case class, not the user defined companion object + val indexedConstructorParams = + constructorMethods.last.paramLists.head.map(_.asTerm).zipWithIndex + + indexedConstructorParams.map { + case (p, idx) => + if (p.isParamWithDefault) { + val method = TermName("apply$default$" + (idx + 1)) + q"$scalaPkg.Some(${genericType.typeSymbol.companion.asTerm}.$method)" + } else q"$scalaPkg.None" + } + } } else List(q"$scalaPkg.None") diff --git a/tests/src/main/scala/tests.scala b/tests/src/main/scala/tests.scala index 4c2a48e..6d883da 100644 --- a/tests/src/main/scala/tests.scala +++ b/tests/src/main/scala/tests.scala @@ -204,6 +204,17 @@ object Tests extends TestApp { Show.gen[Length].show(new Length(100)) }.assert(_ == "100") + + class ParentClass { + case class InnerClass(name: String) + + test("serialize a case class inside another class") { + implicitly[Show[String, InnerClass]].show(InnerClass("foo")) + }.assert(_ == "InnerClass(name=foo)") + } + + new ParentClass + test("show an Account") { Show.gen[Account].show(Account("john_doe", "john.doe@yahoo.com", "john.doe@gmail.com")) }.assert(_ == "Account(id=john_doe,emails=[john.doe@yahoo.com,john.doe@gmail.com])") @@ -215,5 +226,6 @@ object Tests extends TestApp { test("show a Portfolio of Companies") { Show.gen[Portfolio].show(Portfolio(Company("Alice Inc"), Company("Bob & Co"))) }.assert(_ == "Portfolio(companies=[Company(name=Alice Inc),Company(name=Bob & Co)])") + } } |