mirror of
https://github.com/InsanusMokrassar/krontab.git
synced 2025-12-11 23:45:47 +00:00
files replacements
This commit is contained in:
196
src/commonMain/kotlin/builder/SchedulerBuilder.kt
Normal file
196
src/commonMain/kotlin/builder/SchedulerBuilder.kt
Normal file
@@ -0,0 +1,196 @@
|
||||
package dev.inmo.krontab.builder
|
||||
|
||||
import korlibs.time.TimezoneOffset
|
||||
import korlibs.time.minutes
|
||||
import dev.inmo.krontab.KronScheduler
|
||||
import dev.inmo.krontab.KronSchedulerTz
|
||||
import dev.inmo.krontab.internal.*
|
||||
import dev.inmo.krontab.internal.createKronScheduler
|
||||
import dev.inmo.krontab.internal.createKronSchedulerWithOffset
|
||||
import dev.inmo.krontab.utils.Minutes
|
||||
|
||||
/**
|
||||
* Will help to create an instance of [KronScheduler]
|
||||
*
|
||||
* @see dev.inmo.krontab.createSimpleScheduler
|
||||
*/
|
||||
inline fun buildSchedule(settingsBlock: SchedulerBuilder.() -> Unit): KronScheduler {
|
||||
val builder = SchedulerBuilder()
|
||||
|
||||
builder.settingsBlock()
|
||||
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
/**
|
||||
* Will help to create an instance of [KronScheduler]
|
||||
*
|
||||
* @see dev.inmo.krontab.createSimpleScheduler
|
||||
*/
|
||||
inline fun buildSchedule(
|
||||
offset: Minutes,
|
||||
settingsBlock: SchedulerBuilder.() -> Unit
|
||||
): KronSchedulerTz {
|
||||
val builder = SchedulerBuilder(offset = offset)
|
||||
|
||||
builder.settingsBlock()
|
||||
|
||||
return builder.build() as KronSchedulerTz
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new [KronScheduler] with [settingsBlock]
|
||||
*
|
||||
* Since it is inline function, you may break execution of [settingsBlock]
|
||||
* at any time
|
||||
*/
|
||||
inline operator fun KronScheduler.Companion.invoke(
|
||||
offset: Minutes,
|
||||
settingsBlock: SchedulerBuilder.() -> Unit
|
||||
): KronSchedulerTz = buildSchedule(offset, settingsBlock)
|
||||
|
||||
/**
|
||||
* Creates new [KronScheduler] with [settingsBlock]
|
||||
*
|
||||
* Since it is inline function, you may break execution of [settingsBlock]
|
||||
* at any time
|
||||
*/
|
||||
inline operator fun KronScheduler.Companion.invoke(
|
||||
settingsBlock: SchedulerBuilder.() -> Unit
|
||||
): KronScheduler = buildSchedule(settingsBlock)
|
||||
|
||||
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 var year: Array<Int>? = null,
|
||||
private var dayOfWeek: Array<Byte>? = null,
|
||||
private val offset: Minutes? = null,
|
||||
private var milliseconds: Array<Short>? = null
|
||||
) {
|
||||
private fun <I, T : TimeBuilder<I>> callAndReturn(
|
||||
initial: Array<I>?,
|
||||
builder: T,
|
||||
block: T.() -> Unit
|
||||
): List<I>? {
|
||||
builder.block()
|
||||
|
||||
val builderValue = builder.build()
|
||||
|
||||
return initial ?.let {
|
||||
builderValue ?.let { _ ->
|
||||
(it + builderValue).distinct()
|
||||
} ?: builderValue
|
||||
} ?: builderValue
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts an milliseconds block
|
||||
*/
|
||||
fun milliseconds(block: MillisecondsBuilder.() -> Unit) {
|
||||
milliseconds = callAndReturn(
|
||||
milliseconds,
|
||||
MillisecondsBuilder(),
|
||||
block
|
||||
) ?.toTypedArray()
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts an seconds block
|
||||
*/
|
||||
fun seconds(block: SecondsBuilder.() -> Unit) {
|
||||
seconds = callAndReturn(
|
||||
seconds,
|
||||
SecondsBuilder(),
|
||||
block
|
||||
) ?.toTypedArray()
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts an minutes block
|
||||
*/
|
||||
fun minutes(block: MinutesBuilder.() -> Unit) {
|
||||
minutes = callAndReturn(
|
||||
minutes,
|
||||
MinutesBuilder(),
|
||||
block
|
||||
) ?.toTypedArray()
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts an hours block
|
||||
*/
|
||||
fun hours(block: HoursBuilder.() -> Unit) {
|
||||
hours = callAndReturn(
|
||||
hours,
|
||||
HoursBuilder(),
|
||||
block
|
||||
) ?.toTypedArray()
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts an days of month block
|
||||
*/
|
||||
fun dayOfMonth(block: DaysOfMonthBuilder.() -> Unit) {
|
||||
dayOfMonth = callAndReturn(
|
||||
dayOfMonth,
|
||||
DaysOfMonthBuilder(),
|
||||
block
|
||||
) ?.toTypedArray()
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts an hours block
|
||||
*/
|
||||
fun dayOfWeek(block: WeekDaysBuilder.() -> Unit) {
|
||||
dayOfWeek = callAndReturn(
|
||||
dayOfWeek,
|
||||
WeekDaysBuilder(),
|
||||
block
|
||||
) ?.toTypedArray()
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts an months block
|
||||
*/
|
||||
fun months(block: MonthsBuilder.() -> Unit) {
|
||||
month = callAndReturn(
|
||||
month,
|
||||
MonthsBuilder(),
|
||||
block
|
||||
) ?.toTypedArray()
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts an year block
|
||||
*/
|
||||
fun years(block: YearsBuilder.() -> Unit) {
|
||||
year = callAndReturn(
|
||||
year,
|
||||
YearsBuilder(),
|
||||
block
|
||||
) ?.toTypedArray()
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Completely built and independent [KronScheduler]
|
||||
*
|
||||
* @see dev.inmo.krontab.createSimpleScheduler
|
||||
* @see dev.inmo.krontab.internal.createKronScheduler
|
||||
*/
|
||||
fun build(): KronScheduler = offset ?.let {
|
||||
createKronSchedulerWithOffset(
|
||||
seconds,
|
||||
minutes,
|
||||
hours,
|
||||
dayOfMonth,
|
||||
month,
|
||||
year,
|
||||
dayOfWeek,
|
||||
TimezoneOffset(it.minutes),
|
||||
milliseconds ?: millisecondsArrayDefault
|
||||
)
|
||||
} ?: createKronScheduler(seconds, minutes, hours, dayOfMonth, month, year, dayOfWeek, milliseconds ?: millisecondsArrayDefault)
|
||||
}
|
||||
132
src/commonMain/kotlin/builder/TimeBuilder.kt
Normal file
132
src/commonMain/kotlin/builder/TimeBuilder.kt
Normal file
@@ -0,0 +1,132 @@
|
||||
package dev.inmo.krontab.builder
|
||||
|
||||
import dev.inmo.krontab.internal.*
|
||||
|
||||
/**
|
||||
* This class was created for incapsulation of builder work with specified [restrictionsRange]. For example,
|
||||
* [include] function of [TimeBuilder] will always [coerceIn] incoming data using its [restrictionsRange]
|
||||
*/
|
||||
sealed class TimeBuilder<T : Number> (
|
||||
private val restrictionsRange: IntRange,
|
||||
private val converter: Converter<T>
|
||||
) {
|
||||
private var result: Set<Int>? = null
|
||||
|
||||
/**
|
||||
* The first possible value of builder
|
||||
*/
|
||||
val first
|
||||
get() = restrictionsRange.first
|
||||
/**
|
||||
* The last possible value of builder. Using of this variable equal to using "L" in strings
|
||||
*/
|
||||
val last
|
||||
get() = restrictionsRange.last
|
||||
|
||||
/**
|
||||
* After calling of this function this builder will allow any value of current time
|
||||
*/
|
||||
@Suppress("unused")
|
||||
fun allowAll() {
|
||||
result = null
|
||||
}
|
||||
|
||||
/**
|
||||
* Will include all variations from this array inside of this timeline
|
||||
*/
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
infix fun include(array: Array<Int>) {
|
||||
val clamped = array.map { it.coerceIn(restrictionsRange) } + (result ?: emptySet())
|
||||
result = clamped.toSet()
|
||||
}
|
||||
|
||||
/**
|
||||
* Add one [value] to current timeline
|
||||
*/
|
||||
@Suppress("unused")
|
||||
infix fun at(value: Int) {
|
||||
result = (result ?: emptySet()) + value.coerceIn(restrictionsRange)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shortcut for [at]. In fact will
|
||||
*/
|
||||
@Suppress("unused", "NOTHING_TO_INLINE")
|
||||
inline infix fun each(value: Int) = at(value)
|
||||
|
||||
/**
|
||||
* Just wrapper for more obvious writing something like "[from] 2 [every] 5". For example, for [SecondsBuilder] it
|
||||
* will mean "[from] second second [every] 5 seconds", or "2, 7, 13, ..."
|
||||
*/
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline infix fun from(value: Int) = value
|
||||
|
||||
/**
|
||||
* Will create an sequence of times starting [from] [this] [every] [delay] times. For example, for [SecondsBuilder] it
|
||||
* will mean "[from] second second [every] 5 seconds", or "2, 7, 13, ..."
|
||||
*
|
||||
* @see [from]
|
||||
*/
|
||||
infix fun Int.every(delay: Int): Array<Int> {
|
||||
val progression = coerceIn(restrictionsRange) .. restrictionsRange.last step delay
|
||||
val result = progression.toSet().toTypedArray()
|
||||
|
||||
this@TimeBuilder include result
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for "[from] 0 [every] [delay]"
|
||||
*/
|
||||
infix fun every(delay: Int): Array<Int> = this from 0 every delay
|
||||
|
||||
/**
|
||||
* Will fill up this timeline from [this] up to [endIncluding]
|
||||
*/
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
infix fun Int.upTo(endIncluding: Int): Array<Int> {
|
||||
val progression = coerceIn(restrictionsRange) .. endIncluding.coerceIn(restrictionsRange)
|
||||
val result = progression.toSet().toTypedArray()
|
||||
|
||||
this@TimeBuilder include result
|
||||
|
||||
return result
|
||||
}
|
||||
/**
|
||||
* Shortcut for "[from] 0 [upTo] [endIncluding]"
|
||||
*/
|
||||
@Suppress("unused")
|
||||
infix fun upTo(endIncluding: Int): Array<Int> = this from 0 upTo endIncluding
|
||||
/**
|
||||
* Will fill up this timeline from [this] up to [endIncluding]
|
||||
*/
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
infix operator fun Int.rangeTo(endIncluding: Int) = upTo(endIncluding)
|
||||
/**
|
||||
* Shortcut for "[from] 0 [rangeTo] [endIncluding]"
|
||||
*/
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
infix operator fun rangeTo(endIncluding: Int) = (this from 0) rangeTo endIncluding
|
||||
|
||||
/**
|
||||
* Will include the last possible value
|
||||
*/
|
||||
fun includeLast() = at(restrictionsRange.last)
|
||||
/**
|
||||
* Will include the first possible value
|
||||
*/
|
||||
fun includeFirst() = at(restrictionsRange.first)
|
||||
|
||||
internal fun build() = result ?.map(converter)
|
||||
}
|
||||
|
||||
class MillisecondsBuilder : TimeBuilder<Short>(millisecondsRange, intToShortConverter)
|
||||
class SecondsBuilder : TimeBuilder<Byte>(secondsRange, intToByteConverter)
|
||||
class MinutesBuilder : TimeBuilder<Byte>(minutesRange, intToByteConverter)
|
||||
class HoursBuilder : TimeBuilder<Byte>(hoursRange, intToByteConverter)
|
||||
class DaysOfMonthBuilder : TimeBuilder<Byte>(dayOfMonthRange, intToByteConverter)
|
||||
class MonthsBuilder : TimeBuilder<Byte>(monthRange, intToByteConverter)
|
||||
class YearsBuilder : TimeBuilder<Int>(yearRange, intToIntConverter)
|
||||
class WeekDaysBuilder : TimeBuilder<Byte>(dayOfWeekRange, intToByteConverter)
|
||||
Reference in New Issue
Block a user