Last active
March 26, 2017 22:40
-
-
Save leandrob13/f7cee4534147f75e54df2b1eebea4399 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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