files replacements

This commit is contained in:
2023-08-09 13:01:20 +06:00
parent 715d414f51
commit cbfbdc1b33
36 changed files with 0 additions and 0 deletions

View 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)
}

View 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)