diff --git a/kspoon/src/commonMain/kotlin/decoder/HtmlTag.kt b/kspoon/src/commonMain/kotlin/decoder/HtmlTag.kt index 70976be..74b44bf 100644 --- a/kspoon/src/commonMain/kotlin/decoder/HtmlTag.kt +++ b/kspoon/src/commonMain/kotlin/decoder/HtmlTag.kt @@ -19,20 +19,17 @@ internal sealed class HtmlTag { data class Index(val index: Int) : HtmlTag() } -internal fun createSelectorHtmlTag( - selector: String, - selectorAnnotation: Selector?, -) = HtmlTag.Selector( - selector = selector, - textMode = when (selectorAnnotation?.textMode) { +internal fun Selector.toHtmlTag() = HtmlTag.Selector( + selector = value, + textMode = when (textMode) { SelectorHtmlTextMode.Text -> HtmlTextMode.Text SelectorHtmlTextMode.InnerHtml -> HtmlTextMode.InnerHtml SelectorHtmlTextMode.OuterHtml -> HtmlTextMode.OuterHtml SelectorHtmlTextMode.Data -> HtmlTextMode.Data - SelectorHtmlTextMode.Default, null -> null + SelectorHtmlTextMode.Default -> null }, - attribute = selectorAnnotation?.attr?.handleNullability(), - index = selectorAnnotation?.index ?: 0, - defaultValue = selectorAnnotation?.defValue?.handleNullability(), - regex = selectorAnnotation?.regex?.handleNullability()?.toRegex(), + attribute = attr.handleNullability(), + index = index, + defaultValue = defValue.handleNullability(), + regex = regex.handleNullability()?.toRegex(), ) diff --git a/kspoon/src/commonMain/kotlin/decoder/HtmlTreeDecoder.kt b/kspoon/src/commonMain/kotlin/decoder/HtmlTreeDecoder.kt index 8caf9b0..7a53ec2 100644 --- a/kspoon/src/commonMain/kotlin/decoder/HtmlTreeDecoder.kt +++ b/kspoon/src/commonMain/kotlin/decoder/HtmlTreeDecoder.kt @@ -1,5 +1,3 @@ -@file:OptIn(ExperimentalSerializationApi::class, InternalSerializationApi::class) - package dev.burnoo.ksoup.decoder import com.fleeksoft.ksoup.nodes.Comment @@ -16,6 +14,7 @@ import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.InternalSerializationApi import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.StructureKind +import kotlinx.serialization.descriptors.capturedKClass import kotlinx.serialization.descriptors.elementNames import kotlinx.serialization.encoding.CompositeDecoder import kotlinx.serialization.internal.TaggedDecoder @@ -26,6 +25,7 @@ import kotlinx.serialization.modules.overwriteWith import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract +@OptIn(InternalSerializationApi::class, ExperimentalSerializationApi::class) internal class HtmlTreeDecoder internal constructor( private val elements: Elements, private val configuration: KspoonConfiguration, @@ -43,11 +43,17 @@ internal class HtmlTreeDecoder internal constructor( private var elementIndex = 0 override fun SerialDescriptor.getTag(index: Int): HtmlTag { - val selectorAnnotation = getSelectorAnnotations(index) - val selector = selectorAnnotation?.value ?: getElementName(index) - return when (val newIndex = selector.toIntOrNull()) { - null -> createSelectorHtmlTag(selector, selectorAnnotation) - else -> HtmlTag.Index(newIndex) + val selectorAnnotation = getElementSelectorAnnotation(index) + val newIndex = if (selectorAnnotation == null) { + getElementName(index).toIntOrNull() + } else { + null + } + return when { + selectorAnnotation != null -> selectorAnnotation.toHtmlTag() + newIndex != null -> HtmlTag.Index(newIndex) + isElementADocument(index) -> Selector(":root").toHtmlTag() + else -> error("Selector annotation not added for ${getElementDescriptor(index).serialName}") } } @@ -161,10 +167,15 @@ internal class HtmlTreeDecoder internal constructor( return if (matchResult.groupValues.size > 1) matchResult.groupValues[1] else matchResult.value } - private fun SerialDescriptor.getSelectorAnnotations(index: Int): Selector? { + private fun SerialDescriptor.getElementSelectorAnnotation(index: Int): Selector? { return getElementAnnotations(index).filterIsInstance().firstOrNull() } + private fun SerialDescriptor.isElementADocument(index: Int): Boolean { + val elementDescriptor = getElementDescriptor(index) + return elementDescriptor.serialName == "com.fleeksoft.ksoup.nodes.Document" || elementDescriptor.capturedKClass == Document::class + } + private fun Elements.getAtAsElements(index: Int) = getOrNull(index)?.let(::Elements) ?: Elements() inner class SerializerDecoder {