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

entities.EntityId.kt Maven / Gradle / Ivy

There is a newer version: 0.9.27
Show newest version
package com.github.fluidsonic.baku

import org.bson.BsonReader
import org.bson.BsonWriter
import org.bson.types.ObjectId
import kotlin.reflect.KClass


interface EntityId {

	val factory: Factory<*>


	interface Factory {

		val idClass: KClass

		val type: String

		fun parse(string: String): Id?

		fun parseWithoutType(string: String): Id?

		fun BsonReader.readIdValue(): Id

		fun BsonWriter.writeIdValue(id: Id)

		fun Id.serialize(): String

		fun Id.serializeWithoutType(): String
	}


	interface ObjectIdBased : EntityId {

		val raw: ObjectId


		abstract class Factory(
			final override val type: String,
			final override val idClass: KClass,
			private val constructor: (raw: ObjectId) -> Id
		) : EntityId.Factory {

			private val prefix = "$type/"


			final override fun parse(string: String) =
				string
					.takeIf { it.startsWith(prefix) || !it.contains('/') }
					?.removePrefix(prefix)
					?.let { parseWithoutType(it) }


			final override fun parseWithoutType(string: String) =
				string
					.let {
						try {
							ObjectId(it)
						}
						catch (_: Exception) {
							null
						}
					}
					?.let(constructor)


			final override fun BsonReader.readIdValue() =
				constructor(readObjectId())


			final override fun BsonWriter.writeIdValue(id: Id) =
				writeObjectId(id.raw)


			final override fun Id.serialize() =
				prefix + serializeWithoutType()


			override fun Id.serializeWithoutType() =
				raw.toHexString()!!
		}
	}


	interface StringBased : EntityId {

		val raw: String


		abstract class Factory(
			final override val type: String,
			final override val idClass: KClass,
			private val constructor: (raw: String) -> Id
		) : EntityId.Factory {

			private val prefix = "$type/"


			final override fun parse(string: String) =
				string
					.takeIf { it.startsWith(prefix) || !it.contains('/') }
					?.removePrefix(prefix)
					?.let { parseWithoutType(it) }


			final override fun parseWithoutType(string: String) =
				constructor(string)


			final override fun BsonReader.readIdValue() =
				constructor(readString())


			final override fun BsonWriter.writeIdValue(id: Id) =
				writeString(id.raw)


			final override fun Id.serialize() =
				prefix + serializeWithoutType()


			override fun Id.serializeWithoutType() =
				raw
		}
	}
}


val EntityId.typed
	get() = TypedId(this)


@Suppress("UNCHECKED_CAST")
fun EntityId.toStringWithoutType() =
	(factory as EntityId.Factory).run { serializeWithoutType() }


fun  EntityId.Factory.serialize(id: Id) =
	id.run { serialize() }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy