package dev.inmo.tgbotapi.CommonAbstracts import dev.inmo.tgbotapi.types.captionLength import dev.inmo.tgbotapi.types.textLength typealias FullTextSourcesList = List typealias FullTextPartsList = List interface TextSource { val asMarkdownSource: String val asMarkdownV2Source: String val asHtmlSource: String val source: String } interface MultilevelTextSource : TextSource { val textParts: List } data class TextPart( val range: IntRange, val source: TextSource ) fun List.justTextSources() = map { it.source } fun List.makeString() = joinToString("") { it.source } fun List.separateForMessage(limit: IntRange, numberOfParts: Int? = null): List> { if (isEmpty()) { return emptyList() } val resultList = mutableListOf>(mutableListOf()) var currentPartLength = 0 val maxSize = limit.last + 1 for (current in this) { if (current.source.length > maxSize) { error("Currently unsupported parts with size more than target one-message parts (${current.source.length} > ${maxSize})") } if (currentPartLength + current.source.length > maxSize) { if (numberOfParts == null || numberOfParts < resultList.size) { resultList.add(mutableListOf()) currentPartLength = 0 } else { break } } resultList.last().add(current) currentPartLength += current.source.length } return resultList } /** * This method will prepare [TextSource]s list for messages. Remember, that first part will be separated with * [captionLength] and all others with */ fun List.separateForCaption(): List> { val captionPart = separateForMessage(captionLength, 1).first() return listOf(captionPart) + minus(captionPart).separateForMessage(textLength) } /** * This method will prepare [TextSource]s list for messages with [textLength] */ @Suppress("NOTHING_TO_INLINE") inline fun List.separateForText(): List> = separateForMessage(textLength)