Advertisement
Roctik

obj decode/encode for compose navigation

Mar 20th, 2025
2,828
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 2.13 KB | None | 0 0
  1. import kotlin.reflect.full.memberProperties
  2. import kotlin.reflect.full.primaryConstructor
  3. import java.net.URLEncoder
  4. import java.net.URLDecoder
  5. import java.nio.charset.StandardCharsets
  6.  
  7. fun String.encodeToUtf8(): String = URLEncoder.encode(this, StandardCharsets.UTF_8.toString())
  8.  
  9. fun String.decodeFromUtf8(): String = URLDecoder.decode(this, StandardCharsets.UTF_8.toString())
  10.  
  11. fun Any?.encodedIfPossible(): Any? {
  12.     return when (this) {
  13.         is String -> this.encodeToUtf8()
  14.         is List<*> -> this.map { it.encodedIfPossible() }
  15.         is Set<*> -> this.map { it.encodedIfPossible() }.toSet()
  16.         is Map<*, *> -> this.mapValues { it.value.encodedIfPossible() }
  17.         else -> this?.let { if (it::class.isData) it.encodedStrings() else it }
  18.     }
  19. }
  20.  
  21. fun <T : Any> T.encodedStrings(): T {
  22.     val clazz = this::class
  23.     val constructor = clazz.primaryConstructor
  24.         ?: throw IllegalArgumentException("Class ${clazz.simpleName} must have a primary constructor")
  25.  
  26.     val args = constructor.parameters.associateWith { param ->
  27.         val property = clazz.memberProperties.firstOrNull { it.name == param.name }
  28.         val value = property?.call(this)
  29.  
  30.         value.encodedIfPossible()
  31.     }
  32.  
  33.     return constructor.callBy(args)
  34. }
  35.  
  36. fun Any?.decodedIfPossible(): Any? {
  37.     return when (this) {
  38.         is String -> this.decodeFromUtf8()
  39.         is List<*> -> this.map { it.decodedIfPossible() }
  40.         is Set<*> -> this.map { it.decodedIfPossible() }.toSet()
  41.         is Map<*, *> -> this.mapValues { it.value.decodedIfPossible() }
  42.         else -> this?.let { if (it::class.isData) it.decodedStrings() else it }
  43.     }
  44. }
  45.  
  46. fun <T : Any> T.decodedStrings(): T {
  47.     val clazz = this::class
  48.     val constructor = clazz.primaryConstructor
  49.         ?: throw IllegalArgumentException("Class ${clazz.simpleName} must have a primary constructor")
  50.  
  51.     val args = constructor.parameters.associateWith { param ->
  52.         val property = clazz.memberProperties.firstOrNull { it.name == param.name }
  53.         val value = property?.call(this)
  54.  
  55.         value.decodedIfPossible()
  56.     }
  57.  
  58.     return constructor.callBy(args)
  59. }
  60.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement