aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/reading/models/Filter.scala
blob: a74a6f127273b72cd6694baf4b619e3c82bfff66 (plain)
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
67
package reading.models

trait Filter {
  def filter(book: Book): Boolean
  def kind: FilterKind
  def name: String
}

sealed trait FilterKind
case object PeriodKind extends FilterKind
case object ThemeKind extends FilterKind
case object GenreKind extends FilterKind
case object DifficultyKind extends FilterKind
case object ProgramKind extends FilterKind

object Filter {
  def apply[T](in: T)(implicit filterFactory: FilterFactory[T]): Filter =
    filterFactory.create(in)

  def contains(filters: Seq[Filter], filter: Filter): Boolean =
    filters.find(f => f.kind == filter.kind && f.name == filter.name).nonEmpty

  def equals(f1: Filter, f2: Filter): Boolean =
    f1.kind == f2.kind && f1.name == f2.name
}

trait FilterFactory[T] {
  def create(in: T): Filter
}

object FilterFactory {
  implicit object PeriodFilter extends FilterFactory[Period] {
    def create(period: Period): Filter =
      new Filter {
        def filter(book: Book): Boolean = book.period == period
        val kind: FilterKind = PeriodKind
        val name: String = period.toString()
      }
  }

  implicit object ThemeFilter extends FilterFactory[Theme] {
    def create(theme: Theme): Filter =
      new Filter {
        def filter(book: Book): Boolean = book.themes.contains(theme)
        val kind: FilterKind = ThemeKind
        val name: String = theme.toString()
      }
  }

  implicit object GenreFilter extends FilterFactory[Genre] {
    def create(genre: Genre): Filter =
      new Filter {
        def filter(book: Book): Boolean = book.genres.contains(genre)
        val kind: FilterKind = GenreKind
        val name: String = genre.toString()
      }
  }

  implicit object ProgramFilter extends FilterFactory[Program] {
    def create(program: Program): Filter =
      new Filter {
        def filter(book: Book): Boolean = book.program == program
        val kind: FilterKind = ProgramKind
        val name: String = program.toString()
      }
  }
}