Repository: ktorio/ktor
File: ktor-shared/ktor-resources/common/src/io/ktor/resources/serialization/ResourcesFormat.kt (Kotlin)

Code before:
    /**
     * Builds a description of query parameters for a given [serializer]
     *
     * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.resources.serialization.ResourcesFormat.encodeToQueryParameters)
     */
    public fun <T> encodeToQueryParameters(serializer: KSerializer<T>): Set<Parameter> {
        val path = encodeToPathPattern(serializer)

        val allParameters = mutableSetOf<Parameter>()
        collectAllParameters(serializer.descriptor, allParameters)

        return allParameters
            .filterNot { (name, _) ->
                path.contains("{$name}") || path.contains("{$name?}") || path.contains("{$name...}")
            }
            .toSet()
    }

    private fun collectAllParameters(descriptor: SerialDescriptor, result: MutableSet<Parameter>) {
        descriptor.elementNames.forEach { name ->
            val index = descriptor.getElementIndex(name)
            val elementDescriptor = descriptor.getElementDescriptor(index)
            if (!elementDescriptor.isInline && (elementDescriptor.kind is StructureKind.CLASS || elementDescriptor.kind is StructureKind.OBJECT)) {
                collectAllParameters(elementDescriptor, result)
            } else {
                result.add(Parameter(name, descriptor.isElementOptional(index)))
            }
        }
    }

    /**
     * Builds [Parameters] for a resource [T]
     *
     * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.resources.serialization.ResourcesFormat.encodeToParameters)
     */
    public fun <T> encodeToParameters(serializer: KSerializer<T>, value: T): Parameters {
        val encoder = ParametersEncoder(serializersModule)
        encoder.encodeSerializableValue(serializer, value)
        return encoder.parameters
    }

    /**
     * Builds a [T] resource instance from [parameters]
     *
     * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.resources.serialization.ResourcesFormat.decodeFromParameters)
     */
    public fun <T> decodeFromParameters(deserializer: KSerializer<T>, parameters: Parameters): T {
        val input = ParametersDecoder(serializersModule, parameters, emptyList())
        return input.decodeSerializableValue(deserializer)
    }
}

Review comment (suggestion):
The condition would make more sense as an `else if (elementDescriptor.kind !is StructureKind.OBJECT)` to ignore object parameters, since by their nature there will not be any parameters to collect on them.

Code after:
    /**
     * Builds a description of query parameters for a given [serializer]
     *
     * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.resources.serialization.ResourcesFormat.encodeToQueryParameters)
     */
    public fun <T> encodeToQueryParameters(serializer: KSerializer<T>): Set<Parameter> {
        val path = encodeToPathPattern(serializer)

        val allParameters = mutableSetOf<Parameter>()
        collectAllParameters(serializer.descriptor, allParameters)

        return allParameters
            .filterNot { (name, _) ->
                path.contains("{$name}") || path.contains("{$name?}") || path.contains("{$name...}")
            }
            .toSet()
    }

    private fun collectAllParameters(descriptor: SerialDescriptor, result: MutableSet<Parameter>) {
        descriptor.elementNames.forEach { name ->
            val index = descriptor.getElementIndex(name)
            val elementDescriptor = descriptor.getElementDescriptor(index)
            if (!elementDescriptor.isInline && elementDescriptor.kind is StructureKind.CLASS) {
                collectAllParameters(elementDescriptor, result)
            } else if (elementDescriptor.kind !is StructureKind.OBJECT) {
                result.add(Parameter(name, descriptor.isElementOptional(index)))
            }
        }
    }

    /**
     * Builds [Parameters] for a resource [T]
     *
     * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.resources.serialization.ResourcesFormat.encodeToParameters)
     */
    public fun <T> encodeToParameters(serializer: KSerializer<T>, value: T): Parameters {
        val encoder = ParametersEncoder(serializersModule)
        encoder.encodeSerializableValue(serializer, value)
        return encoder.parameters
    }

    /**
     * Builds a [T] resource instance from [parameters]
     *
     * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.resources.serialization.ResourcesFormat.decodeFromParameters)
     */
    public fun <T> decodeFromParameters(deserializer: KSerializer<T>, parameters: Parameters): T {
        val input = ParametersDecoder(serializersModule, parameters, emptyList())
        return input.decodeSerializableValue(deserializer)
    }
}