3.5 KiB
3.5 KiB
author | draft | categories | date | tags | keywords | title | relpermalink | url | decription | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
usbharu | false |
|
2025-01-20T14:08:58+09:00 |
|
|
ActivityStreamsをKotlinでいい感じに扱いたい(DSL編) | posts/2025-01-20/ | posts/2025-01-20/ | ActivityStreamsをKotlinでいい感じに扱いたい(シリアライズ・DSL編) |
前回(ActivityStreamsをKotlinでいい感じに扱いたい(デシリアライズ編) · usbharu - blog)デシリアライズの実装をした際にシリアライズの部分も作ってしまっていたのでDSLのついでに紹介します。
シリアライズ
シリアライズというかマッピングのほうが正しいような気もする
usbharu/activity-streams-serialization at 00dc4f7939655fb9a1c4276016040821569e4f9a
00dc4f7939
(注) CollectionはKotlinのCollectionではなくて独自のCollection
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を作り始めました。
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作るのって簡単そうに見えて意外とややこしいですよね
実装
class JsonLdBuilder(var objectFactory: ObjectFactory = DefaultObjectFactory) {
fun Object(block: ObjectBuilder.() -> Unit = {}): Object {
val objectBuilder = ObjectBuilder(objectFactory, this)
objectBuilder.block()
return objectBuilder.Object
}
fun attachment(objectOrLink: ObjectOrLink?): ObjectBuilder {
Object.attachment += objectOrLink ?: return this
return this
}