diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..0e073e6 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: [JunggiKim] diff --git a/CHANGELOG.md b/CHANGELOG.md index bd3ba57..9a40774 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,13 @@ and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.ht ## [Unreleased] +### Added +- `Validation` convenience default methods: `getOrElse`, `getOrNull`, `toOptional`, `onValid`, `onInvalid`, `mapError`, `recover` +- `ofOrElse(value, defaultValue)` static factory on all refined types (numeric, character, string, collection) for safe fallback creation + ### Changed - Downgraded `com.vanniktech.maven.publish` from 0.36.0 to 0.35.0 for Kotlin 1.9.x compatibility +- Kotlin extensions `getOrNull()`, `onValid()`, `onInvalid()` on `Validation` removed in favor of Java default methods with the same signatures ## [1.1.0] - 2026-03-13 diff --git a/README.md b/README.md index 95a31b5..8ec89fd 100644 --- a/README.md +++ b/README.md @@ -38,25 +38,19 @@ Types replace scattered `if`-checks. Invalid data cannot even reach your method. ## Quick Start ```java -import io.github.junggikim.refined.refined.numeric.PositiveInt; -import io.github.junggikim.refined.refined.string.NonBlankString; -import io.github.junggikim.refined.refined.collection.NonEmptyList; -import io.github.junggikim.refined.validation.Validation; -import io.github.junggikim.refined.violation.Violation; -import java.util.Arrays; - -// of() returns Validation — never throws -Validation age = PositiveInt.of(18); -Validation name = NonBlankString.of("Ada"); -Validation> tags = - NonEmptyList.of(Arrays.asList("java", "fp")); // or List.of() on Java 9+ - -// combine results -Validation summary = - name.zip(age, (n, a) -> n.value() + " (" + a.value() + ")"); - -// unsafeOf() throws on invalid input — use at trusted boundaries +// Trusted data — just unwrap PositiveInt confirmedAge = PositiveInt.unsafeOf(18); + +// Untrusted input — safe fallback +PositiveInt safeAge = PositiveInt.ofOrElse(userInput, 1); +``` + +```java +// Branch on success/failure +EmailString.of(email).fold( + error -> badRequest(error.message()), + valid -> ok(register(valid)) +); ``` ## Installation @@ -96,24 +90,42 @@ Optional module with Kotlin-idiomatic extensions: ```kotlin import io.github.junggikim.refined.kotlin.* +// Scalar extensions val name = "Ada".toNonBlankStringOrThrow() val tags = listOf("java", "fp").toNonEmptyListOrThrow() + +// Validation extensions +val age = PositiveInt.ofOrElse(input, 1) +val age = PositiveInt.of(input).getOrNull() ?: PositiveInt.unsafeOf(1) +val result: Result = PositiveInt.of(input).toResult() ``` -## Error Handling +## Usage Patterns -`Validation` is fail-fast — stops at the first error. Use it for single-field validation. -`Validated` accumulates all errors into a list. Use it when you need every failure at once. +```java +// validate and get — most common +PositiveInt age = PositiveInt.ofOrElse(input, 1); +``` ```java -// fail-fast -Validation bad = NonBlankString.of(" "); -String message = bad.fold( - v -> "invalid: " + v.code() + " - " + v.message(), - ok -> "ok: " + ok.value() -); +// to Optional +Optional maybeAge = PositiveInt.of(input).toOptional(); +``` + +```java +// transform error type +Validation mapped = PositiveInt.of(input) + .mapError(Violation::message); +``` -// error-accumulating +```java +// recover from error +Validation recovered = PositiveInt.of(input) + .recover(err -> PositiveInt.unsafeOf(1)); +``` + +```java +// error-accumulating (multiple fields at once) Validated left = Validated.invalid(Arrays.asList("age")); Validated right = Validated.invalid(Arrays.asList("name")); List errors = left.zip(right, Integer::sum).getErrors(); @@ -126,6 +138,7 @@ All refined wrappers follow the same pattern: - `of(value)` — returns `Validation`, never throws - `unsafeOf(value)` — throws `RefinementException` on invalid input +- `ofOrElse(value, default)` — returns validated instance or falls back to `default` - `ofStream(stream)` — collection wrappers only Collection refined types implement JDK interfaces directly — `NonEmptyList` is a `List`, `NonEmptyMap` is a `Map`. No unwrapping needed. diff --git a/java-refined-kotlin/src/main/kotlin/io/github/junggikim/refined/kotlin/ValidationExtensions.kt b/java-refined-kotlin/src/main/kotlin/io/github/junggikim/refined/kotlin/ValidationExtensions.kt index 8aebfef..3fb3e8e 100644 --- a/java-refined-kotlin/src/main/kotlin/io/github/junggikim/refined/kotlin/ValidationExtensions.kt +++ b/java-refined-kotlin/src/main/kotlin/io/github/junggikim/refined/kotlin/ValidationExtensions.kt @@ -5,31 +5,53 @@ import io.github.junggikim.refined.validation.Validated import io.github.junggikim.refined.validation.Validation import io.github.junggikim.refined.violation.Violation -fun Validation.getOrNull(): A? = - if (isValid) get() else null - +// getOrNull(), onValid(), onInvalid(), getOrElse(Function), recover(Function), mapError(Function) +// are now Java default methods on Validation. +// Kotlin callers invoke the Java defaults directly via SAM conversion. +// Only Kotlin-specific extensions (errorOrNull, getOrThrow, getOrDefault, toResult) remain here. + +/** + * Returns the error if invalid, otherwise `null`. + * + * Mirrors `kotlin.Result.exceptionOrNull`. + */ fun Validation.errorOrNull(): E? = if (isInvalid) error else null +/** + * Returns the value if valid, otherwise throws [RefinementException]. + */ fun Validation.getOrThrow(): A = if (isValid) get() else throw RefinementException(error) -fun Validation.onValid(block: (A) -> Unit): Validation { - if (isValid) { - block(get()) - } - return this -} - -fun Validation.onInvalid(block: (E) -> Unit): Validation { - if (isInvalid) { - block(error) - } - return this -} - +/** + * Returns the value if valid, otherwise returns [default]. + * + * Kotlin-idiomatic alias for Java `Validation.getOrElse(A)`. + * Mirrors `kotlin.Result.getOrDefault`. + */ +fun Validation.getOrDefault(default: A): A = + if (isValid) get() else default + +/** + * Converts this Validation to a `kotlin.Result`. + * + * Valid becomes `Result.success`, Invalid becomes `Result.failure` with [RefinementException]. + */ +fun Validation.toResult(): Result = + if (isValid) Result.success(get()) + else Result.failure(RefinementException(error)) + +/** + * Returns the value if valid, otherwise `null`. + * + * Mirrors `kotlin.Result.getOrNull`. + */ fun Validated.valueOrNull(): A? = if (isValid) get() else null +/** + * Returns the error list if invalid, otherwise `null`. + */ fun Validated.errorsOrNull(): List? = if (isInvalid) errors else null diff --git a/java-refined-kotlin/src/test/kotlin/io/github/junggikim/refined/kotlin/ValidationExtensionsTest.kt b/java-refined-kotlin/src/test/kotlin/io/github/junggikim/refined/kotlin/ValidationExtensionsTest.kt new file mode 100644 index 0000000..4ef685a --- /dev/null +++ b/java-refined-kotlin/src/test/kotlin/io/github/junggikim/refined/kotlin/ValidationExtensionsTest.kt @@ -0,0 +1,134 @@ +package io.github.junggikim.refined.kotlin + +import io.github.junggikim.refined.core.RefinementException +import io.github.junggikim.refined.validation.Validation +import io.github.junggikim.refined.violation.Violation +import kotlin.test.assertEquals +import kotlin.test.assertIs +import kotlin.test.assertNull +import kotlin.test.assertFalse +import kotlin.test.assertTrue +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows + +class ValidationExtensionsTest { + + private val violation: Violation = Violation.of("test-error", "test error message") + private val valid: Validation = Validation.valid("hello") + private val invalid: Validation = Validation.invalid(violation) + + // -- errorOrNull (Kotlin extension) -- + + @Test + fun errorOrNullReturnsNullWhenValid() { + assertNull(valid.errorOrNull()) + } + + @Test + fun errorOrNullReturnsErrorWhenInvalid() { + assertEquals("test-error", invalid.errorOrNull()!!.code) + } + + // -- getOrThrow (Kotlin extension) -- + + @Test + fun getOrThrowReturnsValueWhenValid() { + assertEquals("hello", valid.getOrThrow()) + } + + @Test + fun getOrThrowThrowsWhenInvalid() { + val e = assertThrows { invalid.getOrThrow() } + assertEquals("test-error", e.violation().code) + } + + // -- getOrDefault (Kotlin extension) -- + + @Test + fun getOrDefaultReturnsValueWhenValid() { + assertEquals("hello", valid.getOrDefault("fallback")) + } + + @Test + fun getOrDefaultReturnsDefaultWhenInvalid() { + assertEquals("fallback", invalid.getOrDefault("fallback")) + } + + // -- toResult (Kotlin extension) -- + + @Test + fun toResultReturnsSuccessWhenValid() { + val result = valid.toResult() + assertTrue(result.isSuccess) + assertEquals("hello", result.getOrNull()) + } + + @Test + fun toResultReturnsFailureWhenInvalid() { + val result = invalid.toResult() + assertTrue(result.isFailure) + val exception = result.exceptionOrNull() + assertIs(exception) + assertEquals("test-error", exception.violation().code) + } + + // -- Java default methods accessible from Kotlin (smoke tests) -- + + @Test + fun javaGetOrElseValueOverloadWorksFromKotlin() { + assertEquals("hello", valid.getOrElse("fallback")) + assertEquals("fallback", invalid.getOrElse("fallback")) + } + + @Test + fun javaGetOrElseLambdaOverloadWorksFromKotlin() { + assertEquals("hello", valid.getOrElse { "fallback" }) + assertEquals("fallback", invalid.getOrElse { "fallback" }) + } + + @Test + fun javaRecoverWorksFromKotlin() { + assertTrue(valid.recover { "recovered" }.isValid) + val recovered = invalid.recover { "recovered" } + assertTrue(recovered.isValid) + assertEquals("recovered", recovered.get()) + } + + @Test + fun javaMapErrorWorksFromKotlin() { + val passThrough: Validation = valid.mapError { it.code } + assertTrue(passThrough.isValid) + assertEquals("hello", passThrough.get()) + + val mapped: Validation = invalid.mapError { it.code } + assertTrue(mapped.isInvalid) + assertEquals("test-error", mapped.error) + } + + @Test + fun javaOnValidOnInvalidWorksFromKotlin() { + var validSeen = false + var invalidSeen = false + + valid.onValid { validSeen = true }.onInvalid { invalidSeen = true } + assertTrue(validSeen) + assertTrue(!invalidSeen) + + validSeen = false + invalid.onValid { validSeen = true }.onInvalid { invalidSeen = true } + assertTrue(!validSeen) + assertTrue(invalidSeen) + } + + @Test + fun javaGetOrNullWorksFromKotlin() { + assertEquals("hello", valid.getOrNull()) + assertNull(invalid.getOrNull()) + } + + @Test + fun javaToOptionalWorksFromKotlin() { + assertTrue(valid.toOptional().isPresent) + assertFalse(invalid.toOptional().isPresent) + } +} diff --git a/src/main/java/io/github/junggikim/refined/refined/character/DigitChar.java b/src/main/java/io/github/junggikim/refined/refined/character/DigitChar.java index d500d0d..d45654d 100644 --- a/src/main/java/io/github/junggikim/refined/refined/character/DigitChar.java +++ b/src/main/java/io/github/junggikim/refined/refined/character/DigitChar.java @@ -23,4 +23,18 @@ public static Validation of(Character value) { public static DigitChar unsafeOf(Character value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, DigitChar::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static DigitChar ofOrElse(@org.jetbrains.annotations.Nullable Character value, @org.jetbrains.annotations.NotNull Character defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/character/LetterChar.java b/src/main/java/io/github/junggikim/refined/refined/character/LetterChar.java index 44e5f95..788c20f 100644 --- a/src/main/java/io/github/junggikim/refined/refined/character/LetterChar.java +++ b/src/main/java/io/github/junggikim/refined/refined/character/LetterChar.java @@ -23,4 +23,18 @@ public static Validation of(Character value) { public static LetterChar unsafeOf(Character value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, LetterChar::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static LetterChar ofOrElse(@org.jetbrains.annotations.Nullable Character value, @org.jetbrains.annotations.NotNull Character defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/character/LetterOrDigitChar.java b/src/main/java/io/github/junggikim/refined/refined/character/LetterOrDigitChar.java index 1ec5e23..c9c6a4a 100644 --- a/src/main/java/io/github/junggikim/refined/refined/character/LetterOrDigitChar.java +++ b/src/main/java/io/github/junggikim/refined/refined/character/LetterOrDigitChar.java @@ -23,4 +23,18 @@ public static Validation of(Character value) { public static LetterOrDigitChar unsafeOf(Character value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, LetterOrDigitChar::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static LetterOrDigitChar ofOrElse(@org.jetbrains.annotations.Nullable Character value, @org.jetbrains.annotations.NotNull Character defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/character/LowerCaseChar.java b/src/main/java/io/github/junggikim/refined/refined/character/LowerCaseChar.java index a0e6634..55c8c26 100644 --- a/src/main/java/io/github/junggikim/refined/refined/character/LowerCaseChar.java +++ b/src/main/java/io/github/junggikim/refined/refined/character/LowerCaseChar.java @@ -23,4 +23,18 @@ public static Validation of(Character value) { public static LowerCaseChar unsafeOf(Character value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, LowerCaseChar::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static LowerCaseChar ofOrElse(@org.jetbrains.annotations.Nullable Character value, @org.jetbrains.annotations.NotNull Character defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/character/SpecialChar.java b/src/main/java/io/github/junggikim/refined/refined/character/SpecialChar.java index d591d89..437630d 100644 --- a/src/main/java/io/github/junggikim/refined/refined/character/SpecialChar.java +++ b/src/main/java/io/github/junggikim/refined/refined/character/SpecialChar.java @@ -23,4 +23,18 @@ public static Validation of(Character value) { public static SpecialChar unsafeOf(Character value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, SpecialChar::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static SpecialChar ofOrElse(@org.jetbrains.annotations.Nullable Character value, @org.jetbrains.annotations.NotNull Character defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/character/UpperCaseChar.java b/src/main/java/io/github/junggikim/refined/refined/character/UpperCaseChar.java index ad0f6b8..dfef08e 100644 --- a/src/main/java/io/github/junggikim/refined/refined/character/UpperCaseChar.java +++ b/src/main/java/io/github/junggikim/refined/refined/character/UpperCaseChar.java @@ -23,4 +23,18 @@ public static Validation of(Character value) { public static UpperCaseChar unsafeOf(Character value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, UpperCaseChar::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static UpperCaseChar ofOrElse(@org.jetbrains.annotations.Nullable Character value, @org.jetbrains.annotations.NotNull Character defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/character/WhitespaceChar.java b/src/main/java/io/github/junggikim/refined/refined/character/WhitespaceChar.java index 74941f6..b24c196 100644 --- a/src/main/java/io/github/junggikim/refined/refined/character/WhitespaceChar.java +++ b/src/main/java/io/github/junggikim/refined/refined/character/WhitespaceChar.java @@ -23,4 +23,18 @@ public static Validation of(Character value) { public static WhitespaceChar unsafeOf(Character value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, WhitespaceChar::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static WhitespaceChar ofOrElse(@org.jetbrains.annotations.Nullable Character value, @org.jetbrains.annotations.NotNull Character defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyDeque.java b/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyDeque.java index 7c2484c..63d0123 100644 --- a/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyDeque.java +++ b/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyDeque.java @@ -175,6 +175,24 @@ public T pop() { throw new UnsupportedOperationException(); } + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @param element type + * @return refined instance + * @throws RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonEmptyDeque ofOrElse( + @org.jetbrains.annotations.Nullable Deque value, + @org.jetbrains.annotations.NotNull Deque defaultValue + ) { + Validation> result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } + @Override public Iterator descendingIterator() { final ListIterator iterator = elements.listIterator(elements.size()); diff --git a/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyIterable.java b/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyIterable.java index e2c0e8e..ccfee7b 100644 --- a/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyIterable.java +++ b/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyIterable.java @@ -66,4 +66,22 @@ public T head() { public List tail() { return elements.subList(1, elements.size()); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @param element type + * @return refined instance + * @throws RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonEmptyIterable ofOrElse( + @org.jetbrains.annotations.Nullable Iterable value, + @org.jetbrains.annotations.NotNull Iterable defaultValue + ) { + Validation> result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyList.java b/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyList.java index 083f83b..2c8252c 100644 --- a/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyList.java +++ b/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyList.java @@ -66,4 +66,22 @@ public T head() { public List tail() { return elements.subList(1, elements.size()); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @param element type + * @return refined instance + * @throws RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonEmptyList ofOrElse( + @org.jetbrains.annotations.Nullable List value, + @org.jetbrains.annotations.NotNull List defaultValue + ) { + Validation> result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyMap.java b/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyMap.java index c7916ad..8f91a2f 100644 --- a/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyMap.java +++ b/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyMap.java @@ -78,4 +78,23 @@ public boolean containsValue(Object value) { public int size() { return entries.size(); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @param key type + * @param value type + * @return refined instance + * @throws RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonEmptyMap ofOrElse( + @org.jetbrains.annotations.Nullable Map value, + @org.jetbrains.annotations.NotNull Map defaultValue + ) { + Validation> result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyNavigableMap.java b/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyNavigableMap.java index 65c5023..efb075f 100644 --- a/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyNavigableMap.java +++ b/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyNavigableMap.java @@ -235,4 +235,23 @@ public K firstKey() { public K lastKey() { return entries.lastKey(); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @param key type + * @param value type + * @return refined instance + * @throws RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonEmptyNavigableMap ofOrElse( + @org.jetbrains.annotations.Nullable NavigableMap value, + @org.jetbrains.annotations.NotNull NavigableMap defaultValue + ) { + Validation> result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyNavigableSet.java b/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyNavigableSet.java index 9766e1a..2d6008c 100644 --- a/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyNavigableSet.java +++ b/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyNavigableSet.java @@ -180,4 +180,22 @@ public T first() { public T last() { return elements.last(); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @param element type + * @return refined instance + * @throws RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonEmptyNavigableSet ofOrElse( + @org.jetbrains.annotations.Nullable NavigableSet value, + @org.jetbrains.annotations.NotNull NavigableSet defaultValue + ) { + Validation> result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyQueue.java b/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyQueue.java index 9646097..b50e91e 100644 --- a/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyQueue.java +++ b/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptyQueue.java @@ -88,4 +88,22 @@ public T element() { public T last() { return elements.get(elements.size() - 1); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @param element type + * @return refined instance + * @throws RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonEmptyQueue ofOrElse( + @org.jetbrains.annotations.Nullable Queue value, + @org.jetbrains.annotations.NotNull Queue defaultValue + ) { + Validation> result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptySet.java b/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptySet.java index 7bbe2e0..df45887 100644 --- a/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptySet.java +++ b/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptySet.java @@ -64,4 +64,22 @@ public int size() { public boolean contains(Object value) { return elements.contains(value); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @param element type + * @return refined instance + * @throws RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonEmptySet ofOrElse( + @org.jetbrains.annotations.Nullable Set value, + @org.jetbrains.annotations.NotNull Set defaultValue + ) { + Validation> result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptySortedMap.java b/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptySortedMap.java index bdb509f..cb5f70b 100644 --- a/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptySortedMap.java +++ b/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptySortedMap.java @@ -141,4 +141,23 @@ public boolean containsValue(Object value) { public int size() { return entries.size(); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @param key type + * @param value type + * @return refined instance + * @throws RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonEmptySortedMap ofOrElse( + @org.jetbrains.annotations.Nullable SortedMap value, + @org.jetbrains.annotations.NotNull SortedMap defaultValue + ) { + Validation> result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptySortedSet.java b/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptySortedSet.java index 4f50398..de90f30 100644 --- a/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptySortedSet.java +++ b/src/main/java/io/github/junggikim/refined/refined/collection/NonEmptySortedSet.java @@ -123,4 +123,22 @@ public T first() { public T last() { return elements.last(); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @param element type + * @return refined instance + * @throws RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonEmptySortedSet ofOrElse( + @org.jetbrains.annotations.Nullable SortedSet value, + @org.jetbrains.annotations.NotNull SortedSet defaultValue + ) { + Validation> result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/FiniteDouble.java b/src/main/java/io/github/junggikim/refined/refined/numeric/FiniteDouble.java index 62c76cd..3ef7f17 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/FiniteDouble.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/FiniteDouble.java @@ -23,4 +23,18 @@ public static Validation of(Double value) { public static FiniteDouble unsafeOf(Double value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, FiniteDouble::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static FiniteDouble ofOrElse(@org.jetbrains.annotations.Nullable Double value, @org.jetbrains.annotations.NotNull Double defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/FiniteFloat.java b/src/main/java/io/github/junggikim/refined/refined/numeric/FiniteFloat.java index 1b03781..04637e4 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/FiniteFloat.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/FiniteFloat.java @@ -23,4 +23,18 @@ public static Validation of(Float value) { public static FiniteFloat unsafeOf(Float value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, FiniteFloat::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static FiniteFloat ofOrElse(@org.jetbrains.annotations.Nullable Float value, @org.jetbrains.annotations.NotNull Float defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NaturalBigInteger.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NaturalBigInteger.java index 941da87..e4710dc 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NaturalBigInteger.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NaturalBigInteger.java @@ -24,4 +24,18 @@ public static Validation of(BigInteger value) { public static NaturalBigInteger unsafeOf(BigInteger value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NaturalBigInteger::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NaturalBigInteger ofOrElse(@org.jetbrains.annotations.Nullable BigInteger value, @org.jetbrains.annotations.NotNull BigInteger defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NaturalByte.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NaturalByte.java index 622d8f3..7731c66 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NaturalByte.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NaturalByte.java @@ -23,4 +23,18 @@ public static Validation of(Byte value) { public static NaturalByte unsafeOf(Byte value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NaturalByte::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NaturalByte ofOrElse(@org.jetbrains.annotations.Nullable Byte value, @org.jetbrains.annotations.NotNull Byte defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NaturalInt.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NaturalInt.java index 17ffbaf..afa227a 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NaturalInt.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NaturalInt.java @@ -23,4 +23,18 @@ public static Validation of(Integer value) { public static NaturalInt unsafeOf(Integer value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NaturalInt::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NaturalInt ofOrElse(@org.jetbrains.annotations.Nullable Integer value, @org.jetbrains.annotations.NotNull Integer defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NaturalLong.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NaturalLong.java index 383d027..ac5ff5f 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NaturalLong.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NaturalLong.java @@ -23,4 +23,18 @@ public static Validation of(Long value) { public static NaturalLong unsafeOf(Long value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NaturalLong::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NaturalLong ofOrElse(@org.jetbrains.annotations.Nullable Long value, @org.jetbrains.annotations.NotNull Long defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NaturalShort.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NaturalShort.java index 07fde11..f629ce1 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NaturalShort.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NaturalShort.java @@ -23,4 +23,18 @@ public static Validation of(Short value) { public static NaturalShort unsafeOf(Short value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NaturalShort::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NaturalShort ofOrElse(@org.jetbrains.annotations.Nullable Short value, @org.jetbrains.annotations.NotNull Short defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeBigDecimal.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeBigDecimal.java index aaf13d9..1af9f16 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeBigDecimal.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeBigDecimal.java @@ -24,4 +24,18 @@ public static Validation of(BigDecimal value) { public static NegativeBigDecimal unsafeOf(BigDecimal value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NegativeBigDecimal::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NegativeBigDecimal ofOrElse(@org.jetbrains.annotations.Nullable BigDecimal value, @org.jetbrains.annotations.NotNull BigDecimal defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeBigInteger.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeBigInteger.java index 044adc4..614b2e9 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeBigInteger.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeBigInteger.java @@ -24,4 +24,18 @@ public static Validation of(BigInteger value) { public static NegativeBigInteger unsafeOf(BigInteger value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NegativeBigInteger::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NegativeBigInteger ofOrElse(@org.jetbrains.annotations.Nullable BigInteger value, @org.jetbrains.annotations.NotNull BigInteger defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeByte.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeByte.java index 3235b59..1a84d90 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeByte.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeByte.java @@ -23,4 +23,18 @@ public static Validation of(Byte value) { public static NegativeByte unsafeOf(Byte value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NegativeByte::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NegativeByte ofOrElse(@org.jetbrains.annotations.Nullable Byte value, @org.jetbrains.annotations.NotNull Byte defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeDouble.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeDouble.java index 927d7f6..f8327d8 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeDouble.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeDouble.java @@ -23,4 +23,18 @@ public static Validation of(Double value) { public static NegativeDouble unsafeOf(Double value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NegativeDouble::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NegativeDouble ofOrElse(@org.jetbrains.annotations.Nullable Double value, @org.jetbrains.annotations.NotNull Double defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeFloat.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeFloat.java index b701e8e..c8e4db4 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeFloat.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeFloat.java @@ -23,4 +23,18 @@ public static Validation of(Float value) { public static NegativeFloat unsafeOf(Float value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NegativeFloat::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NegativeFloat ofOrElse(@org.jetbrains.annotations.Nullable Float value, @org.jetbrains.annotations.NotNull Float defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeInt.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeInt.java index c1cd672..7d6aa49 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeInt.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeInt.java @@ -23,4 +23,18 @@ public static Validation of(Integer value) { public static NegativeInt unsafeOf(Integer value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NegativeInt::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NegativeInt ofOrElse(@org.jetbrains.annotations.Nullable Integer value, @org.jetbrains.annotations.NotNull Integer defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeLong.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeLong.java index 8ef248c..2b53fb2 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeLong.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeLong.java @@ -23,4 +23,18 @@ public static Validation of(Long value) { public static NegativeLong unsafeOf(Long value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NegativeLong::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NegativeLong ofOrElse(@org.jetbrains.annotations.Nullable Long value, @org.jetbrains.annotations.NotNull Long defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeShort.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeShort.java index ab472a9..f8b7415 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeShort.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NegativeShort.java @@ -23,4 +23,18 @@ public static Validation of(Short value) { public static NegativeShort unsafeOf(Short value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NegativeShort::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NegativeShort ofOrElse(@org.jetbrains.annotations.Nullable Short value, @org.jetbrains.annotations.NotNull Short defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonNaNDouble.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonNaNDouble.java index 25c5460..f6ae161 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonNaNDouble.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonNaNDouble.java @@ -23,4 +23,18 @@ public static Validation of(Double value) { public static NonNaNDouble unsafeOf(Double value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonNaNDouble::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonNaNDouble ofOrElse(@org.jetbrains.annotations.Nullable Double value, @org.jetbrains.annotations.NotNull Double defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonNaNFloat.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonNaNFloat.java index 46f4583..187a6b0 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonNaNFloat.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonNaNFloat.java @@ -23,4 +23,18 @@ public static Validation of(Float value) { public static NonNaNFloat unsafeOf(Float value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonNaNFloat::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonNaNFloat ofOrElse(@org.jetbrains.annotations.Nullable Float value, @org.jetbrains.annotations.NotNull Float defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeBigDecimal.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeBigDecimal.java index 0567bc6..1898181 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeBigDecimal.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeBigDecimal.java @@ -24,4 +24,18 @@ public static Validation of(BigDecimal value) public static NonNegativeBigDecimal unsafeOf(BigDecimal value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonNegativeBigDecimal::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonNegativeBigDecimal ofOrElse(@org.jetbrains.annotations.Nullable BigDecimal value, @org.jetbrains.annotations.NotNull BigDecimal defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeBigInteger.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeBigInteger.java index 4f93c84..14382f0 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeBigInteger.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeBigInteger.java @@ -24,4 +24,18 @@ public static Validation of(BigInteger value) public static NonNegativeBigInteger unsafeOf(BigInteger value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonNegativeBigInteger::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonNegativeBigInteger ofOrElse(@org.jetbrains.annotations.Nullable BigInteger value, @org.jetbrains.annotations.NotNull BigInteger defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeByte.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeByte.java index 4f075c3..7ea204f 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeByte.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeByte.java @@ -23,4 +23,18 @@ public static Validation of(Byte value) { public static NonNegativeByte unsafeOf(Byte value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonNegativeByte::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonNegativeByte ofOrElse(@org.jetbrains.annotations.Nullable Byte value, @org.jetbrains.annotations.NotNull Byte defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeDouble.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeDouble.java index 6831a6f..e6ef6d8 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeDouble.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeDouble.java @@ -23,4 +23,18 @@ public static Validation of(Double value) { public static NonNegativeDouble unsafeOf(Double value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonNegativeDouble::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonNegativeDouble ofOrElse(@org.jetbrains.annotations.Nullable Double value, @org.jetbrains.annotations.NotNull Double defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeFloat.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeFloat.java index dda28c7..33a1928 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeFloat.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeFloat.java @@ -23,4 +23,18 @@ public static Validation of(Float value) { public static NonNegativeFloat unsafeOf(Float value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonNegativeFloat::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonNegativeFloat ofOrElse(@org.jetbrains.annotations.Nullable Float value, @org.jetbrains.annotations.NotNull Float defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeInt.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeInt.java index bd406aa..a116c05 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeInt.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeInt.java @@ -23,4 +23,18 @@ public static Validation of(Integer value) { public static NonNegativeInt unsafeOf(Integer value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonNegativeInt::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonNegativeInt ofOrElse(@org.jetbrains.annotations.Nullable Integer value, @org.jetbrains.annotations.NotNull Integer defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeLong.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeLong.java index 63ab86b..16fb8a4 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeLong.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeLong.java @@ -23,4 +23,18 @@ public static Validation of(Long value) { public static NonNegativeLong unsafeOf(Long value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonNegativeLong::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonNegativeLong ofOrElse(@org.jetbrains.annotations.Nullable Long value, @org.jetbrains.annotations.NotNull Long defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeShort.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeShort.java index c15540f..cf489a2 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeShort.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonNegativeShort.java @@ -23,4 +23,18 @@ public static Validation of(Short value) { public static NonNegativeShort unsafeOf(Short value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonNegativeShort::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonNegativeShort ofOrElse(@org.jetbrains.annotations.Nullable Short value, @org.jetbrains.annotations.NotNull Short defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveBigDecimal.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveBigDecimal.java index 4d42c5b..0ef513c 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveBigDecimal.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveBigDecimal.java @@ -24,4 +24,18 @@ public static Validation of(BigDecimal value) public static NonPositiveBigDecimal unsafeOf(BigDecimal value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonPositiveBigDecimal::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonPositiveBigDecimal ofOrElse(@org.jetbrains.annotations.Nullable BigDecimal value, @org.jetbrains.annotations.NotNull BigDecimal defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveBigInteger.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveBigInteger.java index b72cbc4..7089c4a 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveBigInteger.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveBigInteger.java @@ -24,4 +24,18 @@ public static Validation of(BigInteger value) public static NonPositiveBigInteger unsafeOf(BigInteger value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonPositiveBigInteger::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonPositiveBigInteger ofOrElse(@org.jetbrains.annotations.Nullable BigInteger value, @org.jetbrains.annotations.NotNull BigInteger defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveByte.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveByte.java index 4c2d50c..0006bbf 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveByte.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveByte.java @@ -23,4 +23,18 @@ public static Validation of(Byte value) { public static NonPositiveByte unsafeOf(Byte value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonPositiveByte::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonPositiveByte ofOrElse(@org.jetbrains.annotations.Nullable Byte value, @org.jetbrains.annotations.NotNull Byte defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveDouble.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveDouble.java index 90f4391..2ac745d 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveDouble.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveDouble.java @@ -23,4 +23,18 @@ public static Validation of(Double value) { public static NonPositiveDouble unsafeOf(Double value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonPositiveDouble::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonPositiveDouble ofOrElse(@org.jetbrains.annotations.Nullable Double value, @org.jetbrains.annotations.NotNull Double defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveFloat.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveFloat.java index 18fdaae..9f3c53e 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveFloat.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveFloat.java @@ -23,4 +23,18 @@ public static Validation of(Float value) { public static NonPositiveFloat unsafeOf(Float value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonPositiveFloat::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonPositiveFloat ofOrElse(@org.jetbrains.annotations.Nullable Float value, @org.jetbrains.annotations.NotNull Float defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveInt.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveInt.java index f79044b..35d18f7 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveInt.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveInt.java @@ -23,4 +23,18 @@ public static Validation of(Integer value) { public static NonPositiveInt unsafeOf(Integer value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonPositiveInt::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonPositiveInt ofOrElse(@org.jetbrains.annotations.Nullable Integer value, @org.jetbrains.annotations.NotNull Integer defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveLong.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveLong.java index e0f23ee..de4b66f 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveLong.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveLong.java @@ -23,4 +23,18 @@ public static Validation of(Long value) { public static NonPositiveLong unsafeOf(Long value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonPositiveLong::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonPositiveLong ofOrElse(@org.jetbrains.annotations.Nullable Long value, @org.jetbrains.annotations.NotNull Long defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveShort.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveShort.java index e4613e6..2d74b9e 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveShort.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonPositiveShort.java @@ -23,4 +23,18 @@ public static Validation of(Short value) { public static NonPositiveShort unsafeOf(Short value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonPositiveShort::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonPositiveShort ofOrElse(@org.jetbrains.annotations.Nullable Short value, @org.jetbrains.annotations.NotNull Short defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroBigDecimal.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroBigDecimal.java index 92a220c..dbaeb27 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroBigDecimal.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroBigDecimal.java @@ -24,4 +24,18 @@ public static Validation of(BigDecimal value) { public static NonZeroBigDecimal unsafeOf(BigDecimal value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonZeroBigDecimal::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonZeroBigDecimal ofOrElse(@org.jetbrains.annotations.Nullable BigDecimal value, @org.jetbrains.annotations.NotNull BigDecimal defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroBigInteger.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroBigInteger.java index 3bc58b9..9251ea0 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroBigInteger.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroBigInteger.java @@ -24,4 +24,18 @@ public static Validation of(BigInteger value) { public static NonZeroBigInteger unsafeOf(BigInteger value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonZeroBigInteger::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonZeroBigInteger ofOrElse(@org.jetbrains.annotations.Nullable BigInteger value, @org.jetbrains.annotations.NotNull BigInteger defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroByte.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroByte.java index f4500a5..381076f 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroByte.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroByte.java @@ -23,4 +23,18 @@ public static Validation of(Byte value) { public static NonZeroByte unsafeOf(Byte value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonZeroByte::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonZeroByte ofOrElse(@org.jetbrains.annotations.Nullable Byte value, @org.jetbrains.annotations.NotNull Byte defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroDouble.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroDouble.java index ffc9c72..1355090 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroDouble.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroDouble.java @@ -23,4 +23,18 @@ public static Validation of(Double value) { public static NonZeroDouble unsafeOf(Double value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonZeroDouble::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonZeroDouble ofOrElse(@org.jetbrains.annotations.Nullable Double value, @org.jetbrains.annotations.NotNull Double defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroFloat.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroFloat.java index 8cddbd9..99eccc6 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroFloat.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroFloat.java @@ -23,4 +23,18 @@ public static Validation of(Float value) { public static NonZeroFloat unsafeOf(Float value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonZeroFloat::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonZeroFloat ofOrElse(@org.jetbrains.annotations.Nullable Float value, @org.jetbrains.annotations.NotNull Float defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroInt.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroInt.java index c2aa56c..b6925a2 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroInt.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroInt.java @@ -23,4 +23,18 @@ public static Validation of(Integer value) { public static NonZeroInt unsafeOf(Integer value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonZeroInt::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonZeroInt ofOrElse(@org.jetbrains.annotations.Nullable Integer value, @org.jetbrains.annotations.NotNull Integer defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroLong.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroLong.java index 57b75d9..8a1248f 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroLong.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroLong.java @@ -23,4 +23,18 @@ public static Validation of(Long value) { public static NonZeroLong unsafeOf(Long value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonZeroLong::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonZeroLong ofOrElse(@org.jetbrains.annotations.Nullable Long value, @org.jetbrains.annotations.NotNull Long defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroShort.java b/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroShort.java index d22e176..99cef64 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroShort.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/NonZeroShort.java @@ -23,4 +23,18 @@ public static Validation of(Short value) { public static NonZeroShort unsafeOf(Short value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonZeroShort::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonZeroShort ofOrElse(@org.jetbrains.annotations.Nullable Short value, @org.jetbrains.annotations.NotNull Short defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveBigDecimal.java b/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveBigDecimal.java index 43f2707..96241e0 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveBigDecimal.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveBigDecimal.java @@ -24,4 +24,18 @@ public static Validation of(BigDecimal value) { public static PositiveBigDecimal unsafeOf(BigDecimal value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, PositiveBigDecimal::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static PositiveBigDecimal ofOrElse(@org.jetbrains.annotations.Nullable BigDecimal value, @org.jetbrains.annotations.NotNull BigDecimal defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveBigInteger.java b/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveBigInteger.java index 145c80f..d358d36 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveBigInteger.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveBigInteger.java @@ -24,4 +24,18 @@ public static Validation of(BigInteger value) { public static PositiveBigInteger unsafeOf(BigInteger value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, PositiveBigInteger::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static PositiveBigInteger ofOrElse(@org.jetbrains.annotations.Nullable BigInteger value, @org.jetbrains.annotations.NotNull BigInteger defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveByte.java b/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveByte.java index b6fd5c9..24a42d0 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveByte.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveByte.java @@ -23,4 +23,18 @@ public static Validation of(Byte value) { public static PositiveByte unsafeOf(Byte value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, PositiveByte::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static PositiveByte ofOrElse(@org.jetbrains.annotations.Nullable Byte value, @org.jetbrains.annotations.NotNull Byte defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveDouble.java b/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveDouble.java index 34f2456..012a5b4 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveDouble.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveDouble.java @@ -23,4 +23,18 @@ public static Validation of(Double value) { public static PositiveDouble unsafeOf(Double value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, PositiveDouble::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static PositiveDouble ofOrElse(@org.jetbrains.annotations.Nullable Double value, @org.jetbrains.annotations.NotNull Double defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveFloat.java b/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveFloat.java index e30223c..a362d3c 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveFloat.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveFloat.java @@ -23,4 +23,18 @@ public static Validation of(Float value) { public static PositiveFloat unsafeOf(Float value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, PositiveFloat::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static PositiveFloat ofOrElse(@org.jetbrains.annotations.Nullable Float value, @org.jetbrains.annotations.NotNull Float defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveInt.java b/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveInt.java index 39cfc93..ebc39b8 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveInt.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveInt.java @@ -23,4 +23,18 @@ public static Validation of(Integer value) { public static PositiveInt unsafeOf(Integer value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, PositiveInt::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static PositiveInt ofOrElse(@org.jetbrains.annotations.Nullable Integer value, @org.jetbrains.annotations.NotNull Integer defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveLong.java b/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveLong.java index b2c0ce5..6fe648d 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveLong.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveLong.java @@ -23,4 +23,18 @@ public static Validation of(Long value) { public static PositiveLong unsafeOf(Long value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, PositiveLong::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static PositiveLong ofOrElse(@org.jetbrains.annotations.Nullable Long value, @org.jetbrains.annotations.NotNull Long defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveShort.java b/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveShort.java index 4e77e3c..2b35586 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveShort.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/PositiveShort.java @@ -23,4 +23,18 @@ public static Validation of(Short value) { public static PositiveShort unsafeOf(Short value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, PositiveShort::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static PositiveShort ofOrElse(@org.jetbrains.annotations.Nullable Short value, @org.jetbrains.annotations.NotNull Short defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/ZeroToOneDouble.java b/src/main/java/io/github/junggikim/refined/refined/numeric/ZeroToOneDouble.java index ab9fda2..08b683d 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/ZeroToOneDouble.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/ZeroToOneDouble.java @@ -23,4 +23,18 @@ public static Validation of(Double value) { public static ZeroToOneDouble unsafeOf(Double value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, ZeroToOneDouble::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static ZeroToOneDouble ofOrElse(@org.jetbrains.annotations.Nullable Double value, @org.jetbrains.annotations.NotNull Double defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/numeric/ZeroToOneFloat.java b/src/main/java/io/github/junggikim/refined/refined/numeric/ZeroToOneFloat.java index 9cdef31..bfcca32 100644 --- a/src/main/java/io/github/junggikim/refined/refined/numeric/ZeroToOneFloat.java +++ b/src/main/java/io/github/junggikim/refined/refined/numeric/ZeroToOneFloat.java @@ -23,4 +23,18 @@ public static Validation of(Float value) { public static ZeroToOneFloat unsafeOf(Float value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, ZeroToOneFloat::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static ZeroToOneFloat ofOrElse(@org.jetbrains.annotations.Nullable Float value, @org.jetbrains.annotations.NotNull Float defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/AlphabeticString.java b/src/main/java/io/github/junggikim/refined/refined/string/AlphabeticString.java index f8f5fea..25a4469 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/AlphabeticString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/AlphabeticString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static AlphabeticString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, AlphabeticString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static AlphabeticString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/AlphanumericString.java b/src/main/java/io/github/junggikim/refined/refined/string/AlphanumericString.java index 7425252..48be626 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/AlphanumericString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/AlphanumericString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static AlphanumericString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, AlphanumericString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static AlphanumericString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/AsciiString.java b/src/main/java/io/github/junggikim/refined/refined/string/AsciiString.java index f06d72f..48471a1 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/AsciiString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/AsciiString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static AsciiString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, AsciiString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static AsciiString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/Base64String.java b/src/main/java/io/github/junggikim/refined/refined/string/Base64String.java index a23c96c..78bb733 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/Base64String.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/Base64String.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static Base64String unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, Base64String::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static Base64String ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/Base64UrlString.java b/src/main/java/io/github/junggikim/refined/refined/string/Base64UrlString.java index b00fc3c..09702bc 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/Base64UrlString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/Base64UrlString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static Base64UrlString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, Base64UrlString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static Base64UrlString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/CidrV4String.java b/src/main/java/io/github/junggikim/refined/refined/string/CidrV4String.java index d1626d5..af4ede0 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/CidrV4String.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/CidrV4String.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static CidrV4String unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, CidrV4String::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static CidrV4String ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/CidrV6String.java b/src/main/java/io/github/junggikim/refined/refined/string/CidrV6String.java index e47bebe..047ca0c 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/CidrV6String.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/CidrV6String.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static CidrV6String unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, CidrV6String::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static CidrV6String ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/CreditCardString.java b/src/main/java/io/github/junggikim/refined/refined/string/CreditCardString.java index 320be68..4bfc75d 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/CreditCardString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/CreditCardString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static CreditCardString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, CreditCardString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static CreditCardString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/EmailString.java b/src/main/java/io/github/junggikim/refined/refined/string/EmailString.java index fbce633..5d0b8fa 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/EmailString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/EmailString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static EmailString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, EmailString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static EmailString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/HexColorString.java b/src/main/java/io/github/junggikim/refined/refined/string/HexColorString.java index c3484a8..166c546 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/HexColorString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/HexColorString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static HexColorString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, HexColorString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static HexColorString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/HexString.java b/src/main/java/io/github/junggikim/refined/refined/string/HexString.java index 7c28649..5615176 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/HexString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/HexString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static HexString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, HexString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static HexString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/HostnameString.java b/src/main/java/io/github/junggikim/refined/refined/string/HostnameString.java index d3854be..e9f5763 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/HostnameString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/HostnameString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static HostnameString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, HostnameString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static HostnameString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/Ipv4String.java b/src/main/java/io/github/junggikim/refined/refined/string/Ipv4String.java index 31fc99c..2ea517f 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/Ipv4String.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/Ipv4String.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static Ipv4String unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, Ipv4String::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static Ipv4String ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/Ipv6String.java b/src/main/java/io/github/junggikim/refined/refined/string/Ipv6String.java index f06a24f..c70dfb6 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/Ipv6String.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/Ipv6String.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static Ipv6String unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, Ipv6String::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static Ipv6String ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/IsbnString.java b/src/main/java/io/github/junggikim/refined/refined/string/IsbnString.java index a3cc4ec..770195e 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/IsbnString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/IsbnString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static IsbnString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, IsbnString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static IsbnString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/Iso8601DateString.java b/src/main/java/io/github/junggikim/refined/refined/string/Iso8601DateString.java index 4a6f702..e87bcd2 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/Iso8601DateString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/Iso8601DateString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static Iso8601DateString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, Iso8601DateString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static Iso8601DateString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/Iso8601DateTimeString.java b/src/main/java/io/github/junggikim/refined/refined/string/Iso8601DateTimeString.java index f3a5ca0..5bdb5f5 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/Iso8601DateTimeString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/Iso8601DateTimeString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static Iso8601DateTimeString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, Iso8601DateTimeString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static Iso8601DateTimeString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/Iso8601DurationString.java b/src/main/java/io/github/junggikim/refined/refined/string/Iso8601DurationString.java index 9e9247e..7cf0459 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/Iso8601DurationString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/Iso8601DurationString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static Iso8601DurationString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, Iso8601DurationString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static Iso8601DurationString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/Iso8601PeriodString.java b/src/main/java/io/github/junggikim/refined/refined/string/Iso8601PeriodString.java index e3eec9a..1e0380e 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/Iso8601PeriodString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/Iso8601PeriodString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static Iso8601PeriodString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, Iso8601PeriodString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static Iso8601PeriodString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/Iso8601TimeString.java b/src/main/java/io/github/junggikim/refined/refined/string/Iso8601TimeString.java index 008ea4f..f431264 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/Iso8601TimeString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/Iso8601TimeString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static Iso8601TimeString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, Iso8601TimeString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static Iso8601TimeString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/JsonString.java b/src/main/java/io/github/junggikim/refined/refined/string/JsonString.java index 91e24ac..28ae0cc 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/JsonString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/JsonString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static JsonString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, JsonString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static JsonString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/JwtString.java b/src/main/java/io/github/junggikim/refined/refined/string/JwtString.java index 35c94ed..e6dbf4d 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/JwtString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/JwtString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static JwtString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, JwtString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static JwtString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/LowerCaseString.java b/src/main/java/io/github/junggikim/refined/refined/string/LowerCaseString.java index 071b36d..a1b61a3 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/LowerCaseString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/LowerCaseString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static LowerCaseString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, LowerCaseString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static LowerCaseString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/MacAddressString.java b/src/main/java/io/github/junggikim/refined/refined/string/MacAddressString.java index 5c7e8cb..67bb62d 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/MacAddressString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/MacAddressString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static MacAddressString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, MacAddressString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static MacAddressString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/NonBlankString.java b/src/main/java/io/github/junggikim/refined/refined/string/NonBlankString.java index b2fb22a..3faf965 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/NonBlankString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/NonBlankString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static NonBlankString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonBlankString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonBlankString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/NonEmptyString.java b/src/main/java/io/github/junggikim/refined/refined/string/NonEmptyString.java index 60a363b..c41513b 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/NonEmptyString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/NonEmptyString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static NonEmptyString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NonEmptyString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NonEmptyString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/NumericString.java b/src/main/java/io/github/junggikim/refined/refined/string/NumericString.java index 9682c05..0d32afb 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/NumericString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/NumericString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static NumericString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, NumericString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static NumericString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/RegexString.java b/src/main/java/io/github/junggikim/refined/refined/string/RegexString.java index f3d36a3..a08ebf1 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/RegexString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/RegexString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static RegexString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, RegexString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static RegexString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/SemVerString.java b/src/main/java/io/github/junggikim/refined/refined/string/SemVerString.java index b41c687..7b32209 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/SemVerString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/SemVerString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static SemVerString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, SemVerString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static SemVerString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/SlugString.java b/src/main/java/io/github/junggikim/refined/refined/string/SlugString.java index 790941d..17e49d0 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/SlugString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/SlugString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static SlugString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, SlugString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static SlugString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/TimeZoneIdString.java b/src/main/java/io/github/junggikim/refined/refined/string/TimeZoneIdString.java index 959aaf8..783c386 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/TimeZoneIdString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/TimeZoneIdString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static TimeZoneIdString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, TimeZoneIdString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static TimeZoneIdString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/TrimmedString.java b/src/main/java/io/github/junggikim/refined/refined/string/TrimmedString.java index f886e13..88eb8fb 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/TrimmedString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/TrimmedString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static TrimmedString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, TrimmedString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static TrimmedString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/UlidString.java b/src/main/java/io/github/junggikim/refined/refined/string/UlidString.java index b05c6d7..9440160 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/UlidString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/UlidString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static UlidString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, UlidString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static UlidString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/UpperCaseString.java b/src/main/java/io/github/junggikim/refined/refined/string/UpperCaseString.java index 413005a..ac8a970 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/UpperCaseString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/UpperCaseString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static UpperCaseString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, UpperCaseString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static UpperCaseString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/UriString.java b/src/main/java/io/github/junggikim/refined/refined/string/UriString.java index 5a4821a..6241b00 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/UriString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/UriString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static UriString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, UriString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static UriString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/UrlString.java b/src/main/java/io/github/junggikim/refined/refined/string/UrlString.java index 672dba2..0e49ee0 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/UrlString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/UrlString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static UrlString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, UrlString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static UrlString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/UuidString.java b/src/main/java/io/github/junggikim/refined/refined/string/UuidString.java index c00931d..971553b 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/UuidString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/UuidString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static UuidString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, UuidString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static UuidString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/ValidBigDecimalString.java b/src/main/java/io/github/junggikim/refined/refined/string/ValidBigDecimalString.java index 812fe9a..aa05856 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/ValidBigDecimalString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/ValidBigDecimalString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static ValidBigDecimalString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, ValidBigDecimalString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static ValidBigDecimalString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/ValidBigIntegerString.java b/src/main/java/io/github/junggikim/refined/refined/string/ValidBigIntegerString.java index b482eee..bcec8f9 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/ValidBigIntegerString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/ValidBigIntegerString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static ValidBigIntegerString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, ValidBigIntegerString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static ValidBigIntegerString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/ValidByteString.java b/src/main/java/io/github/junggikim/refined/refined/string/ValidByteString.java index 3d82d9e..ce217f4 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/ValidByteString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/ValidByteString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static ValidByteString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, ValidByteString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static ValidByteString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/ValidDoubleString.java b/src/main/java/io/github/junggikim/refined/refined/string/ValidDoubleString.java index 0da303c..5d14153 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/ValidDoubleString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/ValidDoubleString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static ValidDoubleString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, ValidDoubleString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static ValidDoubleString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/ValidFloatString.java b/src/main/java/io/github/junggikim/refined/refined/string/ValidFloatString.java index 59b6aa3..386574c 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/ValidFloatString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/ValidFloatString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static ValidFloatString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, ValidFloatString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static ValidFloatString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/ValidIntString.java b/src/main/java/io/github/junggikim/refined/refined/string/ValidIntString.java index 51e253a..7b649de 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/ValidIntString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/ValidIntString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static ValidIntString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, ValidIntString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static ValidIntString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/ValidLongString.java b/src/main/java/io/github/junggikim/refined/refined/string/ValidLongString.java index 5265d23..b3c7371 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/ValidLongString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/ValidLongString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static ValidLongString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, ValidLongString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static ValidLongString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/ValidShortString.java b/src/main/java/io/github/junggikim/refined/refined/string/ValidShortString.java index 8ce95b7..d12c536 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/ValidShortString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/ValidShortString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static ValidShortString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, ValidShortString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static ValidShortString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/XPathString.java b/src/main/java/io/github/junggikim/refined/refined/string/XPathString.java index 335a426..60f2dc9 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/XPathString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/XPathString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static XPathString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, XPathString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static XPathString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/refined/string/XmlString.java b/src/main/java/io/github/junggikim/refined/refined/string/XmlString.java index 323d18d..d222edd 100644 --- a/src/main/java/io/github/junggikim/refined/refined/string/XmlString.java +++ b/src/main/java/io/github/junggikim/refined/refined/string/XmlString.java @@ -23,4 +23,18 @@ public static Validation of(String value) { public static XmlString unsafeOf(String value) { return RefinedSupport.unsafeRefine(value, CONSTRAINT, XmlString::new); } + + /** + * Returns a validated instance, or falls back to {@code defaultValue} if invalid. + * + * @param value input to validate + * @param defaultValue fallback (must itself be valid) + * @return refined instance + * @throws io.github.junggikim.refined.core.RefinementException if defaultValue is also invalid + */ + @org.jetbrains.annotations.NotNull + public static XmlString ofOrElse(@org.jetbrains.annotations.Nullable String value, @org.jetbrains.annotations.NotNull String defaultValue) { + Validation result = of(value); + return result.isValid() ? result.get() : unsafeOf(defaultValue); + } } diff --git a/src/main/java/io/github/junggikim/refined/validation/Validation.java b/src/main/java/io/github/junggikim/refined/validation/Validation.java index 33c3e3e..b6ee898 100644 --- a/src/main/java/io/github/junggikim/refined/validation/Validation.java +++ b/src/main/java/io/github/junggikim/refined/validation/Validation.java @@ -1,9 +1,12 @@ package io.github.junggikim.refined.validation; import java.util.Objects; +import java.util.Optional; import java.util.function.BiFunction; +import java.util.function.Consumer; import java.util.function.Function; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * Fail-fast validation result used by refined constructors and low-level constraints. @@ -122,6 +125,105 @@ default Validation zip( @NotNull E getError(); + /** + * Returns the value if valid, otherwise returns {@code other}. + * + * @param other fallback value + * @return validated value or {@code other} + */ + @NotNull + default A getOrElse(@NotNull A other) { + Objects.requireNonNull(other, "other"); + return isValid() ? get() : other; + } + + /** + * Returns the value if valid, otherwise computes a fallback from the error. + * + * @param handler function that converts the error into a fallback value + * @return validated value or handler result + */ + @NotNull + default A getOrElse(@NotNull Function handler) { + Objects.requireNonNull(handler, "handler"); + return isValid() ? get() : Objects.requireNonNull(handler.apply(getError()), "handler result"); + } + + /** + * Returns the value if valid, otherwise {@code null}. + * + * @return validated value or {@code null} + */ + @Nullable + default A getOrNull() { + return isValid() ? get() : null; + } + + /** + * Returns an {@link Optional} containing the value if valid, or empty. + * + * @return optional of the validated value + */ + @NotNull + default Optional toOptional() { + return isValid() ? Optional.of(get()) : Optional.empty(); + } + + /** + * Executes the given action when this result is valid and returns {@code this} for chaining. + * + * @param action side-effect to run on the success value + * @return this validation + */ + @NotNull + default Validation onValid(@NotNull Consumer action) { + Objects.requireNonNull(action, "action"); + if (isValid()) { + action.accept(get()); + } + return this; + } + + /** + * Executes the given action when this result is invalid and returns {@code this} for chaining. + * + * @param action side-effect to run on the error + * @return this validation + */ + @NotNull + default Validation onInvalid(@NotNull Consumer action) { + Objects.requireNonNull(action, "action"); + if (isInvalid()) { + action.accept(getError()); + } + return this; + } + + /** + * Maps the error when invalid, passes through when valid. + * + * @param f error mapping function + * @param new error type + * @return mapped validation + */ + @NotNull + default Validation mapError(@NotNull Function f) { + Objects.requireNonNull(f, "f"); + return isValid() ? valid(get()) : invalid(f.apply(getError())); + } + + /** + * Recovers from an error by converting it to a success value. + * + * @param f recovery function + * @return this if valid, otherwise a valid result from {@code f} + */ + @NotNull + default Validation recover(@NotNull Function f) { + Objects.requireNonNull(f, "f"); + return isValid() ? this : valid(f.apply(getError())); + } + final class Valid implements Validation { private final A value; diff --git a/src/test/java/io/github/junggikim/refined/refined/OfOrElseCoverageTest.java b/src/test/java/io/github/junggikim/refined/refined/OfOrElseCoverageTest.java new file mode 100644 index 0000000..2a00ac1 --- /dev/null +++ b/src/test/java/io/github/junggikim/refined/refined/OfOrElseCoverageTest.java @@ -0,0 +1,358 @@ +package io.github.junggikim.refined.refined; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import io.github.junggikim.refined.refined.character.DigitChar; +import io.github.junggikim.refined.refined.character.LetterChar; +import io.github.junggikim.refined.refined.character.LetterOrDigitChar; +import io.github.junggikim.refined.refined.character.LowerCaseChar; +import io.github.junggikim.refined.refined.character.SpecialChar; +import io.github.junggikim.refined.refined.character.UpperCaseChar; +import io.github.junggikim.refined.refined.character.WhitespaceChar; +import io.github.junggikim.refined.refined.numeric.FiniteDouble; +import io.github.junggikim.refined.refined.numeric.FiniteFloat; +import io.github.junggikim.refined.refined.numeric.NaturalBigInteger; +import io.github.junggikim.refined.refined.numeric.NaturalByte; +import io.github.junggikim.refined.refined.numeric.NaturalInt; +import io.github.junggikim.refined.refined.numeric.NaturalLong; +import io.github.junggikim.refined.refined.numeric.NaturalShort; +import io.github.junggikim.refined.refined.numeric.NegativeBigDecimal; +import io.github.junggikim.refined.refined.numeric.NegativeBigInteger; +import io.github.junggikim.refined.refined.numeric.NegativeByte; +import io.github.junggikim.refined.refined.numeric.NegativeDouble; +import io.github.junggikim.refined.refined.numeric.NegativeFloat; +import io.github.junggikim.refined.refined.numeric.NegativeInt; +import io.github.junggikim.refined.refined.numeric.NegativeLong; +import io.github.junggikim.refined.refined.numeric.NegativeShort; +import io.github.junggikim.refined.refined.numeric.NonNaNDouble; +import io.github.junggikim.refined.refined.numeric.NonNaNFloat; +import io.github.junggikim.refined.refined.numeric.NonNegativeBigDecimal; +import io.github.junggikim.refined.refined.numeric.NonNegativeBigInteger; +import io.github.junggikim.refined.refined.numeric.NonNegativeByte; +import io.github.junggikim.refined.refined.numeric.NonNegativeDouble; +import io.github.junggikim.refined.refined.numeric.NonNegativeFloat; +import io.github.junggikim.refined.refined.numeric.NonNegativeInt; +import io.github.junggikim.refined.refined.numeric.NonNegativeLong; +import io.github.junggikim.refined.refined.numeric.NonNegativeShort; +import io.github.junggikim.refined.refined.numeric.NonPositiveBigDecimal; +import io.github.junggikim.refined.refined.numeric.NonPositiveBigInteger; +import io.github.junggikim.refined.refined.numeric.NonPositiveByte; +import io.github.junggikim.refined.refined.numeric.NonPositiveDouble; +import io.github.junggikim.refined.refined.numeric.NonPositiveFloat; +import io.github.junggikim.refined.refined.numeric.NonPositiveInt; +import io.github.junggikim.refined.refined.numeric.NonPositiveLong; +import io.github.junggikim.refined.refined.numeric.NonPositiveShort; +import io.github.junggikim.refined.refined.numeric.NonZeroBigDecimal; +import io.github.junggikim.refined.refined.numeric.NonZeroBigInteger; +import io.github.junggikim.refined.refined.numeric.NonZeroByte; +import io.github.junggikim.refined.refined.numeric.NonZeroDouble; +import io.github.junggikim.refined.refined.numeric.NonZeroFloat; +import io.github.junggikim.refined.refined.numeric.NonZeroInt; +import io.github.junggikim.refined.refined.numeric.NonZeroLong; +import io.github.junggikim.refined.refined.numeric.NonZeroShort; +import io.github.junggikim.refined.refined.numeric.PositiveBigDecimal; +import io.github.junggikim.refined.refined.numeric.PositiveBigInteger; +import io.github.junggikim.refined.refined.numeric.PositiveByte; +import io.github.junggikim.refined.refined.numeric.PositiveDouble; +import io.github.junggikim.refined.refined.numeric.PositiveFloat; +import io.github.junggikim.refined.refined.numeric.PositiveInt; +import io.github.junggikim.refined.refined.numeric.PositiveLong; +import io.github.junggikim.refined.refined.numeric.PositiveShort; +import io.github.junggikim.refined.refined.numeric.ZeroToOneDouble; +import io.github.junggikim.refined.refined.numeric.ZeroToOneFloat; +import io.github.junggikim.refined.refined.string.AlphabeticString; +import io.github.junggikim.refined.refined.string.AlphanumericString; +import io.github.junggikim.refined.refined.string.AsciiString; +import io.github.junggikim.refined.refined.string.Base64String; +import io.github.junggikim.refined.refined.string.Base64UrlString; +import io.github.junggikim.refined.refined.string.CidrV4String; +import io.github.junggikim.refined.refined.string.CidrV6String; +import io.github.junggikim.refined.refined.string.CreditCardString; +import io.github.junggikim.refined.refined.string.EmailString; +import io.github.junggikim.refined.refined.string.HexColorString; +import io.github.junggikim.refined.refined.string.HexString; +import io.github.junggikim.refined.refined.string.HostnameString; +import io.github.junggikim.refined.refined.string.Ipv4String; +import io.github.junggikim.refined.refined.string.Ipv6String; +import io.github.junggikim.refined.refined.string.IsbnString; +import io.github.junggikim.refined.refined.string.Iso8601DateString; +import io.github.junggikim.refined.refined.string.Iso8601DateTimeString; +import io.github.junggikim.refined.refined.string.Iso8601DurationString; +import io.github.junggikim.refined.refined.string.Iso8601PeriodString; +import io.github.junggikim.refined.refined.string.Iso8601TimeString; +import io.github.junggikim.refined.refined.string.JsonString; +import io.github.junggikim.refined.refined.string.JwtString; +import io.github.junggikim.refined.refined.string.LowerCaseString; +import io.github.junggikim.refined.refined.string.MacAddressString; +import io.github.junggikim.refined.refined.string.NonBlankString; +import io.github.junggikim.refined.refined.string.NonEmptyString; +import io.github.junggikim.refined.refined.string.NumericString; +import io.github.junggikim.refined.refined.string.RegexString; +import io.github.junggikim.refined.refined.string.SemVerString; +import io.github.junggikim.refined.refined.string.SlugString; +import io.github.junggikim.refined.refined.string.TimeZoneIdString; +import io.github.junggikim.refined.refined.string.TrimmedString; +import io.github.junggikim.refined.refined.string.UlidString; +import io.github.junggikim.refined.refined.string.UpperCaseString; +import io.github.junggikim.refined.refined.string.UriString; +import io.github.junggikim.refined.refined.string.UrlString; +import io.github.junggikim.refined.refined.string.UuidString; +import io.github.junggikim.refined.refined.string.ValidBigDecimalString; +import io.github.junggikim.refined.refined.string.ValidBigIntegerString; +import io.github.junggikim.refined.refined.string.ValidByteString; +import io.github.junggikim.refined.refined.string.ValidDoubleString; +import io.github.junggikim.refined.refined.string.ValidFloatString; +import io.github.junggikim.refined.refined.string.ValidIntString; +import io.github.junggikim.refined.refined.string.ValidLongString; +import io.github.junggikim.refined.refined.string.ValidShortString; +import io.github.junggikim.refined.refined.string.XPathString; +import io.github.junggikim.refined.refined.string.XmlString; +import java.math.BigDecimal; +import java.math.BigInteger; +import org.junit.jupiter.api.Test; + +/** + * Ensures every ofOrElse method is executed for JaCoCo coverage. + * Each type has both a valid-input and an invalid-input (fallback) test path. + */ +class OfOrElseCoverageTest { + + // --- Numeric: Int --- + @Test void positiveIntValid() { assertEquals(5, PositiveInt.ofOrElse(5, 1).value()); } + @Test void positiveIntFallback() { assertEquals(1, PositiveInt.ofOrElse(0, 1).value()); } + @Test void negativeIntValid() { assertEquals(-5, NegativeInt.ofOrElse(-5, -1).value()); } + @Test void negativeIntFallback() { assertEquals(-1, NegativeInt.ofOrElse(0, -1).value()); } + @Test void nonNegativeIntValid() { assertEquals(0, NonNegativeInt.ofOrElse(0, 1).value()); } + @Test void nonNegativeIntFallback() { assertEquals(1, NonNegativeInt.ofOrElse(-1, 1).value()); } + @Test void nonPositiveIntValid() { assertEquals(0, NonPositiveInt.ofOrElse(0, -1).value()); } + @Test void nonPositiveIntFallback() { assertEquals(-1, NonPositiveInt.ofOrElse(1, -1).value()); } + @Test void nonZeroIntValid() { assertEquals(5, NonZeroInt.ofOrElse(5, 1).value()); } + @Test void nonZeroIntFallback() { assertEquals(1, NonZeroInt.ofOrElse(0, 1).value()); } + @Test void naturalIntValid() { assertEquals(0, NaturalInt.ofOrElse(0, 1).value()); } + @Test void naturalIntFallback() { assertEquals(1, NaturalInt.ofOrElse(-1, 1).value()); } + + // --- Numeric: Long --- + @Test void positiveLongValid() { assertEquals(5L, PositiveLong.ofOrElse(5L, 1L).value()); } + @Test void positiveLongFallback() { assertEquals(1L, PositiveLong.ofOrElse(0L, 1L).value()); } + @Test void negativeLongValid() { assertEquals(-5L, NegativeLong.ofOrElse(-5L, -1L).value()); } + @Test void negativeLongFallback() { assertEquals(-1L, NegativeLong.ofOrElse(0L, -1L).value()); } + @Test void nonNegativeLongValid() { assertEquals(0L, NonNegativeLong.ofOrElse(0L, 1L).value()); } + @Test void nonNegativeLongFallback() { assertEquals(1L, NonNegativeLong.ofOrElse(-1L, 1L).value()); } + @Test void nonPositiveLongValid() { assertEquals(0L, NonPositiveLong.ofOrElse(0L, -1L).value()); } + @Test void nonPositiveLongFallback() { assertEquals(-1L, NonPositiveLong.ofOrElse(1L, -1L).value()); } + @Test void nonZeroLongValid() { assertEquals(5L, NonZeroLong.ofOrElse(5L, 1L).value()); } + @Test void nonZeroLongFallback() { assertEquals(1L, NonZeroLong.ofOrElse(0L, 1L).value()); } + @Test void naturalLongValid() { assertEquals(0L, NaturalLong.ofOrElse(0L, 1L).value()); } + @Test void naturalLongFallback() { assertEquals(1L, NaturalLong.ofOrElse(-1L, 1L).value()); } + + // --- Numeric: Byte --- + @Test void positiveByteValid() { assertEquals((byte) 5, PositiveByte.ofOrElse((byte) 5, (byte) 1).value()); } + @Test void positiveByteFallback() { assertEquals((byte) 1, PositiveByte.ofOrElse((byte) 0, (byte) 1).value()); } + @Test void negativeByteValid() { assertEquals((byte) -5, NegativeByte.ofOrElse((byte) -5, (byte) -1).value()); } + @Test void negativeByteFallback() { assertEquals((byte) -1, NegativeByte.ofOrElse((byte) 0, (byte) -1).value()); } + @Test void nonNegativeByteValid() { assertEquals((byte) 0, NonNegativeByte.ofOrElse((byte) 0, (byte) 1).value()); } + @Test void nonNegativeByteFallback() { assertEquals((byte) 1, NonNegativeByte.ofOrElse((byte) -1, (byte) 1).value()); } + @Test void nonPositiveByteValid() { assertEquals((byte) 0, NonPositiveByte.ofOrElse((byte) 0, (byte) -1).value()); } + @Test void nonPositiveByteFallback() { assertEquals((byte) -1, NonPositiveByte.ofOrElse((byte) 1, (byte) -1).value()); } + @Test void nonZeroByteValid() { assertEquals((byte) 5, NonZeroByte.ofOrElse((byte) 5, (byte) 1).value()); } + @Test void nonZeroByteFallback() { assertEquals((byte) 1, NonZeroByte.ofOrElse((byte) 0, (byte) 1).value()); } + @Test void naturalByteValid() { assertEquals((byte) 0, NaturalByte.ofOrElse((byte) 0, (byte) 1).value()); } + @Test void naturalByteFallback() { assertEquals((byte) 1, NaturalByte.ofOrElse((byte) -1, (byte) 1).value()); } + + // --- Numeric: Short --- + @Test void positiveShortValid() { assertEquals((short) 5, PositiveShort.ofOrElse((short) 5, (short) 1).value()); } + @Test void positiveShortFallback() { assertEquals((short) 1, PositiveShort.ofOrElse((short) 0, (short) 1).value()); } + @Test void negativeShortValid() { assertEquals((short) -5, NegativeShort.ofOrElse((short) -5, (short) -1).value()); } + @Test void negativeShortFallback() { assertEquals((short) -1, NegativeShort.ofOrElse((short) 0, (short) -1).value()); } + @Test void nonNegativeShortValid() { assertEquals((short) 0, NonNegativeShort.ofOrElse((short) 0, (short) 1).value()); } + @Test void nonNegativeShortFallback() { assertEquals((short) 1, NonNegativeShort.ofOrElse((short) -1, (short) 1).value()); } + @Test void nonPositiveShortValid() { assertEquals((short) 0, NonPositiveShort.ofOrElse((short) 0, (short) -1).value()); } + @Test void nonPositiveShortFallback() { assertEquals((short) -1, NonPositiveShort.ofOrElse((short) 1, (short) -1).value()); } + @Test void nonZeroShortValid() { assertEquals((short) 5, NonZeroShort.ofOrElse((short) 5, (short) 1).value()); } + @Test void nonZeroShortFallback() { assertEquals((short) 1, NonZeroShort.ofOrElse((short) 0, (short) 1).value()); } + @Test void naturalShortValid() { assertEquals((short) 0, NaturalShort.ofOrElse((short) 0, (short) 1).value()); } + @Test void naturalShortFallback() { assertEquals((short) 1, NaturalShort.ofOrElse((short) -1, (short) 1).value()); } + + // --- Numeric: Float --- + @Test void positiveFloatValid() { assertEquals(1.5f, PositiveFloat.ofOrElse(1.5f, 1.0f).value()); } + @Test void positiveFloatFallback() { assertEquals(1.0f, PositiveFloat.ofOrElse(0.0f, 1.0f).value()); } + @Test void negativeFloatValid() { assertEquals(-1.5f, NegativeFloat.ofOrElse(-1.5f, -1.0f).value()); } + @Test void negativeFloatFallback() { assertEquals(-1.0f, NegativeFloat.ofOrElse(0.0f, -1.0f).value()); } + @Test void nonNegativeFloatValid() { assertEquals(0.0f, NonNegativeFloat.ofOrElse(0.0f, 1.0f).value()); } + @Test void nonNegativeFloatFallback() { assertEquals(1.0f, NonNegativeFloat.ofOrElse(-1.0f, 1.0f).value()); } + @Test void nonPositiveFloatValid() { assertEquals(-0.0f, NonPositiveFloat.ofOrElse(-0.0f, -1.0f).value()); } + @Test void nonPositiveFloatFallback() { assertEquals(-1.0f, NonPositiveFloat.ofOrElse(1.0f, -1.0f).value()); } + @Test void nonZeroFloatValid() { assertEquals(1.0f, NonZeroFloat.ofOrElse(1.0f, 2.0f).value()); } + @Test void nonZeroFloatFallback() { assertEquals(2.0f, NonZeroFloat.ofOrElse(0.0f, 2.0f).value()); } + @Test void finiteFloatValid() { assertEquals(1.0f, FiniteFloat.ofOrElse(1.0f, 2.0f).value()); } + @Test void finiteFloatFallback() { assertEquals(2.0f, FiniteFloat.ofOrElse(Float.POSITIVE_INFINITY, 2.0f).value()); } + @Test void nonNaNFloatValid() { assertEquals(1.0f, NonNaNFloat.ofOrElse(1.0f, 2.0f).value()); } + @Test void nonNaNFloatFallback() { assertEquals(2.0f, NonNaNFloat.ofOrElse(Float.NaN, 2.0f).value()); } + @Test void zeroToOneFloatValid() { assertEquals(0.5f, ZeroToOneFloat.ofOrElse(0.5f, 0.0f).value()); } + @Test void zeroToOneFloatFallback() { assertEquals(0.0f, ZeroToOneFloat.ofOrElse(2.0f, 0.0f).value()); } + + // --- Numeric: Double --- + @Test void positiveDoubleValid() { assertEquals(1.5d, PositiveDouble.ofOrElse(1.5d, 1.0d).value()); } + @Test void positiveDoubleFallback() { assertEquals(1.0d, PositiveDouble.ofOrElse(0.0d, 1.0d).value()); } + @Test void negativeDoubleValid() { assertEquals(-1.5d, NegativeDouble.ofOrElse(-1.5d, -1.0d).value()); } + @Test void negativeDoubleFallback() { assertEquals(-1.0d, NegativeDouble.ofOrElse(0.0d, -1.0d).value()); } + @Test void nonNegativeDoubleValid() { assertEquals(0.0d, NonNegativeDouble.ofOrElse(0.0d, 1.0d).value()); } + @Test void nonNegativeDoubleFallback() { assertEquals(1.0d, NonNegativeDouble.ofOrElse(-1.0d, 1.0d).value()); } + @Test void nonPositiveDoubleValid() { assertEquals(-0.0d, NonPositiveDouble.ofOrElse(-0.0d, -1.0d).value()); } + @Test void nonPositiveDoubleFallback() { assertEquals(-1.0d, NonPositiveDouble.ofOrElse(1.0d, -1.0d).value()); } + @Test void nonZeroDoubleValid() { assertEquals(1.0d, NonZeroDouble.ofOrElse(1.0d, 2.0d).value()); } + @Test void nonZeroDoubleFallback() { assertEquals(2.0d, NonZeroDouble.ofOrElse(0.0d, 2.0d).value()); } + @Test void finiteDoubleValid() { assertEquals(1.0d, FiniteDouble.ofOrElse(1.0d, 2.0d).value()); } + @Test void finiteDoubleFallback() { assertEquals(2.0d, FiniteDouble.ofOrElse(Double.POSITIVE_INFINITY, 2.0d).value()); } + @Test void nonNaNDoubleValid() { assertEquals(1.0d, NonNaNDouble.ofOrElse(1.0d, 2.0d).value()); } + @Test void nonNaNDoubleFallback() { assertEquals(2.0d, NonNaNDouble.ofOrElse(Double.NaN, 2.0d).value()); } + @Test void zeroToOneDoubleValid() { assertEquals(0.5d, ZeroToOneDouble.ofOrElse(0.5d, 0.0d).value()); } + @Test void zeroToOneDoubleFallback() { assertEquals(0.0d, ZeroToOneDouble.ofOrElse(2.0d, 0.0d).value()); } + + // --- Numeric: BigInteger --- + @Test void positiveBigIntegerValid() { assertEquals(BigInteger.TEN, PositiveBigInteger.ofOrElse(BigInteger.TEN, BigInteger.ONE).value()); } + @Test void positiveBigIntegerFallback() { assertEquals(BigInteger.ONE, PositiveBigInteger.ofOrElse(BigInteger.ZERO, BigInteger.ONE).value()); } + @Test void negativeBigIntegerValid() { assertEquals(BigInteger.valueOf(-5), NegativeBigInteger.ofOrElse(BigInteger.valueOf(-5), BigInteger.valueOf(-1)).value()); } + @Test void negativeBigIntegerFallback() { assertEquals(BigInteger.valueOf(-1), NegativeBigInteger.ofOrElse(BigInteger.ZERO, BigInteger.valueOf(-1)).value()); } + @Test void nonNegativeBigIntegerValid() { assertEquals(BigInteger.ZERO, NonNegativeBigInteger.ofOrElse(BigInteger.ZERO, BigInteger.ONE).value()); } + @Test void nonNegativeBigIntegerFallback() { assertEquals(BigInteger.ONE, NonNegativeBigInteger.ofOrElse(BigInteger.valueOf(-1), BigInteger.ONE).value()); } + @Test void nonPositiveBigIntegerValid() { assertEquals(BigInteger.ZERO, NonPositiveBigInteger.ofOrElse(BigInteger.ZERO, BigInteger.valueOf(-1)).value()); } + @Test void nonPositiveBigIntegerFallback() { assertEquals(BigInteger.valueOf(-1), NonPositiveBigInteger.ofOrElse(BigInteger.ONE, BigInteger.valueOf(-1)).value()); } + @Test void nonZeroBigIntegerValid() { assertEquals(BigInteger.TEN, NonZeroBigInteger.ofOrElse(BigInteger.TEN, BigInteger.ONE).value()); } + @Test void nonZeroBigIntegerFallback() { assertEquals(BigInteger.ONE, NonZeroBigInteger.ofOrElse(BigInteger.ZERO, BigInteger.ONE).value()); } + @Test void naturalBigIntegerValid() { assertEquals(BigInteger.ZERO, NaturalBigInteger.ofOrElse(BigInteger.ZERO, BigInteger.ONE).value()); } + @Test void naturalBigIntegerFallback() { assertEquals(BigInteger.ONE, NaturalBigInteger.ofOrElse(BigInteger.valueOf(-1), BigInteger.ONE).value()); } + + // --- Numeric: BigDecimal --- + @Test void positiveBigDecimalValid() { assertEquals(new BigDecimal("5.0"), PositiveBigDecimal.ofOrElse(new BigDecimal("5.0"), BigDecimal.ONE).value()); } + @Test void positiveBigDecimalFallback() { assertEquals(BigDecimal.ONE, PositiveBigDecimal.ofOrElse(BigDecimal.ZERO, BigDecimal.ONE).value()); } + @Test void negativeBigDecimalValid() { assertEquals(new BigDecimal("-5.0"), NegativeBigDecimal.ofOrElse(new BigDecimal("-5.0"), new BigDecimal("-1.0")).value()); } + @Test void negativeBigDecimalFallback() { assertEquals(new BigDecimal("-1.0"), NegativeBigDecimal.ofOrElse(BigDecimal.ZERO, new BigDecimal("-1.0")).value()); } + @Test void nonNegativeBigDecimalValid() { assertEquals(BigDecimal.ZERO, NonNegativeBigDecimal.ofOrElse(BigDecimal.ZERO, BigDecimal.ONE).value()); } + @Test void nonNegativeBigDecimalFallback() { assertEquals(BigDecimal.ONE, NonNegativeBigDecimal.ofOrElse(new BigDecimal("-1"), BigDecimal.ONE).value()); } + @Test void nonPositiveBigDecimalValid() { assertEquals(BigDecimal.ZERO, NonPositiveBigDecimal.ofOrElse(BigDecimal.ZERO, new BigDecimal("-1")).value()); } + @Test void nonPositiveBigDecimalFallback() { assertEquals(new BigDecimal("-1"), NonPositiveBigDecimal.ofOrElse(BigDecimal.ONE, new BigDecimal("-1")).value()); } + @Test void nonZeroBigDecimalValid() { assertEquals(BigDecimal.TEN, NonZeroBigDecimal.ofOrElse(BigDecimal.TEN, BigDecimal.ONE).value()); } + @Test void nonZeroBigDecimalFallback() { assertEquals(BigDecimal.ONE, NonZeroBigDecimal.ofOrElse(BigDecimal.ZERO, BigDecimal.ONE).value()); } + + // --- Character --- + @Test void digitCharValid() { assertEquals('5', DigitChar.ofOrElse('5', '0').value()); } + @Test void digitCharFallback() { assertEquals('0', DigitChar.ofOrElse('a', '0').value()); } + @Test void letterCharValid() { assertEquals('a', LetterChar.ofOrElse('a', 'b').value()); } + @Test void letterCharFallback() { assertEquals('b', LetterChar.ofOrElse('1', 'b').value()); } + @Test void letterOrDigitCharValid() { assertEquals('a', LetterOrDigitChar.ofOrElse('a', 'b').value()); } + @Test void letterOrDigitCharFallback() { assertEquals('b', LetterOrDigitChar.ofOrElse('-', 'b').value()); } + @Test void lowerCaseCharValid() { assertEquals('a', LowerCaseChar.ofOrElse('a', 'b').value()); } + @Test void lowerCaseCharFallback() { assertEquals('b', LowerCaseChar.ofOrElse('A', 'b').value()); } + @Test void upperCaseCharValid() { assertEquals('A', UpperCaseChar.ofOrElse('A', 'B').value()); } + @Test void upperCaseCharFallback() { assertEquals('B', UpperCaseChar.ofOrElse('a', 'B').value()); } + @Test void whitespaceCharValid() { assertEquals(' ', WhitespaceChar.ofOrElse(' ', '\t').value()); } + @Test void whitespaceCharFallback() { assertEquals('\t', WhitespaceChar.ofOrElse('a', '\t').value()); } + @Test void specialCharValid() { assertEquals('!', SpecialChar.ofOrElse('!', '@').value()); } + @Test void specialCharFallback() { assertEquals('@', SpecialChar.ofOrElse('a', '@').value()); } + + // --- String --- + @Test void nonBlankStringValid() { assertEquals("hello", NonBlankString.ofOrElse("hello", "x").value()); } + @Test void nonBlankStringFallback() { assertEquals("x", NonBlankString.ofOrElse(" ", "x").value()); } + @Test void nonEmptyStringValid() { assertEquals("a", NonEmptyString.ofOrElse("a", "x").value()); } + @Test void nonEmptyStringFallback() { assertEquals("x", NonEmptyString.ofOrElse("", "x").value()); } + @Test void trimmedStringValid() { assertEquals("abc", TrimmedString.ofOrElse("abc", "x").value()); } + @Test void trimmedStringFallback() { assertEquals("x", TrimmedString.ofOrElse(" abc ", "x").value()); } + @Test void alphabeticStringValid() { assertEquals("abc", AlphabeticString.ofOrElse("abc", "x").value()); } + @Test void alphabeticStringFallback() { assertEquals("x", AlphabeticString.ofOrElse("123", "x").value()); } + @Test void alphanumericStringValid() { assertEquals("abc123", AlphanumericString.ofOrElse("abc123", "x").value()); } + @Test void alphanumericStringFallback() { assertEquals("x", AlphanumericString.ofOrElse("abc-", "x").value()); } + @Test void asciiStringValid() { assertEquals("hello", AsciiString.ofOrElse("hello", "x").value()); } + @Test void asciiStringFallback() { assertEquals("x", AsciiString.ofOrElse("\u00E9", "x").value()); } + @Test void numericStringValid() { assertEquals("123", NumericString.ofOrElse("123", "0").value()); } + @Test void numericStringFallback() { assertEquals("0", NumericString.ofOrElse("abc", "0").value()); } + @Test void lowerCaseStringValid() { assertEquals("abc", LowerCaseString.ofOrElse("abc", "x").value()); } + @Test void lowerCaseStringFallback() { assertEquals("x", LowerCaseString.ofOrElse("ABC", "x").value()); } + @Test void upperCaseStringValid() { assertEquals("ABC", UpperCaseString.ofOrElse("ABC", "X").value()); } + @Test void upperCaseStringFallback() { assertEquals("X", UpperCaseString.ofOrElse("abc", "X").value()); } + @Test void emailStringValid() { assertEquals("a@b.com", EmailString.ofOrElse("a@b.com", "x@y.com").value()); } + @Test void emailStringFallback() { assertEquals("x@y.com", EmailString.ofOrElse("invalid", "x@y.com").value()); } + @Test void uuidStringValid() { assertEquals("123e4567-e89b-12d3-a456-426614174000", UuidString.ofOrElse("123e4567-e89b-12d3-a456-426614174000", "00000000-0000-0000-0000-000000000000").value()); } + @Test void uuidStringFallback() { assertEquals("00000000-0000-0000-0000-000000000000", UuidString.ofOrElse("bad", "00000000-0000-0000-0000-000000000000").value()); } + @Test void uriStringValid() { assertEquals("https://x.com", UriString.ofOrElse("https://x.com", "https://y.com").value()); } + @Test void uriStringFallback() { assertEquals("https://y.com", UriString.ofOrElse("://bad", "https://y.com").value()); } + @Test void urlStringValid() { assertEquals("https://x.com/p", UrlString.ofOrElse("https://x.com/p", "https://y.com").value()); } + @Test void urlStringFallback() { assertEquals("https://y.com", UrlString.ofOrElse("ht^tp://bad", "https://y.com").value()); } + @Test void ipv4StringValid() { assertEquals("192.168.0.1", Ipv4String.ofOrElse("192.168.0.1", "127.0.0.1").value()); } + @Test void ipv4StringFallback() { assertEquals("127.0.0.1", Ipv4String.ofOrElse("256.1.1.1", "127.0.0.1").value()); } + @Test void ipv6StringValid() { assertEquals("2001:db8::1", Ipv6String.ofOrElse("2001:db8::1", "::1").value()); } + @Test void ipv6StringFallback() { assertEquals("::1", Ipv6String.ofOrElse("bad", "::1").value()); } + @Test void hexStringValid() { assertEquals("deadBEEF", HexString.ofOrElse("deadBEEF", "00").value()); } + @Test void hexStringFallback() { assertEquals("00", HexString.ofOrElse("xyz", "00").value()); } + @Test void hexColorStringValid() { assertEquals("#AABBCC", HexColorString.ofOrElse("#AABBCC", "#000000").value()); } + @Test void hexColorStringFallback() { assertEquals("#000000", HexColorString.ofOrElse("bad", "#000000").value()); } + @Test void regexStringValid() { assertEquals("[a-z]+", RegexString.ofOrElse("[a-z]+", ".*").value()); } + @Test void regexStringFallback() { assertEquals(".*", RegexString.ofOrElse("[a-z", ".*").value()); } + @Test void xmlStringValid() { assertEquals("", XmlString.ofOrElse("", "").value()); } + @Test void xmlStringFallback() { assertEquals("", XmlString.ofOrElse("", "").value()); } + @Test void xpathStringValid() { assertEquals("/root", XPathString.ofOrElse("/root", "/x").value()); } + @Test void xpathStringFallback() { assertEquals("/x", XPathString.ofOrElse("//*[", "/x").value()); } + @Test void base64StringValid() { assertEquals("aGVsbG8=", Base64String.ofOrElse("aGVsbG8=", "eA==").value()); } + @Test void base64StringFallback() { assertEquals("eA==", Base64String.ofOrElse("!!!!", "eA==").value()); } + @Test void base64UrlStringValid() { assertEquals("aGVsbG8", Base64UrlString.ofOrElse("aGVsbG8", "eA").value()); } + @Test void base64UrlStringFallback() { assertEquals("eA", Base64UrlString.ofOrElse("!!!", "eA").value()); } + @Test void jsonStringValid() { assertEquals("{}", JsonString.ofOrElse("{}", "[]").value()); } + @Test void jsonStringFallback() { assertEquals("[]", JsonString.ofOrElse("{bad", "[]").value()); } + @Test void slugStringValid() { assertEquals("hello-world", SlugString.ofOrElse("hello-world", "x").value()); } + @Test void slugStringFallback() { assertEquals("x", SlugString.ofOrElse("Hello World!", "x").value()); } + @Test void semVerStringValid() { assertEquals("1.0.0", SemVerString.ofOrElse("1.0.0", "0.0.1").value()); } + @Test void semVerStringFallback() { assertEquals("0.0.1", SemVerString.ofOrElse("bad", "0.0.1").value()); } + @Test void hostnameStringValid() { assertEquals("example.com", HostnameString.ofOrElse("example.com", "localhost").value()); } + @Test void hostnameStringFallback() { assertEquals("localhost", HostnameString.ofOrElse("-bad", "localhost").value()); } + @Test void macAddressStringValid() { assertEquals("00:11:22:33:44:55", MacAddressString.ofOrElse("00:11:22:33:44:55", "00:00:00:00:00:00").value()); } + @Test void macAddressStringFallback() { assertEquals("00:00:00:00:00:00", MacAddressString.ofOrElse("bad", "00:00:00:00:00:00").value()); } + @Test void cidrV4StringValid() { assertEquals("192.168.0.0/24", CidrV4String.ofOrElse("192.168.0.0/24", "10.0.0.0/8").value()); } + @Test void cidrV4StringFallback() { assertEquals("10.0.0.0/8", CidrV4String.ofOrElse("bad", "10.0.0.0/8").value()); } + @Test void cidrV6StringValid() { assertEquals("2001:db8::/32", CidrV6String.ofOrElse("2001:db8::/32", "::1/128").value()); } + @Test void cidrV6StringFallback() { assertEquals("::1/128", CidrV6String.ofOrElse("bad", "::1/128").value()); } + @Test void creditCardStringValid() { assertEquals("4111111111111111", CreditCardString.ofOrElse("4111111111111111", "5500000000000004").value()); } + @Test void creditCardStringFallback() { assertEquals("5500000000000004", CreditCardString.ofOrElse("bad", "5500000000000004").value()); } + @Test void isbnStringValid() { assertEquals("978-3-16-148410-0", IsbnString.ofOrElse("978-3-16-148410-0", "0-306-40615-2").value()); } + @Test void isbnStringFallback() { assertEquals("0-306-40615-2", IsbnString.ofOrElse("bad", "0-306-40615-2").value()); } + @Test void iso8601DateStringValid() { assertEquals("2026-01-01", Iso8601DateString.ofOrElse("2026-01-01", "2000-01-01").value()); } + @Test void iso8601DateStringFallback() { assertEquals("2000-01-01", Iso8601DateString.ofOrElse("bad", "2000-01-01").value()); } + @Test void iso8601TimeStringValid() { assertEquals("10:30:00", Iso8601TimeString.ofOrElse("10:30:00", "00:00:00").value()); } + @Test void iso8601TimeStringFallback() { assertEquals("00:00:00", Iso8601TimeString.ofOrElse("bad", "00:00:00").value()); } + @Test void iso8601DateTimeStringValid() { assertEquals("2026-01-01T10:30:00", Iso8601DateTimeString.ofOrElse("2026-01-01T10:30:00", "2000-01-01T00:00:00").value()); } + @Test void iso8601DateTimeStringFallback() { assertEquals("2000-01-01T00:00:00", Iso8601DateTimeString.ofOrElse("bad", "2000-01-01T00:00:00").value()); } + @Test void iso8601DurationStringValid() { assertEquals("PT1H", Iso8601DurationString.ofOrElse("PT1H", "PT0S").value()); } + @Test void iso8601DurationStringFallback() { assertEquals("PT0S", Iso8601DurationString.ofOrElse("bad", "PT0S").value()); } + @Test void iso8601PeriodStringValid() { assertEquals("P1Y", Iso8601PeriodString.ofOrElse("P1Y", "P0D").value()); } + @Test void iso8601PeriodStringFallback() { assertEquals("P0D", Iso8601PeriodString.ofOrElse("bad", "P0D").value()); } + @Test void timeZoneIdStringValid() { assertEquals("UTC", TimeZoneIdString.ofOrElse("UTC", "GMT").value()); } + @Test void timeZoneIdStringFallback() { assertEquals("GMT", TimeZoneIdString.ofOrElse("Invalid/Zone", "GMT").value()); } + @Test void ulidStringValid() { assertEquals("01ARZ3NDEKTSV4RRFFQ69G5FAV", UlidString.ofOrElse("01ARZ3NDEKTSV4RRFFQ69G5FAV", "00000000000000000000000000").value()); } + @Test void ulidStringFallback() { assertEquals("00000000000000000000000000", UlidString.ofOrElse("bad", "00000000000000000000000000").value()); } + @Test void jwtStringValid() { + String jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U"; + String def = "eyJhbGciOiJub25lIn0.eyJzdWIiOiIxIn0."; + assertEquals(jwt, JwtString.ofOrElse(jwt, def).value()); + } + @Test void jwtStringFallback() { + String def = "eyJhbGciOiJub25lIn0.eyJzdWIiOiIxIn0."; + assertEquals(def, JwtString.ofOrElse("bad", def).value()); + } + + // --- Numeric string parseable types --- + @Test void validByteStringValid() { assertEquals("127", ValidByteString.ofOrElse("127", "0").value()); } + @Test void validByteStringFallback() { assertEquals("0", ValidByteString.ofOrElse("128", "0").value()); } + @Test void validShortStringValid() { assertEquals("32767", ValidShortString.ofOrElse("32767", "0").value()); } + @Test void validShortStringFallback() { assertEquals("0", ValidShortString.ofOrElse("40000", "0").value()); } + @Test void validIntStringValid() { assertEquals("42", ValidIntString.ofOrElse("42", "0").value()); } + @Test void validIntStringFallback() { assertEquals("0", ValidIntString.ofOrElse("2147483648", "0").value()); } + @Test void validLongStringValid() { assertEquals("42", ValidLongString.ofOrElse("42", "0").value()); } + @Test void validLongStringFallback() { assertEquals("0", ValidLongString.ofOrElse("9223372036854775808", "0").value()); } + @Test void validFloatStringValid() { assertEquals("1.5", ValidFloatString.ofOrElse("1.5", "0").value()); } + @Test void validFloatStringFallback() { assertEquals("0", ValidFloatString.ofOrElse("not-a-float", "0").value()); } + @Test void validDoubleStringValid() { assertEquals("1.5", ValidDoubleString.ofOrElse("1.5", "0").value()); } + @Test void validDoubleStringFallback() { assertEquals("0", ValidDoubleString.ofOrElse("not-a-double", "0").value()); } + @Test void validBigIntegerStringValid() { assertEquals("123", ValidBigIntegerString.ofOrElse("123", "0").value()); } + @Test void validBigIntegerStringFallback() { assertEquals("0", ValidBigIntegerString.ofOrElse("12.3", "0").value()); } + @Test void validBigDecimalStringValid() { assertEquals("123.45", ValidBigDecimalString.ofOrElse("123.45", "0").value()); } + @Test void validBigDecimalStringFallback() { assertEquals("0", ValidBigDecimalString.ofOrElse("12a", "0").value()); } +} diff --git a/src/test/java/io/github/junggikim/refined/refined/OfOrElseTest.java b/src/test/java/io/github/junggikim/refined/refined/OfOrElseTest.java new file mode 100644 index 0000000..e7d9b93 --- /dev/null +++ b/src/test/java/io/github/junggikim/refined/refined/OfOrElseTest.java @@ -0,0 +1,334 @@ +package io.github.junggikim.refined.refined; + +import static io.github.junggikim.refined.support.TestCollections.listOf; +import static io.github.junggikim.refined.support.TestCollections.mapOf; +import static io.github.junggikim.refined.support.TestCollections.setOf; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import io.github.junggikim.refined.core.RefinementException; +import io.github.junggikim.refined.refined.character.DigitChar; +import io.github.junggikim.refined.refined.collection.NonEmptyDeque; +import io.github.junggikim.refined.refined.collection.NonEmptyIterable; +import io.github.junggikim.refined.refined.collection.NonEmptyList; +import io.github.junggikim.refined.refined.collection.NonEmptyMap; +import io.github.junggikim.refined.refined.collection.NonEmptyNavigableMap; +import io.github.junggikim.refined.refined.collection.NonEmptyNavigableSet; +import io.github.junggikim.refined.refined.collection.NonEmptyQueue; +import io.github.junggikim.refined.refined.collection.NonEmptySet; +import io.github.junggikim.refined.refined.collection.NonEmptySortedMap; +import io.github.junggikim.refined.refined.collection.NonEmptySortedSet; +import io.github.junggikim.refined.refined.numeric.NaturalBigInteger; +import io.github.junggikim.refined.refined.numeric.NegativeBigDecimal; +import io.github.junggikim.refined.refined.numeric.NegativeInt; +import io.github.junggikim.refined.refined.numeric.NonNegativeInt; +import io.github.junggikim.refined.refined.numeric.PositiveInt; +import io.github.junggikim.refined.refined.numeric.PositiveLong; +import io.github.junggikim.refined.refined.string.NonBlankString; +import io.github.junggikim.refined.refined.string.EmailString; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.NavigableMap; +import java.util.NavigableSet; +import java.util.Queue; +import java.util.Set; +import java.util.SortedMap; +import java.util.SortedSet; +import java.util.TreeMap; +import java.util.TreeSet; +import org.junit.jupiter.api.Test; + +class OfOrElseTest { + + // --- Numeric types --- + + @Test + void positiveIntOfOrElseReturnsValueWhenValid() { + assertEquals(5, PositiveInt.ofOrElse(5, 1).value()); + } + + @Test + void positiveIntOfOrElseReturnsFallbackWhenInvalid() { + assertEquals(1, PositiveInt.ofOrElse(0, 1).value()); + } + + @Test + void positiveIntOfOrElseReturnsFallbackWhenNull() { + assertEquals(1, PositiveInt.ofOrElse(null, 1).value()); + } + + @Test + void positiveIntOfOrElseThrowsWhenDefaultAlsoInvalid() { + assertThrows(RefinementException.class, () -> PositiveInt.ofOrElse(0, 0)); + } + + @Test + void positiveLongOfOrElseReturnsValueWhenValid() { + assertEquals(5L, PositiveLong.ofOrElse(5L, 1L).value()); + } + + @Test + void positiveLongOfOrElseReturnsFallbackWhenInvalid() { + assertEquals(1L, PositiveLong.ofOrElse(0L, 1L).value()); + } + + @Test + void nonNegativeIntOfOrElseReturnsValueWhenValid() { + assertEquals(0, NonNegativeInt.ofOrElse(0, 1).value()); + } + + @Test + void nonNegativeIntOfOrElseReturnsFallbackWhenInvalid() { + assertEquals(1, NonNegativeInt.ofOrElse(-1, 1).value()); + } + + @Test + void negativeIntOfOrElseReturnsValueWhenValid() { + assertEquals(-5, NegativeInt.ofOrElse(-5, -1).value()); + } + + @Test + void negativeIntOfOrElseReturnsFallbackWhenInvalid() { + assertEquals(-1, NegativeInt.ofOrElse(0, -1).value()); + } + + @Test + void naturalBigIntegerOfOrElseReturnsValueWhenValid() { + assertEquals(BigInteger.TEN, NaturalBigInteger.ofOrElse(BigInteger.TEN, BigInteger.ZERO).value()); + } + + @Test + void naturalBigIntegerOfOrElseReturnsFallbackWhenNull() { + assertEquals(BigInteger.ZERO, NaturalBigInteger.ofOrElse(null, BigInteger.ZERO).value()); + } + + @Test + void negativeBigDecimalOfOrElseReturnsValueWhenValid() { + BigDecimal neg = new BigDecimal("-5.0"); + BigDecimal def = new BigDecimal("-1.0"); + assertEquals(neg, NegativeBigDecimal.ofOrElse(neg, def).value()); + } + + @Test + void negativeBigDecimalOfOrElseReturnsFallbackWhenInvalid() { + BigDecimal def = new BigDecimal("-1.0"); + assertEquals(def, NegativeBigDecimal.ofOrElse(BigDecimal.ZERO, def).value()); + } + + // --- Character types --- + + @Test + void digitCharOfOrElseReturnsValueWhenValid() { + assertEquals('5', DigitChar.ofOrElse('5', '0').value()); + } + + @Test + void digitCharOfOrElseReturnsFallbackWhenInvalid() { + assertEquals('0', DigitChar.ofOrElse('a', '0').value()); + } + + @Test + void digitCharOfOrElseReturnsFallbackWhenNull() { + assertEquals('0', DigitChar.ofOrElse(null, '0').value()); + } + + @Test + void digitCharOfOrElseThrowsWhenDefaultAlsoInvalid() { + assertThrows(RefinementException.class, () -> DigitChar.ofOrElse('a', 'a')); + } + + // --- String types --- + + @Test + void nonBlankStringOfOrElseReturnsValueWhenValid() { + assertEquals("hello", NonBlankString.ofOrElse("hello", "default").value()); + } + + @Test + void nonBlankStringOfOrElseReturnsFallbackWhenInvalid() { + assertEquals("default", NonBlankString.ofOrElse(" ", "default").value()); + } + + @Test + void nonBlankStringOfOrElseReturnsFallbackWhenNull() { + assertEquals("default", NonBlankString.ofOrElse(null, "default").value()); + } + + @Test + void nonBlankStringOfOrElseThrowsWhenDefaultAlsoInvalid() { + assertThrows(RefinementException.class, () -> NonBlankString.ofOrElse(" ", " ")); + } + + @Test + void emailStringOfOrElseReturnsValueWhenValid() { + assertEquals("a@b.com", EmailString.ofOrElse("a@b.com", "x@y.com").value()); + } + + @Test + void emailStringOfOrElseReturnsFallbackWhenInvalid() { + assertEquals("x@y.com", EmailString.ofOrElse("invalid", "x@y.com").value()); + } + + // --- Collection types --- + + @Test + void nonEmptyListOfOrElseReturnsValueWhenValid() { + assertEquals(listOf(1, 2), NonEmptyList.ofOrElse(listOf(1, 2), listOf(9))); + } + + @Test + void nonEmptyListOfOrElseReturnsFallbackWhenInvalid() { + List empty = listOf(); + assertEquals(listOf(9), NonEmptyList.ofOrElse(empty, listOf(9))); + } + + @Test + void nonEmptyListOfOrElseReturnsFallbackWhenNull() { + assertEquals(listOf(9), NonEmptyList.ofOrElse(null, listOf(9))); + } + + @Test + void nonEmptyListOfOrElseThrowsWhenDefaultAlsoInvalid() { + List empty = listOf(); + assertThrows(RefinementException.class, () -> NonEmptyList.ofOrElse(empty, listOf())); + } + + @Test + void nonEmptySetOfOrElseReturnsValueWhenValid() { + Set input = new LinkedHashSet(listOf(1, 2)); + Set fallback = new LinkedHashSet(listOf(9)); + + assertEquals(setOf(1, 2), NonEmptySet.ofOrElse(input, fallback)); + } + + @Test + void nonEmptySetOfOrElseReturnsFallbackWhenNull() { + Set fallback = new LinkedHashSet(listOf(9)); + + assertEquals(setOf(9), NonEmptySet.ofOrElse(null, fallback)); + } + + @Test + void nonEmptyMapOfOrElseReturnsValueWhenValid() { + Map input = new LinkedHashMap(mapOf("a", 1)); + Map fallback = new LinkedHashMap(mapOf("b", 2)); + + assertEquals(mapOf("a", 1), NonEmptyMap.ofOrElse(input, fallback)); + } + + @Test + void nonEmptyMapOfOrElseReturnsFallbackWhenNull() { + Map fallback = new LinkedHashMap(mapOf("b", 2)); + + assertEquals(mapOf("b", 2), NonEmptyMap.ofOrElse(null, fallback)); + } + + @Test + void nonEmptyQueueOfOrElseReturnsValueWhenValid() { + Queue input = new LinkedList(listOf(1, 2)); + Queue fallback = new LinkedList(listOf(9)); + + assertEquals(listOf(1, 2), NonEmptyQueue.ofOrElse(input, fallback)); + } + + @Test + void nonEmptyQueueOfOrElseReturnsFallbackWhenEmpty() { + Queue empty = new LinkedList(); + Queue fallback = new LinkedList(listOf(9)); + + assertEquals(listOf(9), NonEmptyQueue.ofOrElse(empty, fallback)); + } + + @Test + void nonEmptyDequeOfOrElseReturnsValueWhenValid() { + Deque input = new ArrayDeque(listOf(1, 2)); + Deque fallback = new ArrayDeque(listOf(9)); + + assertEquals(listOf(1, 2), NonEmptyDeque.ofOrElse(input, fallback)); + } + + @Test + void nonEmptyDequeOfOrElseReturnsFallbackWhenNull() { + Deque fallback = new ArrayDeque(listOf(9)); + + assertEquals(listOf(9), NonEmptyDeque.ofOrElse(null, fallback)); + } + + @Test + void nonEmptyIterableOfOrElseReturnsValueWhenValid() { + assertEquals(listOf(1), NonEmptyIterable.ofOrElse(listOf(1), listOf(9))); + } + + @Test + void nonEmptyIterableOfOrElseReturnsFallbackWhenEmpty() { + List empty = listOf(); + assertEquals(listOf(9), NonEmptyIterable.ofOrElse(empty, listOf(9))); + } + + @Test + void nonEmptySortedSetOfOrElseReturnsValueWhenValid() { + SortedSet input = new TreeSet(listOf(1, 2)); + SortedSet fallback = new TreeSet(listOf(9)); + + assertEquals(setOf(1, 2), NonEmptySortedSet.ofOrElse(input, fallback)); + } + + @Test + void nonEmptySortedSetOfOrElseReturnsFallbackWhenNull() { + SortedSet fallback = new TreeSet(listOf(9)); + + assertEquals(setOf(9), NonEmptySortedSet.ofOrElse(null, fallback)); + } + + @Test + void nonEmptySortedMapOfOrElseReturnsValueWhenValid() { + SortedMap input = new TreeMap(mapOf("a", 1)); + SortedMap fallback = new TreeMap(mapOf("b", 2)); + + assertEquals(mapOf("a", 1), NonEmptySortedMap.ofOrElse(input, fallback)); + } + + @Test + void nonEmptySortedMapOfOrElseReturnsFallbackWhenNull() { + SortedMap fallback = new TreeMap(mapOf("b", 2)); + + assertEquals(mapOf("b", 2), NonEmptySortedMap.ofOrElse(null, fallback)); + } + + @Test + void nonEmptyNavigableSetOfOrElseReturnsValueWhenValid() { + NavigableSet input = new TreeSet(listOf(1, 2)); + NavigableSet fallback = new TreeSet(listOf(9)); + + assertEquals(setOf(1, 2), NonEmptyNavigableSet.ofOrElse(input, fallback)); + } + + @Test + void nonEmptyNavigableSetOfOrElseReturnsFallbackWhenNull() { + NavigableSet fallback = new TreeSet(listOf(9)); + + assertEquals(setOf(9), NonEmptyNavigableSet.ofOrElse(null, fallback)); + } + + @Test + void nonEmptyNavigableMapOfOrElseReturnsValueWhenValid() { + NavigableMap input = new TreeMap(mapOf("a", 1)); + NavigableMap fallback = new TreeMap(mapOf("b", 2)); + + assertEquals(mapOf("a", 1), NonEmptyNavigableMap.ofOrElse(input, fallback)); + } + + @Test + void nonEmptyNavigableMapOfOrElseReturnsFallbackWhenNull() { + NavigableMap fallback = new TreeMap(mapOf("b", 2)); + + assertEquals(mapOf("b", 2), NonEmptyNavigableMap.ofOrElse(null, fallback)); + } +} diff --git a/src/test/java/io/github/junggikim/refined/validation/ValidationTest.java b/src/test/java/io/github/junggikim/refined/validation/ValidationTest.java index 26dec21..9dd99d3 100644 --- a/src/test/java/io/github/junggikim/refined/validation/ValidationTest.java +++ b/src/test/java/io/github/junggikim/refined/validation/ValidationTest.java @@ -3,10 +3,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import io.github.junggikim.refined.violation.Violation; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicReference; import org.junit.jupiter.api.Test; class ValidationTest { @@ -84,4 +88,182 @@ void validationHashCodesAreNonZero() { assertNotEquals(0, Validation.valid(3).hashCode()); assertNotEquals(0, Validation.invalid(Violation.of("code", "msg")).hashCode()); } + + @Test + void getOrElseWithValueReturnsValueWhenValid() { + assertEquals(10, Validation.valid(10).getOrElse(99)); + } + + @Test + void getOrElseWithValueReturnsFallbackWhenInvalid() { + Validation invalid = Validation.invalid(Violation.of("e", "e")); + + assertEquals(99, invalid.getOrElse(99)); + } + + @Test + void getOrElseWithValueRejectsNullOther() { + Validation valid = Validation.valid(10); + + assertThrows(NullPointerException.class, () -> valid.getOrElse((Integer) null)); + } + + @Test + void getOrElseWithHandlerReturnsValueWhenValid() { + assertEquals(10, Validation.valid(10).getOrElse(err -> 99)); + } + + @Test + void getOrElseWithHandlerReturnsHandlerResultWhenInvalid() { + Validation invalid = Validation.invalid(Violation.of("e", "msg")); + + assertEquals("msg", invalid.getOrElse(err -> err.message())); + } + + @Test + void getOrElseWithHandlerRejectsNullHandler() { + Validation valid = Validation.valid(10); + + assertThrows(NullPointerException.class, + () -> valid.getOrElse((java.util.function.Function) null)); + } + + @Test + void getOrElseWithHandlerRejectsNullHandlerResult() { + Validation invalid = Validation.invalid(Violation.of("e", "e")); + + assertThrows(NullPointerException.class, () -> invalid.getOrElse(err -> null)); + } + + @Test + void getOrNullReturnsValueWhenValid() { + assertEquals(10, Validation.valid(10).getOrNull()); + } + + @Test + void getOrNullReturnsNullWhenInvalid() { + Validation invalid = Validation.invalid(Violation.of("e", "e")); + + assertNull(invalid.getOrNull()); + } + + @Test + void toOptionalReturnsPresentWhenValid() { + Optional result = Validation.valid(10).toOptional(); + + assertTrue(result.isPresent()); + assertEquals(10, result.get()); + } + + @Test + void toOptionalReturnsEmptyWhenInvalid() { + Optional result = Validation.invalid(Violation.of("e", "e")).toOptional(); + + assertFalse(result.isPresent()); + } + + @Test + void onValidExecutesActionWhenValidAndReturnsSameInstance() { + Validation valid = Validation.valid(10); + AtomicReference captured = new AtomicReference<>(); + + Validation returned = valid.onValid(captured::set); + + assertSame(valid, returned); + assertEquals(10, captured.get()); + } + + @Test + void onValidSkipsActionWhenInvalidAndReturnsSameInstance() { + Validation invalid = Validation.invalid(Violation.of("e", "e")); + AtomicReference captured = new AtomicReference<>(); + + Validation returned = invalid.onValid(captured::set); + + assertSame(invalid, returned); + assertNull(captured.get()); + } + + @Test + void onValidRejectsNullAction() { + assertThrows(NullPointerException.class, + () -> Validation.valid(10).onValid(null)); + } + + @Test + void onInvalidExecutesActionWhenInvalidAndReturnsSameInstance() { + Violation error = Violation.of("e", "e"); + Validation invalid = Validation.invalid(error); + AtomicReference captured = new AtomicReference<>(); + + Validation returned = invalid.onInvalid(captured::set); + + assertSame(invalid, returned); + assertEquals(error, captured.get()); + } + + @Test + void onInvalidSkipsActionWhenValidAndReturnsSameInstance() { + Validation valid = Validation.valid(10); + AtomicReference captured = new AtomicReference<>(); + + Validation returned = valid.onInvalid(captured::set); + + assertSame(valid, returned); + assertNull(captured.get()); + } + + @Test + void onInvalidRejectsNullAction() { + assertThrows(NullPointerException.class, + () -> Validation.invalid(Violation.of("e", "e")).onInvalid(null)); + } + + @Test + void mapErrorPassesThroughWhenValid() { + Validation result = Validation.valid(10) + .mapError(Violation::code); + + assertTrue(result.isValid()); + assertEquals(10, result.get()); + } + + @Test + void mapErrorTransformsErrorWhenInvalid() { + Validation result = Validation.invalid(Violation.of("e", "msg")) + .mapError(Violation::code); + + assertTrue(result.isInvalid()); + assertEquals("e", result.getError()); + } + + @Test + void mapErrorRejectsNullFunction() { + assertThrows(NullPointerException.class, + () -> Validation.valid(10).mapError(null)); + } + + @Test + void recoverReturnsSelfWhenValid() { + Validation valid = Validation.valid(10); + Validation result = valid.recover(err -> 99); + + assertSame(valid, result); + assertEquals(10, result.get()); + } + + @Test + void recoverConvertsErrorToSuccessWhenInvalid() { + Validation result = Validation.invalid(Violation.of("e", "e")) + .recover(err -> 99); + + assertTrue(result.isValid()); + assertEquals(99, result.get()); + } + + @Test + void recoverRejectsNullFunction() { + assertThrows(NullPointerException.class, + () -> Validation.valid(10).recover(null)); + } }