Skip to content

Commit

Permalink
Decouple Shows and FieldExpr typeclasses.
Browse files Browse the repository at this point in the history
  • Loading branch information
Antonio Alonso Dominguez committed Feb 4, 2017
1 parent 405df6d commit 3eb6958
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 27 deletions.
10 changes: 9 additions & 1 deletion core/shared/src/main/scala/cron4s/CronField.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@

package cron4s

import scalaz.Equal

/**
* Each of the different fields supported in CRON expressions
*
* @author Antonio Alonso Dominguez
*/
sealed trait CronField extends Serializable
object CronField {
object CronField extends CronFieldInstances {

sealed trait Second extends CronField
case object Second extends Second
Expand All @@ -45,3 +47,9 @@ object CronField {
final val All: List[CronField] = List(Second, Minute, Hour, DayOfMonth, Month, DayOfWeek)

}

private[cron4s] trait CronFieldInstances {

implicit val cronFieldEq: Equal[CronField] = Equal.equalA[CronField]

}
4 changes: 1 addition & 3 deletions core/shared/src/main/scala/cron4s/expr/FieldExpr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@ package cron4s.expr
import cron4s.{CronField, CronUnit}
import cron4s.base.{Enumerated, Predicate}

import scalaz.Show

/**
* Created by alonsodomin on 25/08/2016.
*/
trait FieldExpr[E[_ <: CronField], F <: CronField] extends Enumerated[E[F]] with Show[E[F]] {
trait FieldExpr[E[_ <: CronField], F <: CronField] extends Enumerated[E[F]] {

def matches(e: E[F]): Predicate[Int]

Expand Down
42 changes: 30 additions & 12 deletions core/shared/src/main/scala/cron4s/expr/nodes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import cron4s.base._
import cron4s.syntax.field._
import cron4s.syntax.predicate._

import scalaz.NonEmptyList
import scalaz.{NonEmptyList, Show}
import scalaz.std.anyVal._
import scalaz.std.list._
import scalaz.syntax.show._
Expand All @@ -47,10 +47,15 @@ final case class EachNode[+F <: CronField](implicit val unit: CronUnit[F])

lazy val range: IndexedSeq[Int] = unit.range

override val toString = "*"

}

object EachNode {

implicit def eachNodeShow[F <: CronField]: Show[EachNode[F]] =
Show.showFromToString[EachNode[F]]

implicit def eachNodeInstance[F <: CronField]: FieldExpr[EachNode, F] =
new FieldExpr[EachNode, F] {
def unit(node: EachNode[F]): CronUnit[F] = node.unit
Expand All @@ -62,8 +67,6 @@ object EachNode {
x >= min(node) && x <= max(node)
}

override def shows(node: EachNode[F]): String = "*"

def range(node: EachNode[F]): IndexedSeq[Int] = node.range
}

Expand All @@ -76,10 +79,16 @@ final case class ConstNode[F <: CronField]

lazy val range: IndexedSeq[Int] = Vector(value)

override lazy val toString: String =
textValue.getOrElse(value.toString)

}

object ConstNode {

implicit def constNodeShow[F <: CronField]: Show[ConstNode[F]] =
Show.showFromToString[ConstNode[F]]

implicit def constNodeInstance[F <: CronField]: FieldExpr[ConstNode, F] =
new FieldExpr[ConstNode, F] {
def unit(node: ConstNode[F]): CronUnit[F] = node.unit
Expand All @@ -92,8 +101,6 @@ object ConstNode {
}

def range(node: ConstNode[F]): IndexedSeq[Int] = node.range

override def shows(node: ConstNode[F]): String = node.textValue.getOrElse(node.value.toString)
}

}
Expand All @@ -109,10 +116,16 @@ final case class BetweenNode[F <: CronField]
min to max
}

override lazy val toString: String =
s"${begin.shows}-${end.shows}"

}

object BetweenNode {

implicit def betweenNodeShow[F <: CronField]: Show[BetweenNode[F]] =
Show.showFromToString[BetweenNode[F]]

implicit def betweenNodeInstance[F <: CronField]
(implicit elemExpr: FieldExpr[ConstNode, F]): FieldExpr[BetweenNode, F] =
new FieldExpr[BetweenNode, F] {
Expand All @@ -130,8 +143,6 @@ object BetweenNode {

def range(node: BetweenNode[F]): IndexedSeq[Int] = node.range

override def shows(node: BetweenNode[F]): String =
s"${node.begin.shows}-${node.end.shows}"
}

}
Expand All @@ -144,6 +155,9 @@ final case class SeveralNode[F <: CronField]
lazy val range: IndexedSeq[Int] =
values.list.toVector.view.flatMap(_.range).distinct.sorted.toIndexedSeq

override lazy val toString: String =
values.map(_.shows).list.toList.mkString(",")

}

object SeveralNode {
Expand All @@ -152,6 +166,9 @@ object SeveralNode {
(implicit unit: CronUnit[F]): SeveralNode[F] =
SeveralNode(NonEmptyList(head, tail: _*))

implicit def severalNodeShow[F <: CronField]: Show[SeveralNode[F]] =
Show.showFromToString[SeveralNode[F]]

implicit def severalNodeInstance[F <: CronField]
(implicit elemExpr: FieldExpr[EnumerableNode, F]): FieldExpr[SeveralNode, F] =
new FieldExpr[SeveralNode, F] {
Expand All @@ -165,8 +182,6 @@ object SeveralNode {

def range(node: SeveralNode[F]): IndexedSeq[Int] = node.range

override def shows(node: SeveralNode[F]): String =
node.values.map(_.shows).list.toList.mkString(",")
}

}
Expand All @@ -184,10 +199,16 @@ final case class EveryNode[F <: CronField]
elements.toVector
}

override lazy val toString: String =
s"${base.shows}/$freq"

}

object EveryNode {

implicit def everyNodeShow[F <: CronField]: Show[EveryNode[F]] =
Show.showFromToString[EveryNode[F]]

implicit def everyNodeInstance[F <: CronField]
(implicit baseExpr: FieldExpr[DivisibleNode, F]): FieldExpr[EveryNode, F] =
new FieldExpr[EveryNode, F] {
Expand All @@ -202,9 +223,6 @@ object EveryNode {

def range(node: EveryNode[F]): IndexedSeq[Int] = node.range

override def shows(node: EveryNode[F]): String =
s"${node.base.shows}/${node.freq}"

}

}
22 changes: 13 additions & 9 deletions core/shared/src/main/scala/cron4s/expr/wrappers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import cron4s.base.Predicate

import shapeless._

import scalaz.Show

/**
* Created by alonsodomin on 23/01/2017.
*/
Expand All @@ -31,6 +33,10 @@ final class FieldNode[F <: CronField](private[cron4s] val raw: RawFieldNode[F])
}

object FieldNode {

implicit def fieldNodeShow[F <: CronField]: Show[FieldNode[F]] =
Show.shows(_.raw.fold(ops.show))

implicit def fieldNodeInstance[F <: CronField]: FieldExpr[FieldNode, F] = new FieldExpr[FieldNode, F] {
def matches(node: FieldNode[F]): Predicate[Int] =
node.raw.fold(ops.matches)
Expand All @@ -50,9 +56,6 @@ object FieldNode {

def unit(node: FieldNode[F]): CronUnit[F] =
node.raw.fold(ops.unit)

override def shows(node: FieldNode[F]): String =
node.raw.fold(ops.show)
}
}

Expand All @@ -64,6 +67,9 @@ final class EnumerableNode[F <: CronField](val raw: RawEnumerableNode[F]) extend

object EnumerableNode {

implicit def enumerableNodeShow[F <: CronField]: Show[EnumerableNode[F]] =
Show.shows(_.raw.fold(ops.show))

implicit def enumerableNodeInstance[F <: CronField]: FieldExpr[EnumerableNode, F] =
new FieldExpr[EnumerableNode, F] {
def matches(node: EnumerableNode[F]): Predicate[Int] =
Expand All @@ -83,9 +89,6 @@ object EnumerableNode {

def unit(node: EnumerableNode[F]): CronUnit[F] =
node.raw.fold(ops.unit)

override def shows(node: EnumerableNode[F]): String =
node.raw.fold(ops.show)
}

}
Expand All @@ -97,6 +100,10 @@ final class DivisibleNode[F <: CronField](val raw: RawDivisibleNode[F]) extends
}

object DivisibleNode {

implicit def divisibleNodeShow[F <: CronField]: Show[DivisibleNode[F]] =
Show.shows(_.raw.fold(ops.show))

implicit def divisibleNodeInstance[F <: CronField]: FieldExpr[DivisibleNode, F] =
new FieldExpr[DivisibleNode, F] {
def matches(node: DivisibleNode[F]): Predicate[Int] =
Expand All @@ -115,8 +122,5 @@ object DivisibleNode {

def unit(node: DivisibleNode[F]): CronUnit[F] =
node.raw.fold(ops.unit)

override def shows(node: DivisibleNode[F]): String =
node.raw.fold(ops.show)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ trait DateTimeCronTests[E, DateTime] extends Laws {
"matchAll" -> forAll(laws.matchAll _),
"matchAny" -> forAll(laws.matchAny _),
"forwards" -> forAll(laws.forwards _),
"backwards" -> forAll(laws.backwards _)
"backwards" -> forAll(laws.backwards _),
"supportedFields" -> forAll(laws.supportedFieldsEquality _)
)

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@

package cron4s.testkit.laws

import cron4s.datetime.{IsDateTime, DateTimeCron}
import cron4s.CronField
import cron4s.datetime.{DateTimeCron, IsDateTime}
import cron4s.testkit._
import cron4s.syntax.cron._

Expand Down Expand Up @@ -71,6 +72,9 @@ trait DateTimeCronLaws[E, DateTime] {
def backwards(e: E, from: DateTime): IsEqual[Option[DateTime]] =
e.prev(from) <-> e.step(from, -1)

def supportedFieldsEquality(e: E): IsEqual[List[CronField]] =
supportedFields[E] <-> e.supportedFields

}

object DateTimeCronLaws {
Expand Down

0 comments on commit 3eb6958

Please sign in to comment.