Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A collection of type wrappers that work similar to Kotlin's inline classes, but for Kotlin < 1.3
import java.util.UUID
/**
* Superclass for classes that wrap a single value for type safety purposes.
*/
abstract class WrapperType<T : Any>(val value: T) {
override fun toString() = value.toString()
override fun equals(other: Any?) = other is WrapperType<*> && value == other.value
override fun hashCode() = value.hashCode()
}
/**
* Wrap entity ids in an instance of this class parameterized with a type identifying the entity the id belongs to,
* to reduce the likeliness of accidentally cross-assigning ids to the wrong types.
*
* Example:
*
* ```kotlin
* data class Car(val id: Id<Car>)
* data class Tree(val id: Id<Tree>)
*
* fun getCarById(thingId: Id<Car>): Car
*
* val tree: Tree
* getCarById(tree.id) // Won't compile!
* ```
*/
@Suppress("unused") // Type parameter is only used for compile time validation
class Id<out T>(id: UUID) : WrapperType<UUID>(id) {
companion object {
fun <T> random() = Id<T>(UUID.randomUUID())
fun <T> from(str: String) = Id<T>(UUID.fromString(str))
}
}
/**
* Wrapper for user email adresses for better type safety
*/
class UserEmail(email: String) : WrapperType<String>(email)
/**
* Class to wrap sensitive values in that should not accidentally show up in logs or other places where [toString]
* might be called implicitly.
*
* Does not extend [WrapperType], as those class' functionalities are not wanted by default for sensitive values.
*/
open class Sensitive<out T>(val value: T) {
final override fun toString() = "<Sensitive Value>"
}
/**
* Wrapper class for passwords. Extends [Sensitive] to reduce likeliness of accidental leakage into logs.
*/
class Password(value: String) : Sensitive<String>(value)
/**
* Wrapper class for password hashes. Extends [Sensitive] to reduce likeliness of accidental leakage into logs.
*/
class PasswordHash(value: String) : Sensitive<String>(value)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment