Skip to content

Commit 015d58d

Browse files
committed
Add support for Char type
1 parent f448048 commit 015d58d

File tree

2 files changed

+77
-5
lines changed
  • json-schema-validator-objects/src
    • commonMain/kotlin/io/github/optimumcode/json/schema/objects/wrapper
    • commonTest/kotlin/io/github/optimumcode/json/schema/objects/wrapper

2 files changed

+77
-5
lines changed

json-schema-validator-objects/src/commonMain/kotlin/io/github/optimumcode/json/schema/objects/wrapper/Wrappers.kt

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,28 @@ import kotlin.jvm.JvmOverloads
1414

1515
@ExperimentalApi
1616
public class WrappingConfiguration internal constructor(
17+
/**
18+
* If set to `false` an exception is thrown when wrapping a [Set].
19+
* If set to `true`, [Set] is wrapped the same way as [List]
20+
*/
1721
public val allowSets: Boolean = false,
22+
/**
23+
* If set to `false` the [Char] is converted to [String].
24+
* If set to `true` the [Char] is converted to a codepoint (and then to [Long])
25+
*/
26+
public val charAsCodepoint: Boolean = false,
1827
)
1928

2029
@ExperimentalApi
2130
@JvmOverloads
22-
public fun wrappingConfiguration(allowSets: Boolean = false): WrappingConfiguration = WrappingConfiguration(allowSets)
31+
public fun wrappingConfiguration(
32+
allowSets: Boolean = false,
33+
charAsCodepoint: Boolean = false,
34+
): WrappingConfiguration =
35+
WrappingConfiguration(
36+
allowSets = allowSets,
37+
charAsCodepoint = charAsCodepoint,
38+
)
2339

2440
/**
2541
* Returns an [AbstractElement] produced by converting the [obj] value.
@@ -36,6 +52,7 @@ public fun wrappingConfiguration(allowSets: Boolean = false): WrappingConfigurat
3652
* * [Float]
3753
* * [Double]
3854
* * [Boolean]
55+
* * [Char]
3956
* * `null`
4057
*
4158
* ## Structures:
@@ -47,6 +64,7 @@ public fun wrappingConfiguration(allowSets: Boolean = false): WrappingConfigurat
4764
* Please be aware that in order to have consistent verification results
4865
* the [Set] must be one of the ORDERED types, e.g. [LinkedHashSet].
4966
*/
67+
@JvmOverloads
5068
@ExperimentalApi
5169
public fun wrapAsElement(
5270
obj: Any?,
@@ -62,11 +80,13 @@ public fun wrapAsElement(
6280
obj is Set<*> && configuration.allowSets ->
6381
ListWrapper(obj.map { wrapAsElement(it, configuration) })
6482

65-
obj is String || obj is Number || obj is Boolean -> PrimitiveWrapper(numberToSupportedTypeOrOriginal(obj))
83+
isPrimitive(obj) -> PrimitiveWrapper(convertToSupportedType(obj, configuration))
6684
else -> error("unsupported type to wrap: ${obj::class}")
6785
}
6886
}
6987

88+
private fun isPrimitive(obj: Any): Boolean = obj is String || obj is Number || obj is Boolean || obj is Char
89+
7090
/**
7191
* Returns `true` if the [value] is an integer ([Byte], [Short], [Int], [Long]).
7292
* Otherwise, returns `false`.
@@ -76,9 +96,17 @@ public fun wrapAsElement(
7696
*/
7797
internal expect fun isInteger(value: Number): Boolean
7898

