Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/keyed enum #98

Merged
merged 5 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
buildscript {
ext {
// App version
versionName = '2.2.1'
versionName = '2.2.2'
versionCode = 1

// SDK and tools
Expand Down
8 changes: 5 additions & 3 deletions maven-publish-helper.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,11 @@ afterEvaluate {
version = android.defaultConfig.versionName // or just '1.0'

pom {
signing {
sign publishing.publications.release
sign configurations.archives
if (!project.hasProperty('skip.signing')) {
signing {
sign publishing.publications.release
sign configurations.archives
}
}
name = "substrate-sdk-android"
description = "Nova Substrate SDK is a native Android library to help developers build native mobile apps for Substrate-based networks, e.g. Polkadot, Kusama & parachains"
Expand Down
2 changes: 1 addition & 1 deletion sr25519-java/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "sr25519java"
version = "0.1.0"
authors = ['Novasama Technologies']
edition = "2018"
edition = "2021"

[dependencies]
zeroize = { version="<=1.1.1" }
Expand Down
2 changes: 2 additions & 0 deletions substrate-sdk-android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ publishing {
android {
compileSdkVersion rootProject.compileVersion

ndkVersion "26.1.10909125"

defaultConfig {
minSdkVersion rootProject.minVersion
targetSdkVersion rootProject.targetVersion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import io.novasama.substrate_sdk_android.runtime.definitions.types.TypeReference
import io.novasama.substrate_sdk_android.runtime.definitions.types.errors.EncodeDecodeException
import io.novasama.substrate_sdk_android.runtime.definitions.types.skipAliasesOrNull

@OptIn(ExperimentalUnsignedTypes::class)
open class DictEnum(
name: String,
val elements: Map<Int, Entry<TypeReference>>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
@file:OptIn(ExperimentalUnsignedTypes::class)

package io.novasama.substrate_sdk_android.runtime.metadata.v14

import io.novasama.substrate_sdk_android.runtime.metadata.StorageEntryModifier
Expand All @@ -19,11 +17,11 @@ import io.novasama.substrate_sdk_android.scale.vector

abstract class PostV14MetadataSchema<S : PostV14MetadataSchema<S>> : Schema<S>() {

abstract val lookup: Field<EncodableStruct<LookupSchema>>
abstract val lookup: Field<out EncodableStruct<LookupSchema>>

abstract val pallets: Field<List<EncodableStruct<PostV14PalletMetadataSchema<*>>>>
abstract val pallets: Field<out List<EncodableStruct<PostV14PalletMetadataSchema<*>>>>

abstract val extrinsic: Field<EncodableStruct<PostV14ExtrinsicMetadataSchema<*>>>
abstract val extrinsic: Field<out EncodableStruct<PostV14ExtrinsicMetadataSchema<*>>>
}

abstract class PostV14ExtrinsicMetadataSchema<S : PostV14ExtrinsicMetadataSchema<S>> : Schema<S>() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
@file:OptIn(ExperimentalUnsignedTypes::class)

package io.novasama.substrate_sdk_android.runtime.metadata.v14

import io.novasama.substrate_sdk_android.scale.compactInt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import io.novasama.substrate_sdk_android.scale.dataType.byte
import io.novasama.substrate_sdk_android.scale.dataType.byteArray
import io.novasama.substrate_sdk_android.scale.dataType.byteArraySized
import io.novasama.substrate_sdk_android.scale.dataType.compactInt
import io.novasama.substrate_sdk_android.scale.dataType.keyedUnion
import io.novasama.substrate_sdk_android.scale.dataType.list
import io.novasama.substrate_sdk_android.scale.dataType.long
import io.novasama.substrate_sdk_android.scale.dataType.scalable
Expand Down Expand Up @@ -84,8 +85,18 @@ fun <S : Schema<S>> S.byteArray(default: ByteArray? = null): NonNullFieldDelegat

fun <S : Schema<S>> S.long(default: Long? = null) = NonNullFieldDelegate(long, this, default)

@Deprecated(
message = "Use keyedEnum instead. Check API changes",
replaceWith = ReplaceWith("keyedEnum(*types)")
)
fun <S : Schema<S>> S.enum(vararg types: DataType<*>, default: Any? = null) = NonNullFieldDelegate(union(types), this, default)

fun <S : Schema<S>> S.keyedEnum(vararg types: DataType<*>, default: Pair<Int, Any?>? = null) = NonNullFieldDelegate(
keyedUnion(types.withIndex().associate { (index, dataType) -> index to dataType }),
this,
default
)

fun <S : Schema<S>, E : Enum<E>> S.enum(enumClass: KClass<E>, default: E? = null) = NonNullFieldDelegate(EnumType(enumClass.java), this, default)

fun <S : Schema<S>, T> S.custom(type: DataType<T>, default: T? = null) = NonNullFieldDelegate(type, this, default)
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package io.novasama.substrate_sdk_android.scale

import io.novasama.substrate_sdk_android.scale.dataType.DataType
import io.novasama.substrate_sdk_android.scale.dataType.optional
import io.novasama.substrate_sdk_android.scale.dataType.string

class Field<out T>(val dataType: DataType<out T>, val defaultValue: T? = null)
class Field<T>(val dataType: DataType<T>, val defaultValue: T? = null)

@Suppress("UNCHECKED_CAST", "unused")
class EncodableStruct<out S : Schema<out S>>(val schema: S) {
Expand Down Expand Up @@ -41,4 +42,4 @@ class EncodableStruct<out S : Schema<out S>>(val schema: S) {

fun <S : Schema<S>> EncodableStruct<S>.toHexString() = schema.toHexString(this)

fun <S : Schema<S>> EncodableStruct<S>.toByteArray() = schema.toByteArray(this)
fun <S : Schema<S>> EncodableStruct<S>.toByteArray() = schema.toByteArray(this)
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ abstract class Schema<S : Schema<S>> :

for (field in fields) {
val value = field.dataType.read(reader)
struct[field] = value
struct[field as Field<Any?>] = value
}

return struct
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ class CollectionEnumType(
}
}

@Deprecated("Use keyedUnion instead")
class union(val dataTypes: Array<out DataType<*>>) : DataType<Any?>() {
override fun read(reader: ScaleCodecReader): Any? {
val typeIndex = reader.readByte()
Expand Down Expand Up @@ -170,3 +171,26 @@ class union(val dataTypes: Array<out DataType<*>>) : DataType<Any?>() {
return dataTypes.any { it.conformsType(value) }
}
}

class keyedUnion(val dataTypes: Map<Int, DataType<*>>) : DataType<Pair<Int, Any?>>() {
override fun conformsType(value: Any?): Boolean {
val (index, originalValue) = value as Pair<Int, Any?>
return dataTypes.getValue(index).conformsType(originalValue)
}

override fun read(reader: ScaleCodecReader): Pair<Int, Any?> {
val typeIndex = reader.readByte().toInt()
val type = dataTypes.getValue(typeIndex)

return typeIndex to type.read(reader)
}

override fun write(writer: ScaleCodecWriter, value: Pair<Int, Any?>) {
val (typeIndex, originalValue) = value

val type = dataTypes[typeIndex] as DataType<Any?>

writer.write(uint8, typeIndex.toUByte())
writer.write(type, originalValue)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import io.novasama.substrate_sdk_android.scale.DefaultValues.bytes
import io.novasama.substrate_sdk_android.scale.DefaultValues.text
import io.novasama.substrate_sdk_android.scale.Vector.numbers
import io.novasama.substrate_sdk_android.scale.dataType.DataType
import io.novasama.substrate_sdk_android.scale.dataType.byteArraySized
import io.novasama.substrate_sdk_android.scale.dataType.compactInt
import io.novasama.substrate_sdk_android.scale.dataType.scalable
import io.novasama.substrate_sdk_android.scale.dataType.string
Expand Down Expand Up @@ -129,6 +130,18 @@ object DefaultValues : Schema<DefaultValues>() {
val bigInteger by uint128(default = BIG_INT_DEFAULT)
}

object KeyedEnumSameTypeTest : Schema<KeyedEnumSameTypeTest>() {
const val FIRST_VALUE_INDEX = 0

val value by keyedEnum(byteArraySized(3), byteArraySized(2))
}

object KeyedEnumDifferentTypeTest : Schema<KeyedEnumDifferentTypeTest>() {
const val SECOND_VALUE_INDEX = 1

val value by keyedEnum(Bool, byteArraySized(2))
}

@RunWith(MockitoJUnitRunner::class)
class ScaleStructTest {
@Test
Expand Down Expand Up @@ -264,6 +277,19 @@ class ScaleStructTest {
assertEquals(enum2.toHexString(), "0x002a")
}

@Test
fun `should handle keyed enum`() {
val sameTypeEnum = KeyedEnumSameTypeTest {
it[KeyedEnumSameTypeTest.value] = KeyedEnumSameTypeTest.FIRST_VALUE_INDEX to byteArrayOf(1, 2, 3)
}
assertEquals(sameTypeEnum.toHexString(), "0x00010203")

val differentTypeEnum = KeyedEnumDifferentTypeTest {
it[KeyedEnumDifferentTypeTest.value] = KeyedEnumDifferentTypeTest.SECOND_VALUE_INDEX to byteArrayOf(1, 2)
}
assertEquals(differentTypeEnum.toHexString(), "0x010102")
}

@Test
fun `should handle enum with structs`() {
val enum1 = EnumTest2 {
Expand Down
Loading