From ecb66791a1dbd6a2242419df809eb33825f3787b Mon Sep 17 00:00:00 2001 From: usbharu Date: Mon, 20 Jan 2025 10:32:45 +0900 Subject: [PATCH] =?UTF-8?q?2025-01-20=E3=81=AE=E8=A8=98=E4=BA=8B=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- content/posts/2025-01-20/index.md | 100 ++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 content/posts/2025-01-20/index.md diff --git a/content/posts/2025-01-20/index.md b/content/posts/2025-01-20/index.md new file mode 100644 index 0000000..1021362 --- /dev/null +++ b/content/posts/2025-01-20/index.md @@ -0,0 +1,100 @@ +--- +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 + } +``` \ No newline at end of file