79-
private fun numberToSupportedTypeOrOriginal(obj: Any): Any =
99+
private fun convertToSupportedType(
100+
obj: Any,
101+
configuration: WrappingConfiguration,
102+
): Any =
80103
when {
81-
obj !is Number -> obj
104+
obj !is Number ->
105+
if (obj is Char) {
106+
if (configuration.charAsCodepoint) obj.code.toLong() else obj.toString()
107+
} else {
108+
obj
109+
}
82110
obj is Long -> obj
83111
isInteger(obj) -> obj.toLong()
84112
obj is Double -> obj

json-schema-validator-objects/src/commonTest/kotlin/io/github/optimumcode/json/schema/objects/wrapper/WrappersTest.kt

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class WrappersTest : FunSpec() {
3636
listOf<Any>() to ArrayElement::class,
3737
emptyArray<Any>() to ArrayElement::class,
3838
"test" to PrimitiveElement::class,
39+
't' to PrimitiveElement::class,
3940
42 to PrimitiveElement::class,
4041
42L to PrimitiveElement::class,
4142
42.2 to PrimitiveElement::class,
@@ -76,7 +77,7 @@ class WrappersTest : FunSpec() {
7677
}
7778
}
7879

79-
test("primitive wrapper for number") {
80+
test("primitive wrapper for integer number") {
8081
wrapAsElement(42).shouldBeInstanceOf<PrimitiveElement> { el ->
8182
assertSoftly {
8283
"isString".asClue { el.isString.shouldBeFalse() }
@@ -90,6 +91,20 @@ class WrappersTest : FunSpec() {
9091
}
9192
}
9293

94+
test("primitive wrapper for floating number") {
95+
wrapAsElement(42.5).shouldBeInstanceOf<PrimitiveElement> { el ->
96+
assertSoftly {
97+
"isString".asClue { el.isString.shouldBeFalse() }
98+
"isNumber".asClue { el.isNumber.shouldBeTrue() }
99+
"isBoolean".asClue { el.isBoolean.shouldBeFalse() }
100+
"isNull".asClue { el.isNull.shouldBeFalse() }
101+
"content".asClue { el.content shouldBe "42.5" }
102+
"longOrNull".asClue { el.longOrNull.shouldBeNull() }
103+
"doubleOrNull".asClue { el.doubleOrNull shouldBe 42.5 }
104+
}
105+
}
106+
}
107+
93108
test("primitive wrapper for string") {
94109
wrapAsElement("42").shouldBeInstanceOf<PrimitiveElement> { el ->
95110
assertSoftly {
@@ -104,6 +119,35 @@ class WrappersTest : FunSpec() {
104119
}
105120
}
106121

122+
test("primitive wrapper for char") {
123+
wrapAsElement('4').shouldBeInstanceOf<PrimitiveElement> { el ->
124+
assertSoftly {
125+
"isString".asClue { el.isString.shouldBeTrue() }
126+
"isNumber".asClue { el.isNumber.shouldBeFalse() }
127+
"isBoolean".asClue { el.isBoolean.shouldBeFalse() }
128+
"isNull".asClue { el.isNull.shouldBeFalse() }
129+
"content".asClue { el.content shouldBe "4" }
130+
"longOrNull".asClue { el.longOrNull.shouldBeNull() }
131+
"doubleOrNull".asClue { el.doubleOrNull.shouldBeNull() }
132+
}
133+
}
134+
}
135+
136+
test("primitive wrapper for char as codepoint") {
137+
wrapAsElement('4', wrappingConfiguration(charAsCodepoint = true))
138+
.shouldBeInstanceOf<PrimitiveElement> { el ->
139+
assertSoftly {
140+
"isString".asClue { el.isString.shouldBeFalse() }
141+
"isNumber".asClue { el.isNumber.shouldBeTrue() }
142+
"isBoolean".asClue { el.isBoolean.shouldBeFalse() }
143+
"isNull".asClue { el.isNull.shouldBeFalse() }
144+
"content".asClue { el.content shouldBe "52" }
145+
"longOrNull".asClue { el.longOrNull shouldBe 52L }
146+
"doubleOrNull".asClue { el.doubleOrNull.shouldBeNull() }
147+
}
148+
}
149+
}
150+
107151
test("object wrapper") {
108152
wrapAsElement(
109153
buildMap {

0 commit comments

Comments
 (0)