UncreatedArticle.kt
package com.example.realworldkotlinspringbootjdbc.domain
import arrow.core.Invalid
import arrow.core.NonEmptyList
import arrow.core.Option
import arrow.core.Valid
import arrow.core.ValidatedNel
import arrow.core.invalid
import arrow.core.valid
import arrow.core.zip
import arrow.typeclasses.Semigroup
import com.example.realworldkotlinspringbootjdbc.domain.article.Description
import com.example.realworldkotlinspringbootjdbc.domain.article.Slug
import com.example.realworldkotlinspringbootjdbc.domain.article.Tag
import com.example.realworldkotlinspringbootjdbc.domain.article.Title
import com.example.realworldkotlinspringbootjdbc.domain.user.UserId
import com.example.realworldkotlinspringbootjdbc.util.MyError.ValidationError
import com.example.realworldkotlinspringbootjdbc.domain.article.Body as ArticleBody
interface UncreatedArticle {
val title: Title
val slug: Slug
val description: Description
val body: ArticleBody
val tagList: List<Tag>
val authorId: UserId
/**
* 実装
*/
private data class ValidatedUncreatedArticle(
override val title: Title,
override val slug: Slug,
override val description: Description,
override val body: ArticleBody,
override val tagList: List<Tag>,
override val authorId: UserId
) : UncreatedArticle
/**
* Factory メソッド
*/
companion object {
fun new(
title: String?,
description: String?,
body: String?,
tagList: List<String>?,
authorId: UserId,
): ValidatedNel<ValidationError, UncreatedArticle> {
val convertToValidTagList: (List<String>?) -> ValidatedNel<ValidationError, List<Tag>> = { input ->
Option.fromNullable(input).fold(
{ listOf<Tag>().valid() },
{ tagList ->
val errors = mutableListOf<ValidationError>()
val validatedTagList = mutableListOf<Tag>()
tagList.forEach {
when (val tag = Tag.new(it)) {
is Invalid -> errors.addAll(tag.value)
is Valid -> validatedTagList.add(tag.value)
}
}
when (errors.isEmpty()) {
false -> NonEmptyList.fromList(errors).orNull()!!.invalid()
true -> validatedTagList.valid()
}
}
)
}
return Title.new(title).zip(
Semigroup.nonEmptyList(),
Description.new(description),
ArticleBody.new(body),
convertToValidTagList(tagList)
) { a, b, c, d -> ValidatedUncreatedArticle(a, Slug.new(), b, c, d, authorId) }
}
}
}