public
Last active

Pimpin' + on a T => Either[ERR,T] for easy chaining

  • Download Gist
PimpMyFilter.scala
Scala
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
class Filters[T] {
 
//Some boilerplate-busting aliases
type FilterResult = Either[Rejection, T]
type FilterFunc = (T) => FilterResult
 
//Handy helpers
//Rejection can carry as much info as you wish;
// Filter name, value in error, an exception, etc.
case class Rejection(input: T, msg: String)
 
def pass(x: T): FilterResult = Right(x)
def reject(x: T, msg: String): FilterResult = Left(Rejection(x, msg))
 
//The awesome pimp!
class Chainable(fn: FilterFunc) {
def +(other: FilterFunc): FilterFunc = (input: T) => fn(input).right flatMap other
}
implicit def filterFuncIsChainable(fn: FilterFunc) = new Chainable(fn)
}
 
object StringFilters extends Filters[String] {
 
val rejectNonAlphaNumeric: FilterFunc = (input: String) =>
if (input.matches(".*[0-9a-zA-z].*")) pass(input)
else reject(input, "didn't containin any alphanumeric characters")
 
val rejectSingleChar: FilterFunc = (input: String) =>
if (input.length >= 2) pass(input)
else reject(input, "was a mere single character")
 
val convertToUppercase: FilterFunc = (input: String) => pass(input.toUpperCase)
 
def rejectOverLength(maxLength: Int): FilterFunc = (input: String) =>
if (input.length < maxLength) pass(input)
else reject(input, "was over " + maxLength + " characters long")
}
 
import StringFilters._
 
 
 
//And now... All the juicy magic goodness makes it trivial to use :)
val processor = rejectNonAlphaNumeric + rejectSingleChar + rejectOverLength(20) + convertToUppercase
 
 
processor("hello world")
// Right(HELLO WORLD)
 
processor("x")
// Left(Rejection(x,was a mere single character))
 
processor("22")
// Right(22)
 
processor("_")
// Left(Rejection(_,was a mere single character))
 
processor("__")
// Right(__)
 
processor("''")
// Left(Rejection('',didn't containin any alphanumeric characters))
 
processor("abcdefghijklmnopqrstuvwxyz")
// Left(Rejection(abcdefghijklmnopqrstuvwxyz,was over 20 characters long))

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.