Skip to content

Instantly share code, notes, and snippets.

@leandrob13
Last active March 26, 2017 22:40
Show Gist options
  • Save leandrob13/f7cee4534147f75e54df2b1eebea4399 to your computer and use it in GitHub Desktop.
Save leandrob13/f7cee4534147f75e54df2b1eebea4399 to your computer and use it in GitHub Desktop.
package fp
case class Book(isbn: String, title: String, author: String, genre: Genre)
trait Genre extends Product with Serializable
object Genre {
def apply(g: String): Genre = g match {
case "fiction" => Fiction
case "science-fiction" => ScienceFiction
case "historic-novel" => HistoricNovel
case _ => InvalidGenre
}
case object Fiction extends Genre
case object ScienceFiction extends Genre
case object HistoricNovel extends Genre
case object InvalidGenre extends Genre
}
package imperative
import fp.{Book, Genre}
import scala.collection.mutable.ListBuffer
import scala.util.matching.Regex
trait BookValidation {
private val isbnRegex: Regex =
"""ISBN(?:-13)?:?\x20*(?=.{17}$)97(?:8|9)([ -])\d{1,5}\1\d{1,7}\1\d{1,6}\1\d$""".r
def validateBooks(books: List[Book]): List[Book] =
if (books == Nil) throw new EmptyBookList("Book list was empty")
else {
val booksBuffer = new ListBuffer[Book]
for (book <- books) {
try booksBuffer += validateBook(book) catch { case ex: Exception => println(s"Error $ex") }
}
booksBuffer.toList
}
def validateBook(book: Book): Book = {
validateGenre(book.genre)
validateIsbn(book.isbn)
validateTitle(book.title)
validateAuthor(book.author)
book
}
private def validateGenre(g: Genre): Unit =
if ( g == Genre.InvalidGenre ) throw new InvalidParameter("Book has invalid genre")
private def validateIsbn(isbn: String): Unit = isbn match {
case isbnRegex(all @ _*) => ()
case _ => throw new InvalidParameter("isbn has not a valid format")
}
private def validateTitle(title: String): Unit =
if (title.isEmpty || title == null) throw new InvalidParameter("title must not be empty")
private def validateAuthor(author: String): Unit =
if (author.isEmpty || author == null) throw new InvalidParameter("author must not be empty")
}
class InvalidParameter(message: String) extends Exception
class EmptyBookList(message: String) extends Exception
package fp.scalaTry
import cats.data.NonEmptyList
import fp.{Book, Genre}
import cats.instances.try_._
import cats.syntax.semigroup._
import cats.syntax.cartesian._
import scala.util.{Failure, Try}
import scala.util.matching.Regex
trait BookValidationService {
private val isbnRegex: Regex =
"""ISBN(?:-13)?:?\x20*(?=.{17}$)97(?:8|9)([ -])\d{1,5}\1\d{1,7}\1\d{1,6}\1\d$""".r
def validateBooks(bs: List[Book]): Try[NonEmptyList[Book]] = bs match {
case Nil => Failure(new EmptyBookList("Book list was empty"))
case books => books map validateBook reduce (_ |+| _)
}
def validateBooksAp(bs: List[Book]): Try[NonEmptyList[Book]] = bs match {
case Nil => throw new EmptyBookList("Book list was empty")
case books => books map validateBookAp reduce (_ |+| _)
}
def validateBook(b: Book): Try[NonEmptyList[Book]] =
for {
i <- validateIsbn(b.isbn)
a <- validateAuthor(b.author)
t <- validateTitle(b.title)
g <- validateGenre(b.genre)
} yield NonEmptyList.of(Book(i, t, a, g))
def validateBookAp(b: Book): Try[NonEmptyList[Book]] = (
validateIsbn(b.isbn) |@|
validateAuthor(b.author) |@|
validateTitle(b.title) |@|
validateGenre(b.genre) ) map {
case (isbn, author, title, genre) =>
NonEmptyList.of(Book(isbn, title, author, genre))
}
private def validateGenre(g: Genre): Try[Genre] = Try {
g match {
case Genre.InvalidGenre => throw new InvalidParameter("Book has invalid genre")
case genre => genre
}
}
private def validateIsbn(isbn: String): Try[String] = Try {
isbn match {
case isbnRegex(all @ _*) => isbn
case _ => throw new InvalidParameter("isbn has not a valid format")
}
}
private def validateTitle(title: String): Try[String] = Try {
if (Option(title).forall(_.isEmpty)) throw new InvalidParameter("title must not be empty") else title
}
private def validateAuthor(author: String): Try[String] = Try {
if (Option(author).forall(_.isEmpty)) throw new InvalidParameter("author must not be empty") else author
}
}
class InvalidParameter(message: String) extends Exception(message)
class EmptyBookList(message: String) extends Exception(message)
package fp
sealed trait Error extends Product with Serializable {
val message: String
}
case class InvalidParameter(message: String) extends Error
case class EmptyBookList(message: String) extends Error
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment