100 lines
3.5 KiB
Markdown
100 lines
3.5 KiB
Markdown
|
---
|
|||
|
author: usbharu
|
|||
|
draft: true
|
|||
|
categories:
|
|||
|
- 技術
|
|||
|
date: 2025-01-12T14:08:58+09:00
|
|||
|
tags:
|
|||
|
- Kotlin
|
|||
|
- ActivityPub
|
|||
|
- Kotlin
|
|||
|
- ActivityStreams
|
|||
|
- ActivityVocabulary
|
|||
|
keywords:
|
|||
|
- Kotlin
|
|||
|
- ActivityPub
|
|||
|
- Kotlin
|
|||
|
- ActivityStreams
|
|||
|
- ActivityVocabulary
|
|||
|
title: ActivityStreamsをKotlinでいい感じに扱いたい(DSL編)
|
|||
|
relpermalink: posts/2025-01-12/
|
|||
|
url: posts/2025-01-12/
|
|||
|
decription: ActivityStreamsをKotlinでいい感じに扱いたい(シリアライズ・DSL編)
|
|||
|
---
|
|||
|
|
|||
|
前回([ActivityStreamsをKotlinでいい感じに扱いたい(デシリアライズ編) · usbharu - blog](https://blog.usbharu.dev/posts/2025-01-12/))デシリアライズの実装をした際にシリアライズの部分も作ってしまっていたのでDSLのついでに紹介します。
|
|||
|
|
|||
|
## シリアライズ
|
|||
|
|
|||
|
シリアライズというかマッピングのほうが正しいような気もする
|
|||
|
|
|||
|
usbharu/activity-streams-serialization at 00dc4f7939655fb9a1c4276016040821569e4f9a
|
|||
|
https://github.com/usbharu/activity-streams-serialization/tree/00dc4f7939655fb9a1c4276016040821569e4f9a
|
|||
|
|
|||
|
|
|||
|
(注) CollectionはKotlinのCollectionではなくて独自のCollection
|
|||
|
|
|||
|
```kotlin
|
|||
|
var replies: Collection?
|
|||
|
get() = replies()
|
|||
|
set(value) {
|
|||
|
jsonObject.setOrRemove(Properties.REPLIES, value?.json)
|
|||
|
}
|
|||
|
|
|||
|
fun Object?.replies(objectFactory: ObjectFactory? = this?.objectFactory): Collection? {
|
|||
|
if (this == null) {
|
|||
|
return null
|
|||
|
}
|
|||
|
requireNotNull(objectFactory)
|
|||
|
val jsonNode = jsonObject.obtain(Properties.REPLIES)?.asArray()?.firstOrNull() ?: return null
|
|||
|
require(jsonNode.isObject)
|
|||
|
return objectFactory.create(jsonNode) as Collection
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
シリアライズの方もデシリアライズと同じで、SetterでJsonNodeを直接弄っています。
|
|||
|
|
|||
|
## DSL
|
|||
|
|
|||
|
テストがすっげぇ~~~面倒なのでDSLを作り始めました。
|
|||
|
|
|||
|
[DSL](https://github.com/usbharu/activity-streams-serialization/blob/00dc4f7939655fb9a1c4276016040821569e4f9a/src/test/kotlin/dev/usbharu/hideout/activitystreams/core/ObjectTest.kt#L77-L86)
|
|||
|
|
|||
|
```
|
|||
|
val object1 = JsonLdBuilder().Note {
|
|||
|
attachment {
|
|||
|
listOf(
|
|||
|
Image {
|
|||
|
content("This is what he looks like.")
|
|||
|
url("http://example.org/cat.jpeg")
|
|||
|
})
|
|||
|
}
|
|||
|
name("Have you seen my cat?")
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
こんな感じでオブジェクトを組み立てることができます。attachmentのlistOfをなくせるように作ることも考えたんですが、仕組みが複雑になる割にメリット無いのでやめました。
|
|||
|
|
|||
|
KotlinでDSL作るのって簡単そうに見えて意外とややこしいですよね
|
|||
|
|
|||
|
### 実装
|
|||
|
|
|||
|
[オブジェクトの作成](https://github.com/usbharu/activity-streams-serialization/blob/00dc4f7939655fb9a1c4276016040821569e4f9a/src/main/kotlin/dev/usbharu/hideout/activitystreams/dsl/JsonLd.kt)
|
|||
|
|
|||
|
```kotlin
|
|||
|
class JsonLdBuilder(var objectFactory: ObjectFactory = DefaultObjectFactory) {
|
|||
|
fun Object(block: ObjectBuilder.() -> Unit = {}): Object {
|
|||
|
val objectBuilder = ObjectBuilder(objectFactory, this)
|
|||
|
objectBuilder.block()
|
|||
|
return objectBuilder.Object
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
[プロパティの設定](https://github.com/usbharu/activity-streams-serialization/blob/00dc4f7939655fb9a1c4276016040821569e4f9a/src/main/kotlin/dev/usbharu/hideout/activitystreams/dsl/ObjectBuilder.kt)
|
|||
|
|
|||
|
```kotlin
|
|||
|
fun attachment(objectOrLink: ObjectOrLink?): ObjectBuilder {
|
|||
|
Object.attachment += objectOrLink ?: return this
|
|||
|
return this
|
|||
|
}
|
|||
|
```
|