Skip to content

Commit

Permalink
Added min / max length to work on strings?
Browse files Browse the repository at this point in the history
  • Loading branch information
sksamuel committed Dec 30, 2023
1 parent b053e0d commit 775c27d
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.sksamuel.tribune.core.strings

import arrow.core.Either
import arrow.core.leftNel
import arrow.core.right
import com.sksamuel.tribune.core.Parser
Expand Down Expand Up @@ -39,7 +40,28 @@ fun <I, E> Parser<I, String, E>.length(f: (Int) -> Boolean, ifError: (String) ->
flatMap { if (f(it.length)) it.right() else ifError(it).leftNel() }

/**
* Narrows an existing String -> String [Parser] by enforcing a max length on the input string.
* Narrows an existing I -> String? [Parser] by enforcing a max length on the input string.
*
* For strings which have length longer than the given [len] arguments, an invalid is
* returned with the error message generated by [ifError].
*
* @param len the max length, inclusive
* @param ifError the error generating function
*
* @return valid if the input string is less than or equal to [len] or an invalid otherwise.
*/
@JvmName("maxlenOrNull")
fun <I, E> Parser<I, String?, E>.maxlen(len: Int, ifError: (String) -> E): Parser<I, String?, E> =
flatMap {
when {
it == null -> Either.Right(null)
it.length > len -> ifError(it).leftNel()
else -> it.right()
}
}

/**
* Narrows an existing I -> String? [Parser] by enforcing a max length on the input string.
*
* For strings which have length longer than the given [len] arguments, an invalid is
* returned with the error message generated by [ifError].
Expand All @@ -59,7 +81,7 @@ fun <I, E> Parser<I, String, E>.maxlen(len: Int, ifError: (String) -> E): Parser


/**
* Narrows an existing String -> String [Parser] by enforcing a min length on the input string.
* Narrows an existing I -> String [Parser] by enforcing a min length on the input string.
*
* For strings which have length shorter than the given [len] arguments, an invalid is
* returned with the error message generated by [ifError].
Expand All @@ -76,3 +98,24 @@ fun <I, E> Parser<I, String, E>.minlen(len: Int, ifError: (String) -> E): Parser
else -> it.right()
}
}

/**
* Narrows an existing I -> String? [Parser] by enforcing a min length on the input string.
*
* For strings which have length shorter than the given [len] arguments, an invalid is
* returned with the error message generated by [ifError].
*
* @param len the max length, inclusive
* @param ifError the error generating function
*
* @return valid if the input string is greater than or equal to [len] or an invalid otherwise.
*/
@JvmName("minlenOrNull")
fun <I, E> Parser<I, String?, E>.minlen(len: Int, ifError: (String) -> E): Parser<I, String?, E> =
flatMap {
when {
it == null -> Either.Right(null)
it.length < len -> ifError(it).leftNel()
else -> it.right()
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.sksamuel.tribune.core

import arrow.core.Either
import arrow.core.leftNel
import arrow.core.right
import com.sksamuel.tribune.core.strings.length
Expand Down Expand Up @@ -35,11 +36,26 @@ class StringTest : FunSpec() {
p.parse("abcd") shouldBe Foo("abcd").right()
}

test("min length or null") {
val p = Parser<String?>().minlen(4) { "too short" }.mapIfNotNull { Foo(it) }
p.parse("abc") shouldBe "too short".leftNel()
p.parse("abcd") shouldBe Foo("abcd").right()
p.parse(null) shouldBe Either.Right(null)
}

test("max length") {
val p = Parser<String>().maxlen(4) { "too long" }.map { Foo(it) }
val p = Parser<String>().maxlen(4) { "too long" }.notNull { "not null" }.map { Foo(it) }
p.parse("abcde") shouldBe "too long".leftNel()
p.parse("abcd") shouldBe Foo("abcd").right()
p.parse("abc") shouldBe Foo("abc").right()
}

test("max length on nullable string") {
val p = Parser<String?>().maxlen(4) { "too long" }.mapIfNotNull { Foo(it) }
p.parse("abcde") shouldBe "too long".leftNel()
p.parse("abcd") shouldBe Foo("abcd").right()
p.parse("abc") shouldBe Foo("abc").right()
p.parse(null) shouldBe Either.Right(null)
}

test("length") {
Expand Down

0 comments on commit 775c27d

Please sign in to comment.