Skip to content

Commit

Permalink
Feature/keyed enum (#98)
Browse files Browse the repository at this point in the history
* Support newer rust versions

* Better type safety for Struct dsl

* added keyedEnum data type

* version increment, skip signing parameter

* Remove redundant code

---------

Co-authored-by: Valentun <[email protected]>
Co-authored-by: Den <[email protected]>
  • Loading branch information
3 people authored Nov 19, 2024
1 parent 97e7a39 commit d08d350
Show file tree
Hide file tree
Showing 12 changed files with 77 additions and 16 deletions.
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

0 comments on commit d08d350

Please sign in to comment.