types
types copied to clipboard
💡 The `create` and `createOrNull` factory functions
📝 Description
Originally discussed in #335.
We would like to redesign our factory functions by introducing new create and createOrNull factory functions for creating our stable types with the following behavior:
createfunctions should throw an exception in case of invalid inputscreateOrNullfunctions should returnnullin case of invalid inputs.
Here's the goal of API that we should provide after completing this topic:
// In kotools.types.number package
fun StrictlyPositiveInt.Companion.create(number: Number): StrictlyPositiveInt
fun StrictlyPositiveInt.Companion.create(number: Number, message: (Number) -> Any): StrictlyPositiveInt
fun StrictlyPositiveInt.Companion.createOrNull(number: Number): StrictlyPositiveInt?
fun StrictlyNegativeInt.Companion.create(number: Number): StrictlyNegativeInt
fun StrictlyNegativeInt.Companion.create(number: Number, message: (Number) -> Any): StrictlyNegativeInt
fun StrictlyNegativeInt.Companion.createOrNull(number: Number): StrictlyNegativeInt?
fun PositiveInt.Companion.create(number: Number): PositiveInt
fun PositiveInt.Companion.create(number: Number, message: (Number) -> Any): PositiveInt
fun PositiveInt.Companion.createOrNull(number: Number): PositiveInt?
fun NegativeInt.Companion.create(number: Number): NegativeInt
fun NegativeInt.Companion.create(number: Number, message: (Number) -> Any): NegativeInt
fun NegativeInt.Companion.createOrNull(number: Number): NegativeInt?
fun NonZeroInt.Companion.create(number: Number): NonZeroInt
fun NonZeroInt.Companion.create(number: Number, message: (Number) -> Any): NonZeroInt
fun NonZeroInt.Companion.createOrNull(number: Number): NonZeroInt?
// In kotools.types.text package
fun NotBlankString.Companion.create(value: Any): NotBlankString
fun NotBlankString.Companion.create(value: Any, message: (Any) -> Any): NotBlankString
fun NotBlankString.Companion.createOrNull(value: Any): NotBlankString?
// In kotools.types.collection package
fun <E> NotEmptyList.Companion.create(collection: Collection<E>): NotEmptyList<E>
fun <E> NotEmptyList.Companion.create(collection: Collection<E>, message: (Collection<E>) -> Any): NotEmptyList<E>
fun <E> NotEmptyList.Companion.createOrNull(collection: Collection<E>): NotEmptyList<E>?
fun <E> NotEmptyList.Companion.of(head: E, vararg tail: E): NotEmptyList<E>
fun <E> NotEmptySet.Companion.create(collection: Collection<E>): NotEmptySet<E>
fun <E> NotEmptySet.Companion.create(collection: Collection<E>, message: (Collection<E>) -> Any): NotEmptySet<E>
fun <E> NotEmptySet.Companion.createOrNull(collection: Collection<E>): NotEmptySet<E>?
fun <E> NotEmptySet.Companion.of(head: E, vararg tail: E): NotEmptySet<E>
fun <K, V> NotEmptyMap.Companion.create(map: Map<K, V>): NotEmptyMap<K, V>
fun <K, V> NotEmptyMap.Companion.create(map: Map<K, V>, message: (Map<K, V>) -> Any): NotEmptyMap<K, V>
fun <K, V> NotEmptyMap.Companion.createOrNull(map: Map<K, V>): NotEmptyMap<K, V>?
fun <K, V> NotEmptyMap.Companion.of(head: Pair<K, V>, tail: Pair<K, V>): NotEmptyMap<K, V>
✅ Checklist
- [ ] Wait for the completion of the issues below.
- [ ] Close this topic as completed and update tracking issues if present.
For the StrictlyPositiveInt type:
- [x] #342
- [x] #597
- [x] #438
- [x] #440
- [x] #442
- [x] #443
- [x] #444
- [x] #445
- [x] #446
- [x] #447
- [x] #448
- [x] #449
For the StrictlyNegativeInt type:
- [x] #347
- [x] #598
- [x] #439
- [x] #441
- [x] #450
- [x] #451
- [x] #452
- [x] #453
- [x] #454
- [x] #455
- [x] #456
- [x] #457
For the PositiveInt type:
- [x] #349
- [x] #458
- [x] #459
- [x] #460
- [x] #461
- [x] #462
- [x] #463
- [x] #464
- [x] #465
- [x] #466
- [ ] ✨ New
PositiveInt.Companion.createfunction with custom message
For the NegativeInt type:
- [x] #350
- [x] #467
- [x] #468
- [x] #469
- [x] #470
- [x] #471
- [x] #472
- [x] #473
- [x] #474
- [x] #475
- [ ] ✨ New
NegativeInt.Companion.createfunction with custom message
For the NonZeroInt type:
- [x] #351
- [x] #476
- [x] #477
- [x] #478
- [x] #479
- [x] #480
- [x] #481
- [x] #482
- [x] #483
- [x] #484
- [ ] ✨ New
NonZeroInt.Companion.createfunction with custom message
For the NotBlankString type:
- [x] #341
- [x] #541
- [x] #412
- [x] #395
- [x] #396
- [x] #397
- [x] #398
- [x] #399
- [x] #400
- [x] #401
- [x] #402
- [x] #403
- [ ] ✨ New
NotBlankString.Companion.createfunction with custom message
For the NotEmptyList type:
- [x] #352
- [x] #497
- [x] #498
- [x] #499
- [x] #500
- [x] #501
- [x] #502
- [x] #503
- [x] #504
- [x] #505
- [x] #506
- [x] #507
- [x] #508
- [x] #509
- [x] #510
- [ ] ✨ New
NotEmptyList.Companion.createfunction with custom message
For the NotEmptySet type:
- [x] #353
- [x] #511
- [x] #512
- [x] #513
- [x] #514
- [x] #515
- [x] #516
- [x] #517
- [x] #518
- [x] #519
- [x] #520
- [x] #521
- [x] #522
- [x] #523
- [x] #524
- [ ] ✨ New
NotEmptySet.Companion.createfunction with custom message
For the NotEmptyMap type:
- [x] #354
- [x] #525
- [x] #526
- [x] #527
- [x] #528
- [x] #529
- [x] #530
- [x] #531
- [x] #532
- [x] #533
- [x] #534
- [ ] ✨ New
NotEmptyMap.Companion.createfunction with custom message
Like pointed out by the Kotlin community on Reddit, it may be useful to define an overload of the create functions accepting a custom message for the exception thrown in case of invalid input.
Here's an example for the PositiveInt type:
fun PositiveInt.Companion.create(number: Number, message: (Number) -> Any): PositiveInt
Here's an example of calling this function from Kotlin code:
val number: PositiveInt = PositiveInt.create(1) {
"$it should be greater than or equal to zero."
}
println(number) // 1
Here's the same example of calling this function, but from Java code:
final PositiveInt result = PositiveInt.Companion.create(
1,
number -> number + " should be greater than or equal to zero."
);
System.out.println(result); // 1
If the specified message has a blank string representation, then it is ignored.
PositiveInt.create(-1) { " " } // throws an IllegalArgumentException with a generic message
This idea not being essential for now, we should write it in a new discussion instead.
Like suggested by @lbunschoten in https://github.com/kotools/types/discussions/335#discussioncomment-8904063, we could mark these functions with the JvmStatic annotation for improving user experience on Java. See the Kotlin documentation on that topic.
Ideas like that should be documented in GitHub Discussions instead.