diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/krontab/builder/SchedulerBuilder.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/krontab/builder/SchedulerBuilder.kt new file mode 100644 index 0000000..1d9d004 --- /dev/null +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/krontab/builder/SchedulerBuilder.kt @@ -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? = null, + private var minutes: Array? = null, + private var hours: Array? = null, + private var dayOfMonth: Array? = null, + private var month: Array? = null +) { + private fun callAndReturn( + initial: Array?, + builder: T, + block: T.() -> Unit + ): Array? { + 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()) + } +} diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/krontab/builder/TimeBuilder.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/krontab/builder/TimeBuilder.kt new file mode 100644 index 0000000..edb3d3b --- /dev/null +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/krontab/builder/TimeBuilder.kt @@ -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? = null + + fun allowAll() { + result = null + } + + infix fun include(array: Array) { + 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 { + 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 { + 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)