0

I have here an Enum:

enum class ColorEnum(
    @StringRes val textResource: Int,
): Abbrev {
    blu(R.string.blue) {
        override fun abbrev() = "bl"
    },
    red(R.string.red) {
        override fun abbrev() = "rd"
    },
    grn(R.string.green) {
        override fun abbrev() = "gr"
    },
    wht(R.string.white) {
        override fun abbrev() = "wh"
    },
    blk(R.string.black) {
        override fun abbrev() = "bl"
    },
    ylw(R.string.yellow) {
        override fun abbrev() = "yl"
    },
    brw(R.string.brown) {
        override fun abbrev() = "br"
    }
}

whereas the resources R.string.blue have correct written colors like "Blue", etc. in each language.

Imagine I have a string val colorString = "Blue" how do I map this to a colorEnum object?

val colorEnumItem = ColorEnum.valueOf("Blue")

did not work. But

val colorEnumItem = ColorEnum.valueOf("blu") did.

So how do I get the correct enum, from the long string resoruce like "Blue" ?

EDIT:I changed the example, so that the long string "Blue" and enum blu does not match.

Ralf Wickum
  • 2,850
  • 9
  • 55
  • 103
  • @Sweeper not really. Sorry for misleading question. I changed the OP – Ralf Wickum Mar 15 '23 at 10:20
  • So you are converting a *string* you got from a string resource to an enum constant with that same string resource? In general this is not possible because there can be ambiguities - the same string can be mapped to more than one string resource, and if you consider different languages, the same string could mean different colors in different languages. Do you have access to the string resource `Int`? Converting that to an enum constant is a much more viable option. – Sweeper Mar 15 '23 at 10:33
  • Perhaps [this](https://stackoverflow.com/q/34957155/5133585) could also help if you really only have the string. – Sweeper Mar 15 '23 at 10:36

1 Answers1

1

I'm not aware if there is convinient way to translate R.string.blue to its string representation in Android, but you can always do some manual job and extend ColorEnum with extra property that holds full color name:

enum class ColorEnum(
    @StringRes val textResource: Int,
    val colorName: String
): Abbrev {
    blu(R.string.blue, "Blue") {
        override fun abbrev() = "bl"
    },
    red(R.string.red, "rED") {
        override fun abbrev() = "rd"
    },

    //...and so on...

    brw(R.string.brown, "BROwn") {
        override fun abbrev() = "br"
    };

    companion object {
        private val map = values().associateBy { it.colorName.lowercase() } // to make it case-insensitive

        fun fromString(color: String) =
            map[color.lowercase()] ?: throw IllegalArgumentException("Color '$color' isn't registered")
    }
}

fun main() {
    println(ColorEnum.fromString("Blue"))
    println(ColorEnum.fromString("BLUE"))
    println(ColorEnum.fromString("blue"))
}

Output:

blu
blu
blu
Nikolai Shevchenko
  • 7,083
  • 8
  • 33
  • 42