This is an automated email from the ASF dual-hosted git repository.
chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fury.git
The following commit(s) were added to refs/heads/main by this push:
new 3fb0797b feat(kotlin): Add tests and support for built-in types from
the kotlin stdlib (#1901)
3fb0797b is described below
commit 3fb0797b9f1e54a12a39a81a7ae6afcf876c4dde
Author: Yi Wen Wong <[email protected]>
AuthorDate: Thu Oct 24 09:58:18 2024 -0700
feat(kotlin): Add tests and support for built-in types from the kotlin
stdlib (#1901)
## What does this PR do?
This PR adds tests and covers built-in classes from the kotlin stdlib.
Two specific serializers are added for builtins:
1) Duration
2) Uuid
## Related issues
#683
## Does this PR introduce any user-facing change?
Adds builtin types for kotlin.
## Benchmark
N/A
---
kotlin/README.md | 8 +
kotlin/pom.xml | 8 +
.../fury/serializer/kotlin/KotlinSerializers.java | 58 +++++-
.../fury/serializer/kotlin/DurationSerializer.kt | 121 +++++++++++
.../fury/serializer/kotlin/KotlinToJavaClass.kt | 10 +
.../{KotlinToJavaClass.kt => UuidSerializer.kt} | 30 ++-
.../kotlin/BuiltinClassSerializerTests.kt | 232 +++++++++++++++++++++
7 files changed, 451 insertions(+), 16 deletions(-)
diff --git a/kotlin/README.md b/kotlin/README.md
index a060534c..57eea113 100644
--- a/kotlin/README.md
+++ b/kotlin/README.md
@@ -16,6 +16,12 @@ Fury Kotlin is tested and works with the following types:
- arrays: `Array`, `BooleanArray`, `ByteArray`, `CharArray`, `DoubleArray`,
`FloatArray`, `IntArray`, `LongArray`, `ShortArray`
- all standard array types work out of the box with the default fury java
implementation.
- unsigned arrays: `UByteArray`, `UShortArray`, `UIntArray`, `ULongArray`
+- from stdlib: `Pair`, `Triple`, `Result`
+- kotlin.random: `Random`
+- kotlin.ranges: `CharRange`, `CharProgression`, `IntRange`, `IntProgression`,
`LongRange`, `LongProgression`, `UintRange`, `UintProgression`, `ULongRange`,
`ULongProgression`
+- kotlin.text: `Regex`
+- kotlin.time: `Duration`
+- kotlin.uuid: `Uuid`
Additional support is added for the following classes in kotlin:
@@ -23,6 +29,8 @@ Additional support is added for the following classes in
kotlin:
- Unsigned array types: `UByteArray`, `UShortArray`, `UIntArray`, `ULongArray`
- Empty collections: `emptyList`, `emptyMap`, `emptySet`
- Collections: `ArrayDeque`
+- kotlin.time: `Duration`
+- kotlin.uuid: `Uuid`
Additional Notes:
diff --git a/kotlin/pom.xml b/kotlin/pom.xml
index f31c8dcc..85c46f70 100644
--- a/kotlin/pom.xml
+++ b/kotlin/pom.xml
@@ -160,6 +160,14 @@
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.22.2</version>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>8</source>
+ <target>8</target>
+ </configuration>
+ </plugin>
</plugins>
</build>
diff --git
a/kotlin/src/main/java/org/apache/fury/serializer/kotlin/KotlinSerializers.java
b/kotlin/src/main/java/org/apache/fury/serializer/kotlin/KotlinSerializers.java
index f87f1476..f3760785 100644
---
a/kotlin/src/main/java/org/apache/fury/serializer/kotlin/KotlinSerializers.java
+++
b/kotlin/src/main/java/org/apache/fury/serializer/kotlin/KotlinSerializers.java
@@ -19,6 +19,13 @@
package org.apache.fury.serializer.kotlin;
+import kotlin.*;
+import kotlin.text.*;
+import kotlin.time.Duration;
+import kotlin.time.DurationUnit;
+import kotlin.time.TestTimeSource;
+import kotlin.time.TimedValue;
+import kotlin.uuid.Uuid;
import kotlin.UByteArray;
import kotlin.UIntArray;
import kotlin.ULongArray;
@@ -30,17 +37,16 @@ import org.apache.fury.resolver.ClassResolver;
import org.apache.fury.serializer.collection.CollectionSerializers;
import org.apache.fury.serializer.collection.MapSerializers;
-
/**
* KotlinSerializers provide default serializers for kotlin.
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public class KotlinSerializers {
- public static void registerSerializers(ThreadSafeFury fury) {
- AbstractThreadSafeFury threadSafeFury = (AbstractThreadSafeFury) fury;
- threadSafeFury.registerCallback(KotlinSerializers::registerSerializers);
- }
+ public static void registerSerializers(ThreadSafeFury fury) {
+ AbstractThreadSafeFury threadSafeFury = (AbstractThreadSafeFury) fury;
+
threadSafeFury.registerCallback(KotlinSerializers::registerSerializers);
+ }
public static void registerSerializers(Fury fury) {
ClassResolver resolver = fury.getClassResolver();
@@ -94,5 +100,47 @@ public class KotlinSerializers {
resolver.registerSerializer(UIntArray.class, new
UIntArraySerializer(fury));
resolver.register(ULongArray.class);
resolver.registerSerializer(ULongArray.class, new
ULongArraySerializer(fury));
+
+ // Ranges and Progressions.
+ resolver.register(kotlin.ranges.CharRange.class);
+ resolver.register(kotlin.ranges.CharProgression.class);
+ resolver.register(kotlin.ranges.IntRange.class);
+ resolver.register(kotlin.ranges.IntProgression.class);
+ resolver.register(kotlin.ranges.LongRange.class);
+ resolver.register(kotlin.ranges.LongProgression.class);
+ resolver.register(kotlin.ranges.UIntRange.class);
+ resolver.register(kotlin.ranges.UIntProgression.class);
+ resolver.register(kotlin.ranges.ULongRange.class);
+ resolver.register(kotlin.ranges.ULongProgression.class);
+
+ // Built-in classes.
+ resolver.register(kotlin.Pair.class);
+ resolver.register(kotlin.Triple.class);
+ resolver.register(kotlin.Result.class);
+ resolver.register(Result.Failure.class);
+
+ // kotlin.random
+ resolver.register(KotlinToJavaClass.INSTANCE.getRandomDefaultClass());
+ resolver.register(KotlinToJavaClass.INSTANCE.getRandomInternalClass());
+
resolver.register(KotlinToJavaClass.INSTANCE.getRandomSerializedClass());
+
+ // kotlin.text
+ resolver.register(Regex.class);
+
resolver.register(KotlinToJavaClass.INSTANCE.getRegexSerializedClass());
+ resolver.register(RegexOption.class);
+ resolver.register(CharCategory.class);
+ resolver.register(CharDirectionality.class);
+ resolver.register(HexFormat.class);
+ resolver.register(MatchGroup.class);
+
+ // kotlin.time
+ resolver.register(DurationUnit.class);
+ resolver.register(Duration.class);
+ resolver.registerSerializer(Duration.class, new
DurationSerializer(fury));
+ resolver.register(TimedValue.class);
+
+ // kotlin.uuid
+ resolver.register(Uuid.class);
+ resolver.registerSerializer(Uuid.class, new UuidSerializer(fury));
}
}
diff --git
a/kotlin/src/main/kotlin/org/apache/fury/serializer/kotlin/DurationSerializer.kt
b/kotlin/src/main/kotlin/org/apache/fury/serializer/kotlin/DurationSerializer.kt
new file mode 100644
index 00000000..a1bbfd4f
--- /dev/null
+++
b/kotlin/src/main/kotlin/org/apache/fury/serializer/kotlin/DurationSerializer.kt
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fury.serializer.kotlin
+
+import org.apache.fury.Fury
+import org.apache.fury.memory.MemoryBuffer
+import org.apache.fury.serializer.ImmutableSerializer
+import org.apache.fury.serializer.Serializer
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.days
+import kotlin.time.Duration.Companion.hours
+import kotlin.time.Duration.Companion.microseconds
+import kotlin.time.Duration.Companion.milliseconds
+import kotlin.time.Duration.Companion.minutes
+import kotlin.time.Duration.Companion.nanoseconds
+import kotlin.time.Duration.Companion.seconds
+import kotlin.time.DurationUnit
+
+class DurationSerializer(
+ fury: Fury,
+ needToWriteRef:Boolean
+) : ImmutableSerializer<Duration>(
+ fury,
+ Duration::class.java,
+ needToWriteRef) {
+
+ constructor(
+ fury: Fury,
+ ) : this (fury, fury.config.isTimeRefIgnored)
+
+ private val durationUnitSerializer: Serializer<DurationUnit> by lazy {
+ fury.classResolver.getSerializer(DurationUnit::class.java)
+ }
+
+ override fun write(buffer: MemoryBuffer, value: Duration) {
+ val unit = computeDurationUnitPrecision(value)
+ durationUnitSerializer.write(buffer, unit)
+
+ val rawValue: Long = when (unit) {
+ DurationUnit.NANOSECONDS -> value.inWholeNanoseconds
+ DurationUnit.MICROSECONDS -> value.inWholeMicroseconds
+ DurationUnit.MILLISECONDS -> value.inWholeMilliseconds
+ DurationUnit.SECONDS -> value.inWholeSeconds
+ DurationUnit.MINUTES -> value.inWholeMinutes
+ DurationUnit.HOURS -> value.inWholeHours
+ DurationUnit.DAYS -> value.inWholeDays
+ }
+
+ buffer.writeInt64(rawValue)
+ }
+
+ override fun read(buffer: MemoryBuffer): Duration {
+ val unit = durationUnitSerializer.read(buffer)
+ val rawValue = buffer.readInt64()
+ return when (unit) {
+ DurationUnit.NANOSECONDS -> rawValue.nanoseconds
+ DurationUnit.MICROSECONDS -> rawValue.microseconds
+ DurationUnit.MILLISECONDS -> rawValue.milliseconds
+ DurationUnit.SECONDS -> rawValue.seconds
+ DurationUnit.MINUTES -> rawValue.minutes
+ DurationUnit.HOURS -> rawValue.hours
+ DurationUnit.DAYS -> rawValue.days
+ }
+ }
+
+ private fun computeDurationUnitPrecision(value:Duration) :DurationUnit {
+ if (value == Duration.ZERO) {
+ return DurationUnit.NANOSECONDS
+ }
+ if (value.isInfinite()) {
+ return DurationUnit.MILLISECONDS
+ }
+
+ value.absoluteValue.toComponents { days, hours, minutes, seconds,
nanoseconds ->
+ val millisecondPrecision = nanoseconds >= 1_000_000 && nanoseconds
% 1_000_000 == 0
+ if (millisecondPrecision) {
+ return DurationUnit.MILLISECONDS
+ }
+ val microsecondPrecision= nanoseconds >= 1_000 && nanoseconds %
1_000 == 0
+ if (microsecondPrecision) {
+ return DurationUnit.MICROSECONDS
+ }
+ val nanoSecondPrecision= nanoseconds != 0 && nanoseconds % 1000 != 0
+ if (nanoSecondPrecision) {
+ return DurationUnit.NANOSECONDS
+ }
+
+ if (seconds != 0) {
+ return DurationUnit.SECONDS
+ }
+
+ if (minutes != 0) {
+ return DurationUnit.MINUTES
+ }
+
+ if (hours != 0) {
+ return DurationUnit.HOURS
+ }
+
+ // Return lowest precision unit.
+ return DurationUnit.DAYS
+ }
+ }
+}
diff --git
a/kotlin/src/main/kotlin/org/apache/fury/serializer/kotlin/KotlinToJavaClass.kt
b/kotlin/src/main/kotlin/org/apache/fury/serializer/kotlin/KotlinToJavaClass.kt
index cd962fd6..7da68f53 100644
---
a/kotlin/src/main/kotlin/org/apache/fury/serializer/kotlin/KotlinToJavaClass.kt
+++
b/kotlin/src/main/kotlin/org/apache/fury/serializer/kotlin/KotlinToJavaClass.kt
@@ -19,6 +19,8 @@
package org.apache.fury.serializer.kotlin
+import kotlin.random.Random
+
object KotlinToJavaClass {
// Collections
val ArrayDequeClass = ArrayDeque::class.java
@@ -31,4 +33,12 @@ object KotlinToJavaClass {
val UShortClass = UShort::class.java
val UIntClass = UInt::class.java
val ULongClass = ULong::class.java
+
+ // Random
+ val RandomInternalClass = Random(1)::class.java
+ val RandomDefaultClass = Random.Default::class.java
+ val RandomSerializedClass =
Class.forName("kotlin.random.Random\$Default\$Serialized")
+
+ // Regex
+ val RegexSerializedClass = Class.forName("kotlin.text.Regex\$Serialized")
}
diff --git
a/kotlin/src/main/kotlin/org/apache/fury/serializer/kotlin/KotlinToJavaClass.kt
b/kotlin/src/main/kotlin/org/apache/fury/serializer/kotlin/UuidSerializer.kt
similarity index 57%
copy from
kotlin/src/main/kotlin/org/apache/fury/serializer/kotlin/KotlinToJavaClass.kt
copy to
kotlin/src/main/kotlin/org/apache/fury/serializer/kotlin/UuidSerializer.kt
index cd962fd6..994e40e2 100644
---
a/kotlin/src/main/kotlin/org/apache/fury/serializer/kotlin/KotlinToJavaClass.kt
+++ b/kotlin/src/main/kotlin/org/apache/fury/serializer/kotlin/UuidSerializer.kt
@@ -19,16 +19,24 @@
package org.apache.fury.serializer.kotlin
-object KotlinToJavaClass {
- // Collections
- val ArrayDequeClass = ArrayDeque::class.java
- val EmptyListClass = emptyList<Any>().javaClass
- val EmptySetClass = emptySet<Any>().javaClass
- val EmptyMapClass = emptyMap<Any, Any>().javaClass
+import org.apache.fury.Fury
+import org.apache.fury.memory.MemoryBuffer
+import org.apache.fury.serializer.ImmutableSerializer
+import kotlin.uuid.ExperimentalUuidApi
+import kotlin.uuid.Uuid
- // Unsigned
- val UByteClass = UByte::class.java
- val UShortClass = UShort::class.java
- val UIntClass = UInt::class.java
- val ULongClass = ULong::class.java
+@OptIn(ExperimentalUuidApi::class)
+class UuidSerializer(
+ fury: Fury
+) : ImmutableSerializer<Uuid>(fury, Uuid::class.java) {
+ override fun write(buffer: MemoryBuffer, value: Uuid) {
+ value.toLongs { msb, lsb ->
+ buffer.writeInt64(msb)
+ buffer.writeInt64(lsb)
+ }
+ }
+
+ override fun read(buffer: MemoryBuffer): Uuid {
+ return Uuid.fromLongs(buffer.readInt64(), buffer.readInt64())
+ }
}
diff --git
a/kotlin/src/test/kotlin/org/apache/fury/serializer/kotlin/BuiltinClassSerializerTests.kt
b/kotlin/src/test/kotlin/org/apache/fury/serializer/kotlin/BuiltinClassSerializerTests.kt
new file mode 100644
index 00000000..ce3b5d8c
--- /dev/null
+++
b/kotlin/src/test/kotlin/org/apache/fury/serializer/kotlin/BuiltinClassSerializerTests.kt
@@ -0,0 +1,232 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fury.serializer.kotlin
+
+import org.apache.fury.Fury
+import org.apache.fury.config.Language
+import org.testng.Assert
+import java.util.UUID
+import kotlin.collections.MutableMap.MutableEntry
+import kotlin.random.Random
+import kotlin.test.Test
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.days
+import kotlin.time.Duration.Companion.hours
+import kotlin.time.Duration.Companion.microseconds
+import kotlin.time.Duration.Companion.milliseconds
+import kotlin.time.Duration.Companion.minutes
+import kotlin.time.Duration.Companion.nanoseconds
+import kotlin.time.Duration.Companion.seconds
+import kotlin.uuid.ExperimentalUuidApi
+import kotlin.uuid.Uuid
+
+class BuiltinClassSerializerTests {
+ @Test
+ fun testSerializePair() {
+ val fury: Fury = Fury.builder()
+ .withLanguage(Language.JAVA)
+ .requireClassRegistration(true)
+ .build()
+
+ KotlinSerializers.registerSerializers(fury)
+ val value = Pair(1, "one")
+ Assert.assertEquals(value, fury.deserialize(fury.serialize(value)))
+ }
+
+ @Test
+ fun testSerializeTriple() {
+ val fury: Fury = Fury.builder()
+ .withLanguage(Language.JAVA)
+ .requireClassRegistration(true)
+ .build()
+
+ KotlinSerializers.registerSerializers(fury)
+ val value = Triple(1, "one", null)
+ Assert.assertEquals(value, fury.deserialize(fury.serialize(value)))
+ }
+
+ @Suppress("UNCHECKED_CAST")
+ @Test
+ fun testSerializeResult() {
+ val fury: Fury = Fury.builder()
+ .withLanguage(Language.JAVA)
+ .requireClassRegistration(true)
+ .withRefTracking(true)
+ .build()
+
+ KotlinSerializers.registerSerializers(fury)
+ val value1 = Result.success(5)
+ Assert.assertEquals(value1, fury.deserialize(fury.serialize(value1)))
+
+ val value2 = Result.failure<Int>(IllegalStateException("my exception"))
+ val roundtrip = fury.deserialize(fury.serialize(value2)) as Result<Int>
+ Assert.assertTrue(roundtrip.isFailure)
+ Assert.assertEquals(roundtrip.exceptionOrNull()!!.message, "my
exception")
+ }
+
+ @Test
+ fun testSerializeRanges() {
+ val fury: Fury = Fury.builder()
+ .withLanguage(Language.JAVA)
+ .requireClassRegistration(true)
+ .withRefTracking(true)
+ .build()
+
+ KotlinSerializers.registerSerializers(fury)
+ val value1 = 1..4
+ Assert.assertEquals(value1, fury.deserialize(fury.serialize(value1)))
+
+ val value2 = 4 downTo 1
+ Assert.assertEquals(value2, fury.deserialize(fury.serialize(value2)))
+
+
+ val value3 = 0..<8 step 2
+ Assert.assertEquals(value3, fury.deserialize(fury.serialize(value3)))
+
+ val value4 = 'a' .. 'd'
+ Assert.assertEquals(value4, fury.deserialize(fury.serialize(value4)))
+
+
+ val value5 = 'c' downTo 'a'
+ Assert.assertEquals(value5, fury.deserialize(fury.serialize(value5)))
+
+ val value6 = 0L .. 10L
+ Assert.assertEquals(value6, fury.deserialize(fury.serialize(value6)))
+
+ val value7 = 4L downTo 0L
+ Assert.assertEquals(value7, fury.deserialize(fury.serialize(value7)))
+
+ val value8 = 0u .. 4u
+ Assert.assertEquals(value8, fury.deserialize(fury.serialize(value8)))
+
+ val value9 = 4u downTo 0u
+ Assert.assertEquals(value9, fury.deserialize(fury.serialize(value9)))
+
+ val value10 = 0uL .. 4uL
+ Assert.assertEquals(value10, fury.deserialize(fury.serialize(value10)))
+
+ val value11 = 4uL downTo 0uL
+ Assert.assertEquals(value11, fury.deserialize(fury.serialize(value11)))
+ }
+
+ @Test
+ fun testSerializeRandom() {
+ val fury: Fury = Fury.builder()
+ .withLanguage(Language.JAVA)
+ .requireClassRegistration(true)
+ .withRefTracking(true)
+ .build()
+
+ KotlinSerializers.registerSerializers(fury)
+ val value1 = Random(123)
+ val roundtrip1 = fury.deserialize(fury.serialize(value1)) as Random
+
+ Assert.assertEquals(roundtrip1.nextInt(), value1.nextInt())
+
+ // The default random object will be roundtripped to the platform
default random singleton object.
+ val value2 = Random.Default
+ val roundtrip2 = fury.deserialize(fury.serialize(value2)) as Random
+
+ Assert.assertEquals(roundtrip2, value2)
+ }
+
+ @Test
+ fun testSerializeDuration() {
+ val fury: Fury = Fury.builder()
+ .withLanguage(Language.JAVA)
+ .requireClassRegistration(true)
+ .withRefTracking(true)
+ .build()
+
+ KotlinSerializers.registerSerializers(fury)
+
+ val value1 = Duration.ZERO
+ Assert.assertEquals(value1, fury.deserialize(fury.serialize(value1)))
+
+ val value2 = Duration.INFINITE
+ Assert.assertEquals(value2, fury.deserialize(fury.serialize(value2)))
+
+ val value3 = -Duration.INFINITE
+ Assert.assertEquals(value3, fury.deserialize(fury.serialize(value3)))
+
+ val value4 = 1.nanoseconds
+ Assert.assertEquals(value4, fury.deserialize(fury.serialize(value4)))
+
+ val value5 = 1.microseconds
+ Assert.assertEquals(value5, fury.deserialize(fury.serialize(value5)))
+
+ val value6 = 1.milliseconds
+ Assert.assertEquals(value6, fury.deserialize(fury.serialize(value6)))
+
+ val value7 = 3.141.milliseconds
+ Assert.assertEquals(value7, fury.deserialize(fury.serialize(value7)))
+
+ val value8 = 1.seconds
+ Assert.assertEquals(value8, fury.deserialize(fury.serialize(value8)))
+
+ val value9 = 3.141.seconds
+ Assert.assertEquals(value9, fury.deserialize(fury.serialize(value9)))
+
+ val value10 = 5.minutes
+ Assert.assertEquals(value10, fury.deserialize(fury.serialize(value10)))
+
+ val value11 = 60.minutes
+ Assert.assertEquals(value11, fury.deserialize(fury.serialize(value11)))
+
+ val value12 = 12.hours
+ Assert.assertEquals(value12, fury.deserialize(fury.serialize(value12)))
+
+ val value13 = 13.days
+ Assert.assertEquals(value13, fury.deserialize(fury.serialize(value13)))
+
+ val value14 = 356.days
+ Assert.assertEquals(value14, fury.deserialize(fury.serialize(value14)))
+ }
+
+ @OptIn(ExperimentalUuidApi::class)
+ @Test
+ fun testSerializeUuid() {
+ val fury: Fury = Fury.builder()
+ .withLanguage(Language.JAVA)
+ .requireClassRegistration(true)
+ .withRefTracking(true)
+ .build()
+
+ KotlinSerializers.registerSerializers(fury)
+
+ val value = Uuid.fromLongs(1234L, 56789L)
+ Assert.assertEquals(value, fury.deserialize(fury.serialize(value)))
+ }
+
+ @Test
+ fun testSerializeRegex() {
+ val fury: Fury = Fury.builder()
+ .withLanguage(Language.JAVA)
+ .requireClassRegistration(true)
+ .withRefTracking(true)
+ .build()
+
+ KotlinSerializers.registerSerializers(fury)
+
+ val value = Regex("12345")
+ Assert.assertEquals(value.pattern,
fury.deserialize(fury.serialize(value.pattern)))
+ Assert.assertEquals(value.options,
fury.deserialize(fury.serialize(value.options)))
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]