Remove Boilerplate Use-case thingy

This commit is contained in:
2021-03-03 16:36:08 +01:00
parent 3e1683dfe5
commit a4bf998c5b
37 changed files with 382 additions and 495 deletions
+76
View File
@@ -0,0 +1,76 @@
package be.simplenotes.domain
import arrow.core.Either
import arrow.core.computations.either
import arrow.core.left
import arrow.core.right
import be.simplenotes.domain.validation.NoteValidations
import be.simplenotes.types.NoteMetadata
import com.vladsch.flexmark.html.HtmlRenderer
import com.vladsch.flexmark.parser.Parser
import io.konform.validation.ValidationErrors
import org.yaml.snakeyaml.Yaml
import org.yaml.snakeyaml.parser.ParserException
import org.yaml.snakeyaml.scanner.ScannerException
import javax.inject.Singleton
interface MarkdownService {
fun renderDocument(input: String): Either<MarkdownParsingError, Document>
}
private typealias MetaMdPair = Pair<String, String>
@Singleton
internal class MarkdownServiceImpl(
private val parser: Parser,
private val renderer: HtmlRenderer,
) : MarkdownService {
private val yamlBoundPattern = "-{3}".toRegex()
private fun splitMetaFromDocument(input: String): Either<MarkdownParsingError.MissingMeta, MetaMdPair> {
val split = input.split(yamlBoundPattern, 3)
if (split.size < 3) return MarkdownParsingError.MissingMeta.left()
return (split[1].trim() to split[2].trim()).right()
}
private val yaml = Yaml()
private fun parseMeta(input: String): Either<MarkdownParsingError.InvalidMeta, NoteMetadata> {
val load: Map<String, Any> = try {
yaml.load(input)
} catch (e: ParserException) {
return MarkdownParsingError.InvalidMeta.left()
} catch (e: ScannerException) {
return MarkdownParsingError.InvalidMeta.left()
}
val title = when (val titleNode = load["title"]) {
is String, is Number -> titleNode.toString()
else -> return MarkdownParsingError.InvalidMeta.left()
}
val tagsNode = load["tags"]
val tags = if (tagsNode !is List<*>)
emptyList()
else
tagsNode.map { it.toString() }
return NoteMetadata(title, tags).right()
}
private fun renderMarkdown(markdown: String) = parser.parse(markdown).run(renderer::render)
override fun renderDocument(input: String) = either.eager<MarkdownParsingError, Document> {
val (meta, md) = !splitMetaFromDocument(input)
val parsedMeta = !parseMeta(meta)
!Either.fromNullable(NoteValidations.validateMetadata(parsedMeta)).swap()
val html = renderMarkdown(md)
Document(parsedMeta, html)
}
}
sealed class MarkdownParsingError {
object MissingMeta : MarkdownParsingError()
object InvalidMeta : MarkdownParsingError()
class ValidationError(val validationErrors: ValidationErrors) : MarkdownParsingError()
}
data class Document(val metadata: NoteMetadata, val html: String)