Hi Markus,
I too would try to stick with case classes.
My above pattern allows calling the generated
apply directly and also indirectly by
from. Passing an invalid value to the generated
apply results in an exception while calling
from returns an Option. So, in this schema, the user has the freedom to decide on the instantiation method depending on whether he is sure the validation won't fail.
If you want to revoke this choice from the user and ensure that your check is always run prior to the instantiation, you can work around declaring your case class abstract and provide its implementation within its companion object:
abstract case class C private(...)object C {
class InnerC private[C](override val ...) extends C(...)
def isValid(...): Boolean = ...
def apply(...): Option[C] = if (isValid(...)) Some(new InnerC(...)) else None
def from (...): Option[C] = ...
}Can you go along with that? Sorry, I cannot suggest an easier approach, maybe somebody else can.
Peter