-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from sergeypdev/master
Add InstantPocketbase type with custom Serializable
- Loading branch information
Showing
5 changed files
with
89 additions
and
36 deletions.
There are no files selected for viewing
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
30 changes: 5 additions & 25 deletions
30
src/commonMain/kotlin/io/github/agrevster/pocketbaseKotlin/models/utils/BaseModel.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,46 +1,26 @@ | ||
package io.github.agrevster.pocketbaseKotlin.models.utils | ||
|
||
import io.github.agrevster.pocketbaseKotlin.PocketKtInternal | ||
import kotlinx.datetime.Instant | ||
import kotlinx.datetime.toInstant | ||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
import kotlinx.serialization.Transient | ||
|
||
@Serializable | ||
/** | ||
* The base class used for all [Pocketbase](https://pocketbase.io) models used | ||
* | ||
* @property [id] The unique ID of the model | ||
* @property [initialCreated] the raw created field from the model formatted in the GO timestamp format. | ||
* Use [created] to access the type of [Instant] | ||
* @property [initialUpdated] the raw updated field from the model formatted in the GO timestamp format. | ||
* Use [updated] to access the type of [Instant] | ||
* @property [created] the created field from the model. | ||
* @property [updated] the updated field from the model. | ||
* | ||
*/ | ||
public open class BaseModel(public open val id: String? = null) { | ||
|
||
public val created: InstantPocketbase? = null | ||
|
||
@SerialName("created") | ||
@PocketKtInternal | ||
public val initialCreated: String? = null | ||
|
||
@SerialName("updated") | ||
@PocketKtInternal | ||
public val initialUpdated: String? = null | ||
|
||
@OptIn(PocketKtInternal::class) | ||
@Transient | ||
public val created: Instant? = initialCreated?.replace(" ", "T")?.toInstant() | ||
|
||
@OptIn(PocketKtInternal::class) | ||
@Transient | ||
public val updated: Instant? = initialUpdated?.replace(" ", "T")?.toInstant() | ||
|
||
public val updated: InstantPocketbase? = null | ||
|
||
@OptIn(PocketKtInternal::class) | ||
override fun toString(): String { | ||
return "BaseModel(id=$id, created=$initialCreated, updated=$initialUpdated)" | ||
return "BaseModel(id=$id, created=$created, updated=$updated)" | ||
} | ||
|
||
} |
43 changes: 43 additions & 0 deletions
43
src/commonMain/kotlin/io/github/agrevster/pocketbaseKotlin/models/utils/InsantPocketbase.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,43 @@ | ||
package io.github.agrevster.pocketbaseKotlin.models.utils | ||
|
||
import kotlinx.datetime.Instant | ||
import kotlinx.datetime.TimeZone | ||
import kotlinx.datetime.toLocalDateTime | ||
import kotlinx.serialization.KSerializer | ||
import kotlinx.serialization.Serializable | ||
import kotlinx.serialization.descriptors.PrimitiveKind | ||
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor | ||
import kotlinx.serialization.descriptors.SerialDescriptor | ||
import kotlinx.serialization.encoding.Decoder | ||
import kotlinx.serialization.encoding.Encoder | ||
|
||
public typealias InstantPocketbase = @Serializable(InstantPocketbaseSerializer::class) Instant | ||
|
||
internal fun Int.padded(length: Int): String { | ||
return this.toString().padStart(length, '0') | ||
} | ||
|
||
public fun Instant.toStringPocketbase(): String { | ||
val dt = this.toLocalDateTime(TimeZone.UTC) | ||
|
||
return "${dt.year}-${dt.monthNumber.padded(2)}-${dt.dayOfMonth.padded(2)} ${dt.hour.padded(2)}:${dt.minute.padded(2)}:${dt.second.padded(2)}.${dt.nanosecond / 1_000_000}Z" | ||
} | ||
|
||
public fun Instant.Companion.parsePocketbase(string: String): InstantPocketbase { | ||
return parse(string.replace(' ', 'T')) | ||
} | ||
|
||
public object InstantPocketbaseSerializer : KSerializer<Instant> { | ||
override val descriptor: SerialDescriptor = | ||
PrimitiveSerialDescriptor("Instant", PrimitiveKind.STRING) | ||
|
||
override fun deserialize(decoder: Decoder): Instant { | ||
val dateStr = decoder.decodeString() | ||
return Instant.parsePocketbase(dateStr) | ||
} | ||
|
||
override fun serialize(encoder: Encoder, value: Instant) { | ||
encoder.encodeString(value.toStringPocketbase()) | ||
} | ||
|
||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package models.utils | ||
|
||
import TestingUtils | ||
import io.github.agrevster.pocketbaseKotlin.models.utils.InstantPocketbase | ||
import io.github.agrevster.pocketbaseKotlin.models.utils.InstantPocketbaseSerializer | ||
import kotlinx.datetime.Clock | ||
import kotlinx.datetime.Instant | ||
import kotlinx.serialization.Serializable | ||
import kotlinx.serialization.encodeToString | ||
import kotlinx.serialization.json.Json | ||
import kotlinx.serialization.modules.SerializersModule | ||
import kotlinx.serialization.modules.contextual | ||
import kotlin.test.Test | ||
import kotlin.test.assertEquals | ||
|
||
class InstantPocketbaseTest : TestingUtils() { | ||
@Test | ||
fun testSerializeDeserialize(): Unit { | ||
@Serializable | ||
data class TestSerializable(val instant: InstantPocketbase) | ||
|
||
val original = TestSerializable(Instant.parse("2023-10-24T01:02:03.123Z")) | ||
|
||
val encoded = Json.encodeToString(original) | ||
assertEquals( | ||
expected = "{\"instant\":\"2023-10-24 01:02:03.123Z\"}", | ||
actual = encoded, | ||
) | ||
val decoded: TestSerializable = Json.decodeFromString(encoded) | ||
assertEquals( | ||
expected = original, | ||
actual = decoded, | ||
) | ||
} | ||
} |