Skip to content

Commit c1307e7

Browse files
committed
IgnoreTransientDefaultMarker - add comments
1 parent e614e2d commit c1307e7

File tree

5 files changed

+57
-48
lines changed

5 files changed

+57
-48
lines changed

core/src/main/scala/com/avsystem/commons/serialization/customMarkerWrappers.scala

+22-19
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,18 @@ package serialization
33

44
trait AcceptsAdditionalCustomMarkers extends AcceptsCustomEvents {
55

6-
protected def markers: Set[CustomEventMarker[_]]
6+
protected def markers: Set[CustomEventMarker[?]]
77

88
override def customEvent[T](marker: CustomEventMarker[T], event: T): Boolean =
9-
marker match {
10-
case marker if markers(marker) => true
11-
case _ => super.customEvent(marker, event)
12-
}
9+
markers(marker) || super.customEvent(marker, event)
1310
}
1411

1512
/**
1613
* [[Input]] implementation that adds additional markers [[CustomEventMarker]] to the provided [[Input]] instance
1714
*/
18-
final class CustomMarkersInputWrapper(
15+
final class CustomMarkersInputWrapper private(
1916
override protected val wrapped: Input,
20-
override protected val markers: Set[CustomEventMarker[_]],
17+
override protected val markers: Set[CustomEventMarker[?]],
2118
) extends InputWrapper with AcceptsAdditionalCustomMarkers {
2219

2320
override def readList(): ListInput =
@@ -27,19 +24,22 @@ final class CustomMarkersInputWrapper(
2724
new CustomMarkersInputWrapper.AdjustedObjectInput(super.readObject(), markers)
2825
}
2926
object CustomMarkersInputWrapper {
30-
def apply(input: Input, markers: CustomEventMarker[_]*): CustomMarkersInputWrapper =
31-
new CustomMarkersInputWrapper(input, markers.toSet)
27+
def apply(input: Input, markers: CustomEventMarker[?]*): CustomMarkersInputWrapper =
28+
CustomMarkersInputWrapper(input, markers.toSet)
29+
30+
def apply(input: Input, markers: Set[CustomEventMarker[?]]): CustomMarkersInputWrapper =
31+
new CustomMarkersInputWrapper(input, markers)
3232

3333
private final class AdjustedListInput(
3434
override protected val wrapped: ListInput,
35-
override protected val markers: Set[CustomEventMarker[_]],
35+
override protected val markers: Set[CustomEventMarker[?]],
3636
) extends ListInputWrapper with AcceptsAdditionalCustomMarkers {
3737
override def nextElement(): Input = new CustomMarkersInputWrapper(super.nextElement(), markers)
3838
}
3939

4040
private final class AdjustedFieldInput(
4141
override protected val wrapped: FieldInput,
42-
override protected val markers: Set[CustomEventMarker[_]],
42+
override protected val markers: Set[CustomEventMarker[?]],
4343
) extends FieldInputWrapper with AcceptsAdditionalCustomMarkers {
4444

4545
override def readList(): ListInput = new AdjustedListInput(super.readList(), markers)
@@ -48,7 +48,7 @@ object CustomMarkersInputWrapper {
4848

4949
private final class AdjustedObjectInput(
5050
override protected val wrapped: ObjectInput,
51-
override protected val markers: Set[CustomEventMarker[_]],
51+
override protected val markers: Set[CustomEventMarker[?]],
5252
) extends ObjectInputWrapper with AcceptsAdditionalCustomMarkers {
5353

5454
override def nextField(): FieldInput = new AdjustedFieldInput(super.nextField(), markers)
@@ -60,9 +60,9 @@ object CustomMarkersInputWrapper {
6060
/**
6161
* [[Output]] implementation that adds additional markers [[CustomEventMarker]] to the provided [[Output]] instance
6262
*/
63-
final class CustomMarkersOutputWrapper(
63+
final class CustomMarkersOutputWrapper private(
6464
override protected val wrapped: Output,
65-
override protected val markers: Set[CustomEventMarker[_]],
65+
override protected val markers: Set[CustomEventMarker[?]],
6666
) extends OutputWrapper with AcceptsAdditionalCustomMarkers {
6767

6868
override def writeSimple(): SimpleOutput =
@@ -76,17 +76,20 @@ final class CustomMarkersOutputWrapper(
7676
}
7777

7878
object CustomMarkersOutputWrapper {
79-
def apply(output: Output, markers: CustomEventMarker[_]*): CustomMarkersOutputWrapper =
80-
new CustomMarkersOutputWrapper(output, markers.toSet)
79+
def apply(output: Output, markers: CustomEventMarker[?]*): CustomMarkersOutputWrapper =
80+
CustomMarkersOutputWrapper(output, markers.toSet)
81+
82+
def apply(output: Output, markers: Set[CustomEventMarker[?]]): CustomMarkersOutputWrapper =
83+
new CustomMarkersOutputWrapper(output, markers)
8184

8285
private final class AdjustedSimpleOutput(
8386
override protected val wrapped: SimpleOutput,
84-
override protected val markers: Set[CustomEventMarker[_]],
87+
override protected val markers: Set[CustomEventMarker[?]],
8588
) extends SimpleOutputWrapper with AcceptsAdditionalCustomMarkers
8689

8790
private final class AdjustedListOutput(
8891
override protected val wrapped: ListOutput,
89-
override protected val markers: Set[CustomEventMarker[_]],
92+
override protected val markers: Set[CustomEventMarker[?]],
9093
) extends ListOutputWrapper with AcceptsAdditionalCustomMarkers {
9194

9295
override def writeElement(): Output =
@@ -95,7 +98,7 @@ object CustomMarkersOutputWrapper {
9598

9699
private final class AdjustedObjectOutput(
97100
override protected val wrapped: ObjectOutput,
98-
override protected val markers: Set[CustomEventMarker[_]],
101+
override protected val markers: Set[CustomEventMarker[?]],
99102
) extends ObjectOutputWrapper with AcceptsAdditionalCustomMarkers {
100103

101104
override def writeField(key: String): Output =

core/src/test/scala/com/avsystem/commons/serialization/IgnoreTransientDefaultMarkerTest.scala

+4-2
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ object IgnoreTransientDefaultMarkerTest {
2020
}
2121

2222
class IgnoreTransientDefaultMarkerTest extends AbstractCodecTest {
23-
import IgnoreTransientDefaultMarkerTest._
23+
import IgnoreTransientDefaultMarkerTest.*
2424

2525
override type Raw = Any
2626

2727
def writeToOutput(write: Output => Unit): Any = {
2828
var result: Any = null
29-
write(CustomMarkersOutputWrapper(new SimpleValueOutput(result = _), IgnoreTransientDefaultMarker))
29+
write(CustomMarkersOutputWrapper(new SimpleValueOutput(v => result = v), IgnoreTransientDefaultMarker))
3030
result
3131
}
3232

@@ -40,6 +40,7 @@ class IgnoreTransientDefaultMarkerTest extends AbstractCodecTest {
4040
testWrite(HasDefaults(str = "dafuq"), Map("str" -> "dafuq", "int" -> 42))
4141
}
4242

43+
//noinspection RedundantDefaultArgument
4344
test("read case class with default values") {
4445
testRead(Map("str" -> "lol", "int" -> 42), HasDefaults(str = "lol", int = 42))
4546
testRead(Map("str" -> "lol"), HasDefaults(str = "lol", int = 42))
@@ -54,6 +55,7 @@ class IgnoreTransientDefaultMarkerTest extends AbstractCodecTest {
5455
testWrite(HasOptParam(), Map("flag" -> false))
5556
}
5657

58+
//noinspection RedundantDefaultArgument
5759
test("write nested case class with default values") {
5860
testWrite(
5961
value = NestedHasDefaults(

core/src/test/scala/com/avsystem/commons/serialization/ObjectSizeTest.scala

+6-6
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,39 @@ package serialization
33

44
import org.scalatest.funsuite.AnyFunSuite
55

6-
case class RecordWithDefaults(
6+
final case class RecordWithDefaults(
77
@transientDefault a: String = "",
88
b: Int = 42
99
) {
1010
@generated def c: String = s"$a-$b"
1111
}
1212
object RecordWithDefaults extends HasApplyUnapplyCodec[RecordWithDefaults]
1313

14-
class CustomRecordWithDefaults(val a: String, val b: Int)
14+
final class CustomRecordWithDefaults(val a: String, val b: Int)
1515
object CustomRecordWithDefaults extends HasApplyUnapplyCodec[CustomRecordWithDefaults] {
1616
def apply(@transientDefault a: String = "", b: Int = 42): CustomRecordWithDefaults =
1717
new CustomRecordWithDefaults(a, b)
1818
def unapply(crwd: CustomRecordWithDefaults): Opt[(String, Int)] =
1919
Opt((crwd.a, crwd.b))
2020
}
2121

22-
class CustomWrapper(val a: String)
22+
final class CustomWrapper(val a: String)
2323
object CustomWrapper extends HasApplyUnapplyCodec[CustomWrapper] {
2424
def apply(@transientDefault a: String = ""): CustomWrapper = new CustomWrapper(a)
2525
def unapply(cw: CustomWrapper): Opt[String] = Opt(cw.a)
2626
}
2727

28-
case class RecordWithOpts(
28+
final case class RecordWithOpts(
2929
@optionalParam abc: Opt[String] = Opt.Empty,
3030
@transientDefault flag: Opt[Boolean] = Opt.Empty,
3131
b: Int = 42,
3232
)
3333
object RecordWithOpts extends HasApplyUnapplyCodec[RecordWithOpts]
3434

35-
case class SingleFieldRecordWithOpts(@optionalParam abc: Opt[String] = Opt.Empty)
35+
final case class SingleFieldRecordWithOpts(@optionalParam abc: Opt[String] = Opt.Empty)
3636
object SingleFieldRecordWithOpts extends HasApplyUnapplyCodec[SingleFieldRecordWithOpts]
3737

38-
case class SingleFieldRecordWithTD(@transientDefault abc: String = "abc")
38+
final case class SingleFieldRecordWithTD(@transientDefault abc: String = "abc")
3939
object SingleFieldRecordWithTD extends HasApplyUnapplyCodec[SingleFieldRecordWithTD]
4040

4141
class ObjectSizeTest extends AnyFunSuite {

core/src/test/scala/com/avsystem/commons/serialization/cbor/CborInputOutputTest.scala

+8-6
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import org.scalatest.funsuite.AnyFunSuite
1010

1111
import java.io.{ByteArrayOutputStream, DataOutputStream}
1212

13-
case class Record(
13+
final case class Record(
1414
b: Boolean,
1515
i: Int,
1616
l: List[String],
@@ -19,7 +19,7 @@ case class Record(
1919
)
2020
object Record extends HasGenCodec[Record]
2121

22-
case class CustomKeysRecord(
22+
final case class CustomKeysRecord(
2323
@cborKey(1) first: Int,
2424
@cborKey(true) second: Boolean,
2525
@cborKey(Vector(1, 2, 3)) third: String,
@@ -28,13 +28,13 @@ case class CustomKeysRecord(
2828
)
2929
object CustomKeysRecord extends HasCborCodec[CustomKeysRecord]
3030

31-
case class CustomKeysRecordWithDefaults(
31+
final case class CustomKeysRecordWithDefaults(
3232
@transientDefault @cborKey(1) first: Int = 0,
3333
@cborKey(true) second: Boolean,
3434
)
3535
object CustomKeysRecordWithDefaults extends HasCborCodec[CustomKeysRecordWithDefaults]
3636

37-
case class CustomKeysRecordWithNoDefaults(
37+
final case class CustomKeysRecordWithNoDefaults(
3838
@cborKey(1) first: Int = 0,
3939
@cborKey(true) second: Boolean,
4040
)
@@ -242,11 +242,13 @@ class CborInputOutputTest extends AnyFunSuite {
242242
val value = CustomKeysRecordWithDefaults(first = 0, second = true)
243243
GenCodec.write(output, value)
244244
val bytes = Bytes(baos.toByteArray)
245-
assert(bytes.toString == "A20100F5F5")
245+
246+
val expectedRawValue = "A20100F5F5"
247+
assert(bytes.toString == expectedRawValue)
246248
assert(RawCbor(bytes.bytes).readAs[CustomKeysRecordWithDefaults](keyCodec) == value)
247249

248250
// should be the same as model with @transientDefault and serialization ignoring it
249-
assertRoundtrip(CustomKeysRecordWithNoDefaults(first = 0, second = true), "A20100F5F5")
251+
assertRoundtrip(CustomKeysRecordWithNoDefaults(first = 0, second = true), expectedRawValue)
250252
}
251253

252254
test("chunked text string") {

macros/src/main/scala/com/avsystem/commons/macros/serialization/GenCodecMacros.scala

+17-15
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ class GenCodecMacros(ctx: blackbox.Context) extends CodecMacroCommons(ctx) with
1010

1111
import c.universe._
1212

13+
private def IgnoreTransientDefaultMarkerObj: Tree = q"$SerializationPkg.IgnoreTransientDefaultMarker"
14+
1315
override def allowOptionalParams: Boolean = true
1416

1517
def mkTupleCodec[T: WeakTypeTag](elementCodecs: Tree*): Tree = instrument {
@@ -183,37 +185,37 @@ class GenCodecMacros(ctx: blackbox.Context) extends CodecMacroCommons(ctx) with
183185
doWriteField(p, value, transientValue)
184186
}
185187

186-
def writeFieldTransientDefaultPossible(p: ApplyParam, value: Tree): Tree = {
187-
val transientValue =
188-
if (isTransientDefault(p)) Some(p.defaultValue)
189-
else p.optionLike.map(ol => q"${ol.reference(Nil)}.none")
190-
doWriteField(p, value, transientValue)
191-
}
188+
def writeFieldTransientDefaultPossible(p: ApplyParam, value: Tree): Tree =
189+
if (isTransientDefault(p)) doWriteField(p, value, Some(p.defaultValue))
190+
else writeFieldNoTransientDefault(p, value)
192191

193192
def writeField(p: ApplyParam, value: Tree, ignoreTransientDefault: Tree): Tree =
194-
if (isTransientDefault(p))
193+
if (isTransientDefault(p)) // optimize code to avoid calling 'output.customEvent' when param does not have @transientDefault
195194
q"""
196-
if ($ignoreTransientDefault) ${writeFieldNoTransientDefault(p, value)}
195+
if($ignoreTransientDefault) ${writeFieldNoTransientDefault(p, value)}
197196
else ${writeFieldTransientDefaultPossible(p, value)}
198197
"""
199198
else
200199
writeFieldNoTransientDefault(p, value)
201200

202201
def ignoreTransientDefaultCheck: Tree =
203-
q"output.customEvent($SerializationPkg.IgnoreTransientDefaultMarker, ())"
202+
q"output.customEvent($IgnoreTransientDefaultMarkerObj, ())"
204203

205204
// when params size is 1
206205
def writeSingle(p: ApplyParam, value: Tree): Tree =
207206
writeField(p, value, ignoreTransientDefaultCheck)
208207

209208
// when params size is greater than 1
210209
def writeMultiple(value: ApplyParam => Tree): Tree =
211-
if (anyParamHasTransientDefault) {
210+
// optimize code to avoid calling 'output.customEvent' when there no params with @transientDefault
211+
// extracted to `val` to avoid calling 'output.customEvent' multiple times
212+
if (anyParamHasTransientDefault)
212213
q"""
213214
val ignoreTransientDefault = $ignoreTransientDefaultCheck
214215
..${params.map(p => writeField(p, value(p), q"ignoreTransientDefault"))}
215216
"""
216-
} else q"..${params.map(p => writeFieldNoTransientDefault(p, value(p)))}"
217+
else
218+
q"..${params.map(p => writeFieldNoTransientDefault(p, value(p)))}"
217219

218220
def writeFields: Tree = params match {
219221
case Nil =>
@@ -231,7 +233,7 @@ class GenCodecMacros(ctx: blackbox.Context) extends CodecMacroCommons(ctx) with
231233
else
232234
q"""
233235
val unapplyRes = $companion.$unapply[..${dtpe.typeArgs}](value)
234-
if (unapplyRes.isEmpty) unapplyFailed
236+
if(unapplyRes.isEmpty) unapplyFailed
235237
else ${writeSingle(p, q"unapplyRes.get")}
236238
"""
237239
case _ =>
@@ -240,7 +242,7 @@ class GenCodecMacros(ctx: blackbox.Context) extends CodecMacroCommons(ctx) with
240242
else
241243
q"""
242244
val unapplyRes = $companion.$unapply[..${dtpe.typeArgs}](value)
243-
if (unapplyRes.isEmpty) unapplyFailed
245+
if(unapplyRes.isEmpty) unapplyFailed
244246
else {
245247
val t = unapplyRes.get
246248
${writeMultiple(p => q"t.${tupleGet(p.idx)}")}
@@ -262,10 +264,10 @@ class GenCodecMacros(ctx: blackbox.Context) extends CodecMacroCommons(ctx) with
262264
case None => p.defaultValue
263265
}
264266

265-
// assumes usage in in size(value, output) method implementation
267+
// assumes usage in SizedCodec.size(value, output) method implementation
266268
def countTransientFields: Tree = {
267269
def checkIgnoreTransientDefaultMarker: Tree =
268-
q"output.isDefined && output.get.customEvent($SerializationPkg.IgnoreTransientDefaultMarker, ())"
270+
q"output.isDefined && output.get.customEvent($IgnoreTransientDefaultMarkerObj, ())"
269271

270272
def doCount(paramsToCount: List[ApplyParam], accessor: ApplyParam => Tree): Tree =
271273
paramsToCount.foldLeft[Tree](q"0") {

0 commit comments

Comments
 (0)