Skip to content

Commit

Permalink
Merge pull request #15 from clojj/dev/spike
Browse files Browse the repository at this point in the history
fix dependency directions and put parsers & opaque types together
  • Loading branch information
sksamuel authored Jul 23, 2022
2 parents 4c693b5 + f767938 commit 6e16e1f
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 39 deletions.
13 changes: 13 additions & 0 deletions tribune-examples-model/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

## Opaque Types, constructed by parsers

There should be no other way to construct a value of

1) `com.sksamuel.tribune.examples.valueclass.ParsedBook` (in the case of using `value class`)

2) `com.sksamuel.tribune.examples.dataclass.Book` (in the case of using `data class`)

_outside_ of the gradle-module `tribune-examples-model`.

Hence each of these example types has its constructor declared as `internal`
and offers the user parser functions, which are able to construct valid instances.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.sksamuel.tribune.examples

data class BookInput(
val title: String?,
val author: String?,
val isbn: String?,
)
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package com.sksamuel.tribune.examples.opaque.dataclass
package com.sksamuel.tribune.examples.dataclass

import com.sksamuel.tribune.core.Parser
import com.sksamuel.tribune.core.compose
import com.sksamuel.tribune.core.filter
import com.sksamuel.tribune.core.strings.length
import com.sksamuel.tribune.core.strings.nonBlankString
import com.sksamuel.tribune.core.strings.notNullOrBlank
import com.sksamuel.tribune.examples.BookInput

data class Book internal constructor(
val title: String,
Expand All @@ -28,16 +29,11 @@ val bookIsbnParser: Parser<String?, String, String> =
.length({ it == 10 || it == 13 }) { "Valid ISBNs have length 10 or 13" }
.filter({ it.length == 10 || it.startsWith("9") }, { "13 Digit ISBNs must start with 9" })

data class BookInput(
val title: String?,
val author: String?,
val isbn: String?,
)

val bookParserPrimitive: Parser<BookInput, Book, String> =
val bookParserDataclass: Parser<BookInput, Book, String> =
Parser.compose(
bookTitleParser.contramap { it.title },
bookAuthorParser.contramap { it.author },
bookIsbnParser.contramap { it.isbn },
::Book,
)

Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.sksamuel.tribune.examples.opaque.value
package com.sksamuel.tribune.examples.valueclass

import com.sksamuel.tribune.core.Parser
import com.sksamuel.tribune.core.compose
import com.sksamuel.tribune.core.filter
import com.sksamuel.tribune.core.map
import com.sksamuel.tribune.core.strings.length
import com.sksamuel.tribune.core.strings.nonBlankString
import com.sksamuel.tribune.core.strings.notNullOrBlank
import com.sksamuel.tribune.examples.BookInput

data class ParsedBook(
val title: Title,
Expand Down Expand Up @@ -46,3 +48,10 @@ val isbnParser: Parser<String?, Isbn, String> =
.filter({ it.length == 10 || it.startsWith("9") }, { "13 Digit ISBNs must start with 9" })
.map { Isbn(it) }

val bookParser: Parser<BookInput, ParsedBook, String> =
Parser.compose(
titleParser.contramap { it.title },
authorParser.contramap { it.author },
isbnParser.contramap { it.isbn },
::ParsedBook,
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package com.sksamuel.tribune.examples

import arrow.core.invalidNel
import arrow.core.validNel
import com.sksamuel.tribune.examples.opaque.value.Author
import com.sksamuel.tribune.examples.opaque.value.Isbn
import com.sksamuel.tribune.examples.opaque.value.Title
import com.sksamuel.tribune.examples.opaque.value.authorParser
import com.sksamuel.tribune.examples.opaque.value.isbnParser
import com.sksamuel.tribune.examples.opaque.value.titleParser
import com.sksamuel.tribune.examples.valueclass.Author
import com.sksamuel.tribune.examples.valueclass.Isbn
import com.sksamuel.tribune.examples.valueclass.Title
import com.sksamuel.tribune.examples.valueclass.authorParser
import com.sksamuel.tribune.examples.valueclass.isbnParser
import com.sksamuel.tribune.examples.valueclass.titleParser
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.sksamuel.tribune.examples

import com.sksamuel.tribune.examples.opaque.dataclass.bookParserPrimitive
import com.sksamuel.tribune.examples.dataclass.bookParserDataclass
import com.sksamuel.tribune.examples.valueclass.bookParser
import com.sksamuel.tribune.ktor.jsonHandler
import com.sksamuel.tribune.ktor.withParsedInput
import io.ktor.client.*
Expand All @@ -26,7 +27,7 @@ suspend fun main() {
}
}
put("bookdata") {
withParsedInput(bookParserPrimitive, jsonHandler) {
withParsedInput(bookParserDataclass, jsonHandler) {
val (bookauthor, booktitle, bookisbn) = it
println("Saving book (data class with primitives) $bookauthor, $booktitle, $bookisbn")
call.respond(HttpStatusCode.Created, "Book created")
Expand Down

0 comments on commit 6e16e1f

Please sign in to comment.