Skip to content

Commit

Permalink
Merge pull request #11 from NightGoat/0.0.8
Browse files Browse the repository at this point in the history
0.0.8 version
  • Loading branch information
NightGoat authored Jul 24, 2021
2 parents d76dd97 + 0d58826 commit 0e3f960
Show file tree
Hide file tree
Showing 18 changed files with 415 additions and 81 deletions.
23 changes: 16 additions & 7 deletions KEXtensions/src/main/java/ru/nightgoat/kextensions/BooleanExt.kt
Original file line number Diff line number Diff line change
@@ -1,25 +1,34 @@
package ru.nightgoat.kextensions

fun Boolean?.orTrue(): Boolean = this ?: true

fun Boolean?.orFalse(): Boolean = this ?: false

fun Boolean.takeIfTrue() = this.takeIf { it }

fun Boolean.takeIfFalse() = this.takeIf { !it }

fun Boolean.doIfTrue(doFun: () -> Unit): Boolean {
fun Boolean.doIfTrue(doFun: (Boolean) -> Unit): Boolean {
if (this) {
doFun.invoke()
doFun(this)
}
return this
}

fun Boolean.doIfFalse(doFun: () -> Unit): Boolean {
fun Boolean.doIfFalse(doFun: (Boolean) -> Unit): Boolean {
if (!this) {
doFun.invoke()
doFun.invoke(!this)
}
return this
}

fun Boolean.toBinary() = 1.takeIf { this }.orZero()
/**
* Returns 1 if true or 0
*/
fun Boolean.toBinary() = 1.takeIf { this }.orZero()

/**
* Returns a string represented as the entered characters
* "X" as true, and "" by default
*/
fun Boolean.toStringBy(trueSymbol: String = "X", falseSymbol: String = ""): String {
return if (this) trueSymbol else falseSymbol
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package ru.nightgoat.kextensions

import ru.nightgoat.kextensions.utils.Kex

fun <T> List<T>?.orEmptyMutable(): MutableList<T> = this?.toMutableList() ?: mutableListOf()

fun <T> Set<T>?.orEmptyMutable(): MutableSet<T> = this?.toMutableSet() ?: mutableSetOf()
Expand Down Expand Up @@ -64,10 +66,16 @@ inline fun <reified T> Collection<T>.firstOrElse(elseFun: () -> T): T {
return this.firstOrNull().orIfNull(elseFun)
}

/**
* Returns size in instance of Double
*/
fun <T> List<T>.sizeInDouble(): Double {
return this.size.toDouble()
}

/**
* Returns size in instance of String
*/
fun <T> List<T>.sizeInString(): String {
return this.size.toString()
}
Expand All @@ -94,4 +102,75 @@ inline fun <T, K> List<T>?.mapOrEmpty(transform: (T) -> K): List<K> = this.orEmp
* */
fun <T, R> List<T>.mapAndFind(map: (T) -> R, find: (R) -> Boolean) = this.asSequence()
.map(map)
.find(find)
.find(find)

/**
* Turns object to list of this one object or empty if object is null.
*/
fun <T : Any> T?.toList() = this?.run { listOf(this) }.orEmpty()

/**
* Swaps elements by entered positions and returns list. Returns not changed list, if second index
* less or equals than first. Swaps first and last item by default.
*/
fun <T : Any> MutableList<T>.swap(
firstIndex: Int = 0,
secondIndex: Int = this.lastIndex
): MutableList<T> {
val list = this.toMutableList()
if (secondIndex > firstIndex) {
val first = list.getOrNull(firstIndex)
val last = list.getOrNull(secondIndex)
first?.let {
last?.let {
list.removeAt(firstIndex)
list.removeAt(secondIndex - 1)
list.add(firstIndex, last)
list.add(secondIndex, first)
} ?: Kex.loggE("swap(): item by second index($secondIndex) not found!")
} ?: Kex.loggE("swap(): item by first index($firstIndex) not found!")
} else {
Kex.loggE("swap(): second index($secondIndex) can not be more than first index($firstIndex)!")
}
return list
}

/**
* Swaps first and last item.
*/
fun <T : Any> MutableList<T>.swapFirstAndLastElement(): MutableList<T> {
return this.swap()
}

/**
* Finds object in list and moves to entered position. Moves to first position by default.
*/
fun <T : Any> MutableList<T>.moveToPosition(
position: Int = 0,
findItemBy: (T) -> Boolean
): MutableList<T> {
val list = this.toMutableList()
if (position in 0..list.lastIndex) {
list.find { findItemBy(it) }?.let { found ->
list.remove(found)
list.add(position, found)
}
} else {
Kex.loggE("moveToPosition(): position($position) must be in bounds of a list(in 0..${list.lastIndex}! ")
}
return list
}

/**
* Finds object in list and moves to first position
*/
fun <T : Any> MutableList<T>.moveToFirstPosition(findItemBy: (T) -> Boolean): MutableList<T> {
return moveToPosition(findItemBy = findItemBy)
}

/**
* Finds object in list and moves to last position
*/
fun <T : Any> MutableList<T>.moveToLastPosition(findItemBy: (T) -> Boolean): MutableList<T> {
return moveToPosition(position = this.lastIndex, findItemBy = findItemBy)
}
12 changes: 11 additions & 1 deletion KEXtensions/src/main/java/ru/nightgoat/kextensions/DateExt.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
package ru.nightgoat.kextensions

import ru.nightgoat.kextensions.utils.constants.DateFormats.DATE_FORMAT_dd_mm_yyyy
import java.text.SimpleDateFormat
import java.util.*

/**
* Sums up milliseconds in dates.
* With that you can write something like this: Date() + Date()
*/
operator fun Date.plus(other: Date): Date = Date(this.time + other.time)
operator fun Date.minus(other: Date): Date = Date(this.time - other.time)

fun Date?.orNow() = this ?: Date()
fun Date?.orNow() = this ?: Date()

/**
* Returns Date in String in entered pattern. By default returns in dd.MM.yyyy
*/
fun Date.toStringFormatted(pattern: String = DATE_FORMAT_dd_mm_yyyy): String {
return tryOrEmpty { SimpleDateFormat(pattern, Locale.getDefault()).format(this) }
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package ru.nightgoat.kextensions

import ru.nightgoat.kextensions.utils.Kex
import kotlin.math.abs
import kotlin.math.pow
import kotlin.math.round
Expand Down Expand Up @@ -51,10 +50,9 @@ fun Double.divWith(other: Double, numberOfZeroes: Int = 3, tag: String? = null):
val pow = ((this).toBigDecimal() / (other).toBigDecimal()).toDouble()
pow.roundTo(numberOfZeroes)
} else {
Kex.loggE(
"Division by zero: $this / 0",
tag = tag ?: "Double.divWith(): ",
ArithmeticException()
ArithmeticException().log(
message = "Division by zero: $this / 0",
tag = tag ?: "Double.divWith(): "
)
null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,50 @@ package ru.nightgoat.kextensions

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import ru.nightgoat.kextensions.utils.Kex
import java.util.*

/**
* Shorter version of coroutine context switching to Default dispatcher
*/
suspend fun <T> doOnDefault(doFun: () -> T) = withContext(Dispatchers.Default) {
suspend fun <T> doOnDefault(doFun: suspend () -> T) = withContext(Dispatchers.Default) {
doFun()
}

/**
* Shorter version of coroutine context switching to Main dispatcher
*/
suspend fun <T> doOnMain(doFun: () -> T) = withContext(Dispatchers.Main) {
suspend fun <T> doOnMain(doFun: suspend () -> T) = withContext(Dispatchers.Main) {
doFun()
}

/**
* Shorter version of coroutine context switching to IO dispatcher
*/
suspend fun <T> doOnIO(doFun: () -> T) = withContext(Dispatchers.IO) {
suspend fun <T> doOnIO(doFun: suspend () -> T) = withContext(Dispatchers.IO) {
doFun()
}

/**
* try default fun realisation
*/
fun <T : Any> tryOrDefault(
defaultIfCatches: T,
defaultValue: T,
tag: String = "tryOrDefault(): ",
tryFunc: () -> T
tryFunc: () -> T?
): T {
return try {
tryFunc()
tryFunc() ?: defaultValue
} catch (e: Exception) {
Kex.loggE(tag = tag, message = e.getNameAndMessage(), e = e)
defaultIfCatches
e.log(tag = tag)
defaultValue
}
}

fun <T : Any> tryOrNull(tag: String = "tryOrNull(): ", tryFunc: () -> T): T? {
fun <T : Any> tryOrNull(tag: String = "tryOrNull(): ", tryFunc: () -> T?): T? {
return try {
tryFunc()
} catch (e: Exception) {
Kex.loggE(tag = tag, message = e.getNameAndMessage(), e = e)
e.log(tag = tag)
null
}
}
Expand Down
27 changes: 27 additions & 0 deletions KEXtensions/src/main/java/ru/nightgoat/kextensions/IntExt.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ru.nightgoat.kextensions

import ru.nightgoat.kextensions.utils.Kex
import kotlin.math.abs

fun Int?.orZero() = this ?: 0
Expand All @@ -14,3 +15,29 @@ fun Int.takeIfNotZero() = this.takeIf { it != 0 }

fun Int?.toStringOrEmpty() = this?.toString().orEmpty()
fun Int.takeIfZeroOrEmpty() = this.takeIf { it == 0 }?.toStringOrEmpty()

fun Int?.toBoolean() = this == 1

fun Int?.toBooleanOrNull(): Boolean? {
return when (this) {
1 -> true
0 -> false
else -> null
}
}

fun Int?.divideSafe(divideBy: Int) = if (this != null && divideBy != 0) {
this / divideBy
} else {
Kex.loggE("divideSafe(): division by zero!")
null
}

fun Int?.divideSafeOrZero(divideBy: Int) = if (this != null && divideBy != 0) {
this / divideBy
} else {
Kex.loggE("divideSafe(): division by zero!")
0
}

fun Int.convertSecondsToMilliseconds(): Long = this * 1000L
57 changes: 39 additions & 18 deletions KEXtensions/src/main/java/ru/nightgoat/kextensions/StringExt.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package ru.nightgoat.kextensions

import android.util.Patterns
import ru.nightgoat.kextensions.utils.constants.KexConstants.EMAIL_PATTERN
import ru.nightgoat.kextensions.utils.constants.KexConstants.IP_ADDRESS_PATTERN
import ru.nightgoat.kextensions.utils.constants.KexConstants.PHONE_PATTERN
import ru.nightgoat.kextensions.utils.constants.KexConstants.ZERO_STRING
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.*
import java.util.regex.Pattern

Expand All @@ -27,9 +33,28 @@ fun String?.toLongOrDefault(defaultValue: Long): Long {
return this?.toLongOrNull() ?: defaultValue
}

fun String?.toBooleanFrom(trueSymbol: String = "1"): Boolean {
return this == trueSymbol
}

fun String?.toBooleanFrom(trueSymbol: String, falseSymbol: String): Boolean? {
return when (this) {
trueSymbol -> true
falseSymbol -> false
else -> null
}
}

fun String?.toBooleanFromBinary() = this.toBooleanFrom()

fun String?.toBooleanFromBinaryOrNull(): Boolean? {
return this.toBooleanFrom("1", "0")
}


fun String.trimZeros() = this.trimStart('0')

fun String?.orZero() = this ?: "0"
fun String?.orZero() = this ?: ZERO_STRING

fun String.takeIfNotEmpty() = this.takeIf { it.isNotEmpty() }

Expand Down Expand Up @@ -63,43 +88,31 @@ fun String.normalize() = this.lowercase().replaceFirstChar {
* }
* */
inline fun <reified T : Enum<*>> String.enumValueOrNull(): T? =
T::class.java.enumConstants.firstOrNull { it.name == this }
T::class.java.enumConstants?.firstOrNull { it.name == this }

/**
* get Enum or default value from String by Reflection
* */
inline fun <reified T : Enum<*>> String.enumValueOrDefault(default: T): T =
T::class.java.enumConstants.firstOrNull { it.name == this } ?: default
T::class.java.enumConstants?.firstOrNull { it.name == this } ?: default

fun String.isEmail(): Boolean {
val pattern = Patterns.EMAIL_ADDRESS ?: Pattern.compile(
"[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}" +
"\\@" +
"[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" +
"(" +
"\\." +
"[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25}" +
")+"
EMAIL_PATTERN
)
return isMatchesRegex(pattern)
}

fun String.isPhone(): Boolean {
val pattern = Patterns.PHONE ?: Pattern.compile(
"(\\+[0-9]+[\\- \\.]*)?"
+ "(\\([0-9]+\\)[\\- \\.]*)?"
+ "([0-9][0-9\\- \\.]+[0-9])"
PHONE_PATTERN
)

return isMatchesRegex(pattern)
}

fun String.isIPAddress(): Boolean {
val ipAddressPatternString =
("((25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(25[0-5]|2[0-4]"
+ "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]"
+ "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
+ "|[1-9][0-9]|[0-9]))")
val ipAddressPatternString = IP_ADDRESS_PATTERN
val ipAddressPattern = Pattern.compile(ipAddressPatternString)
val pattern = Patterns.IP_ADDRESS ?: ipAddressPattern
return isMatchesRegex(pattern)
Expand All @@ -115,4 +128,12 @@ fun String.isMatchesRegex(regex: Pattern): Boolean {

fun String.isMatchesRegex(regex: Regex): Boolean {
return regex.matches(this)
}

fun String.toDateFormat(): DateFormat? {
return tryOrNull { SimpleDateFormat(this, Locale.getDefault()) }
}

fun String.toDate(pattern: String): Date? {
return tryOrNull { pattern.toDateFormat()?.parse(this) }
}
Loading

0 comments on commit 0e3f960

Please sign in to comment.