
commonMain.maryk.core.inject.Inject.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of core-jvm Show documentation
Show all versions of core-jvm Show documentation
Maryk is a Kotlin Multiplatform library which helps you to store, query and send data in a structured way over multiple platforms. The data store stores any value with a version, so it is possible to request only the changed data or live listen for updates.
The newest version!
package maryk.core.inject
import maryk.core.exceptions.ContextNotFoundException
import maryk.core.models.serializers.ObjectDataModelSerializer
import maryk.core.models.ContextualDataModel
import maryk.core.properties.IsPropertyContext
import maryk.core.properties.definitions.IsPropertyDefinition
import maryk.core.properties.definitions.contextual.ContextualPropertyReferenceDefinition
import maryk.core.properties.definitions.string
import maryk.core.properties.definitions.wrapper.IsDefinitionWrapper
import maryk.core.properties.definitions.wrapper.contextual
import maryk.core.properties.exceptions.InjectException
import maryk.core.properties.references.IsPropertyReference
import maryk.core.models.values
import maryk.core.query.RequestContext
import maryk.core.values.ObjectValues
import maryk.json.IsJsonLikeReader
import maryk.json.IsJsonLikeWriter
import maryk.json.JsonToken
import maryk.lib.exceptions.ParseException
typealias AnyInject = Inject<*, *>
fun Inject(collectionName: String) = Inject>(collectionName, null)
/**
* To inject a variable into a request
*/
data class Inject>(
internal val collectionName: String,
internal val propertyReference: IsPropertyReference?
) {
/** Resolve a value to inject from [context] */
fun resolve(context: RequestContext): T? {
val result = context.retrieveResult(collectionName)
?: throw InjectException(this.collectionName)
@Suppress("UNCHECKED_CAST")
return propertyReference?.let {
result[propertyReference]
} ?: result as T?
}
internal companion object : ContextualDataModel(
contextTransformer = { requestContext ->
InjectionContext(
requestContext ?: throw ContextNotFoundException()
)
}
) {
val collectionName by string(
1u,
getter = Inject<*, *>::collectionName,
capturer = { context: IsPropertyContext, value ->
(context as InjectionContext).collectionName = value
}
)
val propertyReference by contextual(
index = 2u,
getter = Inject<*, *>::propertyReference,
definition = ContextualPropertyReferenceDefinition { context: InjectionContext? ->
context?.let {
context.resolvePropertyReference()
} ?: throw ContextNotFoundException()
}
)
override fun invoke(values: ObjectValues) = Inject>(
collectionName = values(1u),
propertyReference = values(2u)
)
override val Serializer = object: ObjectDataModelSerializer(this) {
override fun writeObjectAsJson(
obj: AnyInject,
writer: IsJsonLikeWriter,
context: InjectionContext?,
skip: List>?
) {
if (obj.propertyReference != null) {
writer.writeStartObject()
writer.writeFieldName(obj.collectionName)
propertyReference.writeJsonValue(
obj.propertyReference,
writer,
context
)
writer.writeEndObject()
} else {
collectionName.writeJsonValue(obj.collectionName, writer, context)
}
}
override fun readJson(
reader: IsJsonLikeReader,
context: InjectionContext?
): ObjectValues {
if (reader.currentToken == JsonToken.StartDocument) {
reader.nextToken()
}
return when (val startToken = reader.currentToken) {
is JsonToken.StartObject -> {
val currentToken = reader.nextToken()
val collectionName = (currentToken as? JsonToken.FieldName)?.value
?: throw ParseException("Expected a collectionName in an Inject")
Companion.collectionName.capture(context, collectionName)
reader.nextToken()
val propertyReference = Companion.propertyReference.readJson(reader, context)
Companion.propertyReference.capture(context, propertyReference)
reader.nextToken() // read past end object
model.values(context?.requestContext) {
mapNonNulls(
Companion.collectionName withSerializable collectionName,
Companion.propertyReference withSerializable propertyReference
)
}
}
is JsonToken.Value<*> -> {
val collectionName = startToken.value as? String
?: throw ParseException("Expected a collectionName in an Inject")
Companion.collectionName.capture(context, collectionName)
reader.nextToken()
model.values(context?.requestContext) {
mapNonNulls(
Companion.collectionName withSerializable collectionName
)
}
}
else -> throw ParseException("JSON value for Inject should be an Object or String")
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy