add ScheduleBuilder as the variant of DSL

This commit is contained in:
InsanusMokrassar 2019-10-08 22:06:26 +06:00
parent c08bae65cb
commit d1a2b20792
2 changed files with 163 additions and 0 deletions

View File

@ -0,0 +1,109 @@
package com.github.insanusmokrassar.krontab.builder
import com.github.insanusmokrassar.krontab.*
fun buildSchedule(settingsBlock: SchedulerBuilder.() -> Unit): CronDateTimeScheduler {
val builder = SchedulerBuilder()
builder.settingsBlock()
return builder.build()
}
//infix fun Int.withStep(step: Int): PropertyHolder {
// return DivPropertyHolder(this, step)
//}
//
//operator fun Int.minus(including: Int): PropertyHolder {
// return RangePropertyHolder(this, including)
//}
class SchedulerBuilder(
private var seconds: Array<Byte>? = null,
private var minutes: Array<Byte>? = null,
private var hours: Array<Byte>? = null,
private var dayOfMonth: Array<Byte>? = null,
private var month: Array<Byte>? = null
) {
private fun <T : TimeBuilder> callAndReturn(
initial: Array<Byte>?,
builder: T,
block: T.() -> Unit
): Array<Byte>? {
builder.block()
val builderValue = builder.build()
return initial ?.let {
builderValue ?.let { _ ->
(it + builderValue).distinct().toTypedArray()
} ?: builderValue
} ?: builderValue
}
fun seconds(block: SecondsBuilder.() -> Unit) {
seconds = callAndReturn(
seconds,
SecondsBuilder(),
block
)
}
fun minutes(block: MinutesBuilder.() -> Unit) {
minutes = callAndReturn(
minutes,
MinutesBuilder(),
block
)
}
fun hours(block: HoursBuilder.() -> Unit) {
hours = callAndReturn(
hours,
HoursBuilder(),
block
)
}
fun dayOfMonth(block: DaysOfMonthBuilder.() -> Unit) {
dayOfMonth = callAndReturn(
dayOfMonth,
DaysOfMonthBuilder(),
block
)
}
fun months(block: MonthsBuilder.() -> Unit) {
month = callAndReturn(
month,
MonthsBuilder(),
block
)
}
fun build(): CronDateTimeScheduler {
val resultCronDateTimes = mutableListOf(CronDateTime())
seconds ?.fillWith(resultCronDateTimes) { previousCronDateTime: CronDateTime, currentTime: Byte ->
previousCronDateTime.copy(seconds = currentTime)
}
minutes ?.fillWith(resultCronDateTimes) { previousCronDateTime: CronDateTime, currentTime: Byte ->
previousCronDateTime.copy(minutes = currentTime)
}
hours ?.fillWith(resultCronDateTimes) { previousCronDateTime: CronDateTime, currentTime: Byte ->
previousCronDateTime.copy(hours = currentTime)
}
dayOfMonth ?.fillWith(resultCronDateTimes) { previousCronDateTime: CronDateTime, currentTime: Byte ->
previousCronDateTime.copy(dayOfMonth = currentTime)
}
month ?.fillWith(resultCronDateTimes) { previousCronDateTime: CronDateTime, currentTime: Byte ->
previousCronDateTime.copy(month = currentTime)
}
return CronDateTimeScheduler(resultCronDateTimes.toList())
}
}

View File

@ -0,0 +1,54 @@
package com.github.insanusmokrassar.krontab.builder
import com.github.insanusmokrassar.krontab.*
import com.github.insanusmokrassar.krontab.minutesRange
import com.github.insanusmokrassar.krontab.monthRange
import com.github.insanusmokrassar.krontab.secondsRange
import com.github.insanusmokrassar.krontab.utils.clamp
sealed class TimeBuilder (
private val restrictionsRange: IntRange
) {
private var result: Set<Int>? = null
fun allowAll() {
result = null
}
infix fun include(array: Array<Int>) {
val clamped = array.map { it.clamp(restrictionsRange) } + (result ?: emptySet())
result = clamped.toSet()
}
infix fun at(value: Int) {
result = (result ?: emptySet()) + value.clamp(restrictionsRange)
}
inline infix fun from(value: Int) = value
infix fun Int.every(delay: Int): Array<Int> {
val progression = clamp(restrictionsRange) .. restrictionsRange.last step delay
val result = progression.toSet().toTypedArray()
this@TimeBuilder include result
return result
}
infix fun Int.upTo(endIncluding: Int): Array<Int> {
val progression = clamp(restrictionsRange) .. endIncluding.clamp(restrictionsRange)
val result = progression.toSet().toTypedArray()
this@TimeBuilder include result
return result
}
internal fun build() = result ?.map { it.toByte() } ?.toTypedArray()
}
class SecondsBuilder : TimeBuilder(secondsRange)
class MinutesBuilder : TimeBuilder(minutesRange)
class HoursBuilder : TimeBuilder(hoursRange)
class DaysOfMonthBuilder : TimeBuilder(dayOfMonthRange)
class MonthsBuilder : TimeBuilder(monthRange)