Implemented integer value parser

This commit is contained in:
Akash Yadav
2022-11-05 09:53:28 +05:30
parent 86800e7e5e
commit 84cd92001e
4 changed files with 77 additions and 4 deletions
Binary file not shown.
@@ -0,0 +1,6 @@
<resources>
<integer name="test_integer_1">1</integer>
<integer name="test_integer_0">0</integer>
<integer name="test_integer_1_ref">@integer/test_integer_1</integer>
<integer name="test_integer_0_ref">@integer/test_integer_0</integer>
</resources>
@@ -29,9 +29,11 @@ import android.util.TypedValue.COMPLEX_UNIT_PX
import android.util.TypedValue.COMPLEX_UNIT_SP
import android.util.TypedValue.applyDimension
import android.view.ViewGroup.LayoutParams
import androidx.core.text.isDigitsOnly
import com.android.aaptcompiler.AaptResourceType
import com.android.aaptcompiler.AaptResourceType.BOOL
import com.android.aaptcompiler.AaptResourceType.DIMEN
import com.android.aaptcompiler.AaptResourceType.INTEGER
import com.android.aaptcompiler.BinaryPrimitive
import com.android.aaptcompiler.ConfigDescription
import com.android.aaptcompiler.Reference
@@ -62,6 +64,44 @@ fun endParse() {
currentModule = null
}
@JvmOverloads
fun parseInteger(value: String, def: Int = 0): Int {
if (value.isDigitsOnly()) {
return value.toInt()
}
if (value[0] == '@') {
val (pck, type, name) = parseResourceReference(value)
if (type != "integer") {
throwInvalidResType(INTEGER, value)
}
val integerResolver: (Value?) -> Int? = {
if (it is BinaryPrimitive) {
it.resValue.data
} else def
}
return if (pck == null) {
resolveUnqualifiedResourceReference(
type = INTEGER,
name = name,
value = value,
def = def,
resolver = integerResolver
)
} else {
resolveQualifiedResourceReference(
pck = pck,
type = INTEGER,
name = name,
def = def,
resolver = integerResolver
)
}
}
return def
}
@JvmOverloads
fun parseBoolean(value: String, def: Boolean = false): Boolean {
when (value) {
@@ -72,7 +112,7 @@ fun parseBoolean(value: String, def: Boolean = false): Boolean {
if (value[0] == '@') {
val (pck, type, name) = parseResourceReference(value)
if (type != "bool") {
throw IllegalArgumentException("Value must be a reference to a boolean resource. '$value'")
throwInvalidResType(BOOL, value)
}
val booleanResolver: (Value?) -> Boolean? =
fun(resValue): Boolean {
@@ -159,7 +199,7 @@ fun parseDimension(
} else if (c == '@') {
val (pck, type, name) = parseResourceReference(value)
if (type != "dimen") {
throw IllegalArgumentException("Value must be a dimension resource reference '$value'")
throwInvalidResType(DIMEN, value)
}
val resolver: (Value?) -> Int? = {
if (it is BinaryPrimitive) {
@@ -224,8 +264,7 @@ fun <T> resolveUnqualifiedResourceReference(
def: T,
resolver: (Value?) -> T?
): T {
val (table, _, pack, entry) =
lookupUnqualifedResource(type, name, value) ?: return def
val (table, _, pack, entry) = lookupUnqualifedResource(type, name, value) ?: return def
return resolveResourceReference(
table = table,
pck = pack,
@@ -324,3 +363,9 @@ private fun parseResourceReference(value: String): Triple<String?, String, Strin
return Triple<String?, String, String>(null, "", "")
}
private fun throwInvalidResType(type: AaptResourceType, value: String) {
throw IllegalArgumentException(
"Value must be a reference to a ${type.tagName} resource type. '$value'"
)
}
@@ -24,6 +24,7 @@ import com.itsaky.androidide.inflater.internal.utils.endParse
import com.itsaky.androidide.inflater.internal.utils.parseBoolean
import com.itsaky.androidide.inflater.internal.utils.parseDimension
import com.itsaky.androidide.inflater.internal.utils.parseDrawable
import com.itsaky.androidide.inflater.internal.utils.parseInteger
import com.itsaky.androidide.inflater.internal.utils.startParse
import org.junit.Test
import org.junit.runner.RunWith
@@ -98,4 +99,25 @@ class ValueParsersTest {
}
}
}
@Test
fun `integer parser test`() {
inflaterTest { module ->
requiresActivity { activity ->
startParse(module)
assertThat(parseInteger("0", def = 1)).isEqualTo(0)
assertThat(parseInteger("10")).isEqualTo(10)
assertThat(parseInteger("110")).isEqualTo(110)
assertThat(parseInteger("@android:integer/button_pressed_animation_duration")).isEqualTo(100)
assertThat(parseInteger("@android:integer/dock_enter_exit_duration")).isEqualTo(250)
assertThat(parseInteger("@android:integer/kg_carousel_angle")).isEqualTo(75)
assertThat(parseInteger("@android:integer/date_picker_mode")).isEqualTo(1)
assertThat(parseInteger("@integer/test_integer_1")).isEqualTo(1)
assertThat(parseInteger("@integer/test_integer_1_ref")).isEqualTo(1)
assertThat(parseInteger("@integer/test_integer_0", def = 1)).isEqualTo(0)
assertThat(parseInteger("@integer/test_integer_0_ref", def = 1)).isEqualTo(0)
endParse()
}
}
}
}