diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/Captioned.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/Captioned.kt index e9145102ab..5d55cc4854 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/Captioned.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/Captioned.kt @@ -23,4 +23,4 @@ interface CaptionedInput : Captioned { * Convert its [CaptionedInput.captionEntities] to list of [dev.inmo.tgbotapi.CommonAbstracts.TextSource] * with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource] */ -fun CaptionedInput.fullEntitiesList(): FullTextSourcesList = caption ?.fullListOfSubSource(captionEntities) ?.map { it.source } ?: emptyList() +fun CaptionedInput.fullEntitiesList(): TextSourcesList = caption ?.fullListOfSubSource(captionEntities) ?.map { it.source } ?: emptyList() diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/Explained.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/Explained.kt index dd1e659658..40770b027c 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/Explained.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/Explained.kt @@ -29,4 +29,4 @@ interface ExplainedInput : Explained { * Convert its [ExplainedInput.explanationEntities] to list of [dev.inmo.tgbotapi.CommonAbstracts.TextSource] * with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource] */ -fun ExplainedInput.fullEntitiesList(): FullTextSourcesList = explanation ?.fullListOfSubSource(explanationEntities) ?.map { it.source } ?: emptyList() +fun ExplainedInput.fullEntitiesList(): TextSourcesList = explanation ?.fullListOfSubSource(explanationEntities) ?.map { it.source } ?: emptyList() diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/TextSource.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/TextSource.kt index bf20cd6b82..aac31893f5 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/TextSource.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/TextSource.kt @@ -1,10 +1,16 @@ package dev.inmo.tgbotapi.CommonAbstracts +import dev.inmo.tgbotapi.types.MessageEntity.textsources.regular import dev.inmo.tgbotapi.types.MessageEntity.toTextParts import dev.inmo.tgbotapi.types.captionLength import dev.inmo.tgbotapi.types.textLength +const val DirectInvocationOfTextSourceConstructor = "It is strongly not recommended to use constructors directly instead of factory methods" + +typealias TextSourcesList = List +@Deprecated("All lists of TextSource in public API now are full. So, this typealias is redundant") typealias FullTextSourcesList = List +@Deprecated("All lists of TextPart in public API now are full. So, this typealias is redundant") typealias FullTextPartsList = List interface TextSource { @@ -12,8 +18,19 @@ interface TextSource { val asMarkdownV2Source: String val asHtmlSource: String val source: String + + val asText: String + get() = source } +@Suppress("NOTHING_TO_INLINE") +inline operator fun TextSource.plus(other: TextSource) = listOf(this, other) +@Suppress("NOTHING_TO_INLINE") +inline operator fun TextSource.plus(other: List) = listOf(this) + other +@Suppress("NOTHING_TO_INLINE") +inline operator fun TextSource.plus(text: String) = listOf(this, regular(text)) +@Suppress("NOTHING_TO_INLINE") +inline operator fun List.plus(text: String) = this + regular(text) interface MultilevelTextSource : TextSource { @Deprecated("Will be removed in near major release") diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/Texted.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/Texted.kt index b28b796591..9b5ade197b 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/Texted.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/CommonAbstracts/Texted.kt @@ -29,4 +29,4 @@ interface TextedInput : Texted { * Convert its [TextedInput.textEntities] to list of [dev.inmo.tgbotapi.CommonAbstracts.TextSource] * with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource] */ -fun TextedInput.fullEntitiesList(): FullTextSourcesList = text ?.fullListOfSubSource(textEntities) ?.map { it.source } ?: emptyList() +fun TextedInput.fullEntitiesList(): TextSourcesList = text ?.fullListOfSubSource(textEntities) ?.map { it.source } ?: emptyList() diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/RawMessageEntity.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/RawMessageEntity.kt index ce48f51baa..e41728b732 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/RawMessageEntity.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/RawMessageEntity.kt @@ -28,7 +28,7 @@ internal fun RawMessageEntity.asTextParts( "mention" -> MentionTextSource(sourceSubstring, shiftedSubSources) "hashtag" -> HashTagTextSource(sourceSubstring, shiftedSubSources) "cashtag" -> CashTagTextSource(sourceSubstring, shiftedSubSources) - "bot_command" -> BotCommandTextSource(sourceSubstring, shiftedSubSources) + "bot_command" -> BotCommandTextSource(sourceSubstring) "url" -> URLTextSource(sourceSubstring) "email" -> EMailTextSource(sourceSubstring, shiftedSubSources) "phone_number" -> PhoneNumberTextSource(sourceSubstring, shiftedSubSources) @@ -130,6 +130,12 @@ internal fun List.toTextParts(preOffset: Int = 0): List { } } +fun String.removeLeading(word: String) = if (startsWith(word)){ + substring(word.length) +} else { + this +} + internal fun List.toRawMessageEntities(): List = toTextParts().asRawMessageEntities() internal fun RawMessageEntities.asTextParts(sourceString: String): List = sourceString.fullListOfSubSource( diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/BoldTextSource.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/BoldTextSource.kt index 882f2df3ea..41345fe1e0 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/BoldTextSource.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/BoldTextSource.kt @@ -4,7 +4,10 @@ import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.types.MessageEntity.toTextParts import dev.inmo.tgbotapi.utils.* -class BoldTextSource( +/** + * @see bold + */ +data class BoldTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( override val source: String, override val textSources: List ) : MultilevelTextSource { @@ -13,7 +16,9 @@ class BoldTextSource( override val asHtmlSource: String by lazy { boldHTML() } } -@Suppress("NOTHING_TO_INLINE") -inline fun bold(text: String) = BoldTextSource(text, emptyList()) @Suppress("NOTHING_TO_INLINE") inline fun bold(parts: List) = BoldTextSource(parts.makeString(), parts) +@Suppress("NOTHING_TO_INLINE") +inline fun bold(vararg parts: TextSource) = bold(parts.toList()) +@Suppress("NOTHING_TO_INLINE") +inline fun bold(text: String) = bold(regular(text)) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/BotCommandTextSource.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/BotCommandTextSource.kt index 44a8be5e94..ed79857629 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/BotCommandTextSource.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/BotCommandTextSource.kt @@ -1,19 +1,28 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources import dev.inmo.tgbotapi.CommonAbstracts.* +import dev.inmo.tgbotapi.types.MessageEntity.removeLeading import dev.inmo.tgbotapi.utils.* private val commandRegex = Regex("[/!][^@\\s]*") -class BotCommandTextSource( - override val source: String, - override val textSources: List -) : MultilevelTextSource { +/** + * @see botCommand + */ +data class BotCommandTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( + override val source: String +) : TextSource { val command: String by lazy { commandRegex.find(source) ?.value ?.substring(1) ?: source.substring(1)// skip first symbol like "/" or "!" } override val asMarkdownSource: String by lazy { source.commandMarkdown() } - override val asMarkdownV2Source: String by lazy { commandMarkdownV2() } - override val asHtmlSource: String by lazy { commandHTML() } + override val asMarkdownV2Source: String by lazy { source.commandMarkdownV2() } + override val asHtmlSource: String by lazy { source.commandHTML() } } + +/** + * @param command Without leading "/" + */ +@Suppress("NOTHING_TO_INLINE") +inline fun botCommand(command: String) = BotCommandTextSource("/$command") diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/CashTagTextSource.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/CashTagTextSource.kt index b421977893..504a5ebe2f 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/CashTagTextSource.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/CashTagTextSource.kt @@ -3,7 +3,10 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.utils.* -class CashTagTextSource( +/** + * @see cashTag + */ +data class CashTagTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( override val source: String, override val textSources: List ) : MultilevelTextSource { @@ -11,3 +14,10 @@ class CashTagTextSource( override val asMarkdownV2Source: String by lazy { cashTagMarkdownV2() } override val asHtmlSource: String by lazy { cashTagHTML() } } + +@Suppress("NOTHING_TO_INLINE") +inline fun cashTag(parts: List) = CashTagTextSource(parts.makeString(), parts) +@Suppress("NOTHING_TO_INLINE") +inline fun cashTag(vararg parts: TextSource) = cashTag(parts.toList()) +@Suppress("NOTHING_TO_INLINE") +inline fun cashTag(tag: String) = cashTag(regular(tag)) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/CodeTextSource.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/CodeTextSource.kt index c47cbbdb91..d4102a622e 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/CodeTextSource.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/CodeTextSource.kt @@ -1,12 +1,19 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources +import dev.inmo.tgbotapi.CommonAbstracts.DirectInvocationOfTextSourceConstructor import dev.inmo.tgbotapi.CommonAbstracts.TextSource import dev.inmo.tgbotapi.utils.* -class CodeTextSource( +/** + * @see code + */ +data class CodeTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( override val source: String ) : TextSource { override val asMarkdownSource: String by lazy { source.codeMarkdown() } override val asMarkdownV2Source: String by lazy { source.codeMarkdownV2() } override val asHtmlSource: String by lazy { source.codeHTML() } } + +@Suppress("NOTHING_TO_INLINE") +inline fun code(code: String) = CodeTextSource(code) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/EMailTextSource.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/EMailTextSource.kt index b4355986bf..9fceafd296 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/EMailTextSource.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/EMailTextSource.kt @@ -3,7 +3,10 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.utils.* -class EMailTextSource( +/** + * @see email + */ +data class EMailTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( override val source: String, override val textSources: List ) : MultilevelTextSource { @@ -11,3 +14,10 @@ class EMailTextSource( override val asMarkdownV2Source: String by lazy { emailMarkdownV2(source) } override val asHtmlSource: String by lazy { emailHTML(source) } } + +@Suppress("NOTHING_TO_INLINE") +inline fun email(parts: List) = EMailTextSource(parts.makeString(), parts) +@Suppress("NOTHING_TO_INLINE") +inline fun email(vararg parts: TextSource) = email(parts.toList()) +@Suppress("NOTHING_TO_INLINE") +inline fun email(emailAddress: String) = email(regular(emailAddress)) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/HashTagTextSource.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/HashTagTextSource.kt index 4ff9ddd98a..f7f2787c07 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/HashTagTextSource.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/HashTagTextSource.kt @@ -3,18 +3,30 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.utils.* -private val String.withoutSharp - get() = if (startsWith("#")){ - substring(1) - } else { - this - } - -class HashTagTextSource( +/** + * @see hashtag + */ +data class HashTagTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( override val source: String, override val textSources: List ) : MultilevelTextSource { override val asMarkdownSource: String by lazy { source.hashTagMarkdown() } override val asMarkdownV2Source: String by lazy { hashTagMarkdownV2() } override val asHtmlSource: String by lazy { hashTagHTML() } + + init { + if (!source.startsWith("#")) { + error("HashTag source must starts with #, but actual value is \"$source\"") + } + } } + +@Suppress("NOTHING_TO_INLINE", "EXPERIMENTAL_API_USAGE") +inline fun hashtag(parts: List) = (regular("#") + parts).let { HashTagTextSource(it.makeString(), it) } +@Suppress("NOTHING_TO_INLINE") +inline fun hashtag(vararg parts: TextSource) = hashtag(parts.toList()) +/** + * Without sharp (#) + */ +@Suppress("NOTHING_TO_INLINE") +inline fun hashtag(hashtag: String) = hashtag(regular(hashtag)) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/ItalicTextSource.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/ItalicTextSource.kt index d142936213..8821e1a05b 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/ItalicTextSource.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/ItalicTextSource.kt @@ -3,7 +3,10 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.utils.* -class ItalicTextSource( +/** + * @see italic + */ +data class ItalicTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( override val source: String, override val textSources: List ) : MultilevelTextSource { @@ -11,3 +14,11 @@ class ItalicTextSource( override val asMarkdownV2Source: String by lazy { italicMarkdownV2() } override val asHtmlSource: String by lazy { italicHTML() } } + +@Suppress("NOTHING_TO_INLINE") +inline fun italic(parts: List) = ItalicTextSource(parts.makeString(), parts) +@Suppress("NOTHING_TO_INLINE") +inline fun italic(vararg parts: TextSource) = italic(parts.toList()) +@Suppress("NOTHING_TO_INLINE") +inline fun italic(text: String) = italic(regular(text)) + diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/MentionTextSource.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/MentionTextSource.kt index f3251eea49..0c6a168053 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/MentionTextSource.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/MentionTextSource.kt @@ -1,6 +1,7 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources import dev.inmo.tgbotapi.CommonAbstracts.* +import dev.inmo.tgbotapi.types.MessageEntity.removeLeading import dev.inmo.tgbotapi.utils.* private val String.withoutCommercialAt @@ -10,11 +11,32 @@ private val String.withoutCommercialAt this } -class MentionTextSource( +/** + * @see mention + */ +data class MentionTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( override val source: String, override val textSources: List ) : MultilevelTextSource { override val asMarkdownSource: String by lazy { source.mentionMarkdown() } override val asMarkdownV2Source: String by lazy { mentionMarkdownV2() } override val asHtmlSource: String by lazy { mentionHTML() } + + init { + if (!source.startsWith("@")) { + error("Mention source must starts with @, but actual value is \"$source\"") + } + } } + +@Suppress("NOTHING_TO_INLINE") +inline fun mention(parts: List) = (regular("@") + parts).let { MentionTextSource(it.makeString(), it) } +@Suppress("NOTHING_TO_INLINE") +inline fun mention(vararg parts: TextSource) = mention(parts.toList()) + +/** + * Without leading "@" + */ +@Suppress("NOTHING_TO_INLINE") +inline fun mention(whoToMention: String) = mention(regular(whoToMention)) + diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/PhoneNumberTextSource.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/PhoneNumberTextSource.kt index c3c697ee73..dada89e413 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/PhoneNumberTextSource.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/PhoneNumberTextSource.kt @@ -3,7 +3,10 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.utils.* -class PhoneNumberTextSource( +/** + * @see phone + */ +data class PhoneNumberTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( override val source: String, override val textSources: List ) : MultilevelTextSource { @@ -11,3 +14,11 @@ class PhoneNumberTextSource( override val asMarkdownV2Source: String by lazy { phoneMarkdownV2() } override val asHtmlSource: String by lazy { phoneHTML() } } + +@Suppress("NOTHING_TO_INLINE") +inline fun phone(parts: List) = PhoneNumberTextSource(parts.makeString(), parts) +@Suppress("NOTHING_TO_INLINE") +inline fun phone(vararg parts: TextSource) = phone(parts.toList()) +@Suppress("NOTHING_TO_INLINE") +inline fun phone(number: String) = phone(regular(number)) + diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/PreTextSource.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/PreTextSource.kt index efebe3d252..62e4371746 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/PreTextSource.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/PreTextSource.kt @@ -1,9 +1,12 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources -import dev.inmo.tgbotapi.CommonAbstracts.TextSource +import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.utils.* -class PreTextSource( +/** + * @see pre + */ +data class PreTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( override val source: String, val language: String? = null ) : TextSource { @@ -11,3 +14,7 @@ class PreTextSource( override val asMarkdownV2Source: String by lazy { source.preMarkdownV2(language) } override val asHtmlSource: String by lazy { source.preHTML(language) } } + +@Suppress("NOTHING_TO_INLINE") +inline fun pre(code: String, language: String? = null) = PreTextSource(code, language) + diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/RegularTextSource.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/RegularTextSource.kt index 4439bcaf4d..87807b935d 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/RegularTextSource.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/RegularTextSource.kt @@ -1,12 +1,18 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources -import dev.inmo.tgbotapi.CommonAbstracts.TextSource +import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.utils.* -class RegularTextSource( +/** + * @see regular + */ +data class RegularTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( override val source: String ) : TextSource { override val asMarkdownSource: String by lazy { source.regularMarkdown() } override val asMarkdownV2Source: String by lazy { source.regularMarkdownV2() } override val asHtmlSource: String by lazy { source.regularHtml() } } + +@Suppress("NOTHING_TO_INLINE") +inline fun regular(text: String) = RegularTextSource(text) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/StrikethroughTextSource.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/StrikethroughTextSource.kt index 0d34b23f2a..34a5cb9775 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/StrikethroughTextSource.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/StrikethroughTextSource.kt @@ -3,11 +3,21 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.utils.* -class StrikethroughTextSource( +/** + * @see strikethrough + */ +data class StrikethroughTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( override val source: String, override val textSources: List ) : MultilevelTextSource { override val asHtmlSource: String by lazy { strikethroughHTML() } override val asMarkdownV2Source: String by lazy { strikethroughMarkdownV2() } override val asMarkdownSource: String by lazy { source.strikethroughMarkdown() } -} \ No newline at end of file +} + +@Suppress("NOTHING_TO_INLINE") +inline fun strikethrough(parts: List) = StrikethroughTextSource(parts.makeString(), parts) +@Suppress("NOTHING_TO_INLINE") +inline fun strikethrough(vararg parts: TextSource) = strikethrough(parts.toList()) +@Suppress("NOTHING_TO_INLINE") +inline fun strikethrough(text: String) = strikethrough(regular(text)) \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/TextLinkTextSource.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/TextLinkTextSource.kt index 82bc46c3b3..0a8a3c512b 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/TextLinkTextSource.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/TextLinkTextSource.kt @@ -1,9 +1,12 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources -import dev.inmo.tgbotapi.CommonAbstracts.TextSource +import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.utils.* -class TextLinkTextSource( +/** + * @see link + */ +data class TextLinkTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( override val source: String, val url: String ) : TextSource { @@ -11,3 +14,6 @@ class TextLinkTextSource( override val asMarkdownV2Source: String by lazy { source.linkMarkdownV2(url) } override val asHtmlSource: String by lazy { source.linkHTML(url) } } + +@Suppress("NOTHING_TO_INLINE") +inline fun link(text: String, url: String) = TextLinkTextSource(text, url) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/TextMentionTextSource.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/TextMentionTextSource.kt index f71cb532dc..086e232510 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/TextMentionTextSource.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/TextMentionTextSource.kt @@ -4,7 +4,10 @@ import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.types.User import dev.inmo.tgbotapi.utils.* -class TextMentionTextSource( +/** + * @see mention + */ +data class TextMentionTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( override val source: String, val user: User, override val textSources: List @@ -13,3 +16,10 @@ class TextMentionTextSource( override val asMarkdownV2Source: String by lazy { textMentionMarkdownV2(user.id) } override val asHtmlSource: String by lazy { textMentionHTML(user.id) } } + +@Suppress("NOTHING_TO_INLINE") +inline fun mention(parts: List, user: User) = TextMentionTextSource(parts.makeString(), user, parts) +@Suppress("NOTHING_TO_INLINE") +inline fun mention(user: User, vararg parts: TextSource) = mention(parts.toList(), user) +@Suppress("NOTHING_TO_INLINE") +inline fun mention(text: String, user: User) = mention(user, regular(text)) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/URLTextSource.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/URLTextSource.kt index b5763b8538..806d54cde9 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/URLTextSource.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/URLTextSource.kt @@ -1,12 +1,18 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources -import dev.inmo.tgbotapi.CommonAbstracts.TextSource +import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.utils.* -class URLTextSource( +/** + * @see link + */ +data class URLTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( override val source: String ) : TextSource { override val asMarkdownSource: String by lazy { source.linkMarkdown(source) } override val asMarkdownV2Source: String by lazy { source.linkMarkdownV2(source) } override val asHtmlSource: String by lazy { source.linkHTML(source) } } + +@Suppress("NOTHING_TO_INLINE") +inline fun link(url: String) = URLTextSource(url) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/UnderlineTextSource.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/UnderlineTextSource.kt index 35799730da..ef6250b253 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/UnderlineTextSource.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/MessageEntity/textsources/UnderlineTextSource.kt @@ -3,11 +3,21 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources import dev.inmo.tgbotapi.CommonAbstracts.* import dev.inmo.tgbotapi.utils.* -class UnderlineTextSource( +/** + * @see underline + */ +data class UnderlineTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor ( override val source: String, override val textSources: List ) : MultilevelTextSource { override val asMarkdownSource: String by lazy { source.underlineMarkdown() } override val asMarkdownV2Source: String by lazy { underlineMarkdownV2() } override val asHtmlSource: String by lazy { underlineHTML() } -} \ No newline at end of file +} + +@Suppress("NOTHING_TO_INLINE") +inline fun underline(parts: List) = UnderlineTextSource(parts.makeString(), parts) +@Suppress("NOTHING_TO_INLINE") +inline fun underline(vararg parts: TextSource) = underline(parts.toList()) +@Suppress("NOTHING_TO_INLINE") +inline fun underline(text: String) = underline(regular(text)) \ No newline at end of file diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/TextContent.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/TextContent.kt index 33cc9c3319..4fbe499201 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/TextContent.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/message/content/TextContent.kt @@ -1,6 +1,6 @@ package dev.inmo.tgbotapi.types.message.content -import dev.inmo.tgbotapi.CommonAbstracts.FullTextSourcesList +import dev.inmo.tgbotapi.CommonAbstracts.TextSourcesList import dev.inmo.tgbotapi.CommonAbstracts.TextPart import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.requests.send.SendTextMessage @@ -81,4 +81,4 @@ data class TextContent( * Convert its [TextContent.entities] to list of [dev.inmo.tgbotapi.CommonAbstracts.TextSource] * with [dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource] */ -fun TextContent.fullEntitiesList(): FullTextSourcesList = text.fullListOfSubSource(entities).map { it.source } +fun TextContent.fullEntitiesList(): TextSourcesList = text.fullListOfSubSource(entities).map { it.source } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/CaptionAndTextSourcesToText.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/CaptionAndTextSourcesToText.kt index 715c9d41d0..be317d0bf3 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/CaptionAndTextSourcesToText.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/CaptionAndTextSourcesToText.kt @@ -7,7 +7,7 @@ import dev.inmo.tgbotapi.types.message.content.TextContent import dev.inmo.tgbotapi.types.message.content.fullEntitiesList internal fun createFormattedText( - entities: FullTextSourcesList, + entities: TextSourcesList, partLength: Int = textLength.last, mode: ParseMode = MarkdownParseMode ): List { @@ -48,17 +48,17 @@ internal fun createFormattedText( internal fun createMarkdownText( - entities: FullTextSourcesList, + entities: TextSourcesList, partLength: Int = textLength.last ): List = createFormattedText(entities, partLength, MarkdownParseMode) -internal fun FullTextSourcesList.toMarkdownTexts(): List = createMarkdownText( +internal fun TextSourcesList.toMarkdownTexts(): List = createMarkdownText( this, textLength.last ) internal fun TextContent.toMarkdownTexts(): List = fullEntitiesList().toMarkdownTexts() -internal fun FullTextSourcesList.toMarkdownExplanations(): List = createMarkdownText( +internal fun TextSourcesList.toMarkdownExplanations(): List = createMarkdownText( this, explanationLimit.last ) @@ -66,23 +66,23 @@ internal fun ExplainedInput.toMarkdownExplanations(): List = fullEntitie internal fun createMarkdownV2Text( - entities: FullTextSourcesList, + entities: TextSourcesList, partLength: Int = textLength.last ): List = createFormattedText(entities, partLength, MarkdownV2ParseMode) -internal fun FullTextSourcesList.toMarkdownV2Captions(): List = createMarkdownV2Text( +internal fun TextSourcesList.toMarkdownV2Captions(): List = createMarkdownV2Text( this, captionLength.last ) internal fun CaptionedInput.toMarkdownV2Captions(): List = fullEntitiesList().toMarkdownV2Captions() -internal fun FullTextSourcesList.toMarkdownV2Texts(): List = createMarkdownV2Text( +internal fun TextSourcesList.toMarkdownV2Texts(): List = createMarkdownV2Text( this, textLength.last ) internal fun TextContent.toMarkdownV2Texts(): List = fullEntitiesList().toMarkdownV2Texts() -internal fun FullTextSourcesList.toMarkdownV2Explanations(): List = createMarkdownV2Text( +internal fun TextSourcesList.toMarkdownV2Explanations(): List = createMarkdownV2Text( this, explanationLimit.last ) @@ -90,17 +90,17 @@ internal fun ExplainedInput.toMarkdownV2Explanations(): List = fullEntit internal fun createHtmlText( - entities: FullTextSourcesList, + entities: TextSourcesList, partLength: Int = textLength.last ): List = createFormattedText(entities, partLength, HTMLParseMode) -internal fun FullTextSourcesList.toHtmlCaptions(): List = createHtmlText( +internal fun TextSourcesList.toHtmlCaptions(): List = createHtmlText( this, captionLength.last ) internal fun CaptionedInput.toHtmlCaptions(): List = fullEntitiesList().toHtmlCaptions() -internal fun FullTextSourcesList.toHtmlTexts(): List = createHtmlText( +internal fun TextSourcesList.toHtmlTexts(): List = createHtmlText( this, textLength.last ) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/MultilevelTextSourceFormatting.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/MultilevelTextSourceFormatting.kt index 0a8a14ae9b..0c6ed5bf1b 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/MultilevelTextSourceFormatting.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/MultilevelTextSourceFormatting.kt @@ -98,6 +98,16 @@ internal fun MultilevelTextSource.linkHTML( ) = "${textSources.joinSubSourcesHtml()}" +internal fun MultilevelTextSource.optionalPrefix( + mustStartsWith: String, + controlWord: String = mustStartsWith +) = if (source.startsWith(mustStartsWith)) { + "" +} else { + controlWord +} + + internal fun MultilevelTextSource.emailMarkdownV2(address: String): String = linkMarkdownV2("mailto://$address") internal fun MultilevelTextSource.emailHTML(address: String): String = linkHTML("mailto://$address}") @@ -125,18 +135,21 @@ internal fun MultilevelTextSource.underlineHTML(): String = htmlDefault(htmlUnde internal fun MultilevelTextSource.textMentionMarkdownV2(userId: UserId): String = linkMarkdownV2(userId.link) internal fun MultilevelTextSource.textMentionHTML(userId: UserId): String = linkHTML(userId.link) -internal fun MultilevelTextSource.mentionMarkdownV2(): String = "@${textSources.joinSubSourcesMarkdownV2()}" -internal fun MultilevelTextSource.mentionHTML(): String = "@${textSources.joinSubSourcesHtml()}" +internal fun MultilevelTextSource.mentionMarkdownV2(): String = optionalPrefix("@") + textSources.joinSubSourcesMarkdownV2() +internal fun MultilevelTextSource.mentionHTML(): String = optionalPrefix("@") + textSources.joinSubSourcesHtml() -internal fun MultilevelTextSource.hashTagMarkdownV2(): String = "\\#${textSources.joinSubSourcesMarkdownV2()}" -internal fun MultilevelTextSource.hashTagHTML(): String = "#${textSources.joinSubSourcesHtml()}" +internal fun MultilevelTextSource.hashTagMarkdownV2(): String = when { + source.startsWith("\\#") || source.startsWith("#") -> "" + else -> "\\#" +} + textSources.joinSubSourcesMarkdownV2() +internal fun MultilevelTextSource.hashTagHTML(): String = optionalPrefix("#") + textSources.joinSubSourcesHtml() internal fun MultilevelTextSource.phoneMarkdownV2(): String = textSources.joinSubSourcesMarkdownV2() internal fun MultilevelTextSource.phoneHTML(): String = textSources.joinSubSourcesHtml() -internal fun MultilevelTextSource.commandMarkdownV2(): String = "/${textSources.joinSubSourcesMarkdownV2()}" -internal fun MultilevelTextSource.commandHTML(): String = "/${textSources.joinSubSourcesHtml()}" +internal fun MultilevelTextSource.commandMarkdownV2(): String = optionalPrefix("/") + textSources.joinSubSourcesMarkdownV2() +internal fun MultilevelTextSource.commandHTML(): String = optionalPrefix("/") + textSources.joinSubSourcesHtml() diff --git a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/EntitiesTestText.kt b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/EntitiesTestText.kt new file mode 100644 index 0000000000..e754be23b6 --- /dev/null +++ b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/EntitiesTestText.kt @@ -0,0 +1,56 @@ +package dev.inmo.tgbotapi.types.MessageEntity + +import dev.inmo.tgbotapi.CommonAbstracts.TextPart +import dev.inmo.tgbotapi.types.MessageEntity.textsources.* +import kotlin.test.assertTrue + +const val testText = "It is simple hello world with #tag and @mention" +const val formattedV2Text = "It *_is_ ~__simple__~* hello world with \\#tag and @mention" +const val formattedHtmlText = "It is simple hello world with #tag and @mention" +internal val testTextEntities = listOf( + RawMessageEntity( + "bold", + 3, + 9 + ), + RawMessageEntity( + "italic", + 3, + 2 + ), + RawMessageEntity( + "strikethrough", + 6, + 6 + ), + RawMessageEntity( + "underline", + 6, + 6 + ), + RawMessageEntity( + "hashtag", + 30, + 4 + ), + RawMessageEntity( + "mention", + 39, + 6 + ) +) + +fun List.testTextParts() { + assertTrue (first().source is RegularTextSource) + assertTrue (get(1).source is BoldTextSource) + assertTrue (get(2).source is RegularTextSource) + assertTrue (get(3).source is HashTagTextSource) + assertTrue (get(4).source is RegularTextSource) + assertTrue (get(5).source is MentionTextSource) + + val boldSource = get(1).source as BoldTextSource + assertTrue (boldSource.textSources.first() is ItalicTextSource) + assertTrue (boldSource.textSources[1] is RegularTextSource) + assertTrue (boldSource.textSources[2] is StrikethroughTextSource) + assertTrue ((boldSource.textSources[2] as StrikethroughTextSource).textSources.first() is UnderlineTextSource) +} diff --git a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/utils/StringFormattingTests.kt b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/StringFormattingTests.kt similarity index 55% rename from tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/utils/StringFormattingTests.kt rename to tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/StringFormattingTests.kt index 7db4187b1c..b5c16de001 100644 --- a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/utils/StringFormattingTests.kt +++ b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/StringFormattingTests.kt @@ -1,5 +1,9 @@ -package dev.inmo.tgbotapi.utils +package dev.inmo.tgbotapi.types.MessageEntity +import dev.inmo.tgbotapi.CommonAbstracts.TextSource +import dev.inmo.tgbotapi.types.MessageEntity.textsources.* +import dev.inmo.tgbotapi.CommonAbstracts.plus +import dev.inmo.tgbotapi.utils.* import kotlin.test.Test import kotlin.test.assertEquals @@ -33,4 +37,20 @@ class StringFormattingTests { originalHelloWorld.preMarkdown() ) } + + @Test + fun testThatCreatingOfStringWithSimpleDSLWorksCorrectly() { + val sources: List = regular("It ") + + bold(italic("is") + + " " + + strikethrough(underline("simple"))) + + " hello world with " + + hashtag("tag") + + " and " + + mention("mention") + sources.toTextParts().testTextParts() + + assertEquals(formattedV2Text, sources.toMarkdownV2Texts().first()) + assertEquals(formattedHtmlText, sources.toHtmlTexts().first()) + } } diff --git a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/TextPartsCreatingTests.kt b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/TextPartsCreatingTests.kt index afb30a7196..d1721cc2fb 100644 --- a/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/TextPartsCreatingTests.kt +++ b/tgbotapi.core/src/commonTest/kotlin/dev/inmo/tgbotapi/types/MessageEntity/TextPartsCreatingTests.kt @@ -8,42 +8,8 @@ import kotlin.test.* class TextPartsCreatingTests { @Test fun testThatTextWithMultilevelPartsCorrectlyCreating() { - val text = "It is simple hello world" - val formattedV2Text = "It *_is_ ~__simple__~* hello world" - val entities = listOf( - RawMessageEntity( - "bold", - 3, - 9 - ), - RawMessageEntity( - "italic", - 3, - 2 - ), - RawMessageEntity( - "strikethrough", - 6, - 6 - ), - RawMessageEntity( - "underline", - 6, - 6 - ) - ) - - val textParts = entities.asTextParts(text) - - assertTrue (textParts.first().source is RegularTextSource) - assertTrue (textParts[1].source is BoldTextSource) - assertTrue (textParts[2].source is RegularTextSource) - - val boldSource = textParts[1].source as BoldTextSource - assertTrue (boldSource.textSources.first() is ItalicTextSource) - assertTrue (boldSource.textSources[1] is RegularTextSource) - assertTrue (boldSource.textSources[2] is StrikethroughTextSource) - assertTrue ((boldSource.textSources[2] as StrikethroughTextSource).textSources.first() is UnderlineTextSource) + val textParts = testTextEntities.asTextParts(testText) + textParts.testTextParts() assertEquals( formattedV2Text, @@ -53,42 +19,8 @@ class TextPartsCreatingTests { @Test fun testThatTextWithMultilevelPartsCorrectlyCreatingInHtml() { - val text = "It is simple hello world" - val formattedHtmlText = "It is simple hello world" - val entities = listOf( - RawMessageEntity( - "bold", - 3, - 9 - ), - RawMessageEntity( - "italic", - 3, - 2 - ), - RawMessageEntity( - "strikethrough", - 6, - 6 - ), - RawMessageEntity( - "underline", - 6, - 6 - ) - ) - - val textParts = entities.asTextParts(text) - - assertTrue (textParts.first().source is RegularTextSource) - assertTrue (textParts[1].source is BoldTextSource) - assertTrue (textParts[2].source is RegularTextSource) - - val boldSource = textParts[1].source as BoldTextSource - assertTrue (boldSource.textSources.first() is ItalicTextSource) - assertTrue (boldSource.textSources[1] is RegularTextSource) - assertTrue (boldSource.textSources[2] is StrikethroughTextSource) - assertTrue ((boldSource.textSources[2] as StrikethroughTextSource).textSources.first() is UnderlineTextSource) + val textParts = testTextEntities.asTextParts(testText) + textParts.testTextParts() assertEquals( formattedHtmlText, diff --git a/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/BotExtensions.kt b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/BotExtensions.kt index f3f02d62a2..c931181091 100644 --- a/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/BotExtensions.kt +++ b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/BotExtensions.kt @@ -8,12 +8,22 @@ import io.ktor.client.HttpClient import io.ktor.client.HttpClientConfig import io.ktor.client.engine.* +/** + * Allows to create bot using bot [urlsKeeper] + */ +fun telegramBot( + urlsKeeper: TelegramAPIUrlsKeeper +): TelegramBot = KtorRequestsExecutor( + urlsKeeper, + HttpClient() +) + /** * Allows to create bot using bot [urlsKeeper] and already prepared [client] */ fun telegramBot( urlsKeeper: TelegramAPIUrlsKeeper, - client: HttpClient = HttpClient() + client: HttpClient ): TelegramBot = KtorRequestsExecutor( urlsKeeper, client @@ -60,6 +70,15 @@ inline fun telegramBot( HttpClient(clientConfig) ) +/** + * Allows to create bot using bot [token], [apiUrl] (for custom api servers) and already prepared [client] + */ +@Suppress("NOTHING_TO_INLINE") +inline fun telegramBot( + token: String, + apiUrl: String = telegramBotAPIDefaultUrl +): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, apiUrl)) + /** * Allows to create bot using bot [token], [apiUrl] (for custom api servers) and already prepared [client] */ @@ -67,7 +86,7 @@ inline fun telegramBot( inline fun telegramBot( token: String, apiUrl: String = telegramBotAPIDefaultUrl, - client: HttpClient = HttpClient() + client: HttpClient ): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, apiUrl), client) @Suppress("NOTHING_TO_INLINE") @@ -106,7 +125,7 @@ inline fun telegramBot( inline fun telegramBot( token: String, apiUrl: String = telegramBotAPIDefaultUrl, - noinline clientConfig: HttpClientConfig<*>.() -> Unit = {} + noinline clientConfig: HttpClientConfig<*>.() -> Unit ) = telegramBot( TelegramAPIUrlsKeeper(token, apiUrl), clientConfig diff --git a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/formatting/ResendingTextFormatting.kt b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/formatting/ResendingTextFormatting.kt index 68fbaf58fb..a459574b13 100644 --- a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/formatting/ResendingTextFormatting.kt +++ b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/formatting/ResendingTextFormatting.kt @@ -7,7 +7,7 @@ import dev.inmo.tgbotapi.types.message.content.TextContent import dev.inmo.tgbotapi.types.message.content.fullEntitiesList fun createFormattedText( - entities: FullTextSourcesList, + entities: TextSourcesList, partLength: Int = textLength.last, mode: ParseMode = MarkdownParseMode ): List { @@ -48,23 +48,23 @@ fun createFormattedText( fun createMarkdownText( - entities: FullTextSourcesList, + entities: TextSourcesList, partLength: Int = textLength.last ): List = createFormattedText(entities, partLength, MarkdownParseMode) -fun FullTextSourcesList.toMarkdownCaptions(): List = createMarkdownText( +fun TextSourcesList.toMarkdownCaptions(): List = createMarkdownText( this, captionLength.last ) fun CaptionedInput.toMarkdownCaptions(): List = fullEntitiesList().toMarkdownCaptions() -fun FullTextSourcesList.toMarkdownTexts(): List = createMarkdownText( +fun TextSourcesList.toMarkdownTexts(): List = createMarkdownText( this, textLength.last ) fun TextContent.toMarkdownTexts(): List = fullEntitiesList().toMarkdownTexts() -fun FullTextSourcesList.toMarkdownExplanations(): List = createMarkdownText( +fun TextSourcesList.toMarkdownExplanations(): List = createMarkdownText( this, explanationLimit.last ) @@ -72,23 +72,23 @@ fun ExplainedInput.toMarkdownExplanations(): List = fullEntitiesList().t fun createMarkdownV2Text( - entities: FullTextSourcesList, + entities: TextSourcesList, partLength: Int = textLength.last ): List = createFormattedText(entities, partLength, MarkdownV2ParseMode) -fun FullTextSourcesList.toMarkdownV2Captions(): List = createMarkdownV2Text( +fun TextSourcesList.toMarkdownV2Captions(): List = createMarkdownV2Text( this, captionLength.last ) fun CaptionedInput.toMarkdownV2Captions(): List = fullEntitiesList().toMarkdownV2Captions() -fun FullTextSourcesList.toMarkdownV2Texts(): List = createMarkdownV2Text( +fun TextSourcesList.toMarkdownV2Texts(): List = createMarkdownV2Text( this, textLength.last ) fun TextContent.toMarkdownV2Texts(): List = fullEntitiesList().toMarkdownV2Texts() -fun FullTextSourcesList.toMarkdownV2Explanations(): List = createMarkdownV2Text( +fun TextSourcesList.toMarkdownV2Explanations(): List = createMarkdownV2Text( this, explanationLimit.last ) @@ -96,23 +96,23 @@ fun ExplainedInput.toMarkdownV2Explanations(): List = fullEntitiesList() fun createHtmlText( - entities: FullTextSourcesList, + entities: TextSourcesList, partLength: Int = textLength.last ): List = createFormattedText(entities, partLength, HTMLParseMode) -fun FullTextSourcesList.toHtmlCaptions(): List = createHtmlText( +fun TextSourcesList.toHtmlCaptions(): List = createHtmlText( this, captionLength.last ) fun CaptionedInput.toHtmlCaptions(): List = fullEntitiesList().toHtmlCaptions() -fun FullTextSourcesList.toHtmlTexts(): List = createHtmlText( +fun TextSourcesList.toHtmlTexts(): List = createHtmlText( this, textLength.last ) fun TextContent.toHtmlTexts(): List = fullEntitiesList().toHtmlTexts() -fun FullTextSourcesList.toHtmlExplanations(): List = createHtmlText( +fun TextSourcesList.toHtmlExplanations(): List = createHtmlText( this, explanationLimit.last )