A simple and easy validation syntax for Scala and Java classes
For more detailed information, please refer to the API Documentation.
Requires: Scala 2.12, 2.11
- Add it to your project
- Basic Usage
- Nested Classes
- Validating With
- Reporting an Issue
- Contributing
- License
Using sbt:
In build.sbt:
libraryDependencies += "com.github.vickumar1981" %% "svalidate" % "1.0.1"Using gradle:
In build.gradle:
dependencies {
compile 'com.github.vickumar1981:svalidate_2.12:1.0.1'
}Using Maven:
In pom.xml:
<dependency>
<groupId>com.github.vickumar1981</groupId>
<artifactId>svalidate_2.12</artifactId>
<version>1.0.1</version>
</dependency>Note: For Java 7 or Scala 2.11, please use the svalidate_2.11 artifact as a dependency instead.
Let's create a simple class called Address that looks like:
package test.example
case class Address(street: String,
city: String,
state: String,
zipCode: String)The rules for validating an Address are:
- street address is required
- city is required
- state abbr. must be exactly two capital letters
- zip code must be exactly 5 digits
Using sValidate's validation syntax, we can add a new validator of the type Validatable<Address>
package test.example
import com.github.vickumar1981.svalidate.{Validatable, Validation}
object ModelValidations {
implicit object AddressValidator extends Validatable[Address] {
override def validate(value: Address): Validation = {
(value.street.nonEmpty orElse "Street addr. is required") ++
(value.city.nonEmpty orElse "City is required") ++
(value.zipCode.matches("\\d{5}") orElse "Zip code must be 5 digits") ++
(value.state.matches("[A-Z]{2}") orElse "State abbr must be 2 letters")
}
}
}To extend validation to the Address class, we import our validator and the validation syntax.
import test.example.Address
object TestValidation {
import test.example.ModelValidations._
import com.github.vickumar1981.svalidate.ValidationSyntax._
def main(args: Array[String]): Unit = {
val addr = Address("", "", "", "")
val errors = addr.validate().errors
println(errors)
// ArrayBuffer(Street addr. is required, City is required, Zip code must be 5 digits, State abbr must be 2 letters)
}
}See Scala Address validation example
See Java Address validation example
Let's say we have a Person class which contains an Address instance,
and whose validation depends upon the validation of the address member instance.
Additionally, a Person also has a hasContact: Boolean indicator
The class might look like:
case class Person(firstName: String,
lastName: String,
hasContactInfo: Boolean,
address: Option[Address] = None,
phone: Option[String] = None)
The rules for validating a Person are:
- first name is required
- last name is required
- phone number and address are both optional, and their
validation depends upon the
hasContactInfoindicator - a phone number must be exactly 10 numbers
- if the
hasContactInfoflag is true, then bothphoneandaddressshould be validated - if the
hasContactInfoflag is false, then bothphoneandaddressshould be empty
An example validator for Person might look like:
package text.example
import com.github.vickumar1981.svalidate.{Validatable, Validation}
object ModelValidations {
implicit object PersonValidator extends Validatable[Person] {
def validateContactInfo(value: Person): Validation = {
(value.address errorIfEmpty "Address is required") ++
(value.phone errorIfEmpty "Phone # is required") ++
value.address.maybeValidate() ++
value.phone.maybeValidate(_.matches("\\d{10}") orElse "Phone # must be 10 digits")
}
override def validate(value: Person): Validation = {
(value.firstName.nonEmpty orElse "First name is required") ++
(value.lastName.nonEmpty orElse "Last name is required") ++
(value.hasContactInfo andThen validateContactInfo(value)) ++
value.hasContactInfo.orElse {
(value.address errorIfDefined "Address must be empty") ++
(value.phone errorIfDefined "Phone # must be empty")
}
}
}
}See Scala Person validation example
See Java Person validation example
Sometimes, validation depends on an external value. This is where we can use the .validateWith[T](t: T) syntax.
Let's say we have a Contacts class which contains an optional list of Facebook and Twitter emails.
Each user in our system also has a ContactSettings object, that determines the validation of the user's Contacts
The two classes might look like:
case class Contacts(facebook: Option[List[String]] = None, twitter: Option[List[String]] = None)
case class ContactSettings(hasFacebookContacts: Option[Boolean] = Some(true),
hasTwitterContacts: Option[Boolean] = Some(true))The rules for validating a user's Contacts are:
- If the
hasFacebookContactsorhasTwitterContactsindicators are set totrue, then the respectivefacebookortwitterlist of emails for a user must be supplied - If the
hasFacebookContactsorhasTwitterContactsindicators are set tofalse, then the respectivefacebookortwitterlist of emails for a user must be empty - If the
hasFacebookContactsorhasTwitterContactsindicators are empty, then the respectivefacebookortwitterlist of emails can be empty or supplied
We will use a ValidatableWith[Contacts, ContactSettings] validator.
An example implementation might look like:
package text.example
import com.github.vickumar1981.svalidate.{ValidatableWith, Validation}
object ModelValidations {
implicit object ContactInfoValidator extends ValidatableWith[Contacts, ContactSettings] {
override def validateWith(value: Contacts, contactSettings: ContactSettings): Validation = {
contactSettings.hasFacebookContacts.maybeValidate {
contacts =>
(contacts andThen { value.facebook errorIfEmpty "Facebook contacts are required" }) ++
(contacts orElse { value.facebook errorIfDefined "Facebook contacts must be empty"})
} ++
contactSettings.hasTwitterContacts.maybeValidate {
contacts =>
(contacts andThen { value.twitter errorIfEmpty "Twitter contacts are required" }) ++
(contacts orElse { value.twitter errorIfDefined "Twitter contacts must be empty" })
}
}
}
}An example of using .validateWith:
import test.example.{ContactSettings, ContactInfo}
object TestValidation {
import test.example.ModelValidations._
import com.github.vickumar1981.svalidate.ValidationSyntax._
def main(args: Array[String]): Unit = {
val contacts = Contacts(None, None)
val contactSettings = ContactSettings(None, None)
val result = contact.validateWith(contactSettings)
println(result.isSuccess)
// true
}
}See Scala Contacts validation example
Note: There is currently no .validateWith syntax for Java
Please report any issues or bugs to the Github issues page.
Please view the contributing guidelines
This project is licensed under the Apache 2 License.
