Skip to content

Commit

Permalink
by-value API
Browse files Browse the repository at this point in the history
  • Loading branch information
RustedBones committed Nov 12, 2024
1 parent 3a1f747 commit b231259
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 4 deletions.
6 changes: 3 additions & 3 deletions core/src/main/scala/magnolia1/impl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ object CaseClassDerivation:
override def apply(): Option[p] = defaults.get(label).flatten.flatMap(d => unsafeCast(d.apply))
paramFromMaps[Typeclass, A, p](
label,
new CallByNeed(tc),
new CallByNeed(d, () => true),
CallByNeed.createLazy(tc),
CallByNeed.createValueEvaluator(d),
repeated,
annotations,
inheritedAnnotations,
Expand Down Expand Up @@ -203,7 +203,7 @@ trait SealedTraitDerivation:
IArray.from(paramTypeAnns[A]),
isObject[s],
idx,
new CallByNeed(tc),
CallByNeed.createLazy(tc),
isType,
asType
)
Expand Down
17 changes: 16 additions & 1 deletion core/src/main/scala/magnolia1/interface.scala
Original file line number Diff line number Diff line change
Expand Up @@ -363,17 +363,32 @@ object CallByNeed:
/** Initializes a class that allows for suspending evaluation of a value until it is needed. Evaluation of a value via `.value` can only
* happen once.
*/
def createLazy[A](a: () => A): CallByNeed[A] = new CallByNeed(a, () => false)

/** Initializes a class that allows for suspending evaluation of a value until it is needed. Evaluation of a value via `.value` can only
* happen once.
*
* If by-name parameter causes serialization issue, use [[createLazy]].
*/
def apply[A](a: => A): CallByNeed[A] = new CallByNeed(() => a, () => false)

/** Initializes a class that allows for suspending evaluation of a value until it is needed. Evaluation of a value via `.value` can only
* happen once. Evaluation of a value via `.valueEvaluator.map(evaluator => evaluator())` will happen every time the evaluator is called
*/
def createValueEvaluator[A](a: () => A): CallByNeed[A] = new CallByNeed(a, () => true)

/** Initializes a class that allows for suspending evaluation of a value until it is needed. Evaluation of a value via `.value` can only
* happen once. Evaluation of a value via `.valueEvaluator.map(evaluator => evaluator())` will happen every time the evaluator is called
*
* If by-name parameter causes serialization issue, use [[withValueEvaluator]].
*/
def withValueEvaluator[A](a: => A): CallByNeed[A] = new CallByNeed(() => a, () => true)
end CallByNeed

// Both params are later nullified to reduce overhead and increase performance.
// The supportDynamicValueEvaluation is passed as a function so that it can be nullified. Otherwise, there is no need for the function value.
final class CallByNeed[+A](private[this] var eval: () => A, private var supportDynamicValueEvaluation: () => Boolean) extends Serializable {
final class CallByNeed[+A] private (private[this] var eval: () => A, private var supportDynamicValueEvaluation: () => Boolean)
extends Serializable {

// This second constructor is necessary to support backwards compatibility for v1.3.6 and earlier
def this(eval: () => A) = this(eval, () => false)
Expand Down

0 comments on commit b231259

Please sign in to comment.