Skip to content

Instantly share code, notes, and snippets.

@jdegoes
Created May 14, 2020 11:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jdegoes/7eb5f63cfb51c7c2d19ec3157bd299e0 to your computer and use it in GitHub Desktop.
Save jdegoes/7eb5f63cfb51c7c2d19ec3157bd299e0 to your computer and use it in GitHub Desktop.
package zio.cron
import java.time.Instant
final case class Cron(moh: Option[MinuteOfHour], hod: Option[HourOfDay], dom: Option[DayOfMonth], moy: Option[MonthOfYear], dow: Option[DayOfWeek]) {
/**
* Returns a `Cron` that describes execution only when both this `Cron` and
* the specified `Cron` would run.
*/
def && (that: Cron): Cron = ???
/**
* Returns a `Cron` that describes execution when either this `Cron` or
* the specified `Cron` would run.
*/
def || (that: Cron): Cron = ???
def + (that: Cron): Cron = this || that
def next(now: Instant): Instant = schedule(now).dropWhile(_ == now).head
def previous(now: Instant): Instant = ???
def render: String = ???
def schedule(start: Instant): Stream[Instant] = ???
}
object Cron {
def empty: Cron = Cron(None, None, None, None, None)
def fromString(string: String): Either[String, Cron] = ???
def minute(minuteOfHour: MinuteOfHour): Cron = ???
def hour(hour: HourOfDay): Cron = ???
}
sealed trait MinuteOfHour { self =>
import MinuteOfHour._
def && (that: MinuteOfHour): MinuteOfHour =
(self, that) match {
case (AnyValue, that) => that
case (self, AnyValue) => self
case (self, that) => values((self.toValues.toSet intersect that.toValues.toSet).toList.sorted: _*)
}
def || (that: MinuteOfHour): MinuteOfHour =
(self, that) match {
case (AnyValue, _) => AnyValue
case (_, AnyValue) => AnyValue
case (self, that) => values((self.toValues.toSet union that.toValues.toSet).toList.sorted: _*)
}
def render: String
def toValues: List[Int]
}
object MinuteOfHour {
case object AnyValue extends MinuteOfHour {
def render = "*"
def toValues: List[Int] = (0 to 59).toList
}
sealed abstract class Values private[cron] (List: List[Int]) extends MinuteOfHour {
def render = List.map(_.toString).mkString(",")
def toValues: List[Int] = List
}
sealed abstract class Step private[cron] (value: Int) extends MinuteOfHour {
def render = s"*/${value}"
def toValues: List[Int] = (0 to 59 by value).toList
}
sealed abstract class Range private[cron] (min: Int, max: Int) extends MinuteOfHour {
def render = s"${min}-${max}"
def toValues: List[Int] = (min to max).toList
}
def any: MinuteOfHour = AnyValue
def values(values: Int*): MinuteOfHour = ???
def step(value: Int): MinuteOfHour = ???
def range(r: scala.Range): MinuteOfHour = new Range(r.start, r.end) {}
def fromIterable(vs: Iterable[Int]): MinuteOfHour = values(vs.toSeq: _*)
}
sealed trait HourOfDay {
def render: String
}
object HourOfDay {
case object AnyValue extends HourOfDay {
def render: String = "*"
}
final case class Values(List: List[Int]) extends HourOfDay {
def render: String = List.map(_.toString).mkString(",")
}
final case class Step(value: Int) extends HourOfDay {
def render = s"*/${value}"
}
final case class Range(min: Int, max: Int) extends HourOfDay {
def render = s"${min}-${max}"
}
}
sealed trait DayOfMonth {
def render: String
}
object DayOfMonth {
case object AnyValue extends DayOfMonth {
def render: String = "*"
}
final case class Values(List: List[Int]) extends DayOfMonth {
def render: String = List.map(_.toString).mkString(",")
}
final case class Step(value: Int) extends DayOfMonth {
def render = s"*/${value}"
}
final case class Range(min: Int, max: Int) extends DayOfMonth {
def render = s"${min}-${max}"
}
}
sealed trait MonthOfYear {
def render: String
}
object MonthOfYear {
case object AnyValue extends MonthOfYear {
def render: String = "*"
}
final case class Values(List: List[Int]) extends MonthOfYear {
def render: String = List.map(_.toString).mkString(",")
}
final case class Step(value: Int) extends MonthOfYear {
def render = s"*/${value}"
}
final case class Range(min: Int, max: Int) extends MonthOfYear {
def render = s"${min}-${max}"
}
}
sealed trait DayOfWeek {
def render: String
}
object DayOfWeek {
case object AnyValue extends DayOfWeek {
def render: String = "*"
}
sealed trait SpecificDay extends DayOfWeek {
def ordinal: Int
final def render: String = ordinal.toString
}
case object Monday extends SpecificDay {
def ordinal = 1
}
case object Tuesday extends SpecificDay {
def ordinal = 2
}
case object Wednesday extends SpecificDay {
def ordinal = 3
}
case object Thursday extends SpecificDay {
def ordinal = 4
}
case object Friday extends SpecificDay {
def ordinal = 5
}
case object Saturday extends SpecificDay {
def ordinal = 6
}
case object Sunday extends SpecificDay {
def ordinal = 7
}
final case class Values(List: List[SpecificDay]) extends DayOfWeek {
def render: String = List.map(_.render).mkString(",")
}
final case class Step(value: Int) extends MonthOfYear {
def render = s"*/${value}"
}
final case class Range(min: SpecificDay, max: SpecificDay) extends MonthOfYear {
def render = s"${min.render}-${max.render}"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment