Usage
In order to the structible library including any derivation provided by its satellite projects, you first need a create a structible instance. Once you have that check the sub-pages on the left for library-specific derivations.
Dependency
- sbt
libraryDependencies += "com.github.cerst" % "structible-core" % "0.6.4"
- Maven
<dependency> <groupId>com.github.cerst</groupId> <artifactId>structible-core</artifactId> <version>0.6.4</version> </dependency>
- Gradle
dependencies { compile group: 'com.github.cerst', name: 'structible-core', version: '0.6.4' }
Basic Example
Here’s an example for a UserId value class:
import com.github.cerst.structible.core._
object BasicExample {
final class UserId private (val value: Long) extends AnyVal
object UserId {
private val structible: Structible[Long, UserId] =
Structible.structible(new UserId(_), _.value, c.unconstrained)
def apply(value: Long): UserId = structible.construct(value)
}
}
Structible.structible takes four parameters:
- a construct function - usually a constructor/ function which may throw - but you can also use functions returning Either[String, R], Option[R] or Try[R]
- a destruct function - the opposite of construct which is expected to be safe (i.e. not to throw)
- a constraint to be checked - in this case unconstrained which does not require anything
Constraints
Structible Constraints are based on the standard operators you’d use in a typical require expression (e.g. >=, matches, length) and can be combined using the || and && operator with && having a high precedence.
Let’s assume, you want the value of UserId to be a UInt:
import com.github.cerst.structible.core._
import com.github.cerst.structible.core.DefaultConstraints._
object ConstraintExample {
final class UserId private (val value: Long) extends AnyVal
object UserId {
private final val MaxValue = Math.pow(2, 32).toLong
private val structible: Structible[Long, UserId] =
Structible.structible(new UserId(_), _.value, c >= 0L && c <= MaxValue)
def apply(value: Long): UserId = structible.construct(value)
}
}
Note the additional import DefaultConstraints._ which is required because structible constraints are implemented as type classes. To see the available constraint syntax and instances, check the sources of ConstraintSyntax and DefaultConstraints respectively.
Working without class tags
In some circumstances, you might not be able to get a ClassTag[R] from the compiler. To fix that, all structible methods provide an overload accepting either what is expected to be the companion object of R or a plain String.
Concerning AnyVal and access modifiers ( private )
You may have noticed that the above example uses AnyVal to form a value class and defines both the constructor as well as the structible member in the companion object as private. However, none of that is a requirement.
Rather, structible is intended to work with any (_value_) class definition style. Likewise, constructor and field are merely set to private to show that external access isn’t needed. Indeed, it may make sense to keep the structible as public and even implicit assuming that you (eventually) want to use self-made or external integration (though none are known at the time of writing).