-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for referencing direct Map keys in graphs.
- Loading branch information
Showing
8 changed files
with
215 additions
and
24 deletions.
There are no files selected for viewing
5 changes: 4 additions & 1 deletion
5
core/src/commonMain/kotlin/maryk/core/properties/graph/GraphContext.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,13 @@ | ||
package maryk.core.properties.graph | ||
|
||
import maryk.core.models.IsDataModel | ||
import maryk.core.properties.definitions.IsSerializablePropertyDefinition | ||
import maryk.core.properties.references.IsPropertyReference | ||
import maryk.core.query.ContainsDataModelContext | ||
|
||
/** Context for Graph serializing */ | ||
class GraphContext( | ||
override var dataModel: IsDataModel? = null, | ||
var subDataModel: IsDataModel? = null | ||
var subDataModel: IsDataModel? = null, | ||
var reference: IsPropertyReference<*, IsSerializablePropertyDefinition<*, *>, *>? = null, | ||
) : ContainsDataModelContext<IsDataModel> |
125 changes: 125 additions & 0 deletions
125
core/src/commonMain/kotlin/maryk/core/properties/graph/GraphMapItem.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
package maryk.core.properties.graph | ||
|
||
import maryk.core.exceptions.ContextNotFoundException | ||
import maryk.core.models.ContextualDataModel | ||
import maryk.core.models.IsDataModel | ||
import maryk.core.models.IsValuesDataModel | ||
import maryk.core.models.serializers.ObjectDataModelSerializer | ||
import maryk.core.models.values | ||
import maryk.core.properties.IsPropertyContext | ||
import maryk.core.properties.definitions.IsMapDefinition | ||
import maryk.core.properties.definitions.contextual.ContextualPropertyReferenceDefinition | ||
import maryk.core.properties.definitions.contextual.ContextualSubDefinition | ||
import maryk.core.properties.definitions.wrapper.IsDefinitionWrapper | ||
import maryk.core.properties.definitions.wrapper.IsMapDefinitionWrapper | ||
import maryk.core.properties.definitions.wrapper.contextual | ||
import maryk.core.properties.graph.PropRefGraph.Companion.parent | ||
import maryk.core.properties.graph.PropRefGraph.Companion.properties | ||
import maryk.core.properties.references.IsMapReference | ||
import maryk.core.query.ContainsDataModelContext | ||
import maryk.core.values.ObjectValues | ||
import maryk.json.IsJsonLikeReader | ||
import maryk.json.IsJsonLikeWriter | ||
import maryk.json.JsonToken | ||
import maryk.lib.exceptions.ParseException | ||
|
||
|
||
operator fun <K: Any, DM: IsDataModel> IsMapDefinitionWrapper<K, *, *, *, *>.get( | ||
key: K | ||
) = GraphMapItem<K, DM>( | ||
mapReference = this.ref() as IsMapReference<*, *, *, *>, | ||
key = key, | ||
) | ||
|
||
/** | ||
* Represents a Property Reference Graph branch below a [parent] with all [properties] to fetch | ||
* [properties] should always be sorted by index so processing graphs is a lot easier | ||
*/ | ||
data class GraphMapItem<K: Any, DM: IsDataModel> internal constructor( | ||
val mapReference: IsMapReference<*, *, *, *>, | ||
val key: K, | ||
) : IsPropRefGraphNode<DM>, IsTransportablePropRefGraphNode { | ||
override val index = mapReference.index | ||
override val graphType = PropRefGraphType.MapKey | ||
|
||
override fun toString() = "${this.mapReference.name}[$key]" | ||
|
||
companion object : ContextualDataModel<GraphMapItem<*, *>, Companion, ContainsDataModelContext<*>, GraphContext>( | ||
contextTransformer = { | ||
if (it is GraphContext && it.subDataModel != null) { | ||
GraphContext(it.subDataModel) | ||
} else { | ||
GraphContext(it?.dataModel) | ||
} | ||
} | ||
) { | ||
val mapReference by contextual( | ||
index = 1u, | ||
getter = GraphMapItem<*, *>::mapReference, | ||
definition = ContextualPropertyReferenceDefinition( | ||
contextualResolver = { context: GraphContext? -> | ||
(context?.subDataModel ?: context?.dataModel) as? IsValuesDataModel? ?: throw ContextNotFoundException() | ||
} | ||
), | ||
capturer = { context, value -> | ||
@Suppress("UNCHECKED_CAST") | ||
context.reference = value as IsMapReference<Comparable<Any>, Any, IsPropertyContext, IsMapDefinitionWrapper<Comparable<Any>, Any, Any, IsPropertyContext, Any>> | ||
} | ||
) | ||
|
||
val key by contextual( | ||
index = 2u, | ||
getter = GraphMapItem<*, *>::key, | ||
definition = ContextualSubDefinition( | ||
contextualResolver = { context: GraphContext? -> | ||
@Suppress("UNCHECKED_CAST") | ||
(context?.reference as IsMapReference<Comparable<Any>, Any, IsPropertyContext, IsMapDefinitionWrapper<Comparable<Any>, Any, Any, IsPropertyContext, Any>>?)?.propertyDefinition?.definition?.keyDefinition | ||
?: throw ContextNotFoundException() | ||
} | ||
) | ||
) | ||
|
||
override fun invoke(values: ObjectValues<GraphMapItem<*, *>, Companion>): GraphMapItem<*, *> = GraphMapItem<Any, IsDataModel>( | ||
mapReference = values(1u), | ||
key = values(2u) | ||
) | ||
|
||
override val Serializer = object: ObjectDataModelSerializer<GraphMapItem<*, *>, Companion, ContainsDataModelContext<*>, GraphContext>(this) { | ||
override fun writeObjectAsJson( | ||
obj: GraphMapItem<*, *>, | ||
writer: IsJsonLikeWriter, | ||
context: GraphContext?, | ||
skip: List<IsDefinitionWrapper<*, *, *, GraphMapItem<*, *>>>? | ||
) { | ||
writer.writeString("${obj.mapReference.name}[${obj.key}]") | ||
} | ||
|
||
override fun readJson( | ||
reader: IsJsonLikeReader, | ||
context: GraphContext? | ||
): ObjectValues<GraphMapItem<*, *>, Companion> { | ||
val tokenToParse: JsonToken.Value<*> = reader.currentToken as? JsonToken.Value<*> | ||
?: throw ParseException("Expected value token") | ||
|
||
val (name, keyAsString) = tokenToParse.value.toString().split("[", "]") | ||
|
||
val mapReference = context?.dataModel?.getPropertyReferenceByName(name, context) as? IsMapReference<*, *, *, *> | ||
?: throw ParseException("Expected MapReference") | ||
|
||
@Suppress("UNCHECKED_CAST") | ||
val key = when (val mapDef = mapReference.comparablePropertyDefinition) { | ||
is IsMapDefinition<*, *, *> -> mapDef.keyDefinition.fromString(keyAsString) as Comparable<Any> | ||
else -> throw ParseException("Unknown MapReference type") | ||
} | ||
|
||
return values { | ||
mapNonNulls( | ||
this.mapReference withSerializable mapReference, | ||
this.key withSerializable key | ||
) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.