2020-11-21 08:58:19 +00:00
|
|
|
package dev.inmo.krontab.builder
|
2019-10-08 16:06:26 +00:00
|
|
|
|
2020-11-21 08:58:19 +00:00
|
|
|
import dev.inmo.krontab.internal.*
|
2019-10-08 16:06:26 +00:00
|
|
|
|
2020-06-03 15:36:01 +00:00
|
|
|
/**
|
|
|
|
* This class was created for incapsulation of builder work with specified [restrictionsRange]. For example,
|
2021-04-22 05:58:19 +00:00
|
|
|
* [include] function of [TimeBuilder] will always [coerceIn] incoming data using its [restrictionsRange]
|
2020-06-03 15:36:01 +00:00
|
|
|
*/
|
2021-01-02 15:35:08 +00:00
|
|
|
sealed class TimeBuilder<T : Number> (
|
|
|
|
private val restrictionsRange: IntRange,
|
|
|
|
private val converter: Converter<T>
|
2019-10-08 16:06:26 +00:00
|
|
|
) {
|
|
|
|
private var result: Set<Int>? = null
|
|
|
|
|
2020-10-10 15:12:32 +00:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
|
2020-06-03 15:36:01 +00:00
|
|
|
/**
|
|
|
|
* After calling of this function this builder will allow any value of current time
|
|
|
|
*/
|
|
|
|
@Suppress("unused")
|
2019-10-08 16:06:26 +00:00
|
|
|
fun allowAll() {
|
|
|
|
result = null
|
|
|
|
}
|
|
|
|
|
2020-06-03 15:36:01 +00:00
|
|
|
/**
|
|
|
|
* Will include all variations from this array inside of this timeline
|
|
|
|
*/
|
|
|
|
@Suppress("MemberVisibilityCanBePrivate")
|
2019-10-08 16:06:26 +00:00
|
|
|
infix fun include(array: Array<Int>) {
|
2021-04-22 05:58:19 +00:00
|
|
|
val clamped = array.map { it.coerceIn(restrictionsRange) } + (result ?: emptySet())
|
2019-10-08 16:06:26 +00:00
|
|
|
result = clamped.toSet()
|
|
|
|
}
|
|
|
|
|
2020-06-03 15:36:01 +00:00
|
|
|
/**
|
|
|
|
* Add one [value] to current timeline
|
|
|
|
*/
|
|
|
|
@Suppress("unused")
|
2019-10-08 16:06:26 +00:00
|
|
|
infix fun at(value: Int) {
|
2021-04-22 05:58:19 +00:00
|
|
|
result = (result ?: emptySet()) + value.coerceIn(restrictionsRange)
|
2019-10-08 16:06:26 +00:00
|
|
|
}
|
|
|
|
|
2020-10-10 15:39:00 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Shortcut for [at]. In fact will
|
|
|
|
*/
|
|
|
|
@Suppress("unused", "NOTHING_TO_INLINE")
|
|
|
|
inline infix fun each(value: Int) = at(value)
|
|
|
|
|
2020-06-03 15:36:01 +00:00
|
|
|
/**
|
|
|
|
* 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, ..."
|
|
|
|
*/
|
2020-03-22 12:35:06 +00:00
|
|
|
@Suppress("NOTHING_TO_INLINE")
|
2020-06-03 15:36:01 +00:00
|
|
|
inline infix fun from(value: Int) = value
|
2019-10-08 16:06:26 +00:00
|
|
|
|
2020-06-03 15:36:01 +00:00
|
|
|
/**
|
|
|
|
* 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]
|
|
|
|
*/
|
2019-10-08 16:06:26 +00:00
|
|
|
infix fun Int.every(delay: Int): Array<Int> {
|
2021-04-22 05:58:19 +00:00
|
|
|
val progression = coerceIn(restrictionsRange) .. restrictionsRange.last step delay
|
2019-10-08 16:06:26 +00:00
|
|
|
val result = progression.toSet().toTypedArray()
|
|
|
|
|
|
|
|
this@TimeBuilder include result
|
|
|
|
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2020-06-03 15:36:01 +00:00
|
|
|
/**
|
|
|
|
* 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")
|
2019-10-08 16:06:26 +00:00
|
|
|
infix fun Int.upTo(endIncluding: Int): Array<Int> {
|
2021-04-22 05:58:19 +00:00
|
|
|
val progression = coerceIn(restrictionsRange) .. endIncluding.coerceIn(restrictionsRange)
|
2019-10-08 16:06:26 +00:00
|
|
|
val result = progression.toSet().toTypedArray()
|
|
|
|
|
|
|
|
this@TimeBuilder include result
|
|
|
|
|
|
|
|
return result
|
|
|
|
}
|
2020-06-03 15:36:01 +00:00
|
|
|
/**
|
|
|
|
* Shortcut for "[from] 0 [upTo] [endIncluding]"
|
|
|
|
*/
|
|
|
|
@Suppress("unused")
|
|
|
|
infix fun upTo(endIncluding: Int): Array<Int> = this from 0 upTo endIncluding
|
2020-07-24 07:16:56 +00:00
|
|
|
/**
|
|
|
|
* 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
|
2019-10-08 16:06:26 +00:00
|
|
|
|
2020-10-10 15:12:32 +00:00
|
|
|
/**
|
|
|
|
* Will include the last possible value
|
|
|
|
*/
|
|
|
|
fun includeLast() = at(restrictionsRange.last)
|
|
|
|
/**
|
|
|
|
* Will include the first possible value
|
|
|
|
*/
|
|
|
|
fun includeFirst() = at(restrictionsRange.first)
|
|
|
|
|
2021-01-02 15:35:08 +00:00
|
|
|
internal fun build() = result ?.map(converter)
|
2019-10-08 16:06:26 +00:00
|
|
|
}
|
|
|
|
|
2022-04-29 15:57:10 +00:00
|
|
|
class MillisecondsBuilder : TimeBuilder<Short>(millisecondsRange, intToShortConverter)
|
2021-01-02 15:35:08 +00:00
|
|
|
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)
|
2021-04-22 05:58:19 +00:00
|
|
|
class WeekDaysBuilder : TimeBuilder<Byte>(dayOfWeekRange, intToByteConverter)
|