Skip to content

Commit

Permalink
Merge branch 'feature/serialization' into 'develop'
Browse files Browse the repository at this point in the history
Serialization support

See merge request pika-lab/tuprolog/2p-in-kotlin!86
  • Loading branch information
gciatto committed Jul 1, 2020
2 parents 5ed81d5 + 08e4034 commit 6523be3
Show file tree
Hide file tree
Showing 68 changed files with 2,097 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ variables:
BEFORE_TASK: ""
AFTER_TASK: ""
GCMD: "gradle"
BUILD_TASK: "assemble"
BUILD_TASK: "clean assemble"
TEST_TASK: "check -x dokka"
TEST_JVM_TASK: "jvmTest -x dokka"
TEST_JS_TASK: "clean jsTest -x dokka"
Expand Down
29 changes: 28 additions & 1 deletion buildSrc/src/main/kotlin/Libs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@ import kotlin.String
* `$ ./gradlew buildSrcVersions`
*/
object Libs {
/**
* https://github.com/FasterXML/jackson-dataformat-xml
*/
const val jackson_dataformat_xml: String =
"com.fasterxml.jackson.dataformat:jackson-dataformat-xml:" +
Versions.com_fasterxml_jackson_dataformat

/**
* https://github.com/FasterXML/jackson-dataformats-text
*/
const val jackson_dataformat_yaml: String =
"com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:" +
Versions.com_fasterxml_jackson_dataformat

/**
* https://javaeden.github.io/Orchid/latest/core/
*/
Expand Down Expand Up @@ -123,11 +137,24 @@ object Libs {
Versions.com_jfrog_bintray_gradle_plugin

/**
* 2.7.1
* https://github.com/FasterXML/jackson-modules-java8
*/
const val jackson_datatype_jsr310: String =
"com.fasterxml.jackson.datatype:jackson-datatype-jsr310:" +
Versions.jackson_datatype_jsr310

/**
* 2.8.0
*/
const val clikt_multiplatform: String = "com.github.ajalt:clikt-multiplatform:" +
Versions.clikt_multiplatform

/**
* https://github.com/FasterXML/jackson-core
*/
const val jackson_core: String = "com.fasterxml.jackson.core:jackson-core:" +
Versions.jackson_core

/**
* http://plantuml.sourceforge.net
*/
Expand Down
12 changes: 9 additions & 3 deletions buildSrc/src/main/kotlin/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import org.gradle.plugin.use.PluginDependencySpec
* YOU are responsible for updating manually the dependency version.
*/
object Versions {
const val io_github_javaeden_orchid: String = "0.21.0"
const val com_fasterxml_jackson_dataformat: String = "2.11.1"

const val io_github_javaeden_orchid: String = "0.21.1"

const val org_jetbrains_kotlin: String = "1.3.72"

Expand All @@ -24,18 +26,22 @@ object Versions {

const val org_jetbrains_kotlin_multiplatform_gradle_plugin: String = "1.3.72"

const val com_github_johnrengelman_shadow_gradle_plugin: String = "5.2.0"
const val com_github_johnrengelman_shadow_gradle_plugin: String = "6.0.0"

const val de_fayard_buildsrcversions_gradle_plugin: String = "0.7.0"

const val com_eden_orchidplugin_gradle_plugin: String = "0.20.0" // available: "0.21.0"
const val com_eden_orchidplugin_gradle_plugin: String = "0.21.1"

const val org_jetbrains_dokka_gradle_plugin: String = "0.10.1"

const val com_jfrog_bintray_gradle_plugin: String = "1.8.5"

const val jackson_datatype_jsr310: String = "2.11.1"

const val clikt_multiplatform: String = "2.7.1"

const val jackson_core: String = "2.11.1"

const val plantuml: String = "1.2020.2" // available: "8059"

const val kt_math: String = "0.1.3"
Expand Down
7 changes: 7 additions & 0 deletions core/src/commonMain/kotlin/it/unibo/tuprolog/core/Real.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ interface Real : Numeric {
@JvmField
val REAL_REGEX_PATTERN = "^[+\\-]?(($INT$DEC$EXP?)|($INT$EXP)|($DEC$EXP?))$".toRegex()

@JvmStatic
@JsName("toStringEnsuringDecimal")
fun toStringEnsuringDecimal(real: BigDecimal): String =
real.toString().let {
if ("." !in it) "$it.0" else it
}

@JvmStatic
@JsName("ofBigDecimal")
fun of(real: BigDecimal): Real = RealImpl(real)
Expand Down
6 changes: 6 additions & 0 deletions core/src/commonMain/kotlin/it/unibo/tuprolog/core/Scope.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ interface Scope {
@JsName("structOfSequence")
fun structOf(functor: String, args: Sequence<Term>): Struct

@JsName("structOfIterable")
fun structOf(functor: String, args: Iterable<Term>): Struct

@JsName("structOfList")
fun structOf(functor: String, args: List<Term>): Struct

@JsName("tupleOf")
fun tupleOf(vararg terms: Term): Tuple

Expand Down
5 changes: 4 additions & 1 deletion core/src/commonMain/kotlin/it/unibo/tuprolog/core/Struct.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package it.unibo.tuprolog.core
import it.unibo.tuprolog.core.impl.StructImpl
import kotlin.js.JsName
import kotlin.jvm.JvmField
import kotlin.jvm.JvmOverloads
import kotlin.jvm.JvmStatic
import kotlin.collections.List as KtList

Expand Down Expand Up @@ -144,6 +143,10 @@ interface Struct : Term {
@JsName("ofSequence")
fun of(functor: String, args: Sequence<Term>): Struct = of(functor, args.toList())

@JvmStatic
@JsName("ofIterable")
fun of(functor: String, args: Iterable<Term>): Struct = of(functor, args.toList())

@JvmStatic
@JsName("foldListNullTerminated")
fun fold(operator: String, terms: KtList<Term>): Struct =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ internal class RealImpl(override val value: BigDecimal) : NumericImpl(), Real {
value.toBigInteger()
}

override fun toString(): String = value.toString()
override fun toString(): String =
Real.toStringEnsuringDecimal(value)

override fun equals(other: Any?): Boolean {
if (this === other) return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ internal class ScopeImpl(private val _variables: MutableMap<String, Var>) : Scop
override fun structOf(functor: String, args: Sequence<Term>): Struct =
Struct.of(functor, args)

override fun structOf(functor: String, args: Iterable<Term>): Struct =
Struct.of(functor, args)

override fun structOf(functor: String, args: List<Term>): Struct =
Struct.of(functor, args)

override fun factOf(head: Struct): Fact =
Fact.of(head)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ internal class RealImplTest {

@Test
fun correctToString() {
val expectedToString = RealUtils.bigDecimals.map { it.toString() }
val expectedToString = RealUtils.bigDecimals.map { Real.toStringEnsuringDecimal(it) }

onCorrespondingItems(expectedToString, realInstances.map { it.toString() }) { expectedString, realToString ->
assertEquals(expectedString, realToString)
Expand Down
29 changes: 29 additions & 0 deletions serialize-core/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
kotlin {

sourceSets {
val commonMain by getting {
dependencies {
api(project(":core"))
}
}

jvm {
compilations["main"].defaultSourceSet {
dependencies {
implementation(Libs.jackson_core)
implementation(Libs.jackson_datatype_jsr310)
implementation(Libs.jackson_dataformat_yaml)
implementation(Libs.jackson_dataformat_xml)
}
}
}

js {
compilations["main"].defaultSourceSet {
dependencies {
api(npm("yaml", "^1.10.0"))
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package it.unibo.tuprolog.serialize

import it.unibo.tuprolog.core.exception.TuPrologException

class DeobjectificationException(`object`: Any) : TuPrologException("Error while deobjectifying $`object`")
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package it.unibo.tuprolog.serialize

import kotlin.js.JsName

interface Deobjectifier<T> {
@JsName("deobjectify")
fun deobjectify(`object`: Any): T

@JsName("deobjectifyMany")
fun deobjectifyMany(`object`: Any): Iterable<T>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package it.unibo.tuprolog.serialize

import kotlin.js.JsName

interface Deserializer<T> {
@JsName("mimeType")
val mimeType: MimeType

@JsName("deserialize")
fun deserialize(string: String): T

@JsName("deserializeMany")
fun deserializeMany(string: String): Iterable<T>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package it.unibo.tuprolog.serialize

import kotlin.js.JsName

sealed class MimeType(
@JsName("type")
val type: String,
@JsName("subType")
val subType: String
) {

object Json : MimeType("application", "json")

object Yaml : MimeType("application", "yaml")

object Xml : MimeType("application", "xml")

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package it.unibo.tuprolog.objectify

import kotlin.js.JsName

interface Objectifier<T> {
@JsName("objectify")
fun objectify(value: T): Any

@JsName("objectifyMany")
fun objectifyMany(vararg values: T): Any =
objectifyMany(listOf(*values))

@JsName("objectifyManyIterable")
fun objectifyMany(values: Iterable<T>): Any

@JsName("objectifyManySequence")
fun objectifyMany(values: Sequence<T>): Any =
objectifyMany(values.asIterable())
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package it.unibo.tuprolog.serialize

expect object ObjectsUtils {
fun parseAsObject(string: String, mimeType: MimeType): Any

fun deeplyEqual(obj1: Any?, obj2: Any?): Boolean
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package it.unibo.tuprolog.serialize

import it.unibo.tuprolog.core.Term
import it.unibo.tuprolog.core.exception.TuPrologException

class SerializationException(term: Term) : TuPrologException("Error while serialising $term")
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package it.unibo.tuprolog.serialize

import kotlin.js.JsName

interface Serializer<T> {
@JsName("mimeType")
val mimeType: MimeType

@JsName("serialize")
fun serialize(value: T): String

@JsName("serializeMany")
fun serializeMany(vararg values: T): String =
serializeMany(listOf(*values))

@JsName("serializeManyIterable")
fun serializeMany(values: Iterable<T>): String

@JsName("serializeManySequence")
fun serializeMany(values: Sequence<T>): String =
serializeMany(values.asIterable())
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package it.unibo.tuprolog.serialize

import it.unibo.tuprolog.core.Term
import kotlin.js.JsName
import kotlin.jvm.JvmStatic

interface TermDeobjectifier : Deobjectifier<Term> {
companion object {
@JsName("default")
@JvmStatic
val default: TermDeobjectifier
get() = termDeobjectifier()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package it.unibo.tuprolog.serialize

import it.unibo.tuprolog.core.Term
import kotlin.js.JsName
import kotlin.jvm.JvmStatic

interface TermDeserializer : Deserializer<Term> {
companion object {
@JvmStatic
@JsName("of")
fun of(mimeType: MimeType): TermDeserializer {
return termDeserializer(mimeType)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package it.unibo.tuprolog.serialize

import it.unibo.tuprolog.core.Term
import it.unibo.tuprolog.core.TermVisitor
import it.unibo.tuprolog.objectify.Objectifier
import kotlin.js.JsName
import kotlin.jvm.JvmStatic

interface TermObjectifier : Objectifier<Term>, TermVisitor<Any> {
override fun objectify(value: Term): Any = visit(value)

companion object {
@JsName("default")
@JvmStatic
val default: TermObjectifier
get() = termObjectifier()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@file:JvmName("TermSerialization")

package it.unibo.tuprolog.serialize

import kotlin.jvm.JvmName

expect fun termSerializer(mimeType: MimeType): TermSerializer

expect fun termDeserializer(mimeType: MimeType): TermDeserializer

expect fun termObjectifier(): TermObjectifier

expect fun termDeobjectifier(): TermDeobjectifier
Loading

0 comments on commit 6523be3

Please sign in to comment.