All Downloads are FREE. Search and download functionalities are using the official Maven repository.

loggersoft.kotlin.utils.PropertyRange.kt Maven / Gradle / Ivy

/*
 * Copyright (C) 2018 Alexander Kornilov ([email protected])
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

@file:Suppress("NOTHING_TO_INLINE")

package loggersoft.kotlin.utils

import java.lang.IllegalArgumentException
import kotlin.reflect.KProperty

/**
 * Default violation handler.
 */
@Suppress("UNUSED_PARAMETER")
inline fun > defaultViolation(newValue: T, bound: T): T = bound

/**
 * Violation handler which throws an exception [IllegalArgumentException].
 */
@Suppress("UNUSED_PARAMETER")
inline fun > exceptionViolation(newValue: T, bound: T): T = throw IllegalArgumentException()

/**
 * Represents range validator for properties with comparable type (e.g. [Int], [Long])
 *
 * @param initValue an initial value of the property.
 * @param min a minimum bound of the value.
 * @param max a maximum bound of the value.
 * @param violation a violation handler.
 *
 * @author Alexander Kornilov ([email protected]).
 */
class PropertyRange>(initValue: T,
                                      private val min: T? = null,
                                      private val max: T? = null,
                                      private val violation: (newValue: T, bound: T) -> T = ::defaultViolation) {

    /**
     * Creates [PropertyRange] by [ClosedRange].
     *
     * @param initValue an initial value of the property.
     * @param range a valid range of the value.
     * @param violation a violation handler.
     */
    constructor(initValue: T, range: ClosedRange, violation: (newValue: T, bound: T) -> T = ::defaultViolation): this(initValue, range.start, range.endInclusive, violation)

    /**
     * Returns property value within the range.
     */
    operator fun getValue(obj: Any, prop: KProperty<*>): T = value

    /**
     * Sets a new property value with validation.
     */
    operator fun setValue(obj: Any, prop: KProperty<*>, newValue: T) {
        value = validateValue(newValue)
    }

    private var value: T = validateValue(initValue)

    private inline fun validateValue(value: T): T = when {
        min != null && value < min -> violation(value, min)
        max != null && value > max -> violation(value, max)
        else -> value
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy